Ejemplo n.º 1
0
def nan_vector(size, freeze=True):
    from mathutils import Vector
    from math import nan
    nan_vec = Vector([nan for i in range(size)])

    if not freeze:
        return nan_vec

    # vectors must be frozen before used in a deque
    frozen = nan_vec.freeze()
    del nan_vec
    return frozen
    def __load_XYZNUV(self, iposition, vposition):
        if self.__debug:  #Print divider
            print('-' * 48)
        self.__pfile.seek(iposition)  #Go to index position
        if self.__debug:  #Print location of linked sections
            print('   [Import Debug] Vertex position of %s: %d' %
                  (self.vertices_section_name, vposition))
            print('   [Import Debug] Index position of %s: %d' %
                  (self.indices_section_name, iposition))
        indexFormat = self.__pfile.read(64).split(b'\x00')[0].decode(
            'utf-8')  #IndexFormat (either 'list' or 'list32')
        nIndices = unpack('<I', self.__pfile.read(4))[0]  #Number of indices
        nTriangleGroups = unpack(
            '<I', self.__pfile.read(4))[0]  #Number of groups, should be 1
        if nTriangleGroups != 1:
            raise Exception("More than one primitives group")
        self.PrimitiveGroups = [
        ]  #List the TriangleGroups, should only have one element
        if 'list32' in indexFormat:  #Index format
            UINT_LEN = 4
        else:
            UINT_LEN = 2

        try:
            offset = nIndices * UINT_LEN + 72  #Skip past the metadata and indices to the packed information
        except:
            print('   [Import Error] Index Format not found')
            raise Exception("Can't recognize index format")

        self.__pfile.seek(iposition + offset)  #Goto the group block

        startIndex = unpack(
            '<I', self.__pfile.read(4)
        )[0]  #Offset of the index group, normally 0 b/c there is only 1 group
        nPrimitives = unpack(
            '<I', self.__pfile.read(4)
        )[0]  #Number of triangles, same as the metadata in the indices group divided by three
        startVertex = unpack(
            '<I', self.__pfile.read(4)
        )[0]  #Offset of the vertex group, normally 0 b/c there is only 1 group
        nVertices = unpack('<I', self.__pfile.read(4))[
            0]  #Number of vertices, same as the metadata in the vertices group
        self.PrimitiveGroups.append({
            'startIndex': startIndex,
            'nPrimitives': nPrimitives,
            'startVertex': startVertex,
            'nVertices': nVertices
        })
        if self.__debug:  #Print number of vertices and faces
            print('   [Import Debug] Number of vertices of %s: %d' %
                  (self.vertices_section_name, nVertices))
            print('   [Import Debug] Number of faces of %s: %d' %
                  (self.indices_section_name, nPrimitives))

        self.__pfile.seek(vposition)  #Goto the vertices block

        vertices_type = self.__pfile.read(64).split(b'\x00')[0].decode(
            'utf-8')  #Vertices format
        verticesCount = unpack('<l',
                               self.__pfile.read(4))[0]  #Number of vertices

        pos = self.__pfile.tell()  #Just vposition+68

        byte_size = 0  #Byte size of each vertex
        is_skinned = False  #Is weighted type, used for main armament
        is_alpha = False  #Is alpha type, used for nets and glass
        is_wire = False  #Is wire type, used for railings and wires

        if 'xyznuvtb' in vertices_type:  #If standard type
            if self.__debug:
                print('   [Import Debug] Standard import')
            byte_size = 32
            unpack_format = '<3fI2f2I'
            self.vertices_type = 'xyznuvtb'

        elif 'xyznuviiiwwtb' in vertices_type:  #If weighted type
            if self.__debug:
                print('   [Import Debug] Gun import')
            byte_size = 37
            unpack_format = '<3fI2f5B2I'
            is_skinned = True
            self.vertices_type = 'xyznuviiiwwtb'

        elif 'xyznuvr' in vertices_type:  #If wire type
            if self.__debug:
                print('   [Import Debug] Wire import')
            byte_size = 36
            unpack_format = '<9f'
            is_wire = True
            self.vertices_type = 'xyznuvr'

        elif 'xyznuv' in vertices_type:  #If alpha type
            if self.__debug:
                print('   [Import Debug] Alpha import')
            byte_size = 32
            unpack_format = '<8f'
            is_alpha = True
            self.vertices_type = 'xyznuv'
        else:
            print('   [Import Error] Format=%s' % self.vertices_type)
            raise Exception("Unrecognized vertex format")

        vert_list = []  #List of vertices

        for i in range(verticesCount):
            self.__pfile.seek(pos)  #Goto vertex data position

            t, bn = None, None  #Tangent, binormal

            if is_skinned:
                if byte_size == 37:
                    (x, z, y, n, u, v, index_1, index_2, index_3, weight_1,
                     weight_2, t, bn) = unpack(unpack_format,
                                               self.__pfile.read(byte_size))
                    y = -y  #Skinned is flipped?
                    IIIWW = (index_1, index_2, index_3, weight_1, weight_2)

            else:
                if byte_size == 36:
                    (x, z, y, n1, n2, n3, u, v,
                     r) = unpack(unpack_format, self.__pfile.read(byte_size))
                elif byte_size == 32 and not is_alpha:
                    (x, z, y, n, u, v, t,
                     bn) = unpack(unpack_format, self.__pfile.read(byte_size))
                elif byte_size == 32 and is_alpha:
                    (x, z, y, n1, n2, n3, u,
                     v) = unpack(unpack_format, self.__pfile.read(byte_size))

            XYZ = Vector((x, y, z))
            XYZ.freeze()
            if not is_wire and not is_alpha:  #If not wire or alpha types
                N = UnpackNormal(n)
            else:  #If wire or alpha type
                N = Vector((n1, n2, n3))

            if t and bn:  #If standard model
                T = UnpackNormal(t)
                BN = UnpackNormal(bn)
            else:  #Else, empty vectors
                T = Vector((0.0, 0.0, 0.0))
                BN = Vector((0.0, 0.0, 0.0))

            N.freeze()
            T.freeze()
            BN.freeze()

            UV = Vector((u, 1 - v))
            UV.freeze()

            XYZNUV2TB = (XYZ, N, UV, T, BN)
            if is_skinned:
                XYZNUV2TB += (IIIWW, )

            #Add to vertices list
            vert_list.append(XYZNUV2TB)
            pos += byte_size  #Shift to next vertice

        if not is_skinned:  #Set sublists
            (self.vertices, self.normal_list, self.uv_list, self.tangent_list,
             self.binormal_list) = zip(*vert_list)
        else:  #Set sublists
            (self.vertices, self.normal_list, self.uv_list, self.tangent_list,
             self.binormal_list, self.bones_info) = zip(*vert_list)

        self.indices = []  #Array of triangles
        self.__pfile.seek(iposition +
                          self.PrimitiveGroups[0]['startIndex'] * UINT_LEN +
                          72)  #Goto indices for the group
        for cnt in range(self.PrimitiveGroups[0]['nPrimitives']):
            if UINT_LEN == 2:  #If smaller vertices number (<32768)
                v1 = unpack('<H', self.__pfile.read(2))[0]
                v2 = unpack('<H', self.__pfile.read(2))[0]
                v3 = unpack('<H', self.__pfile.read(2))[0]
            elif UINT_LEN == 4:  #If larger vertices number (>32767)
                v1 = unpack('<I', self.__pfile.read(4))[0]
                v2 = unpack('<I', self.__pfile.read(4))[0]
                v3 = unpack('<I', self.__pfile.read(4))[0]
            TRIANGLE = (v1, v2, v3)
            self.indices.append(
                TRIANGLE)  #Add the tuple of indices of vertices