Source code for moderngl_window.scene.mesh

from pyrr import matrix44
import numpy

[docs] class Mesh: """Mesh info and geometry"""
[docs] def __init__( self, name, vao=None, material=None, attributes=None, bbox_min=None, bbox_max=None, ): """Initialize mesh. Args: name (str): name of the mesh Keyword Args: vao (VAO): geometry material (Material): material for the mesh attributes (dict): Details info about each mesh attribute (dict) bbox_min: xyz min values bbox_max: xyz max values Attributes example:: { "NORMAL": {"name": "in_normal", "components": 3, "type": GL_FLOAT}, "POSITION": {"name": "in_position", "components": 3, "type": GL_FLOAT} } """ = name self.vao = vao self.material = material self.attributes = attributes or {} self.bbox_min = bbox_min self.bbox_max = bbox_max self.mesh_program = None
[docs] def draw( self, projection_matrix=None, model_matrix=None, camera_matrix=None, time=0.0 ): """Draw the mesh using the assigned mesh program Keyword Args: projection_matrix (bytes): projection_matrix view_matrix (bytes): view_matrix camera_matrix (bytes): camera_matrix """ if self.mesh_program: self.mesh_program.draw( self, projection_matrix=projection_matrix, model_matrix=model_matrix, camera_matrix=camera_matrix, time=time, )
[docs] def draw_bbox(self, proj_matrix, model_matrix, cam_matrix, program, vao): """Renders the bounding box for this mesh. Args: proj_matrix: Projection matrix model_matrix: View/model matrix cam_matrix: Camera matrix program: The moderngl.Program rendering the bounding box vao: The vao mesh for the bounding box """ program["m_proj"].write(proj_matrix) program["m_model"].write(model_matrix) program["m_cam"].write(cam_matrix) program["bb_min"].write(self.bbox_min.astype("f4").tobytes()) program["bb_max"].write(self.bbox_max.astype("f4").tobytes()) vao.render(program)
[docs] def draw_wireframe(self, proj_matrix, model_matrix, program): """Render the mesh as wireframe. proj_matrix: Projection matrix model_matrix: View/model matrix program: The moderngl.Program rendering the wireframe """ program["m_proj"].write(proj_matrix) program["m_model"].write(model_matrix) self.vao.render(program)
[docs] def add_attribute(self, attr_type, name, components): """ Add metadata about the mesh :param attr_type: POSITION, NORMAL etc :param name: The attribute name used in the program :param components: Number of floats """ self.attributes[attr_type] = {"name": name, "components": components}
[docs] def calc_global_bbox(self, view_matrix, bbox_min, bbox_max): """Calculates the global bounding. Args: view_matrix: View matrix bbox_min: xyz min bbox_max: xyz max Returns: bbox_min, bbox_max: Combined bbox """ # Copy and extend to vec4 bb1 = numpy.append(self.bbox_min[:], 1.0).astype("f4") bb2 = numpy.append(self.bbox_max[:], 1.0).astype("f4") # Transform the bbox values bmin = (matrix44.apply_to_vector(view_matrix, bb1),) bmax = (matrix44.apply_to_vector(view_matrix, bb2),) bmin = numpy.asarray(bmin, dtype="f4")[0] bmax = numpy.asarray(bmax, dtype="f4")[0] # If a rotation happened there is an axis change and we have to ensure max-min is positive for i in range(3): if bmax[i] - bmin[i] < 0: bmin[i], bmax[i] = bmax[i], bmin[i] if bbox_min is None or bbox_max is None: return bmin[0:3], bmax[0:3] for i in range(3): bbox_min[i] = min(bbox_min[i], bmin[i]) for i in range(3): bbox_max[i] = max(bbox_max[i], bmax[i]) return bbox_min, bbox_max
[docs] def has_normals(self) -> bool: """ Returns: bool: Does the mesh have a normals? """ return "NORMAL" in self.attributes
[docs] def has_uvs(self, layer=0) -> bool: """ Returns: bool: Does the mesh have texture coordinates? """ return "TEXCOORD_{}".format(layer) in self.attributes