def _calculate_global_tranform(self): if not self.parent: self._global_transform = self return parent_global_transform = self.parent.get_global_transform() position = vector3.add( parent_global_transform.position, Quaternion.rotate_vector(self.position, parent_global_transform.rotation)) rotation = Quaternion.composite_rotations( self.rotation, parent_global_transform.rotation) scale = Quaternion.rotate_vector(self.scale, parent_global_transform.rotation) obj = self.object transform = Transform(obj, position, rotation, scale) transform.forward = Quaternion.rotate_vector( self.forward, parent_global_transform.rotation) transform.backward = Quaternion.rotate_vector( self.backward, parent_global_transform.rotation) transform.right = Quaternion.rotate_vector( self.right, parent_global_transform.rotation) transform.left = Quaternion.rotate_vector( self.left, parent_global_transform.rotation) transform.up = Quaternion.rotate_vector( self.up, parent_global_transform.rotation) transform.down = Quaternion.rotate_vector( self.down, parent_global_transform.rotation) self._global_transform = transform
def Point_collision(box, point): box_center = vector3.add( box.parent.transform.position, Quaternion.rotate_vector(box.center, box.parent.transform.rotation)) rotated_point = Quaternion.rotate_vector( vector3.subtract(point, box_center), box.parent.transform.rotation.conjugate()) if abs(rotated_point[0]) > box.size[0] * box.parent.transform.scale[0]: return False if abs(rotated_point[1]) > box.size[1] * box.parent.transform.scale[1]: return False if abs(rotated_point[2]) > box.size[2] * box.parent.transform.scale[2]: return False return True
def _update_mesh_(self): if not 'mesh' in dir(self.object): return mesh = self.object.mesh if 'vertices' in dir(mesh): for i in range(0, len(mesh.vertices_init)): vertex = vector3.scale_by_vector(mesh.vertices_init[i], self.scale) mesh.vertices[i] = self._rotate_vertex_(vertex) if 'edges' in dir(mesh): for i in range(0, len(mesh.edges_init)): vertex_a = vector3.scale_by_vector(mesh.edges_init[i].A, self.scale) vertex_b = vector3.scale_by_vector(mesh.edges_init[i].B, self.scale) mesh.edges[i].A = self._rotate_vertex_(vertex_a) mesh.edges[i].B = self._rotate_vertex_(vertex_b) if 'faces' in dir(mesh): for i in range(0, len(mesh.faces_init)): for k in range(0, len(mesh.faces_init[i].vertex)): vertex = vector3.scale_by_vector( mesh.faces_init[i].vertex[k], self.scale) mesh.faces[i].vertex[k] = self._rotate_vertex_(vertex) mesh.faces[i].normal = Quaternion.rotate_vector( mesh.faces_init[i].normal, self.rotation)
def Rotate(self, angle=0, axis=(0, 0, 0), rotation=Quaternion(1, (0, 0, 0))): """Rotation of the object""" if axis == (0, 0, 0): self.rotation = Quaternion.composite_rotations( self.rotation, rotation) else: rotQuaternion = Quaternion.from_angle_axis(angle, axis) self.rotation = Quaternion.composite_rotations( self.rotation, rotQuaternion) self._update_mesh_() self.forward = Quaternion.rotate_vector((1, 0, 0), self.rotation) self.backward = vector3.scale(self.forward, -1) self.right = Quaternion.rotate_vector((0, -1, 0), self.rotation) self.left = vector3.scale(self.right, -1) self.up = Quaternion.rotate_vector((0, 0, 1), self.rotation) self.down = vector3.scale(self.up, -1)
def SAT_collision(collider1, collider2): points1 = list(collider1.points) center1 = vector3.add( collider1.parent.transform.position, Quaternion.rotate_vector(collider1.center, collider1.parent.transform.rotation)) for i in range(0, len(points1)): points1[i] = Quaternion.rotate_vector( points1[i], collider1.parent.transform.rotation) points1[i] = vector3.add(points1[i], center1) points2 = list(collider2.points) center2 = vector3.add( collider2.parent.transform.position, Quaternion.rotate_vector(collider2.center, collider2.parent.transform.rotation)) for i in range(0, len(points2)): points2[i] = Quaternion.rotate_vector( points2[i], collider2.parent.transform.rotation) points2[i] = vector3.add(points2[i], center2) for normal in collider1.normals: rotated_normal = Quaternion.rotate_vector( Quaternion.rotate_vector(normal, collider1.rotation), collider1.parent.transform.rotation) min1 = None max1 = None for point in points1: axis_view = vector3.dot(rotated_normal, point) if min1 == None or min1 > axis_view: min1 = axis_view if max1 == None or max1 < axis_view: max1 = axis_view min2 = None max2 = None for point in points2: axis_view = vector3.dot(rotated_normal, point) if min2 == None or min2 > axis_view: min2 = axis_view if max2 == None or max2 < axis_view: max2 = axis_view if min1 > max2 or max1 < min2: return False for normal in collider2.normals: rotated_normal = Quaternion.rotate_vector( Quaternion.rotate_vector(normal, collider2.rotation), collider2.parent.transform.rotation) min1 = None max1 = None for point in points1: axis_view = vector3.dot(rotated_normal, point) if min1 == None or min1 > axis_view: min1 = axis_view if max1 == None or max1 < axis_view: max1 = axis_view min2 = None max2 = None for point in points2: axis_view = vector3.dot(rotated_normal, point) if min2 == None or min2 > axis_view: min2 = axis_view if max2 == None or max2 < axis_view: max2 = axis_view if max1 < min2 or min1 > max2: return False return True
def Local_to_world_space(point, transform): point_rotated = Quaternion.rotate_vector(point, transform.rotation) point_rotated_and_translated = vector3.add(point_rotated, transform.position) return point_rotated_and_translated
def World_to_local_space(point, transform): point_translated = vector3.subtract(point, transform.position) point_translated_and_rotated = Quaternion.rotate_vector(point_translated, transform.rotation.inverse()) return point_translated_and_rotated
def _rotate_vertex_(self, vertex_init): resultant_local_pos = Quaternion.rotate_vector(vertex_init, self.rotation) resultant_global_pos = vector3.add(resultant_local_pos, self.position) return resultant_global_pos