コード例 #1
0
    def custom_test_update(self, dt):

        if self.grab == True:
            self.entities[0].get_transform().set_local_position(
                self.camera.get_local_position() +
                vector3.Vector3(0.0, -2.0, 0.0))
            self.entities[0].get_component(
                "RigidBody").linear_velocity = vector3.Vector3()
            self.entities[0].get_component(
                "RigidBody").angular_velocity = vector3.Vector3()

        self.time = self.time + dt
コード例 #2
0
    def __init__(self, w, h, d):
        super().__init__()

        h_w = w * 0.5
        h_h = h * 0.5
        h_d = d * 0.5

        self.collision_base_points.append(vector3.Vector3(-h_w, -h_h,
                                                          -h_d))  #000
        self.collision_base_points.append(vector3.Vector3(-h_w, -h_h,
                                                          h_d))  #001
        self.collision_base_points.append(vector3.Vector3(-h_w, h_h,
                                                          -h_d))  #010
        self.collision_base_points.append(vector3.Vector3(-h_w, h_h,
                                                          h_d))  #011

        self.collision_base_points.append(vector3.Vector3(h_w, -h_h,
                                                          -h_d))  #100
        self.collision_base_points.append(vector3.Vector3(h_w, -h_h,
                                                          h_d))  #101
        self.collision_base_points.append(vector3.Vector3(h_w, h_h,
                                                          -h_d))  #110
        self.collision_base_points.append(vector3.Vector3(h_w, h_h, h_d))  #111

        self.transformed_collision_points = self.collision_base_points
コード例 #3
0
    def __init__(self, entity=None):

        self.attached_entity = entity
        self.position = vector3.Vector3()
        self.rotation = quaternion.Quaternion()
        self.scale = vector3.Vector3()

        self.result_matrix = matrix4.Matrix4()
        self.rotation_matrix = matrix4.Matrix4()
        self.position_matrix = matrix4.Matrix4()
        self.scale_matrix = matrix4.Matrix4()

        self.need_update = False
        self.childs = []
        self.parent = None
コード例 #4
0
	def __init__(self, scene_mgr):
		self.scene_mgr = scene_mgr
		self.physics_entities = []

		self.gravity = vector3.Vector3(0.0, -9.81, 0.0)

		self.debug_contact = 0.0
コード例 #5
0
    def from_matrix(matrix):
        trace = matrix.m[0][0] + matrix.m[1][1] + matrix.m[2][2]

        if trace > 0.0:
            s = 0.5 / math.sqrt(trace + 1.0)
            m_w = 0.25 / s
            m_x = (matrix.m[1][2] - matrix.m[2][1]) * s
            m_y = (matrix.m[2][0] - matrix.m[0][2]) * s
            m_z = (matrix.m[0][1] - matrix.m[1][0]) * s
        else:
            if matrix.m[0][0] > matrix.m[1][1] and matrix.m[0][0] > matrix.m[
                    2][2]:
                s = math.sqrt(1.0 + matrix.m[0][0] - matrix.m[1][1] -
                              matrix.m[2][2]) * 2.0
                m_w = (matrix.m[1][2] - matrix.m[2][1]) / s
                m_x = 0.25 * s
                m_y = (matrix.m[1][0] + matrix.m[0][1]) / s
                m_z = (matrix.m[2][0] + matrix.m[0][2]) / s
            elif matrix.m[1][1] > matrix.m[2][2]:
                s = math.sqrt(1.0 + matrix.m[1][1] - matrix.m[0][0] -
                              matrix.m[2][2]) * 2.0
                m_w = (matrix.m[2][0] - matrix.m[0][2]) / s
                m_x = (matrix.m[1][0] + matrix.m[0][1]) / s
                m_y = 0.25 * s
                m_z = (matrix.m[2][1] + matrix.m[1][2]) / s
            else:
                s = math.sqrt(1.0 + matrix.m[2][2] - matrix.m[0][0] -
                              matrix.m[1][1]) * 2.0
                m_w = (matrix.m[0][1] - matrix.m[1][0]) / s
                m_x = (matrix.m[2][0] + matrix.m[0][2]) / s
                m_y = (matrix.m[2][1] + matrix.m[1][2]) / s
                m_z = 0.25 * s

        return Quaternion(vector3.Vector3(m_x, m_y, m_z), m_w)
コード例 #6
0
    def update_positions(self, dt):

        if self.awake == False:
            return

        transform = self.attached_entity.transform
        #integrate rotation
        spin = quaternion.Quaternion(self.angular_velocity,
                                     0.0).mul_value(0.5) * transform.rotation
        new_rot = transform.rotation + spin.mul_value(dt)

        self.update_position_from_global_centroid()
        transform.set_local_rotation(new_rot.get_normalized())

        #reset force and torque so that an push doesnt happened forever
        self.force_accumulator = vector3.Vector3()
        self.torque_accumulator = vector3.Vector3()
コード例 #7
0
ファイル: aabb.py プロジェクト: Nophlock/Python-3D-Engine
    def __init__(self,
                 min=vector3.Vector3(),
                 max=vector3.Vector3(),
                 calc_knots=False):
        self.min = min
        self.max = max

        self.projected = {}
        self.projected["min"] = min
        self.projected["max"] = max
        self.projected["base_knots"] = []
        self.projected["transformed_knots"] = []

        if calc_knots:
            self.calculate_knots("base_knots", min, max)
            self.projected["transformed_knots"] = self.projected[
                "base_knots"]  #at the beginning they should be the same
コード例 #8
0
	def mul_vec3(self, vector):
		result = vector3.Vector3()

		result.x = self.m[0][0] * vector.x + self.m[1][0] * vector.y + self.m[2][0] * vector.z
		result.y = self.m[0][1] * vector.x + self.m[1][1] * vector.y + self.m[2][1] * vector.z
		result.z = self.m[0][2] * vector.x + self.m[1][2] * vector.y + self.m[2][2] * vector.z

		return result
コード例 #9
0
    def mul_vector3(self, vec):

        n_w = -self.axis.x * vec.x - self.axis.y * vec.y - self.axis.z * vec.z
        n_x = self.w * vec.x + self.axis.y * vec.z - self.axis.z * vec.y
        n_y = self.w * vec.y + self.axis.z * vec.x - self.axis.x * vec.z
        n_z = self.w * vec.z + self.axis.x * vec.y - self.axis.y * vec.x

        return Quaternion(vector3.Vector3(n_x, n_y, n_z), n_w)
コード例 #10
0
    def __mul__(self, other):
        a = self
        b = other

        n_w = a.w * b.w - a.axis.x * b.axis.x - a.axis.y * b.axis.y - a.axis.z * b.axis.z
        n_x = a.w * b.axis.x + a.axis.x * b.w + a.axis.y * b.axis.z - a.axis.z * b.axis.y
        n_y = a.w * b.axis.y - a.axis.x * b.axis.z + a.axis.y * b.w + a.axis.z * b.axis.x
        n_z = a.w * b.axis.z + a.axis.x * b.axis.y - a.axis.y * b.axis.x + a.axis.z * b.w

        return Quaternion(vector3.Vector3(n_x, n_y, n_z), n_w)
コード例 #11
0
    def get_centroid(self):

        centroid = vector3.Vector3()

        for i in range(len(self.collision_base_points)):
            centroid = centroid + self.collision_base_points[i]

        centroid = centroid * len(self.collision_base_points)

        return centroid
コード例 #12
0
    def get_normalized(self):
        length = self.get_len()

        if (length == 0):
            length = 1.0

        norm_axis = vector3.Vector3(self.axis.x / length, self.axis.y / length,
                                    self.axis.z / length)
        norm_w = self.w / length

        return Quaternion(norm_axis, norm_w)
コード例 #13
0
    def create_box_shape(w, h, d):

        points = []
        vertices = []
        ibo = [0, 1, 3, 2, 0, 4, 5, 1, 0, 4, 6, 7, 5, 7, 3, 2, 6]

        h_w = w * 0.5
        h_h = h * 0.5
        h_d = d * 0.5

        points.append(vector3.Vector3(-h_w, -h_h, -h_d))  #000
        points.append(vector3.Vector3(-h_w, -h_h, h_d))  #001
        points.append(vector3.Vector3(-h_w, h_h, -h_d))  #010
        points.append(vector3.Vector3(-h_w, h_h, h_d))  #011
        points.append(vector3.Vector3(h_w, -h_h, -h_d))  #100
        points.append(vector3.Vector3(h_w, -h_h, h_d))  #101
        points.append(vector3.Vector3(h_w, h_h, -h_d))  #110
        points.append(vector3.Vector3(h_w, h_h, h_d))  #111

        for i in range(8):
            vertices.append(points[i].x)
            vertices.append(points[i].y)
            vertices.append(points[i].z)

        data = {}

        data["vbo"] = {}
        data["vbo"]["type"] = GL_ARRAY_BUFFER
        data["vbo"]["size"] = ctypes.sizeof(GLfloat * len(vertices))
        data["vbo"]["data"] = (GLfloat * len(vertices))(*vertices)
        data["vbo"]["attributes"] = [{}]

        data["vbo"]["attributes"][0]["size"] = 3
        data["vbo"]["attributes"][0]["type"] = GL_FLOAT
        data["vbo"]["attributes"][0]["stride"] = 0
        data["vbo"]["attributes"][0]["offset"] = 0
        data["vbo"]["attributes"][0]["normalized"] = GL_FALSE

        data["ibo"] = {}
        data["ibo"]["type"] = GL_ELEMENT_ARRAY_BUFFER
        data["ibo"]["size"] = ctypes.sizeof(GLuint * len(ibo))
        data["ibo"]["data"] = (GLuint * len(ibo))(*ibo)

        mesh = Mesh("dbg_aabb")

        mesh.get_buffer().clear_buffer()
        mesh.get_buffer().prepare_buffer(GL_LINE_STRIP, len(ibo),
                                         GL_UNSIGNED_INT, data)
        mesh.get_buffer().create_buffer()

        return mesh
コード例 #14
0
ファイル: aabb.py プロジェクト: Nophlock/Python-3D-Engine
    def calculate_aabb_unprojected(self, transform):

        matrix = transform.get_transformation_matrix()

        u_min = vector3.Vector3(math.inf, math.inf, math.inf)
        u_max = vector3.Vector3(-math.inf, -math.inf, -math.inf)

        for i in range(len(self.projected["base_knots"])):
            t_vec = matrix.mul_vec3(self.projected["base_knots"][i])

            u_min.x = min(t_vec.x, u_min.x)
            u_min.y = min(t_vec.y, u_min.y)
            u_min.z = min(t_vec.z, u_min.z)

            u_max.x = max(t_vec.x, u_max.x)
            u_max.y = max(t_vec.y, u_max.y)
            u_max.z = max(t_vec.z, u_max.z)

        self.projected["min"] = u_min
        self.projected["max"] = u_max
        self.calculate_knots("transformed_knots", u_min, u_max)
コード例 #15
0
    def __init__(self, col_shape):
        super().__init__(col_shape)

        self.mass = 1.0
        self.inv_mass = 1.0 / self.mass

        self.damping = 1.0
        self.friction = 0.05

        self.col_shape.calculate_inertia_tensor(self.mass)

        self.world_rotational_inertia = self.col_shape.get_inertia_tensor()
        self.inv_world_rotational_inertia = self.col_shape.get_inverse_inertia_tensor(
        )

        self.local_centroid = self.col_shape.get_centroid()
        self.world_centroid = self.local_centroid

        self.linear_velocity = vector3.Vector3()
        self.angular_velocity = vector3.Vector3()

        self.force_accumulator = vector3.Vector3()
        self.torque_accumulator = vector3.Vector3()
コード例 #16
0
ファイル: aabb.py プロジェクト: Nophlock/Python-3D-Engine
    def calculate_knots(self, index, min, max):

        self.projected[index] = []
        self.projected[index].append(vector3.Vector3(min.x, min.y,
                                                     min.z))  #000
        self.projected[index].append(vector3.Vector3(min.x, min.y,
                                                     max.z))  #001
        self.projected[index].append(vector3.Vector3(min.x, max.y,
                                                     min.z))  #010
        self.projected[index].append(vector3.Vector3(min.x, max.y,
                                                     max.z))  #011
        self.projected[index].append(vector3.Vector3(max.x, min.y,
                                                     min.z))  #100
        self.projected[index].append(vector3.Vector3(max.x, min.y,
                                                     max.z))  #101
        self.projected[index].append(vector3.Vector3(max.x, max.y,
                                                     min.z))  #110
        self.projected[index].append(vector3.Vector3(max.x, max.y,
                                                     max.z))  #111
コード例 #17
0
ファイル: frustum.py プロジェクト: Nophlock/Python-3D-Engine
    def extract_frustum_planes(self, matrix):

        self.planes = []
        m = matrix.m

        #left plane
        a = m[0][3] + m[0][0]
        b = m[1][3] + m[1][0]
        c = m[2][3] + m[2][0]
        d = m[3][3] + m[3][0]

        self.planes.append(plane.Plane(vector3.Vector3(a, b, c), d))

        #right plane
        a = m[0][3] - m[0][0]
        b = m[1][3] - m[1][0]
        c = m[2][3] - m[2][0]
        d = m[3][3] - m[3][0]

        self.planes.append(plane.Plane(vector3.Vector3(a, b, c), d))

        #top plane
        a = m[0][3] + m[0][1]
        b = m[1][3] + m[1][1]
        c = m[2][3] + m[2][1]
        d = m[3][3] + m[3][1]

        self.planes.append(plane.Plane(vector3.Vector3(a, b, c), d))

        #bottom plane
        a = m[0][3] - m[0][1]
        b = m[1][3] - m[1][1]
        c = m[2][3] - m[2][1]
        d = m[3][3] - m[3][1]

        self.planes.append(plane.Plane(vector3.Vector3(a, b, c), d))

        #near plane
        a = m[0][3] + m[0][2]
        b = m[1][3] + m[1][2]
        c = m[2][3] + m[2][2]
        d = m[3][3] + m[3][2]

        self.planes.append(plane.Plane(vector3.Vector3(a, b, c), d))

        #bottom plane
        a = m[0][3] - m[0][2]
        b = m[1][3] - m[1][2]
        c = m[2][3] - m[2][2]
        d = m[3][3] - m[3][2]

        self.planes.append(plane.Plane(vector3.Vector3(a, b, c), d))
コード例 #18
0
ファイル: camera.py プロジェクト: Nophlock/Python-3D-Engine
    def get_mouse_direction(self):
        mx, my = self.key_mapper.get_mouse_position()
        width, height = self.engine.get_size()

        nx = mx / width
        ny = my / height

        nx = nx * 2.0 - 1.0
        ny = ny * 2.0 - 1.0

        ray_clip = vector3.Vector3(nx, ny, -1.0)

        ray_eye = self.inv_perspective_matrix.mul_vec3(ray_clip, 1.0)
        ray_eye.z = -1.0

        ray_world = self.inverse_matrix.mul_vec3(ray_eye, 0.0)

        return ray_world
コード例 #19
0
	def set_look_matrix(self, direction, up_vector = vector3.Vector3(0.0,1.0,0.0)):
		z_axis	= direction
		z_axis.normalize()

		x_axis	= up_vector.cross( z_axis )
		x_axis.normalize()

		y_axis	= z_axis.cross(x_axis)

		self.m[0][0] = x_axis.x
		self.m[1][0] = x_axis.y
		self.m[2][0] = x_axis.z

		self.m[0][1] = y_axis.x
		self.m[1][1] = y_axis.y
		self.m[2][1] = y_axis.z

		self.m[0][2] = z_axis.x
		self.m[1][2] = z_axis.y
		self.m[2][2] = z_axis.z
コード例 #20
0
 def __init__(self, axis=vector3.Vector3(), w=1.0):
     self.axis = axis
     self.w = w
コード例 #21
0
    def load_file(self, file_path):

        mesh_data = {}
        abs_file_path = os.path.abspath(file_path)

        with open(abs_file_path, "rb") as file:
            magic = file.read(16)

            if magic.decode("utf-8") != "INTERQUAKEMODEL\0":
                mesh_data["error"] = "Doesnt match magic"
                return mesh_data

            header = {}
            #reads the header informations
            header["version"] = int.from_bytes(file.read(4), "little")
            header["filesize"] = int.from_bytes(file.read(4), "little")
            header["flags"] = int.from_bytes(file.read(4), "little")
            header["num_text"] = int.from_bytes(file.read(4), "little")
            header["ofs_text"] = int.from_bytes(file.read(4), "little")
            header["num_meshes"] = int.from_bytes(file.read(4), "little")
            header["ofs_meshes"] = int.from_bytes(file.read(4), "little")
            header["num_vertexarr"] = int.from_bytes(file.read(4), "little")
            header["num_vertexes"] = int.from_bytes(file.read(4), "little")
            header["ofs_vertexarr"] = int.from_bytes(file.read(4), "little")
            header["num_triangle"] = int.from_bytes(file.read(4), "little")
            header["ofs_triangle"] = int.from_bytes(file.read(4), "little")
            header["ofs_adjacency"] = int.from_bytes(file.read(4), "little")
            header["num_joints"] = int.from_bytes(file.read(4), "little")
            header["ofs_joints"] = int.from_bytes(file.read(4), "little")
            header["num_poses"] = int.from_bytes(file.read(4), "little")
            header["ofs_poses"] = int.from_bytes(file.read(4), "little")
            header["num_anims"] = int.from_bytes(file.read(4), "little")
            header["ofs_anims"] = int.from_bytes(file.read(4), "little")
            header["num_frames"] = int.from_bytes(file.read(4), "little")
            header["num_framechannels"] = int.from_bytes(
                file.read(4), "little")
            header["ofs_frames"] = int.from_bytes(file.read(4), "little")
            header["ofs_bounds"] = int.from_bytes(file.read(4), "little")
            header["num_comment"] = int.from_bytes(file.read(4), "little")
            header["ofs_comment"] = int.from_bytes(file.read(4), "little")
            header["num_extension"] = int.from_bytes(file.read(4), "little")
            header["ofs_extension"] = int.from_bytes(file.read(4), "little")

            if header["version"] != 2:
                mesh_data[
                    "error"] = "Model is outdated, only Version 2 is supported"
                return mesh_data

            indices = []
            vertex_arrays = []
            meshes = []

            #read the text parts
            file.seek(header["ofs_text"])
            text_blob = file.read(header["num_text"]).decode("utf-8")

            #reads the mesh vertex informations
            file.seek(header["ofs_vertexarr"])

            for i in range(header["num_vertexarr"]):
                vertex_data = {}

                vertex_data["type"] = int.from_bytes(file.read(4), "little")
                vertex_data["flags"] = int.from_bytes(file.read(4), "little")
                vertex_data["format"] = int.from_bytes(file.read(4), "little")
                vertex_data["size"] = int.from_bytes(file.read(4), "little")
                vertex_data["offset"] = int.from_bytes(file.read(4), "little")
                vertex_data["num_entries"] = header[
                    "num_vertexes"] * vertex_data["size"]
                vertex_data["str_type"] = VERTEX_ORDER[i]

                vertex_arrays.append(vertex_data)

            center_of_mass_values = []
            center_of_mass_vector = vector3.Vector3()

            for i in range(len(vertex_arrays)):
                data = []

                file.seek(vertex_arrays[i]["offset"])

                for _ in range(vertex_arrays[i]["num_entries"]):

                    gl_type = VERTEX_FORMAT[vertex_arrays[i]["format"]][0]
                    value = 0

                    if gl_type == GL_FLOAT:
                        (value, ) = struct.unpack("f", file.read(4))
                    elif gl_type == GL_BYTE:
                        value = int.from_bytes(file.read(1),
                                               byteorder="little",
                                               signed=True)
                    elif gl_type == GL_UNSIGNED_BYTE:
                        value = int.from_bytes(file.read(1), "little")
                    elif gl_type == GL_INT:
                        value = int.from_bytes(file.read(4),
                                               "little",
                                               signed=True)
                    elif gl_type == GL_UINT:
                        value = int.from_bytes(file.read(4), "little")
                    else:
                        print("IQM-Loader: Not implemented datatype - ",
                              gl_type)

                    if i == 0:
                        center_of_mass_values.append(value)

                        if len(center_of_mass_values) == 3:
                            center_of_mass_vector = center_of_mass_vector + vector3.Vector3(
                                center_of_mass_values[0],
                                center_of_mass_values[1],
                                center_of_mass_values[2])
                            center_of_mass_values = []

                    data.append(value)

                vertex_arrays[i]["data"] = data

            #calculate the center of mass as a centroid
            center_of_mass_vector = center_of_mass_vector / (
                vertex_arrays[0]["num_entries"] / 3)
            mesh_data["center_of_mass"] = center_of_mass_vector

            #reads the ibo-data
            file.seek(header["ofs_triangle"])

            for i in range(header["num_triangle"]):
                indices.append(int.from_bytes(file.read(4), "little"))
                indices.append(int.from_bytes(file.read(4), "little"))
                indices.append(int.from_bytes(file.read(4), "little"))

            #reads the mesh information to later load them
            file.seek(header["ofs_meshes"])
            base_path = os.path.dirname(file_path)
            tex_pool = self.scene_manager.get_texture_pool()

            for i in range(header["num_meshes"]):
                mesh_informations = {}

                mesh_informations["name"] = int.from_bytes(
                    file.read(4), "little")
                mesh_informations["material"] = int.from_bytes(
                    file.read(4), "little")
                mesh_informations["first_vertex"] = int.from_bytes(
                    file.read(4), "little")
                mesh_informations["num_vertices"] = int.from_bytes(
                    file.read(4), "little")
                mesh_informations["first_triangle"] = int.from_bytes(
                    file.read(4), "little")
                mesh_informations["num_triangle"] = int.from_bytes(
                    file.read(4), "little")
                mesh_informations["str_name"] = self.resolve_name(
                    text_blob, mesh_informations["name"])
                mesh_informations["str_material"] = self.resolve_name(
                    text_blob, mesh_informations["material"])

                tex_pool.load_texture(mesh_informations["str_material"],
                                      base_path,
                                      mesh_informations["str_material"]
                                      )  #load the material texture
                material = Material()
                material.assign_material("diffuse_texture",
                                         mesh_informations["str_material"])

                mesh_informations["material_obj"] = material
                meshes.append(mesh_informations)

            anim_data = self.load_animation(header, file, text_blob)

            if anim_data != None:
                mesh_data["animation_data"] = anim_data

            #reads the stored bbox (should be atleast one)
            mesh_data["bboxes"] = []

            file.seek(header["ofs_bounds"])

            if header["num_frames"] == 0:
                mesh_data["bboxes"].append(AABB())
            else:
                for i in range(header["num_frames"]):
                    (min_x, ) = struct.unpack("f", file.read(4))
                    (min_y, ) = struct.unpack("f", file.read(4))
                    (min_z, ) = struct.unpack("f", file.read(4))

                    (max_x, ) = struct.unpack("f", file.read(4))
                    (max_y, ) = struct.unpack("f", file.read(4))
                    (max_z, ) = struct.unpack("f", file.read(4))

                    (xyradius, ) = struct.unpack("f", file.read(4))
                    (radius, ) = struct.unpack("f", file.read(4))

                    aabb = AABB(vector3.Vector3(min_x, min_y, min_z),
                                vector3.Vector3(max_x, max_y, max_z), True)

                    mesh_data["bboxes"].append(aabb)

        mesh_data["buffers"] = []
        mesh_data["indices"] = indices
        mesh_data["mesh_informations"] = meshes

        for i in range(len(vertex_arrays)):
            buffer = {}
            buffer["size"] = vertex_arrays[i]["size"]
            buffer["data"] = vertex_arrays[i]["data"]
            buffer["data_type"] = VERTEX_FORMAT[vertex_arrays[i]["format"]]

            buffer["normalized"] = GL_FALSE

            if i == 5:
                buffer["normalized"] = GL_TRUE

            mesh_data["buffers"].append(buffer)

        return mesh_data
コード例 #22
0
    def load_animation(self, header, file, text_blob):

        if header["num_anims"] == 0:
            return None

        animation_data = {}
        animation_data["frame_positions"] = []

        joints = []
        poses = []
        animations = []
        frames = []

        #load all joints if we have any
        if header["ofs_joints"] != 0:
            file.seek(header["ofs_joints"])

            for i in range(header["num_joints"]):
                joint = {}

                joint["name"] = self.resolve_name(
                    text_blob, int.from_bytes(file.read(4), "little"))
                joint["parent"] = int.from_bytes(file.read(4),
                                                 byteorder="little",
                                                 signed=True)

                (tx, ) = struct.unpack("f", file.read(4))
                (ty, ) = struct.unpack("f", file.read(4))
                (tz, ) = struct.unpack("f", file.read(4))

                (rx, ) = struct.unpack("f", file.read(4))
                (ry, ) = struct.unpack("f", file.read(4))
                (rz, ) = struct.unpack("f", file.read(4))
                (rw, ) = struct.unpack("f", file.read(4))

                (sx, ) = struct.unpack("f", file.read(4))
                (sy, ) = struct.unpack("f", file.read(4))
                (sz, ) = struct.unpack("f", file.read(4))

                joint["translate"] = vector3.Vector3(tx, ty, tz)
                joint["rotate"] = quaternion.Quaternion(
                    vector3.Vector3(rx, ry, rz), rw).get_normalized()
                joint["scale"] = vector3.Vector3(sx, sy, sz)

                joints.append(joint)

            animation_data["joints"] = joints

        #load all animations if we have any
        if header["ofs_anims"] != 0:
            file.seek(header["ofs_anims"])

            for i in range(header["num_anims"]):
                animation = {}

                animation["name"] = self.resolve_name(
                    text_blob, int.from_bytes(file.read(4), "little"))
                animation["first_frame"] = int.from_bytes(
                    file.read(4), "little")
                animation["num_frames"] = int.from_bytes(
                    file.read(4), "little")

                (framerate, ) = struct.unpack("f", file.read(4))

                animation["framerate"] = framerate
                animation["flags"] = int.from_bytes(file.read(4), "little")

                animations.append(animation)

            animation_data["animations"] = animations

        #load all frame_data and translate them if we have any
        if header["ofs_poses"] != 0:
            file.seek(header["ofs_frames"])

            for i in range(header["num_frames"] * header["num_framechannels"]):
                value = int.from_bytes(file.read(2), "little")

                frames.append(value)

            file.seek(header["ofs_poses"])

            #load all poses, but in raw, since we need to modify/stretch them to match them witch all animation we will have
            for i in range(header["num_poses"]):
                pose = {}

                pose["parent"] = int.from_bytes(file.read(4),
                                                byteorder="little",
                                                signed=True)
                pose["channel_mask"] = int.from_bytes(file.read(4), "little")

                channel_offset = []
                channel_scale = []

                for i in range(10):
                    (val, ) = struct.unpack("f", file.read(4))
                    channel_offset.append(val)

                for i in range(10):
                    (val, ) = struct.unpack("f", file.read(4))
                    channel_scale.append(val)

                pose[
                    "channel_offset"] = channel_offset  #translation, rotation, scale
                pose["channel_scale"] = channel_scale
                poses.append(pose)

            animation_data["poses"] = poses
            frame_index = 0

            #remap all our animation data
            for i in range(header["num_frames"]):
                animation_data["frame_positions"].append([])

                for j in range(header["num_poses"]):

                    channel_mask = poses[j]["channel_mask"]
                    channel_offset = poses[j]["channel_offset"]
                    channel_scale = poses[j]["channel_scale"]

                    translate = vector3.Vector3()
                    scale = vector3.Vector3()

                    translate.x, frame_index = self.extract_frame_data(
                        channel_offset, channel_mask, channel_scale, frames,
                        frame_index, 0)
                    translate.y, frame_index = self.extract_frame_data(
                        channel_offset, channel_mask, channel_scale, frames,
                        frame_index, 1)
                    translate.z, frame_index = self.extract_frame_data(
                        channel_offset, channel_mask, channel_scale, frames,
                        frame_index, 2)

                    rx, frame_index = self.extract_frame_data(
                        channel_offset, channel_mask, channel_scale, frames,
                        frame_index, 3)
                    ry, frame_index = self.extract_frame_data(
                        channel_offset, channel_mask, channel_scale, frames,
                        frame_index, 4)
                    rz, frame_index = self.extract_frame_data(
                        channel_offset, channel_mask, channel_scale, frames,
                        frame_index, 5)
                    rw, frame_index = self.extract_frame_data(
                        channel_offset, channel_mask, channel_scale, frames,
                        frame_index, 6)

                    scale.x, frame_index = self.extract_frame_data(
                        channel_offset, channel_mask, channel_scale, frames,
                        frame_index, 7)
                    scale.y, frame_index = self.extract_frame_data(
                        channel_offset, channel_mask, channel_scale, frames,
                        frame_index, 8)
                    scale.z, frame_index = self.extract_frame_data(
                        channel_offset, channel_mask, channel_scale, frames,
                        frame_index, 9)

                    rotation = quaternion.Quaternion(
                        vector3.Vector3(rx, ry, rz), rw
                    )  #we need to assign it here with the constructor, otherwise everything explodes for some reason ...

                    animation_data["frame_positions"][i].append({
                        "pose":
                        poses[j],
                        "translate":
                        translate,
                        "rotate":
                        rotation,
                        "scale":
                        scale
                    })

        return animation_data
コード例 #23
0
 def get_z_vector(self):
     return vector3.Vector3(self.m[0][2], self.m[1][2], self.m[2][2])
コード例 #24
0
 def get_y_vector(self):
     return vector3.Vector3(self.m[0][1], self.m[1][1], self.m[2][1])
コード例 #25
0
 def get_x_vector(self):
     return vector3.Vector3(self.m[0][0], self.m[1][0], self.m[2][0])
コード例 #26
0
    def look_at(direction, up_vector=vector3.Vector3(0.0, 1.0, 0.0)):
        matrix = matrix4.Matrix4()
        matrix.set_Look_matrix(direction, up_vector)

        return Quaternion.from_matrix(matrix)
コード例 #27
0
    def look_at(self, direction, up_vector=vector3.Vector3(0.0, 1.0, 0.0)):
        self.rotation_matrix.set_look_matrix(direction, up_vector)
        self.rotation = quaternion.Quaternion.from_matrix(self.rotation_matrix)
        self.rotation_matrix = self.rotation.to_matrix()

        self.need_update = True
コード例 #28
0
ファイル: epa.py プロジェクト: Nophlock/Python-3D-Engine
    def get_penetration_data(simplex_points, polygon_a, mat_a, polygon_b,
                             mat_b):

        a = simplex_points[0]
        b = simplex_points[1]
        c = simplex_points[2]
        d = simplex_points[3]

        faces = []

        for i in range(EPA_MAX_NUM_FACES):
            pack = [a, b, c, vector3.Vector3()]

            faces.append(pack)

        faces[0] = [
            a, b, c, (b[VECTOR] - a[VECTOR]).cross(c[VECTOR] -
                                                   a[VECTOR]).get_normalized()
        ]  #abc
        faces[1] = [
            a, c, d, (c[VECTOR] - a[VECTOR]).cross(d[VECTOR] -
                                                   a[VECTOR]).get_normalized()
        ]  #acd
        faces[2] = [
            a, d, b, (d[VECTOR] - a[VECTOR]).cross(b[VECTOR] -
                                                   a[VECTOR]).get_normalized()
        ]  #adb
        faces[3] = [
            b, d, c, (d[VECTOR] - b[VECTOR]).cross(c[VECTOR] -
                                                   b[VECTOR]).get_normalized()
        ]  #bdc

        num_faces = 4
        closest_face = 0

        for iteration in range(EPA_MAX_NUM_ITERATIONS):

            min_dist = faces[0][0][VECTOR].dot(faces[0][3])
            closest_face = 0

            for i in range(1, num_faces):
                dist = faces[i][0][VECTOR].dot(faces[i][3])

                if dist < min_dist:
                    min_dist = dist
                    closest_face = i

            search_dir = faces[closest_face][3]
            p = gjk.GJK.support_function(polygon_a, polygon_b, search_dir)

            if p[VECTOR].dot(search_dir) - min_dist < EPA_TOLERANCE:
                break

            loose_edges = []
            for i in range(EPA_MAX_NUM_LOOSE_EDGES):
                loose_edges.append([0, 0])

            num_loose_edges = 0
            i = 0

            while i < num_faces:

                if faces[i][3].dot(p[VECTOR] - faces[i][0][VECTOR]) > 0:

                    for j in range(3):

                        current_edge = [faces[i][j], faces[i][(j + 1) % 3]]
                        found_edge = False
                        k = 0

                        while k < num_loose_edges:

                            if loose_edges[k][1] == current_edge[
                                    0] and loose_edges[k][0] == current_edge[1]:
                                loose_edges[k][0] = loose_edges[num_loose_edges
                                                                - 1][0]
                                loose_edges[k][1] = loose_edges[num_loose_edges
                                                                - 1][1]
                                num_loose_edges = num_loose_edges - 1

                                found_edge = True
                                k = num_loose_edges

                            k = k + 1

                        if not found_edge:

                            if num_loose_edges >= EPA_MAX_NUM_LOOSE_EDGES:
                                break

                            loose_edges[num_loose_edges][0] = current_edge[0]
                            loose_edges[num_loose_edges][1] = current_edge[1]
                            num_loose_edges = num_loose_edges + 1

                    faces[i][0] = faces[num_faces - 1][0]
                    faces[i][1] = faces[num_faces - 1][1]
                    faces[i][2] = faces[num_faces - 1][2]
                    faces[i][3] = faces[num_faces - 1][3]

                    num_faces = num_faces - 1
                    i = i - 1

                i = i + 1

            for i in range(num_loose_edges):

                if num_faces >= EPA_MAX_NUM_FACES:
                    break

                faces[num_faces][0] = loose_edges[i][0]
                faces[num_faces][1] = loose_edges[i][1]
                faces[num_faces][2] = p
                faces[num_faces][3] = (loose_edges[i][0][VECTOR] -
                                       loose_edges[i][1][VECTOR]
                                       ).cross(loose_edges[i][0][VECTOR] -
                                               p[VECTOR]).get_normalized()

                if faces[num_faces][0][VECTOR].dot(
                        faces[num_faces][3]) + EPA_TOLERANCE < 0:
                    tmp = faces[num_faces][0]

                    faces[num_faces][0] = faces[num_faces][1]
                    faces[num_faces][1] = tmp
                    faces[num_faces][3] = faces[num_faces][3].negate()

                num_faces = num_faces + 1

        if iteration >= EPA_MAX_NUM_ITERATIONS:
            print("warning, epa couldnt find the closes triangle point")

        min_normal = search_dir
        min_distance = min_normal.dot(p[VECTOR]) + 0.0001

        #this method here will only give one collision point
        contact_points = []
        local_contact_points = []

        point_on_closest_triangle = min_normal * min_distance
        closest_triangle_a = faces[closest_face][0][VECTOR]
        closest_triangle_b = faces[closest_face][1][VECTOR]
        closest_triangle_c = faces[closest_face][2][VECTOR]

        v, w, u = EPA.barycentric(point_on_closest_triangle, min_normal,
                                  closest_triangle_a, closest_triangle_b,
                                  closest_triangle_c)

        polygon_triangle_a_0 = polygon_a[faces[closest_face][0][1]]
        polygon_triangle_a_1 = polygon_a[faces[closest_face][1][1]]
        polygon_triangle_a_2 = polygon_a[faces[closest_face][2][1]]

        contact_point = polygon_triangle_a_0 * v + polygon_triangle_a_1 * w + polygon_triangle_a_2 * u

        #note that our contact point should be inside of the mesh not on top of them
        contact_points.append(contact_point - min_normal * min_distance)

        local_contact_points.append(
            mat_a.get_inverse().mul_vec3(contact_point))
        local_contact_points.append(
            mat_b.get_inverse().mul_vec3(contact_point))

        #based on http://allenchou.net/2013/12/game-physics-contact-generation-epa/
        if min_normal.x >= 0.57735:
            t = vector3.Vector3(min_normal.y, -min_normal.x, 0.0)
        else:
            t = vector3.Vector3(0.0, min_normal.z, -min_normal.y)

        t1 = t.get_normalized()
        t2 = min_normal.cross(t1)

        data = {}
        data["seperation_point"] = min_normal * min_distance
        data["contact_points"] = contact_points
        data["local_contact_points"] = local_contact_points
        data["tangents"] = [t1, t2]
        data["min_normal"] = min_normal
        data["min_distance"] = min_distance

        return data
コード例 #29
0
    def create_test_scene(self):
        self.loader = mesh_loader.MeshLoader(self)
        self.mesh_pool = []
        self.mesh_pool.append(
            self.loader.get_meshs("data/models/objs/cube.obj"))
        self.mesh_pool.append(
            self.loader.get_meshs("data/models/objs/ground_box.obj"))
        #self.mesh_pool.append(self.loader.get_meshs("data/models/iqms/mrfixit/mrfixit.iqm"))

        ent = Entity(self)
        ent.add_component(mesh_renderer.MeshRenderer(self.mesh_pool[0]))
        ent.add_component(mesh_debug_renderer.MeshDebugRenderer())

        b_size = self.mesh_pool[0][0].get_aabb().get_size()
        ent.add_component(
            rigid_body.RigidBody(
                box_collision_shape.BoxCollisionShape(b_size.x, b_size.y,
                                                      b_size.z)))

        self.entities.append(ent)

        ent2 = Entity(self)
        ent2.add_component(mesh_renderer.MeshRenderer(self.mesh_pool[0]))
        ent2.add_component(mesh_debug_renderer.MeshDebugRenderer())

        b_size = self.mesh_pool[0][0].get_aabb().get_size()
        ent2.add_component(
            static_body.StaticBody(
                box_collision_shape.BoxCollisionShape(b_size.x, b_size.y,
                                                      b_size.z)))

        self.entities.append(ent2)

        ent3 = Entity(self)
        ent3.add_component(mesh_renderer.MeshRenderer(self.mesh_pool[1]))
        ent3.add_component(mesh_debug_renderer.MeshDebugRenderer())

        b_size = self.mesh_pool[1][0].get_aabb().get_size()
        ent3.add_component(
            static_body.StaticBody(
                box_collision_shape.BoxCollisionShape(b_size.x, -b_size.y,
                                                      b_size.z)))

        self.entities.append(ent3)

        ent4 = Entity(self)
        ent4.add_component(
            primitive_render.PrimitiveRender(
                DebugShapes.create_box_shape(b_size.x * 0.5, b_size.y,
                                             b_size.z)))

        self.entities.append(ent4)

        #for testing we say the mesh is at the origin for now
        quat = quaternion.Quaternion(vector3.Vector3(0.0, 0.0, -1.0),
                                     3.141 * 0.5).get_axis_quaternion()
        quat = quat * quaternion.Quaternion(vector3.Vector3(0.0, -1.0, 0.0),
                                            3.141 * 0.5).get_axis_quaternion()

        self.t1_position = vector3.Vector3(0.0, 5.0, -10.0)

        self.entities[0].get_transform().set_local_rotation(
            quaternion.Quaternion.from_axis(vector3.Vector3(), 1.0))
        self.entities[0].get_transform().set_local_position(self.t1_position)

        self.entities[1].get_transform().set_local_rotation(
            quat.get_normalized())
        self.entities[1].get_transform().set_local_position(
            vector3.Vector3(5.0, -5.0, -10.0))

        self.entities[0].get_component("MeshRenderer").play_animation(
            "idle", 1.0)
        self.entities[1].get_component("MeshRenderer").play_animation(
            "idle", 1.0)

        self.entities[2].get_transform().set_local_position(
            vector3.Vector3(0.0, -8, 0.0))
        self.entities[2].get_component(
            "MeshRenderer").get_materials()[0].assign_material(
                "mesh_color", [0.5, 0.5, 0.5, 1.0])

        self.entities[3].get_transform().set_local_position(
            vector3.Vector3(0.0, -8, 0.0))
コード例 #30
0
	def read_file(self, file_path):

		tex_pool = self.scene_manager.get_texture_pool()

		meshes = []
		mesh_data = {}
		global_data = {}
		line_count = 0
		calc_face_offset = 0

		global_data["raw_vertices"] = []
		global_data["raw_tex_coords"] = []
		global_data["raw_normals"] = []


		for line in open(file_path, "r"):

			if line.startswith("#"):
				continue

			values = line.split()

			if not values:
				continue

			if values[0] == "o":

				if "name" in mesh_data:
					meshes.append(mesh_data)

				mesh_data = {}

				mesh_data["center_of_mass"] = vector3.Vector3()
				mesh_data["name"] = values[1]
				mesh_data["type"] = GL_TRIANGLES

				mesh_data["vertices"] = []
				mesh_data["indices"] = []
				mesh_data["diffuse_texture"] = ""
				mesh_data["aabb"] = AABB(vector3.Vector3(math.inf, math.inf, math.inf), vector3.Vector3(-math.inf, -math.inf, -math.inf))


			if values[0] == "v":
				x = float(values[1])
				y = float(values[2])
				z = float(values[3])

				global_data["raw_vertices"].append(x)
				global_data["raw_vertices"].append(y)
				global_data["raw_vertices"].append(z)

				mesh_data["center_of_mass"].x += x
				mesh_data["center_of_mass"].y += y
				mesh_data["center_of_mass"].z += z

				mesh_data["aabb"].min.x = min(mesh_data["aabb"].min.x, x)
				mesh_data["aabb"].min.y = min(mesh_data["aabb"].min.y, y)
				mesh_data["aabb"].min.z = min(mesh_data["aabb"].min.z, z)

				mesh_data["aabb"].max.x = max(mesh_data["aabb"].max.x, x)
				mesh_data["aabb"].max.y = max(mesh_data["aabb"].max.y, y)
				mesh_data["aabb"].max.z = max(mesh_data["aabb"].max.z, z)

			if values[0] == "vt":
				global_data["raw_tex_coords"].append(float(values[1]) )
				global_data["raw_tex_coords"].append(float(values[2]) )

			if values[0] == "vn":
				global_data["raw_normals"].append(float(values[1]) )
				global_data["raw_normals"].append(float(values[2]) )
				global_data["raw_normals"].append(float(values[3]) )

			if values[0] == "f":

				mesh_data["type"] = FACE_MAPPING[len(values)-1]

				for v in values[1:]:
					vals = v.split("/")

					v_indx = (int(vals[0]) - 1) * 3
					tx_indx = (int(vals[1]) - 1) * 2
					n_indx = (int(vals[2]) - 1) * 3

					mesh_data["vertices"].append(global_data["raw_vertices"][v_indx] )
					mesh_data["vertices"].append(global_data["raw_vertices"][v_indx+1] )
					mesh_data["vertices"].append(global_data["raw_vertices"][v_indx+2] )

					mesh_data["vertices"].append(global_data["raw_tex_coords"][tx_indx] )
					mesh_data["vertices"].append(global_data["raw_tex_coords"][tx_indx+1] )

					mesh_data["vertices"].append(global_data["raw_normals"][n_indx] )
					mesh_data["vertices"].append(global_data["raw_normals"][n_indx+1] )
					mesh_data["vertices"].append(global_data["raw_normals"][n_indx+2] )

					mesh_data["indices"].append( len(mesh_data["indices"]) )

			line_count = line_count + 1

		meshes.append(mesh_data)

		base_path = os.path.dirname(file_path)
		base_name = os.path.basename(os.path.splitext(file_path)[0])
		materials = []

		for i in range(len(meshes)):
			meshes[i]["center_of_mass"] = meshes[i]["center_of_mass"] / (len(meshes[i]["vertices"]) / 3)
			materials.append(Material())

		if os.path.isfile(base_path + "/" + base_name + ".mtl"):



			for line in open(base_path + "/" + base_name + ".mtl", "r"):

				if line.startswith("#"):
					continue

				values = line.split()

				if not values:
					continue

				if values[0] == "map_Kd":
					tex_pool.load_texture(values[1], base_path, base_path + "/" + values[1])#load the material texture

					for i in range(len(meshes)):
						materials[i].assign_material("diffuse_texture", values[1])

		for i in range(len(meshes)):
			meshes[i]["material"] = materials[i]


		return meshes