def test_matrix_inversion(mat4): # Confirm `__invert__` method matches long hand utility method: inverse_1 = inverse(mat4) inverse_2 = ~mat4 assert round(inverse_1, 9) == round(inverse_2, 9) # Confirm that Matrix @ its inverse == identity Matrix: assert round(mat4 @ inverse_1, 9) == Mat4() assert round(mat4 @ inverse_2, 9) == Mat4()
def _set_modelview_matrix(self): # NOTE: Matrix operations can be optimized later with transform feedback translate = Mat4.from_translation(*self.translation) rotate_x = Mat4().rotate(radians(self.rotation[0]), x=1) rotate_y = Mat4().rotate(radians(self.rotation[1]), y=1) rotate_z = Mat4().rotate(radians(self.rotation[2]), z=1) view = rotate_z @ rotate_y @ rotate_x @ translate with self.program.uniform_buffers['WindowBlock'] as window_block: window_block.view[:] = view
def update(self): width = max(1, self.view_port.width) height = max(1, self.view_port.height) pyglet.gl.glViewport(0, 0, width, height) with self.program.uniform_buffers['WindowBlock'] as window_block: window_block.projection[:] = Mat4.orthogonal_projection( self.clip_port.left, self.clip_port.right, self.clip_port.bottom, self.clip_port.top, -MAX_Z_DEPTH, MAX_Z_DEPTH) if not self._view: # Set view to Identity Matrix self._view = Mat4() window_block.view[:] = self._view
def row_swap(matrix, r1, r2): lo = min(r1, r2) hi = max(r1, r2) values = (matrix[:lo * 4] + matrix[hi * 4:hi * 4 + 4] + matrix[lo * 4 + 4:hi * 4] + matrix[lo * 4:lo * 4 + 4] + matrix[hi * 4 + 4:]) return Mat4(values)
class BaseMaterialGroup(graphics.Group): default_vert_src = None default_frag_src = None matrix = Mat4() def __init__(self, material, program, order=0, parent=None): super().__init__(order, parent) self.material = material self.program = program
def set_modelview_matrix(self): # NOTE: Matrix operations can be optimized later with transform feedback view = Mat4() view = view.rotate(radians(self.rotation[2]), z=1) view = view.rotate(radians(self.rotation[1]), y=1) view = view.rotate(radians(self.rotation[0]), x=1) view = view.translate(*self.translation) self.program['view'] = view
def set_modelview_matrix(self): # NOTE: Matrix operations can be optimized later with transform feedback view = Mat4() view = view.rotate(radians(self.rotation[2]), z=1) view = view.rotate(radians(self.rotation[1]), y=1) view = view.rotate(radians(self.rotation[0]), x=1) view = view.translate(*self.translation) with graphics.get_default_shader( ).uniform_buffers['WindowBlock'] as window_block: window_block.view[:] = view
def set_modelview_matrix(self): # NOTE: Matrix operations can be optimized later with transform feedback view = Mat4() view = view.rotate(radians(self.rotation[2]), Vec3(0, 0, 1)) view = view.rotate(radians(self.rotation[1]), Vec3(0, 1, 0)) view = view.rotate(radians(self.rotation[0]), Vec3(1, 0, 0)) view = view.translate(self.translation) # TODO: separate the projection block, and remove this hack block = self.program.uniform_blocks['WindowBlock'] ubo = block.create_ubo(0) with ubo as window_block: window_block.projection[:] = pyglet.math.Mat4.perspective_projection(0, 720, 0, 480, z_near=0.1, z_far=255) window_block.view[:] = view
def inverse(matrix): """The inverse of a Matrix. Using Gauss-Jordan elimination, the matrix supplied is transformed into the identity matrix using a sequence of elementary row operations (below). The same sequence of operations is applied to the identity matrix, transforming it into the supplied matrix's inverse. Elementary row operations: - multiply row by a scalar - swap two rows - add two rows together""" i = Mat4() # identity matrix # The pivot in each column is the element at Matrix[c, c] (diagonal elements). # The pivot row is the row containing the pivot element. Pivot elements must # be non-zero. # Any time matrix is changed, so is i. for c in range(4): # Find and swap pivot row into place if matrix[4 * c + c] == 0: for r in range(c + 1, 4): if matrix[4 * r + c] != 0: matrix = row_swap(matrix, c, r) i = row_swap(i, c, r) # Make 0's in column for rows that aren't pivot row for r in range(4): if r != c: # not the pivot row r_piv = matrix[4 * r + c] if r_piv != 0: piv = matrix[4 * c + c] scalar = r_piv / piv matrix = row_mul(matrix, c, scalar) matrix = row_sub(matrix, c, r) i = row_mul(i, c, scalar) i = row_sub(i, c, r) # Put matrix in reduced row-echelon form. piv = matrix[4 * c + c] matrix = row_mul(matrix, c, 1 / piv) i = row_mul(i, c, 1 / piv) return i
def __init__(self, vertex_lists, groups, batch): """Create a model. :Parameters: `vertex_lists` : list A list of `~pyglet.graphics.VertexList` or `~pyglet.graphics.IndexedVertexList`. `groups` : list A list of `~pyglet.model.TexturedMaterialGroup`, or `~pyglet.model.MaterialGroup`. Each group corresponds to a vertex list in `vertex_lists` of the same index. `batch` : `~pyglet.graphics.Batch` Optional batch to add the model to. If no batch is provided, the model will maintain its own internal batch. """ self.vertex_lists = vertex_lists self.groups = groups self._batch = batch self._modelview_matrix = Mat4()
def test_creation_from_list(mat4): mat4_from_list = Mat4([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]) assert mat4_from_list == mat4
def row_mul(matrix, r, x): values = (matrix[:r * 4] + tuple(v * x for v in matrix[r * 4:r * 4 + 4]) + matrix[r * 4 + 4:]) return Mat4(values)
def mat4(): return Mat4()