def calc_global_bbox(self, view_matrix, bbox_min, bbox_max): # 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
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
def _plate_nor(self) -> Vector3: x_rot = matrix44.create_from_axis_rotation(axis=X_AXIS, theta=self.plate_theta_x) y_rot = matrix44.create_from_axis_rotation(axis=Y_AXIS, theta=self.plate_theta_y) # pitch then roll nor = matrix44.apply_to_vector(mat=x_rot, vec=Z_AXIS) nor = matrix44.apply_to_vector(mat=y_rot, vec=nor) nor = vector.normalize(nor) return Vector3(nor)
def test_procedural_examples(self): from pyrr import quaternion, matrix44, vector3 import numpy as np point = vector3.create(1.,2.,3.) orientation = quaternion.create() translation = vector3.create() scale = vector3.create(1,1,1) # translate along X by 1 translation += [1.0, 0.0, 0.0] # rotate about Y by pi/2 rotation = quaternion.create_from_y_rotation(np.pi / 2.0) orientation = quaternion.cross(rotation, orientation) # create a matrix # start our matrix off using the scale matrix = matrix44.create_from_scale(scale) # apply our orientation orientation = matrix44.create_from_quaternion(orientation) matrix = matrix44.multiply(matrix, orientation) # apply our translation translation_matrix = matrix44.create_from_translation(translation) matrix = matrix44.multiply(matrix, translation_matrix) # transform our point by the matrix point = matrix44.apply_to_vector(matrix, point)
def apply_test(m, point, inside): p = matrix44.apply_to_vector(m, point) # the values are now in clip space from (-1.,-1.,-1.) -> (1.,1.,1.) # to be inside = all(-1. < value < 1.) self.assertTrue(inside == (np.amax(np.absolute(p[:3])) <= 1.), (inside, point, p))
def world_to_plate(self, x: float, y: float, z: float) -> Vector3: move = matrix44.create_from_translation([ -self.plate.x, -self.plate.y, -(self.plate.z + PLATE_ORIGIN_TO_SURFACE_OFFSET), ]) vec = matrix44.apply_to_vector(mat=move, vec=[x, y, z]) # rotate x_rot = matrix44.create_from_axis_rotation([1.0, 0.0, 0.0], -self.plate_theta_x) y_rot = matrix44.create_from_axis_rotation([0.0, 1.0, 0.0], -self.plate_theta_y) vec = matrix44.apply_to_vector(mat=x_rot, vec=vec) vec = matrix44.apply_to_vector(mat=y_rot, vec=vec) return Vector3(vec)
def apply_test(m, point, inside): p = matrix44.apply_to_vector(m, point) if p[3] == 0.: self.assertFalse(inside) # the values are now in clip space from (-1.,-1.,-1.) -> (1.,1.,1.) # to be inside = all(-1. < value < 1.) self.assertTrue(inside == (np.amax(np.absolute(p[:3])) <= 1.), (inside, point, p))
def test_axis( unittest, transform_space, matrix ): x_axis = matrix44.apply_to_vector( matrix, [1.0, 0.0, 0.0] ) y_axis = matrix44.apply_to_vector( matrix, [0.0, 1.0, 0.0] ) z_axis = matrix44.apply_to_vector( matrix, [0.0, 0.0, 1.0] ) # Object space unittest.assertTrue( numpy.allclose( transform_space.x, x_axis ), "X axis incorrect" ) unittest.assertTrue( numpy.allclose( transform_space.y, y_axis ), "Y axis incorrect" ) unittest.assertTrue( numpy.allclose( transform_space.z, z_axis ), "Z axis incorrect" )
def apply_test(m, point, inside): p = matrix44.apply_to_vector(m, point) if np.allclose(p[3], 0.): self.assertFalse(inside) # the values are now in clip space from (-1.,-1.,-1.) -> (1.,1.,1.) # to be inside = all(-1. < value < 1.) if np.allclose(p[3],0.): p[:] = [np.inf,np.inf,np.inf,np.inf] else: p[:3] /= p[3] self.assertTrue(inside == (np.amax(np.absolute(p[:3])) <= 1.), (inside, point, p))
def test_create_look_at_4(self): m = matrix44.create_look_at( np.array((0.0, 0.0, 0.0)), np.array((0.0, 0.0, -1.0)), np.array((0.0, 1.0, 0.0)), ) x, y, z, _ = matrix44.apply_to_vector(m, (1.0, 0.0, 0.0, 0.0)) self.assertAlmostEqual(x, 1.0) self.assertAlmostEqual(y, 0.0) self.assertAlmostEqual(z, 0.0) x, y, z, _ = matrix44.apply_to_vector(m, (0.0, 1.0, 0.0, 0.0)) self.assertAlmostEqual(x, 0.0) self.assertAlmostEqual(y, 1.0) self.assertAlmostEqual(z, 0.0) x, y, z, _ = matrix44.apply_to_vector(m, (0.0, 0.0, 1.0, 0.0)) self.assertAlmostEqual(x, 0.0) self.assertAlmostEqual(y, 0.0) self.assertAlmostEqual(z, 1.0)
def rotated_z(): mat = matrix44.create_from_z_rotation( math.pi ) vec = vector3.unit.x result = matrix44.apply_to_vector( mat, vec ) expected = -vec self.assertTrue( numpy.allclose( result, expected ), "Matrix44 apply_to_vector incorrect with rotation about Y" )
def identity(): mat = matrix44.create_identity() vec = vector3.unit.x result = matrix44.apply_to_vector( mat, vec ) expected = vec self.assertTrue( numpy.array_equal( result, expected ), "Matrix44 apply_to_vector incorrect with identity" )
def get_near_far_from_view(self, view: Matrix44) -> Tuple[float, float]: nearest_view_z: float = -1000000 farthest_view_z: float = 1000000 for pos in self.extends: view_position = Vector4(matrix44.apply_to_vector(view, pos)) if view_position.z > nearest_view_z: nearest_view_z = view_position.z if view_position.z < farthest_view_z: farthest_view_z = view_position.z if nearest_view_z > 0: nearest_view_z = 0 return nearest_view_z, farthest_view_z
def translation(): mat = matrix44.create_identity() vec = numpy.array([0.0, 0.0, 0.0]) mat[3,0:3] = [1.0, 2.0, 3.0] result = matrix44.apply_to_vector( mat, vec ) expected = mat[3,0:3] self.assertTrue( numpy.allclose( result, expected ), "Matrix44 apply_to_vector incorrect with translation" )
def translation(self): if self._translation == None: if self.parent == None: # we don't have a parent # so just use our current local translation self._translation = self._transform.translation.copy() else: # rotate our translation by our parent's # world orientation # this will include our parent's world translation self._translation = matrix44.apply_to_vector( self.parent.matrix, self._transform.translation) return self._translation
def test_operators_vector4(self): m = Matrix44.identity() v = Vector4([1,1,1,1]) # add self.assertRaises(ValueError, lambda: m + v) # subtract self.assertRaises(ValueError, lambda: m - v) # multiply self.assertTrue(np.array_equal(m * v, matrix44.apply_to_vector(matrix44.create_identity(), [1,1,1,1]))) # divide self.assertRaises(ValueError, lambda: m / v)
def translation( self ): if self._translation == None: if self.parent == None: # we don't have a parent # so just use our current local translation self._translation = self._transform.translation.copy() else: # rotate our translation by our parent's # world orientation # this will include our parent's world translation self._translation = matrix44.apply_to_vector( self.parent.matrix, self._transform.translation ) return self._translation
def test_create_look_at(self): m = matrix44.create_look_at( np.array((300.0, 200.0, 100.0)), np.array((0.0, 0.0, 10.0)), np.array((0.0, 0.0, 1.0)), ) points = [ (-10.0, -10.0, 0.0, 1.0), (-10.0, 10.0, 0.0, 1.0), (10.0, -10.0, 0.0, 1.0), (10.0, 10.0, 0.0, 1.0), (-10.0, -10.0, 20.0, 1.0), (-10.0, 10.0, 20.0, 1.0), (10.0, -10.0, 20.0, 1.0), (10.0, 10.0, 20.0, 1.0), ] for point in points: x, y, z, w = matrix44.apply_to_vector(m, point) self.assertTrue(-20.0 < x and x < 20.0) self.assertTrue(-20.0 < y and y < 20.0) self.assertTrue(z < 0.0) self.assertAlmostEqual(w, 1.0)
def test_apply_to_vector_with_translation(self): mat = matrix44.create_from_translation([2., 3., 4.]) result = matrix44.apply_to_vector(mat, [1., 1., 1.]) np.testing.assert_almost_equal(result, [3., 4., 5.], decimal=5)
def test_apply_to_vector_identity(self): mat = matrix44.create_identity() result = matrix44.apply_to_vector(mat, [1., 0., 0.]) np.testing.assert_almost_equal(result, [1., 0., 0.], decimal=5)
def test_apply_to_vector_z_rotation(self): mat = matrix44.create_from_z_rotation(np.pi) result = matrix44.apply_to_vector(mat, [1., 0., 0.]) np.testing.assert_almost_equal(result, [-1., 0., 0.], decimal=5)
def getEyeSpacePosition(self, light, viewMatrix): position = light.getPosition() eyeSpacePos = Vector4((position[0], position[1], position[2], 1.0)) eyeSpacePos = matrix44.apply_to_vector(viewMatrix, eyeSpacePos) return Vector3((eyeSpacePos[0], eyeSpacePos[1], eyeSpacePos[2]))
def test_apply_to_vector_with_translation(self): mat = matrix44.create_from_translation([2.,3.,4.]) result = matrix44.apply_to_vector(mat, [1.,1.,1.]) np.testing.assert_almost_equal(result, [3.,4.,5.], decimal=5)
def test_apply_to_vector_z_rotation(self): mat = matrix44.create_from_z_rotation(np.pi) result = matrix44.apply_to_vector(mat, [1.,0.,0.]) np.testing.assert_almost_equal(result, [-1.,0.,0.], decimal=5)
def test_apply_to_vector_identity(self): mat = matrix44.create_identity() result = matrix44.apply_to_vector(mat, [1.,0.,0.]) np.testing.assert_almost_equal(result, [1.,0.,0.], decimal=5)