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 __init__(self, parent, center, size_tuple, rotation=Quaternion(1, (0, 0, 0))): self.parent = parent self.center = center self.size = size_tuple self.rotation = rotation self.normals = [(1, 0, 0), (0, -1, 0), (0, 0, 1), (-1, 0, 0), (0, 1, 0), (0, 0, -1)] self.points = [(self.size[0], self.size[1], self.size[2]), (self.size[0], self.size[1], -self.size[2]), (self.size[0], -self.size[1], self.size[2]), (self.size[0], -self.size[1], -self.size[2]), (-self.size[0], self.size[1], self.size[2]), (-self.size[0], self.size[1], -self.size[2]), (-self.size[0], -self.size[1], self.size[2]), (-self.size[0], -self.size[1], -self.size[2])] self.faces = [ Mesh.Face((self.points[0], self.points[1], self.points[2], self.points[3])), Mesh.Face((self.points[4], self.points[5], self.points[6], self.points[7])), Mesh.Face((self.points[0], self.points[1], self.points[4], self.points[5])), Mesh.Face((self.points[2], self.points[3], self.points[6], self.points[7])), Mesh.Face((self.points[0], self.points[2], self.points[4], self.points[6])), Mesh.Face((self.points[1], self.points[3], self.points[5], self.points[7])), ]
def __init__(self, position, rotation = Quaternion.identity(), scale = (1,1,1), main = True, resolution = (1200, 600)): self.transform = Transform(self, position, rotation, scale) if main == True or len(all_cameras)==0: for cam in all_cameras: cam.main = False self.main = True all_cameras.append(self) global main_camera main_camera = self self.parent = None self.clip_min = 0.1 self.clip_max = 100 self.resolution = resolution self.aspect_ratio = resolution[0]/resolution[1] self.FOV = 120 # tg(FOV/2) = tg(FOV_vertical/2)*aspect_ratio self.FOV_vertical = math.degrees(math.atan((math.tan(math.radians(self.FOV/2))/self.aspect_ratio)))*2 self.middle_pixel = (int(vector2.scale(main_camera.resolution, (1/2))[0]), int(vector2.scale(main_camera.resolution, (1/2))[1])) self.left_top_pixel = (0,0) self.right_top_pixel = (self.resolution[0],0) self.left_bottom_pixel = (0, self.resolution[1]) self.right_bottom_pixel = (self.resolution[0], self.resolution[1]) self._clipping_plane_manager = ClippingPlaneManager(self)
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 __init__(self, position, rotation=Quaternion(1, (0, 0, 0)), scale=(1, 1, 1), mesh=None, collider=None, name="Default", material=None, parent=None): self.parent = parent self.transform = Transform(self, position, rotation, scale) if not material: self.material = Color.default_material else: self.material = material self.mesh = mesh if self.mesh: self.mesh.parent = self for face in self.mesh.faces_init: face.material = self.material for face in self.mesh.faces: face.material = self.material self.collider = collider if mesh and not collider: self.Calculate_collider() self.transform._update_mesh_() self.rigidbody = Rigidbody(self) if self.mesh == None: name = "Empty" self.name = None for obj in objects: if obj.name == name: i = 1 name = name + "[" + str(i) + "]" self.name = name if not self.name: self.name = name objects.append(self)
def __init__(self, position, rotation = Quaternion(1,(0,0,0)), scale = (1,1,1)): self.transform = Transform(self, position, rotation, scale) self.edges_init = [] self.vertices_init = [] self.vertices_init.append(vector3.add((0.5,0.5,0.5), self.transform.position)) self.vertices_init.append(vector3.add((0.5,-0.5,0.5), self.transform.position)) self.vertices_init.append(vector3.add((-0.5,-0.5,0.5), self.transform.position)) self.vertices_init.append(vector3.add((-0.5,0.5,0.5), self.transform.position)) self.vertices_init.append(vector3.add((0.5,0.5,-0.5), self.transform.position)) self.vertices_init.append(vector3.add((0.5,-0.5,-0.5), self.transform.position)) self.vertices_init.append(vector3.add((-0.5,-0.5,-0.5), self.transform.position)) self.vertices_init.append(vector3.add((-0.5,0.5,-0.5), self.transform.position)) self.edges_init.append(Edge(self.vertices_init[0], self.vertices_init[1])) self.edges_init.append(Edge(self.vertices_init[1], self.vertices_init[2])) self.edges_init.append(Edge(self.vertices_init[2], self.vertices_init[3])) self.edges_init.append(Edge(self.vertices_init[3], self.vertices_init[0])) self.edges_init.append(Edge(self.vertices_init[4], self.vertices_init[5])) self.edges_init.append(Edge(self.vertices_init[5], self.vertices_init[6])) self.edges_init.append(Edge(self.vertices_init[6], self.vertices_init[7])) self.edges_init.append(Edge(self.vertices_init[7], self.vertices_init[4])) self.edges_init.append(Edge(self.vertices_init[0], self.vertices_init[4])) self.edges_init.append(Edge(self.vertices_init[1], self.vertices_init[5])) self.edges_init.append(Edge(self.vertices_init[2], self.vertices_init[6])) self.edges_init.append(Edge(self.vertices_init[3], self.vertices_init[7])) self.edges = [] self.vertices = [] for edge in self.edges_init: A = edge.A B = edge.B self.edges.append(Edge(A, B)) for vertex in self.vertices_init: self.vertices.append(vertex) # if rotation.struct !=(1,0,0,0): # self.transform.Rotate(rotation = 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 Set_collider(self, center, size, rotation=Quaternion(1, (0, 0, 0))): self.collider = Collider.Box_collider(self, center, size, rotation)
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
def Import_obj(obj_file, position, rotation=Quaternion(1, (0, 0, 0)), scale=(1, 1, 1)): path = "models/" + obj_file obj_lines = open(path, "r").readlines() vertices = [] edges = [] normals = [] faces = [] for line in obj_lines: if line[0] == "v" and line[1] == " ": vertex_coords = [] value = "" for sign in line: if ord(sign) == 45 or (ord(sign) >= 48 and ord(sign) <= 57) or ord(sign) == 46: value += sign if ord(sign) == 32 and len(value) > 0: vertex_coords.append(float(value)) value = "" vertex_coords.append(float(value)) vertex = tuple(vertex_coords) vertices.append(vertex) if line[0] == "v" and line[1] == "n" and line[2] == " ": normal_coords = [] value = "" for sign in line: if ord(sign) == 45 or (ord(sign) >= 48 and ord(sign) <= 57) or ord(sign) == 46: value += sign if ord(sign) == 32 and len(value) > 0: normal_coords.append(float(value)) value = "" normal_coords.append(float(value)) normal = tuple(normal_coords) normals.append(normal) if line[0] == "f" and line[1] == " ": vertex_list = [] value = "" slash_passed = False for sign in line: if ord(sign) == 45 or (ord(sign) >= 48 and ord(sign) <= 57) or ord(sign) == 46: value += sign if ord(sign) == 47 and len(value) > 0: if not slash_passed: vertex_list.append(vertices[int(value) - 1]) slash_passed = True value = "" if ord(sign) == 32 and len(value) > 0: slash_passed = False normal = normals[int(value) - 1] value = "" faces.append(Mesh.Face(vertex_list, normal)) face_edges = [] if len(vertex_list) == 4: face_edges.append(Mesh.Edge(vertex_list[0], vertex_list[1])) face_edges.append(Mesh.Edge(vertex_list[1], vertex_list[2])) face_edges.append(Mesh.Edge(vertex_list[2], vertex_list[3])) face_edges.append(Mesh.Edge(vertex_list[3], vertex_list[0])) # print("Only triangles accepted") else: face_edges.append(Mesh.Edge(vertex_list[0], vertex_list[1])) face_edges.append(Mesh.Edge(vertex_list[1], vertex_list[2])) face_edges.append(Mesh.Edge(vertex_list[2], vertex_list[0])) for face_edge in face_edges: already_exists = False for edge in edges: if edge.A == face_edge.A and edge.B == face_edge.B: already_exists = True break if edge.A == face_edge.B and edge.B == face_edge.A: already_exists = True break if not already_exists: edges.append(face_edge) mesh = Mesh.Mesh(None, vertices, edges, faces) obj = Mesh.Object(position, rotation, scale, mesh) name = "" for i in range(0, len(obj_file) - 4): name += obj_file[i] obj.name = name return obj