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 (Msterial): 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} } """ self.name = 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()) program["color"].value = (0.75, 0.75, 0.75) 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) bb2 = numpy.append(self.bbox_max[:], 1.0) # Transform the bbox values bmin = matrix44.apply_to_vector(view_matrix, bb1), bmax = matrix44.apply_to_vector(view_matrix, bb2), bmin = numpy.asarray(bmin)[0] bmax = numpy.asarray(bmax)[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