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