def parse_file(self): '''Main parser method''' idstring = self.inFile.readBytes(6) self.inFile.readShort() self.inFile.readShort() self.read_name() meshName = self.read_name() self.inFile.readByte() # delim? bbox = self.inFile.read('6f') self.inFile.readUInt() self.inFile.readUInt() numVerts, numIdx = self.inFile.read('2H') vertBuff = self.parse_vertices(numVerts) idxBuff = self.parse_faces(numIdx) self.parse_materials() rapi.rpgSetName(meshName) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 32, 0) rapi.rpgBindNormalBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 32, 12) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 32, 24) rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_SHORT, numIdx, noesis.RPGEO_TRIANGLE, 1)
def parse_LD_submesh(self, meshNum): meshCount = len(self.meshList) meshName = self.read_name(64) rapi.rpgSetName(meshName) self.submeshList[meshNum].append(meshName) meshID, matNum, null, matID, texID = self.inFile.read('5L') texInfo = self.inFile.read('13L') numVerts = self.inFile.readUInt() numIdx = self.inFile.readUInt() matFlag = self.inFile.read('4L') self.inFile.seek(432, 1) # nulls if matID: material = self.matIDs[matID] matName = material.name if texID != 0: #self.add_texture_name(matNum, self.tempTex[texID]) texture = self.texIDs[texID] material.setTexture(texture.name) self.parse_vertices(meshName, numVerts) self.parse_faces(meshName, numIdx, matName) self.inFile.read('6L') #nulls self.meshList.append(meshName) self.tempMesh[meshID] = meshCount
def parse_mesh(self, line): line = self.tokenize(line) meshName = line[1] rapi.rpgSetName(meshName) line = self.inFile.readline().strip() while not line.startswith("}"): if not line: continue args = line.split() if args[0] == "BVertex": numVerts = int(args[1]) self.parse_binary_vertices(numVerts) elif args[0] == "vertex": numVerts = int(args[1]) vertList = self.parse_vertices(numVerts) elif args[0] == "weit": self.parse_weit() line = self.inFile.readline().strip() line = self.skip_lines("face") numFaces = int(line.strip().strip('{').split()[1]) triBuffs, quadBuffs = self.parse_faces(numFaces) self.build_mesh_tris(vertList, triBuffs) self.build_mesh_quads(vertList, quadBuffs)
def parse_mesh(self, numMesh): for i in range(numMesh): self.read_name() # scene root meshName = self.read_name() rapi.rpgSetName(meshName) numVerts, numIdx, unk = self.inFile.read("3L") triStrip, flag1, unk, unk = self.inFile.read("4B") self.inFile.seek(496, 1) idxBuff = self.parse_faces(numIdx) self.parse_vertices(numVerts) print(self.inFile.tell()) if self.hasBones: numBones = self.inFile.readUInt() self.parse_mesh_bones(numBones) texName = meshName + ".dds" matName = "material" material = NoeMaterial(matName, texName) self.matList.append(material) print(self.inFile.tell()) rapi.rpgSetMaterial(matName) if triStrip: rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_USHORT, numIdx, noesis.RPGEO_TRIANGLE_STRIP, 1) else: rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_USHORT, numIdx, noesis.RPGEO_TRIANGLE, 1)
def build_meshes(self): for meshInfo in self.meshInfo: vertBuff = meshInfo[0] idxBuff = meshInfo[1] numIdx = meshInfo[2] matNum = meshInfo[3] meshName = meshInfo[4] if self.xxFormat >= 4: rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 70, 2) rapi.rpgBindNormalBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 70, 30) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 70, 42) else: rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 52, 4) rapi.rpgBindNormalBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 52, 32) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 52, 44) if len(self.matList) > matNum: mat = self.matList[matNum] matName = mat.name rapi.rpgSetMaterial(matName) rapi.rpgSetName(meshName) rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_USHORT, numIdx, noesis.RPGEO_TRIANGLE, 1) rapi.rpgClearBufferBinds()
def build_meshes(self): rapi.rpgSetOption(noesis.RPGOPT_TRIWINDBACKWARD, 1) for i in range(len(self.meshList)): mesh = self.meshList[i] rapi.rpgSetName(mesh.name) if mesh.vertSize == 32: rapi.rpgBindPositionBufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 32, 0) rapi.rpgBindNormalBufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 32, 12) rapi.rpgBindUV1BufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 32, 24) elif mesh.vertSize == 40: rapi.rpgBindPositionBufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 40, 0) rapi.rpgBindNormalBufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 40, 20) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 40, 32) elif mesh.vertSize == 48: rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 48, 0) rapi.rpgBindNormalBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 48, 28) rapi.rpgBindUV1BufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 48, 40) for sub in mesh.submeshes: idxStart = sub.idxOfs idxEnd = idxStart + sub.numIdx * 2 idxBuff = mesh.idxBuff[idxStart:idxEnd] rapi.rpgSetMaterial(self.tex) rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_USHORT, sub.numIdx, noesis.RPGEO_TRIANGLE, 1)
def build_vertices(self, mesh, meshName): vertBuff = bytes() normBuff = bytes() uvBuff = bytes() idxBuff = bytes() rapi.rpgSetName(meshName) for i in range(mesh.numIdx): index = mesh.idxList[i] vertBuff += struct.pack('3f', *mesh.vertList[index]) normBuff += struct.pack('3f', *mesh.normList[index]) uvBuff += struct.pack('2f', *mesh.uvList[i]) idxBuff += struct.pack('H', i) rapi.rpgBindPositionBuffer(vertBuff, noesis.RPGEODATA_FLOAT, 12) rapi.rpgBindNormalBuffer(normBuff, noesis.RPGEODATA_FLOAT, 12) rapi.rpgBindUV1Buffer(uvBuff, noesis.RPGEODATA_FLOAT, 8) matName = meshName material = NoeMaterial(matName, self.basename) material.setDefaultBlend(0) self.matList.append(material) rapi.rpgSetMaterial(meshName) rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_USHORT, mesh.numIdx, noesis.RPGEO_TRIANGLE, 1)
def parse_mesh(self, numMesh): for i in range(numMesh): self.read_name() #scene root meshName = self.read_name() rapi.rpgSetName(meshName) numVerts, numIdx, unk = self.inFile.read('3L') triStrip, flag1, unk, unk = self.inFile.read('4B') self.inFile.seek(496, 1) idxBuff = self.parse_faces(numIdx) self.parse_vertices(numVerts) print(self.inFile.tell()) if self.hasBones: numBones = self.inFile.readUInt() self.parse_mesh_bones(numBones) texName = meshName + ".dds" matName = "material" material = NoeMaterial(matName, texName) self.matList.append(material) print(self.inFile.tell()) rapi.rpgSetMaterial(matName) if triStrip: rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_USHORT, numIdx, noesis.RPGEO_TRIANGLE_STRIP, 1) else: rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_USHORT, numIdx, noesis.RPGEO_TRIANGLE, 1)
def build_meshes(self): matCount = 0 for i in range(len(self.meshList)): mesh = self.meshList[i] if mesh.matNum != -1: mat = self.tempMats[mesh.matNum] rapi.rpgSetName(mesh.meshName) rapi.rpgBindPositionBufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 56, 0) rapi.rpgBindNormalBufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 56, 12) rapi.rpgBindUV1BufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 56, 24) for j in range(len(mesh.faceGroups)): numIdx, idxBuff = mesh.faceGroups[j] if numIdx == 0: continue matName = "Material[%d]" % matCount texName = mat.texNames[i] material = NoeMaterial(matName, texName) self.matList.append(material) rapi.rpgSetMaterial(matName) rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_USHORT, numIdx, noesis.RPGEO_TRIANGLE, 1)
def build_mesh(self): for mesh in self.meshList: rapi.rpgBindPositionBufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 92, 0) rapi.rpgBindNormalBufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 92, 12) rapi.rpgBindUV1BufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 92, 28) rapi.rpgSetName(mesh.meshName) matName = self.matList[mesh.matNum].name rapi.rpgSetMaterial(matName) rapi.rpgCommitTriangles(mesh.idxBuff, noesis.RPGEODATA_UINT, mesh.numIdx, noesis.RPGEO_TRIANGLE, 1)
def parse_mesh(self, numMesh): for i in range(numMesh): meshName = self.read_name() rapi.rpgSetName(meshName) unk1, numVerts = self.inFile.read('2L') self.inFile.readByte() self.parse_vertices(numVerts) unk2, numSects = self.inFile.read('2L') self.parse_face_section(numSects) self.parse_unk1()
def build_mesh(self): for mesh in self.meshList: rapi.rpgBindPositionBuffer(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 12) self.plot_points(mesh.numVerts) rapi.rpgSetName(mesh.name) if mesh.triCount: rapi.rpgCommitTriangles(mesh.triBuff, noesis.RPGEODATA_UINT, mesh.triCount, noesis.RPGEO_TRIANGLE, 1) if mesh.quadCount: rapi.rpgCommitTriangles(mesh.quadBuff, noesis.RPGEODATA_UINT, mesh.quadCount, noesis.RPGEO_QUAD_ABC_ACD, 1)
def build_mesh(self): for i in range(len(self.meshList)): mesh = self.meshList[i] rapi.rpgSetName(self.filename) rapi.rpgBindPositionBufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 40, 0) rapi.rpgBindNormalBufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 40, 16) rapi.rpgBindUV1BufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 40, 32) matName = self.matList[0].name rapi.rpgSetMaterial(matName) rapi.rpgCommitTriangles(mesh.idxBuff, noesis.RPGEODATA_UINT, mesh.numIdx, noesis.RPGEO_TRIANGLE, 1)
def build_mesh(self): for i in range(len(self.meshList)): mesh = self.meshList[i] rapi.rpgBindPositionBufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 32, 0) rapi.rpgBindNormalBufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 32, 12) rapi.rpgBindUV1BufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 32, 24) meshName = "Mesh%d" %i rapi.rpgSetName(meshName) mat = self.matList[i] rapi.rpgSetMaterial(mat.name) rapi.rpgCommitTriangles(mesh.idxBuff, noesis.RPGEODATA_USHORT, mesh.numIdx, noesis.RPGEO_TRIANGLE, 1)
def build_mesh(self): for mesh in self.meshList: rapi.rpgBindPositionBufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 92, 0) rapi.rpgBindNormalBufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 92, 12) rapi.rpgBindUV1BufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 92, 28) trans = NoeMat43((NoeVec3((-1, 0, 0)), NoeVec3((0, 1, 0)), NoeVec3((0, 0, 1)), NoeVec3((0, 0, 0)))) rapi.rpgSetTransform(trans) rapi.rpgSetName(mesh.matName) rapi.rpgSetMaterial(mesh.matName) rapi.rpgCommitTriangles(mesh.idxBuff, noesis.RPGEODATA_UINT, mesh.numIdx, noesis.RPGEO_TRIANGLE, 1)
def parse_file(self): '''Main parser method.''' meshName = "temp" rapi.rpgSetName(meshName) numCoords = self.inFile.readInt() self.parse_coords(numCoords) numNorms = self.inFile.readInt() self.parse_normals(numNorms) numUV = self.inFile.readUInt() self.parse_uv(numUV) numUnk1 = self.inFile.readUInt() self.parse_unk1(numUnk1) numIdx = self.inFile.readUInt() self.parse_faces(numIdx)
def build_mesh(self): rapi.rpgSetName(self.filename) rapi.rpgBindPositionBufferOfs(self.vertBuff, noesis.RPGEODATA_FLOAT, 32, 0) if self.hasNormals: rapi.rpgBindNormalBufferOfs(self.vertBuff, noesis.RPGEODATA_FLOAT, 32, 12) rapi.rpgBindUV1BufferOfs(self.vertBuff, noesis.RPGEODATA_FLOAT, 32, 24) if len(self.matList) > 0: material = self.matList[0] rapi.rpgSetMaterial(material.name) rapi.rpgCommitTriangles(self.idxBuff, noesis.RPGEODATA_UINT, self.numIdx, noesis.RPGEO_TRIANGLE, 1)
def parse_mesh(self, template): '''Build a mesh from the template''' #initialize a dict for the mesh object self.meshes.append({}) self.meshes[-1]["materials"] = [] token = template.get_token() if token == TOKEN_NAME: rapi.rpgSetName(token.get_value()) token = template.get_token() numVerts = token.get_value()[1] token = template.get_token() self.parse_vertices(token) token = template.get_token() self.parse_faces(token)
def psaLoadModel(data, mdlList): ctx = rapi.rpgCreateContext() bs = NoeBitStream(data) bs.setEndian(NOE_BIGENDIAN) rapi.rpgSetOption(noesis.RPGOPT_BIGENDIAN, 1) rapi.rpgSetOption(noesis.RPGOPT_TRIWINDBACKWARD, 1) IdMagic = bs.readBytes(4).decode("ASCII") version = bs.readUInt() modelCount = bs.readUInt() fvfTableOffset = bs.readUInt() bs.seek(fvfTableOffset, NOESEEK_ABS) for i in range(0, modelCount): bs.seek(fvfTableOffset + (0x80 * i), NOESEEK_ABS) bs.seek(0x08, NOESEEK_REL) vertexCount = bs.readUShort() indexCount = bs.readUShort() #print('Index Count: ' + str(indexCount)) bs.seek(0x04, NOESEEK_REL) indexOffset = bs.readUInt() #print('Index Offset: ' + str(indexOffset)) indexSize = bs.readUShort() unk01 = bs.readUShort() vertexOffset = bs.readUInt() unkown01Offset = bs.readUInt() vertexSize = bs.readUShort() bs.seek(0x5E, NOESEEK_REL) bs.seek(indexOffset, NOESEEK_ABS) edgeData = bs.readBytes(indexSize) edgeDecomp = rapi.decompressEdgeIndices(edgeData, indexCount) for i in range(0, indexCount): #decompressEdgeIndices returns indices in little-endian, so swap back to big because rpg is in bigendian mode t = edgeDecomp[i*2] edgeDecomp[i*2] = edgeDecomp[i*2 + 1] edgeDecomp[i*2 + 1] = t bs.seek(vertexOffset, NOESEEK_ABS) vertexSize = 16 * vertexCount vertbuff = bs.readBytes(vertexSize) rapi.rpgBindPositionBufferOfs(vertbuff, noesis.RPGEODATA_FLOAT, 16, 0) #print(outputIndices[len(outputIndices) - 1]) #print(outputIndices) rapi.rpgSetName(str(i)) #rapi.rpgCommitTriangles(None, noesis.RPGEODATA_USHORT, (vertexSize // 16), noesis.RPGEO_POINTS, 1) rapi.rpgCommitTriangles(edgeDecomp, noesis.RPGEODATA_USHORT, indexCount, noesis.RPGEO_TRIANGLE, 1) mdl = rapi.rpgConstructModel() mdlList.append(mdl) rapi.rpgClearBufferBinds() return 1
def build_mesh(self): for i in range(len(self.meshList)): mesh = self.meshList[i] rapi.rpgBindPositionBufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 32, 0) rapi.rpgBindNormalBufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 32, 12) rapi.rpgBindUV1BufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 32, 24) meshName = "Mesh%d" % i rapi.rpgSetName(meshName) mat = self.matList[i] rapi.rpgSetMaterial(mat.name) rapi.rpgCommitTriangles(mesh.idxBuff, noesis.RPGEODATA_USHORT, mesh.numIdx, noesis.RPGEO_TRIANGLE, 1)
def build_mesh(self): for i in range(len(self.meshList)): mesh = self.meshList[i] rapi.rpgBindPositionBufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 76, 0) #rapi.rpgBindNormalBufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 76, 56) rapi.rpgBindUV1BufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 76, 68) #self.matList[0].setNormalTexture(self.texList[1].name) matName = self.matList[0].name rapi.rpgSetName(mesh.name) rapi.rpgSetMaterial(matName) rapi.rpgCommitTriangles(mesh.idxBuff, noesis.RPGEODATA_USHORT, mesh.numIdx, noesis.RPGEO_TRIANGLE, 1) if _LOAD_FIRST_MESH: break
def parse_mesh(self, numMesh): for i in range(numMesh): self.inFile.readUInt() meshName = self.read_name() rapi.rpgSetName(meshName) self.inFile.read('16f') self.inFile.readUInt() numVerts = self.inFile.readUInt() self.inFile.readUByte() self.parse_vertices(numVerts) unk2, unk3, numIdx = self.inFile.read('3L') idxList = self.parse_faces(numIdx) matIndex = self.inFile.readUInt() matName = self.read_name() self.parse_submesh() #now create triangles rapi.rpgSetMaterial(matName) rapi.rpgCommitTriangles(idxList, noesis.RPGEODATA_USHORT, numIdx, noesis.RPGEO_TRIANGLE, 1)
def parse_faces(self): total_faces = int(self.get_data()) numFaceGroups = int(self.get_data()) for i in range(numFaceGroups): matNum = int(self.get_data()) numFaces = int(self.get_data()) numIdx = numFaces * 3 idxBuff = bytes() for j in range(numFaces): indices = map(int, self.readline().split(" ")) idxBuff = b''.join([idxBuff, struct.pack('3L', *indices)]) matName = self.matList[matNum].name rapi.rpgSetName("mesh[%d]" %i) rapi.rpgSetMaterial(matName) rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_UINT, numIdx, noesis.RPGEO_TRIANGLE, 1) # empty line self.readline()
def parse_file(self): '''Main parser method.''' self.inFile.read('3L') meshName = self.read_name() rapi.rpgSetName(meshName) self.inFile.readUInt() numCoords = self.inFile.readUInt() self.parse_coords(numCoords) numNorms = self.inFile.readUInt() self.parse_normals(numNorms) numUV = self.inFile.readUInt() self.parse_uv(numUV) numUnk1 = self.inFile.readUInt() self.parse_unk1(numUnk1) numUnk2 = self.inFile.readUInt() self.parse_unk2(numUnk2) numUnk3 = self.inFile.readUInt() self.parse_unk3(numUnk3) numIdx = self.inFile.readUInt() self.parse_faces(numIdx)
def parse_faces(self): total_faces = int(self.get_data()) numFaceGroups = int(self.get_data()) for i in range(numFaceGroups): matNum = int(self.get_data()) numFaces = int(self.get_data()) numIdx = numFaces * 3 idxBuff = bytes() for j in range(numFaces): indices = map(int, self.readline().split(" ")) idxBuff = b''.join([idxBuff, struct.pack('3L', *indices)]) matName = self.matList[matNum].name rapi.rpgSetName("mesh[%d]" % i) rapi.rpgSetMaterial(matName) rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_UINT, numIdx, noesis.RPGEO_TRIANGLE, 1) # empty line self.readline()
def build_meshes(self): matCount = 0 for i in range(len(self.meshList)): mesh = self.meshList[i] if mesh.matNum != -1: mat = self.tempMats[mesh.matNum] rapi.rpgSetName(mesh.meshName) rapi.rpgBindPositionBufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 56, 0) rapi.rpgBindNormalBufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 56, 12) rapi.rpgBindUV1BufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 56, 24) for j in range(len(mesh.faceGroups)): numIdx, idxBuff = mesh.faceGroups[j] if numIdx == 0: continue matName = "Material[%d]" %matCount texName = mat.texNames[i] material = NoeMaterial(matName, texName) self.matList.append(material) rapi.rpgSetMaterial(matName) rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_USHORT, numIdx, noesis.RPGEO_TRIANGLE, 1)
def noepyLoadModel(data, mdlList): ctx = rapi.rpgCreateContext() bs = NoeBitStream(data) bs.seek(0x18, NOESEEK_ABS) #seek 0x18h/24 numMeshes = bs.read("h") #number of meshes numTextures = bs.read("h") #number of textures bs.seek(0x50, NOESEEK_ABS) #seek 0x50h/80 offset50offset = bs.read("i") offsetMeshHeader = bs.read("i") offsetMaterialNameOffsets = bs.read("i") bs.seek(0x70, NOESEEK_ABS) #seek to Mesh Header meshHeader = [] #mesh header data meshName = [] #mesh names matName = [] #materialname used by meshes texName = [] #texture names will be used matList = [] #Noesis built-in must have material list texList = [] #Noesis built-in must have texture list offsetMaterialUsageMesh = [] offsetMaterialUsageTexture = [] #for loop to get meshHeader data for i in range(0, numMeshes[0]): offsetMeshName = bs.read("i") unkFloat = bs.read("f") #nem kell offsetMeshName olvassa numUsedTextures = bs.read("h") numBones = bs.read("h") unKnown = bs.read("h") #nem kell numBones olvassa numVertexBytes = bs.read("h") numVertices = bs.read("i") numFaces = bs.read("i") offsetVertices = bs.read("i") offsetMaterialUsage = bs.read("i") offsetFace = bs.read("i") unkOffset = bs.read("i") #nem kell offsetFace olvassa meshHeader.append([ offsetMeshName[0], numUsedTextures[0], numVertexBytes[0], numVertices[0], numFaces[0], offsetVertices[0], offsetMaterialUsage[0], offsetFace[0] ]) #0 #1 #2 #3 #4 #5 #6 #7 #------------------------------------------------------------- #for loop to get meshName data for i in range(0, numMeshes[0]): bs.seek((meshHeader[i][0]), NOESEEK_ABS) nameLength = 0 boolP = True while (boolP == True): wak = bs.read("b") if (wak[0] != 0): nameLength = nameLength + 1 else: boolP = False bs.seek((meshHeader[i][0]), NOESEEK_ABS) meshName.append(bs.readBytes(nameLength).decode("ASCII").rstrip("\0")) #------------------------------------------------------------- #for loop to get matName data matNameOffsetList = [] bs.seek(offsetMaterialNameOffsets[0], NOESEEK_ABS) #seek to 0x50 offsetMaterialNameOffset for i in range(0, numTextures[0]): #fill matNameOffsetList matNameOffsetList.append(bs.read("i")) for i in range(0, numTextures[0]): bs.seek((matNameOffsetList[i][0]), NOESEEK_ABS) nameLength = 0 boolP = True while (boolP == True): wak = bs.read("b") if (wak[0] != 0): nameLength = nameLength + 1 else: boolP = False bs.seek(matNameOffsetList[i][0], NOESEEK_ABS) matName.append(bs.readBytes(nameLength).decode("ASCII").rstrip("\0")) texName = [s + "_d" for s in matName] #------------------------------------------------------------- #for loop to get materialUsage data for i in range(0, numMeshes[0]): # meshszamszor vegrehajt pl 3 mesh bs.seek((meshHeader[i][6]), NOESEEK_ABS) for j in range(0, (meshHeader[i][1] )): #hasznalt textura szamszor vegrehajt pl 4 texture materialFacesIndex = bs.read("i") materialNumFaces = bs.read( "i") #szorozni harommal a vertex szamhoz textureID = bs.read("i") numIdx = materialNumFaces * 3 bs.seek(0x24, NOESEEK_REL) offsetMaterialUsageMesh.append([ materialFacesIndex[0], materialNumFaces[0], textureID[0], numIdx[0] ]) #0 #1 #2 #3 offsetMaterialUsageTexture.append(offsetMaterialUsageMesh) offsetMaterialUsageMesh = [] #------------------------------------------------------------- #material naming for i in range(0, numTextures[0]): material = NoeMaterial(matName[i], "") material.setTexture(matName[i] + "_d.dds") material.nrmTexName = (matName[i] + "_n.dds") material.specTexName = (matName[i] + "_s.dds") material.setDefaultBlend(0) matList.append(material) #------------------------------------------------------------- #the draw for i in range(0, numMeshes[0]): bs.seek(meshHeader[i][5], NOESEEK_ABS) #set pointer to vertex offset if meshHeader[i][2] == 12: VertBuff = bs.seek(((meshHeader[i][3]) * 0xC), NOESEEK_REL) #rapi.rpgBindPositionBufferOfs(VertBuff, noesis.RPGEODATA_FLOAT, 12, 0) elif meshHeader[i][2] == 24: VertBuff = bs.readBytes((meshHeader[i][3]) * 0x18) rapi.rpgBindPositionBufferOfs(VertBuff, noesis.RPGEODATA_FLOAT, 24, 0) rapi.rpgBindUV1BufferOfs(VertBuff, noesis.RPGEODATA_HALFFLOAT, 24, 20) elif meshHeader[i][2] == 32: VertBuff = bs.readBytes((meshHeader[i][3]) * 0x20) rapi.rpgBindPositionBufferOfs(VertBuff, noesis.RPGEODATA_FLOAT, 32, 0) rapi.rpgBindUV1BufferOfs(VertBuff, noesis.RPGEODATA_HALFFLOAT, 32, 28) #rapi.rpgCommitTriangles(None, noesis.RPGEODATA_USHORT, meshHeader[i][3], noesis.RPGEO_POINTS, 1) bs.seek(meshHeader[i][7], NOESEEK_ABS) for j in range(0, meshHeader[i][1]): FaceBuff = bs.readBytes( (offsetMaterialUsageTexture[i][j][1] * 3) * 2) rapi.rpgSetMaterial(matName[offsetMaterialUsageTexture[i][j][2]]) rapi.rpgSetName(meshName[i]) rapi.rpgCommitTriangles(FaceBuff, noesis.RPGEODATA_USHORT, offsetMaterialUsageTexture[i][j][1] * 3, noesis.RPGEO_TRIANGLE, 1) rapi.rpgClearBufferBinds() mdl = rapi.rpgConstructModel() mdl.setModelMaterials(NoeModelMaterials(texList, matList)) mdlList.append(mdl) rapi.rpgClearBufferBinds() return 1
def pso2LoadModel(data, mdlList): ctx = rapi.rpgCreateContext() bs = NoeBitStream(data) Bones = [] Bone_Pallet = [] Bone_Matrix = [] Bone_Name = [] Bone_Parent = [] vertSize = [] vertCount = [] vtxeOffset = [] vtxlOffset = [] psetOffset = [] boneFileName = rapi.getDirForFilePath(rapi.getInputName()) + rapi.getLocalFileName(rapi.getInputName()).rstrip(".aqo") + ".aqn" if (rapi.checkFileExists(boneFileName)): boneData = rapi.loadIntoByteArray(boneFileName) if boneData is not None: bd = NoeBitStream(boneData) bd.seek(0xC, NOESEEK_ABS) start = bd.readInt() bd.seek(start + 0x10, NOESEEK_ABS) while not bd.checkEOF(): chunkStart = bd.tell() chunkType = bd.readBytes(4).decode("ASCII") chunkSize = bd.readInt() subChunkType = bd.readBytes(4).decode("ASCII") #print([chunkType,chunkSize,subChunkType]) for case in switch(subChunkType): if case('AQGF'): bd.seek(chunkStart + chunkSize, NOESEEK_ABS) break if case('ROOT'): bd.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS) break if case('NODE'): bd.seek(6, NOESEEK_REL) while bd.tell() < chunkStart + 8 + chunkSize: nodeChunkStart = bd.tell() nodeChunkType = bd.readUShort() #print([nodeChunkType,nodeChunkStart]) for case in switch(nodeChunkType): if case(0x903): nodeTest1 = bd.readInt() break if case(0x804): BoneParent = bd.readInt() Bone_Parent.append(BoneParent) break if case(0x80F): nodeTest1 = bd.readInt() break if case(0x805): nodeTest1 = bd.readInt() break if case(0x806): nodeTest1 = bd.readInt() break if case(0x4A07): bd.seek(0xD, NOESEEK_REL) break if case(0x4A08): bd.seek(0xD, NOESEEK_REL) break if case(0x4A09): bd.seek(0xD, NOESEEK_REL) break if case(0xCA0A): bd.seek(0x2, NOESEEK_REL) BoneMatrix = NoeMat44.fromBytes(bd.readBytes(64)).toMat43() Bone_Matrix.append(BoneMatrix.inverse()) break if case(0x90B): nodeTest1 = bd.readInt() break if case(0x90C): nodeTest1 = bd.readInt() break if case(0x20D): nSize = bd.readUByte() boneName = bd.readBytes(nSize).decode("ASCII") Bone_Name.append(boneName) break if case(0xFD): break break if case('NODO'): bd.seek(bd.getSize(), NOESEEK_ABS) break if case(): # default, could also just omit condition or 'if True' bd.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS) # No need to break here, it'll stop anyway for a in range(0, len(Bone_Matrix)): bn = NoeBone(a, Bone_Name[a], Bone_Matrix[a], None, Bone_Parent[a]) Bones.append(bn) aqoMagic = bs.readInt() while not bs.checkEOF(): chunkStart = bs.tell() chunkType = bs.readBytes(4).decode("ASCII") chunkSize = bs.readInt() subChunkType = bs.readBytes(4).decode("ASCII") #print([chunkType,chunkSize,subChunkType]) for case in switch(subChunkType): if case('AQGF'): bs.seek(chunkStart + chunkSize, NOESEEK_ABS) break if case('ROOT'): bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS) break if case('OBJC'): bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS) break if case('VSET'): while bs.tell() < chunkStart + 8 + chunkSize: vsetChunkStart = bs.tell() vsetChunkType = bs.readUShort() #print([vsetChunkStart,vsetChunkType]) for case in switch(vsetChunkType): if case(0x9B6): vsetVertSize = bs.readInt() vertSize.append(vsetVertSize) #print([vsetChunkType,vsetVertSize]) break if case(0x9BF): vsetUnk01 = bs.readInt() break if case(0x9B9): vsetVertCount = bs.readInt() vertCount.append(vsetVertCount) #print([vsetChunkType,vsetVertCount]) break if case(0x9C4): vsetUnk01 = bs.readInt() break if case(0x9BD): vsetUnk01 = bs.readInt() if vsetUnk01 == 0: Bone_Pallet.append(()) break if case(0x86BE): test = bs.readByte() test = bs.readUByte() BonePallet = bs.read("H"*(test + 1)) Bone_Pallet.append(BonePallet) break if case(0x6BE): test = bs.readByte() test = bs.readUByte() Bone_Pallet.append(()) break if case(0x9C8): vsetUnk01 = bs.readInt() break if case(0x9CC): vsetUnk01 = bs.readInt() break if case(0x9C9): vsetUnk01 = bs.readInt() break if case(0xFD): break bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS) break if case('VTXE'): vtxeOffset.append([chunkStart,chunkSize]) bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS) break if case('MESH'): bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS) break if case('REND'): bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS) break if case('SHAD'): bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS) break if case('SHAP'): bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS) break if case('TSTA'): bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS) break if case('TSET'): bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS) break if case('VTXL'): vtxlOffset.append([chunkStart,chunkSize]) bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS) break if case('TEXF'): bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS) break if case('PSET'): psetOffset.append(chunkStart) bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS) break if case(): # default, could also just omit condition or 'if True' bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS) # No need to break here, it'll stop anyway #bs.readBytes(8).decode("ASCII").rstrip("\0") FaceOff = psetOffset[0] + 18 rapi.rpgSetUVScaleBias(NoeVec3 ((1.0, -1.0, 1.0)), NoeVec3 ((1.0, 1.0, 1.0))) for i in range(0, len(vertSize)): bs.seek(vtxlOffset[i][0] + 18, NOESEEK_ABS) test = bs.readByte() if test == 8: test = bs.readUByte() VertBuff = bs.readBytes(vtxlOffset[i][1] - 12) elif test == 24: test = bs.readInt() VertBuff = bs.readBytes(vtxlOffset[i][1] - 15) else: test = bs.readUShort() VertBuff = bs.readBytes(vtxlOffset[i][1] - 13) bs.seek(vtxeOffset[i][0] + 18, NOESEEK_ABS) for j in range(0, (vtxeOffset[i][1] - 10) // 26): vtxeChunkTypeid = bs.readUShort() vtxeChunkType = bs.readInt() vtxeChunkType2id = bs.readUShort() vtxeChunkType2 = bs.readInt() vtxeChunkPosId = bs.readUShort() vtxeChunkPos = bs.readInt() vtxeChunkUnkid = bs.readUShort() vtxeChunkUnk = bs.readInt() vtxeChunkTerm = bs.readUShort() if vtxeChunkType == 0: rapi.rpgBindPositionBufferOfs(VertBuff, noesis.RPGEODATA_FLOAT, vertSize[i], vtxeChunkPos) elif vtxeChunkType == 1: rapi.rpgBindBoneWeightBufferOfs(VertBuff, noesis.RPGEODATA_FLOAT, vertSize[i], vtxeChunkPos, 4) elif vtxeChunkType == 2: #rapi.rpgBindNormalBufferOfs(VertBuff, noesis.RPGEODATA_FLOAT, vertSize[i], vtxeChunkPos) pass elif vtxeChunkType == 3: rapi.rpgBindColorBufferOfs(VertBuff, noesis.RPGEODATA_UBYTE, vertSize[i], vtxeChunkPos, 4) elif vtxeChunkType == 4: pass#4 bytes as floats 2nd vertex color? elif vtxeChunkType == 11: rapi.rpgBindBoneIndexBufferOfs(VertBuff, noesis.RPGEODATA_UBYTE, vertSize[i], vtxeChunkPos, 4) elif vtxeChunkType == 16: rapi.rpgBindUV1BufferOfs(VertBuff, noesis.RPGEODATA_FLOAT, vertSize[i], vtxeChunkPos) elif vtxeChunkType == 17: rapi.rpgBindUV2BufferOfs(VertBuff, noesis.RPGEODATA_FLOAT, vertSize[i], vtxeChunkPos) elif vtxeChunkType == 32: pass#tangents? elif vtxeChunkType == 33: pass#binormals/tangents? else: print(vtxeChunkType) bs.seek(FaceOff, NOESEEK_ABS) bs.seek(0x1A, NOESEEK_REL) test = bs.readByte() if test == 8: FaceCount = bs.readUByte() FaceBuff = bs.readBytes((FaceCount + 1) * 2) elif test == 16: FaceCount = bs.readUShort() FaceBuff = bs.readBytes((FaceCount + 1) * 2) else: FaceCount = bs.readInt() FaceBuff = bs.readBytes((FaceCount + 1) * 2) bs.seek(0x8, NOESEEK_REL) FaceOff = bs.tell() rapi.rpgSetName(str(i)) rapi.rpgSetMaterial(str(i)) material = NoeMaterial((str(i)), "") if len(Bone_Pallet) > 0: if len(Bone_Pallet[i]) > 0: rapi.rpgSetBoneMap(Bone_Pallet[i]) rapi.rpgCommitTriangles(FaceBuff, noesis.RPGEODATA_USHORT, FaceCount + 1, noesis.RPGEO_TRIANGLE_STRIP, 1) mdl = rapi.rpgConstructModel() mdl.setBones(Bones) mdlList.append(mdl) rapi.rpgClearBufferBinds() return 1
def __init__(self, data): fName = rapi.getInputName().split('\\')[-1][:-4] self.data = NoeBitStream(data) self.magix = noeStrFromBytes(self.data.readBytes(4)) self.version = self.data.readUShort() print("Version:", self.version) self.matList = [] if self.version != 120: self.padding = self.data.readUShort() if self.padding > 0: self.data.seek(self.padding, 1) while not self.data.checkEOF(): current = self.data.tell() chunkID = self.data.readUShort() cSize = self.data.readUInt() if chunkID == 47066: self.skeleton = WZMSkeleton(self.data, self.version) if self.data.tell() != current + cSize: self.data.seek(current + cSize - self.data.tell(), 1) elif chunkID == 47057: if self.version <= 112: print("Skeleton won't show up correctly") mesh = WZMmesh112(self.data, self) elif self.version == 113 or self.version == 114: mesh = WZMmesh112(self.data, self) elif self.version == 117: mesh = WZMmesh117(self.data, self) elif self.version in [118, 119]: mesh = WZMmesh118(self.data, self) elif self.version == 120: mesh = WZMmesh120(self.data, self) else: print("###\nUnknown mesh format\n###\nVersion: %d\n###" % self.version) self.data.seek(cSize - 6, 1) elif chunkID == 47058: if cSize == 8: self.data.seek(2, 1) maxWeight = 1 else: count = self.data.readUShort() maxWeight = 0 extraWeight = [] for i in range(count): extraWeight.append(WZMBoneWeight(self.data)) if extraWeight[-1].count > maxWeight: maxWeight = extraWeight[-1].count else: try: self.data.seek(cSize - 6, 1) except: print(self.data.tell(), cSize) break for subMesh in mesh.subMesh: vertBuffer = b'' for i in range(subMesh.numVert): vert = subMesh.vertBuff[i] vertBuffer += mesh.posBuffer[vert.vertID] vertBuffer += vert.normal vertBuffer += vert.tangent vertBuffer += vert.uv rapi.rpgBindPositionBufferOfs(vertBuffer, noesis.RPGEODATA_FLOAT, 44, 0) if self.version == 112: rapi.rpgSetPosScaleBias((1, -1, 1), (0, 0, -5)) rapi.rpgBindNormalBufferOfs(vertBuffer, noesis.RPGEODATA_FLOAT, 44, 12) rapi.rpgBindTangentBufferOfs(vertBuffer, noesis.RPGEODATA_FLOAT, 44, 24) rapi.rpgBindUV1BufferOfs(vertBuffer, noesis.RPGEODATA_FLOAT, 44, 36) wB = NoeBitStream() weightLength = maxWeight * 6 for i in range(subMesh.numVert): vert = subMesh.vertBuff[i] if vert.boneID >= 0: wB.writeUShort(vert.boneID) for n in range(maxWeight - 1): wB.writeUShort(0) wB.writeFloat(1) for n in range(maxWeight - 1): wB.writeFloat(0) else: ID = abs(vert.boneID) - 1 weight = extraWeight[ID] for bID in weight.boneID: wB.writeUShort(bID) for n in range(maxWeight - len(weight.boneID)): wB.writeUShort(0) for bW in weight.weight: wB.writeFloat(bW) for n in range(maxWeight - len(weight.weight)): wB.writeFloat(0) weightBuffer = wB.getBuffer() rapi.rpgBindBoneIndexBufferOfs(weightBuffer, noesis.RPGEODATA_USHORT, weightLength, 0, maxWeight) rapi.rpgBindBoneWeightBufferOfs(weightBuffer, noesis.RPGEODATA_FLOAT, weightLength, maxWeight * 2, maxWeight) material = NoeMaterial(subMesh.diffuse, subMesh.diffuse) material.setSpecularTexture(subMesh.specular) self.matList.append(material) rapi.rpgSetMaterial(subMesh.diffuse) rapi.rpgSetName(fName) rapi.rpgCommitTriangles(subMesh.idxBuffer, noesis.RPGEODATA_UINT, subMesh.numIdx * 3, noesis.RPGEO_TRIANGLE, 1)
def noepyLoadModel(data, mdlList): bs = NoeBitStream(data) if bs.readInt() != NOEPY_HEADER: return 0 if bs.readInt() != NOEPY_VERSION: return 0 #no need to explicitly free the context (created contexts are auto-freed after the handler), but DO NOT hold any references to it outside of this method ctx = rapi.rpgCreateContext() numMeshes = bs.readInt() for i in range(0, numMeshes): meshName = bs.readString() meshMat = bs.readString() numIdx = bs.readInt() numPos = bs.readInt() numNrm = bs.readInt() numUVs = bs.readInt() numTan = bs.readInt() numClr = bs.readInt() numWeights = bs.readInt() numBoneRefs = bs.readInt() if numBoneRefs > 0: boneMap = bs.read("i" * numBoneRefs) rapi.rpgSetBoneMap(boneMap) #set the bone map rapi.rpgSetName(meshName) rapi.rpgSetMaterial(meshMat) triangles = bs.readBytes(numIdx * 4) positions = bs.readBytes(numPos * 12) normals = bs.readBytes(numPos * 12) if numNrm == numPos else None uvs = bs.readBytes(numPos * 12) if numUVs == numPos else None tans = bs.readBytes(numPos * 48) if numTan == numPos else None colors = bs.readBytes(numPos * 16) if numClr == numPos else None rapi.rpgBindPositionBuffer(positions, noesis.RPGEODATA_FLOAT, 12) rapi.rpgBindNormalBuffer(normals, noesis.RPGEODATA_FLOAT, 12) rapi.rpgBindUV1Buffer(uvs, noesis.RPGEODATA_FLOAT, 12) rapi.rpgBindColorBuffer(colors, noesis.RPGEODATA_FLOAT, 16, 4) if numWeights > 0: vwList = [] for j in range(0, numWeights): vwNum = bs.readInt() bidx = [] bwgt = [] for k in range(0, vwNum): bidx.append(bs.readInt()) for k in range(0, vwNum): bwgt.append(bs.readFloat()) vwList.append(NoeVertWeight(bidx, bwgt)) fw = NoeFlatWeights(vwList) rapi.rpgBindBoneIndexBuffer(fw.flatW[:fw.weightValOfs], noesis.RPGEODATA_INT, 4 * fw.weightsPerVert, fw.weightsPerVert) rapi.rpgBindBoneWeightBuffer(fw.flatW[fw.weightValOfs:], noesis.RPGEODATA_FLOAT, 4 * fw.weightsPerVert, fw.weightsPerVert) numMorphFrames = bs.readInt() for j in range(0, numMorphFrames): numMFPos = bs.readInt() numMFNrm = bs.readInt() morphPosAr = bs.readBytes(numMFPos * 12) rapi.rpgFeedMorphTargetPositions(morphPosAr, noesis.RPGEODATA_FLOAT, 12) if numMFNrm > 0: morphNrmAr = bs.readBytes(numMFNrm * 12) rapi.rpgFeedMorphTargetNormals(morphNrmAr, noesis.RPGEODATA_FLOAT, 12) rapi.rpgCommitMorphFrame(numMFPos) rapi.rpgCommitMorphFrameSet() rapi.rpgCommitTriangles(triangles, noesis.RPGEODATA_INT, numIdx, noesis.RPGEO_TRIANGLE, 1) rapi.rpgClearBufferBinds( ) #reset in case a subsequent mesh doesn't have the same components mdl = rapi.rpgConstructModel() bones = [] numBones = bs.readInt() for i in range(0, numBones): bone = noepyReadBone(bs) bones.append(bone) anims = [] numAnims = bs.readInt() for i in range(0, numAnims): animName = bs.readString() numAnimBones = bs.readInt() animBones = [] for j in range(0, numAnimBones): animBone = noepyReadBone(bs) animBones.append(animBone) animNumFrames = bs.readInt() animFrameRate = bs.readFloat() numFrameMats = bs.readInt() animFrameMats = [] for j in range(0, numFrameMats): frameMat = NoeMat43.fromBytes(bs.readBytes(48)) animFrameMats.append(frameMat) anim = NoeAnim(animName, animBones, animNumFrames, animFrameMats, animFrameRate) anims.append(anim) mdl.setBones(bones) mdl.setAnims(anims) mdlList.append( mdl) #important, don't forget to put your loaded model in the mdlList return 1
def noepyLoadModel(data, mdlList): bs = NoeBitStream(data) if bs.readInt() != NOEPY_HEADER: return 0 if bs.readInt() != NOEPY_VERSION: return 0 #no need to explicitly free the context (created contexts are auto-freed after the handler), but DO NOT hold any references to it outside of this method ctx = rapi.rpgCreateContext() numMeshes = bs.readInt() for i in range(0, numMeshes): meshName = bs.readString() meshMat = bs.readString() numIdx = bs.readInt() numPos = bs.readInt() numNrm = bs.readInt() numUVs = bs.readInt() numTan = bs.readInt() numClr = bs.readInt() numWeights = bs.readInt() numBoneRefs = bs.readInt() if numBoneRefs > 0: boneMap = bs.read("i"*numBoneRefs) rapi.rpgSetBoneMap(boneMap) #set the bone map rapi.rpgSetName(meshName) rapi.rpgSetMaterial(meshMat) triangles = bs.readBytes(numIdx * 4) positions = bs.readBytes(numPos * 12) normals = bs.readBytes(numPos * 12) if numNrm == numPos else None uvs = bs.readBytes(numPos * 12) if numUVs == numPos else None tans = bs.readBytes(numPos * 48) if numTan == numPos else None colors = bs.readBytes(numPos * 16) if numClr == numPos else None rapi.rpgBindPositionBuffer(positions, noesis.RPGEODATA_FLOAT, 12) rapi.rpgBindNormalBuffer(normals, noesis.RPGEODATA_FLOAT, 12) rapi.rpgBindUV1Buffer(uvs, noesis.RPGEODATA_FLOAT, 12) rapi.rpgBindColorBuffer(colors, noesis.RPGEODATA_FLOAT, 16, 4) if numWeights > 0: vwList = [] for j in range(0, numWeights): vwNum = bs.readInt() bidx = [] bwgt = [] for k in range(0, vwNum): bidx.append(bs.readInt()) for k in range(0, vwNum): bwgt.append(bs.readFloat()) vwList.append(NoeVertWeight(bidx, bwgt)) fw = NoeFlatWeights(vwList) rapi.rpgBindBoneIndexBuffer(fw.flatW[:fw.weightValOfs], noesis.RPGEODATA_INT, 4*fw.weightsPerVert, fw.weightsPerVert) rapi.rpgBindBoneWeightBuffer(fw.flatW[fw.weightValOfs:], noesis.RPGEODATA_FLOAT, 4*fw.weightsPerVert, fw.weightsPerVert) numMorphFrames = bs.readInt() for j in range(0, numMorphFrames): numMFPos = bs.readInt() numMFNrm = bs.readInt() morphPosAr = bs.readBytes(numMFPos * 12) rapi.rpgFeedMorphTargetPositions(morphPosAr, noesis.RPGEODATA_FLOAT, 12) if numMFNrm > 0: morphNrmAr = bs.readBytes(numMFNrm * 12) rapi.rpgFeedMorphTargetNormals(morphNrmAr, noesis.RPGEODATA_FLOAT, 12) rapi.rpgCommitMorphFrame(numMFPos) rapi.rpgCommitMorphFrameSet() rapi.rpgCommitTriangles(triangles, noesis.RPGEODATA_INT, numIdx, noesis.RPGEO_TRIANGLE, 1) rapi.rpgClearBufferBinds() #reset in case a subsequent mesh doesn't have the same components mdl = rapi.rpgConstructModel() bones = [] numBones = bs.readInt() for i in range(0, numBones): bone = noepyReadBone(bs) bones.append(bone) anims = [] numAnims = bs.readInt() for i in range(0, numAnims): animName = bs.readString() numAnimBones = bs.readInt() animBones = [] for j in range(0, numAnimBones): animBone = noepyReadBone(bs) animBones.append(animBone) animNumFrames = bs.readInt() animFrameRate = bs.readFloat() numFrameMats = bs.readInt() animFrameMats = [] for j in range(0, numFrameMats): frameMat = NoeMat43.fromBytes(bs.readBytes(48)) animFrameMats.append(frameMat) anim = NoeAnim(animName, animBones, animNumFrames, animFrameMats, animFrameRate) anims.append(anim) mdl.setBones(bones) mdl.setAnims(anims) mdlList.append(mdl) #important, don't forget to put your loaded model in the mdlList return 1
def noepyLoadModel(data, mdlList): ctx = rapi.rpgCreateContext() bs = NoeBitStream(data) bs.setEndian(NOE_BIGENDIAN) rapi.rpgSetOption(noesis.RPGOPT_BIGENDIAN, 1) fvfInto = [] texList = [] matList = [] header = bs.readBytes(4).decode("ASCII") version1 = bs.readInt() version2 = bs.readInt() modelSize = bs.readInt() unk01 = bs.readUShort() sceneName = bs.readBytes(30).decode("ASCII").rstrip("\0") offset00 = bs.readInt()#Bone Matrix / Parent / 0x80 count00 = bs.readInt() offset01 = bs.readInt()#info related to section before last? / 0x40 count01 = bs.readInt() faceInfoOff = bs.readInt()#Face Info /0x40 faceInfoSize = bs.readInt() materialOff = bs.readInt() materialCount = bs.readInt() offset04 = bs.readInt()#? / 0x10 count04 = bs.readInt() offset05 = bs.readInt()#Some Matrix / 0x40 count05 = bs.readInt() vertInfoOff = bs.readInt()#Vertex Info / 0x20 vertInfoSize = bs.readInt() vertOff = bs.readInt()#Vertex Start / 1 vertOffSize = bs.readInt() texOff = bs.readInt()#Some Names / 0x20 texCount = bs.readInt() offset09 = bs.readInt()#Some Names / 0x20 count09 = bs.readInt() offset10 = bs.readInt()#Bone Names / 0x20 count10 = bs.readInt() faceOff = bs.readInt()#Some Face Info / 2 faceOffSize = bs.readInt() offset12 = bs.readInt()#? / 1 count12 = bs.readInt() offset13 = bs.readInt()#? / 1 count13 = bs.readInt() texName = [] bs.seek(texOff, NOESEEK_ABS) for i in range(0, texCount): id = bs.readUShort() tmp = bs.readBytes(30).decode("ASCII").rstrip("\0") texName.append(tmp) bs.seek(materialOff, NOESEEK_ABS) for i in range(0, materialCount): matInfo = bs.read(">" + "h"*32) matInfo2 = bs.read(">" + "f"*16) material = NoeMaterial((str(i)), "") if matInfo[17] != -1: material.setTexture(texName[matInfo[17]] + ".dds") matList.append(material) #print(matInfo) faceInfo = [] bs.seek(faceInfoOff, NOESEEK_ABS) for i in range(0, faceInfoSize): faceInfoTmp = bs.read(">iiiiiiiiiiiiiiii") #print(faceInfoTmp) faceInfo.append(faceInfoTmp) #for i in range(0, faceInfoSize): # print(faceInfo[i]) from operator import itemgetter faceInfo = sorted(faceInfo, key=itemgetter(2,1)) #for i in range(0, faceInfoSize): #print(faceInfo[i]) faceInfo2 = [] for i in range(0, vertInfoSize): tmp = [] for a in range(0, faceInfoSize): if faceInfo[a][2] == i: tmp.append(faceInfo[a]) faceInfo2.append(tmp) #print(faceInfo2) bs.seek(vertInfoOff, NOESEEK_ABS) for i in range(0, vertInfoSize): meshID = bs.readInt() vertCount = bs.readInt() fvf00 = bs.readUByte() fvf01 = bs.readUByte() fvf02 = bs.readUByte() fvf03 = bs.readUByte() fvf04 = bs.readUByte() fvf05 = bs.readUByte() fvf06 = bs.readUByte() fvf07 = bs.readUByte() vertStart = bs.readInt() vertDataSize = bs.readInt() vertSize = bs.readInt() null = bs.readInt() fvfInto.append([meshID,vertCount,vertStart,vertDataSize,vertSize,fvf00,fvf01,fvf02,fvf03,fvf04,fvf05,fvf06,fvf07]) print(fvfInto) for i in range(0, vertInfoSize): bs.seek((vertOff + fvfInto[i][2]), NOESEEK_ABS) VertBuff = bs.readBytes(fvfInto[i][3]) rapi.rpgBindPositionBufferOfs(VertBuff, noesis.RPGEODATA_FLOAT, fvfInto[i][4], 0) if fvfInto[i][8] == 4: rapi.rpgBindUV1BufferOfs(VertBuff, noesis.RPGEODATA_HALFFLOAT, fvfInto[i][4], (fvfInto[i][4] - 4)) if fvfInto[i][8] == 0x44: rapi.rpgBindUV1BufferOfs(VertBuff, noesis.RPGEODATA_HALFFLOAT, fvfInto[i][4], (fvfInto[i][4] - 8)) for a in range(0, len(faceInfo2[i])): rapi.rpgSetName(str(faceInfo2[i][a][1])) rapi.rpgSetMaterial(str(faceInfo2[i][a][1])) bs.seek(faceOff + (2 * faceInfo2[i][a][5]), NOESEEK_ABS) FaceBuff = bs.readBytes(faceInfo2[i][a][4] * 2) rapi.rpgCommitTriangles(FaceBuff, noesis.RPGEODATA_USHORT, faceInfo2[i][a][4], noesis.RPGEO_TRIANGLE, 1) bs.seek(faceOff + (2 * faceInfo2[i][a][7]), NOESEEK_ABS) FaceBuff = bs.readBytes(faceInfo2[i][a][6] * 2) rapi.rpgCommitTriangles(FaceBuff, noesis.RPGEODATA_USHORT, faceInfo2[i][a][6], noesis.RPGEO_TRIANGLE_STRIP, 1) bs.seek(faceOff + (2 * faceInfo2[i][a][9]), NOESEEK_ABS) FaceBuff = bs.readBytes(faceInfo2[i][a][8] * 2) rapi.rpgCommitTriangles(FaceBuff, noesis.RPGEODATA_USHORT, faceInfo2[i][a][8], noesis.RPGEO_TRIANGLE_STRIP, 1) mdl = rapi.rpgConstructModel() mdl.setModelMaterials(NoeModelMaterials(texList, matList)) mdlList.append(mdl) rapi.rpgClearBufferBinds() return 1
def noepyLoadModel(data, mdlList): ctx = rapi.rpgCreateContext() bs = NoeBitStream(data) #rapi.rpgSetPosScaleBias((-1,-1,1),(0,0,0)) boneList = [] boneCount = bs.readInt() boneOffset = bs.tell() + bs.readInt() texCount = bs.readInt() texOffset = bs.tell() + bs.readInt() matCount = bs.readInt() matOffset = bs.tell() + bs.readInt() meshCount = bs.readInt() meshOffset = bs.tell() + bs.readInt() bs.seek(boneOffset, NOESEEK_ABS) for i in range(0, boneCount): boneName = bs.readBytes(0x20).decode("ASCII").rstrip("\0") boneMtx = NoeMat44.fromBytes(bs.readBytes(0x40)).toMat43() bs.readBytes(0x40) boneParent = bs.readInt() bs.readBytes(0x8) pos = NoeVec3.fromBytes(bs.readBytes(12)) bs.readBytes(0x8) quat = NoeQuat.fromBytes(bs.readBytes(16)) NoeVec3.fromBytes(bs.readBytes(12)) bs.readBytes(0x14) boneMtx = quat.toMat43() boneMtx[3] = pos newBone = NoeBone(i, boneName, boneMtx, None, boneParent) boneList.append(newBone) boneList = rapi.multiplyBones(boneList) texInfo = [] texList = [] bs.seek(texOffset, NOESEEK_ABS) for i in range(0, texCount): texName = bs.readBytes(0x20).decode("ASCII").rstrip("\0") texStart = bs.tell() + bs.readInt() bs.readBytes(0xC) texInfo.append([texName,texStart]) #print(texInfo) for i in range(0, texCount): bs.seek(texInfo[i][1], NOESEEK_ABS) bs.readBytes(0xC) palOff = bs.tell() + bs.readInt() texType, unk02, pixWidth, pixHeight, unk03, unk04 = bs.read("6H") texSize = bs.readInt() texOff = bs.tell() + bs.readInt() bs.seek(texOff, NOESEEK_ABS) texData = bs.readBytes(texSize) bs.seek(palOff, NOESEEK_ABS) unk11, unk22 = bs.read("2H") palSize, Null = bs.read("2I") palStart = bs.tell() + bs.readInt() bs.seek(palStart, NOESEEK_ABS) palData = [] for a in range(0, palSize // 4): pR, pG, pB, pA = bs.read("4B") if pR == 0 and pG == 255 and pB == 0 and pA == 255: pG = 0 pA = 0 palData.append(pR) palData.append(pG) palData.append(pB) palData.append(pA) palData = struct.pack("<" + 'B'*len(palData), *palData) if texType == 5: pix = rapi.imageUntwiddlePSP(texData, pixWidth, pixHeight, 8) pix = rapi.imageDecodeRawPal(pix, palData, pixWidth, pixHeight, 8, "r8g8b8a8") elif texType == 4: pix = rapi.imageUntwiddlePSP(texData, pixWidth, pixHeight, 4) pix = rapi.imageDecodeRawPal(pix, palData, pixWidth, pixHeight, 4, "r8g8b8a8") texList.append(NoeTexture(texInfo[i][0], pixWidth, pixHeight, pix, noesis.NOESISTEX_RGBA32)) matList = [] bs.seek(matOffset, NOESEEK_ABS) for i in range(0, matCount): matName = bs.readBytes(0x20).decode("ASCII").rstrip("\0") bs.readBytes(0xC) texID = bs.readInt() unk01, unk02, unk03, unk04 = bs.read("4B") bs.readBytes(0x8) material = NoeMaterial(matName, "") if texID >= 0: material.setTexture(texInfo[texID][0]) #material.setOpacityTexture(texInfo[texID][0]) matList.append(material) meshList = [] bs.seek(meshOffset, NOESEEK_ABS) for i in range(0, meshCount): meshName = bs.readBytes(0x20).decode("ASCII").rstrip("\0") mshCount = bs.readInt() unk11 = bs.readInt() meshStart = bs.tell() + bs.readInt() bs.readBytes(0xC) meshList.append([meshName, meshStart, mshCount, unk11]) #print(meshList) for a in range(0, len(meshList)): mshInfo = [] #print(meshList[a][0]) bs.seek(meshList[a][1], NOESEEK_ABS) for b in range(0, meshList[a][2]): unk20 = bs.readInt() matID = bs.readInt() mshC = bs.readInt() MshOff = bs.tell() + bs.readInt() mshInfo.append([matID, mshC, MshOff]) #print(mshInfo) mshInfo2 = [] for b in range(0, len(mshInfo)): bs.seek(mshInfo[b][2], NOESEEK_ABS) for c in range(0, mshInfo[b][1]): meshPc = bs.readInt() vType = bs.readInt() meshPc2 = bs.readInt() mshPo = bs.tell() + bs.readInt() mshPo2 = bs.tell() + bs.readInt() mshInfo2.append([meshPc, vType, meshPc2, mshPo, mshPo2, matList[(mshInfo[b][0])].name]) #print(mshInfo2) for b in range(0, len(mshInfo2)): mshInfo3 = [] rapi.rpgSetMaterial(mshInfo2[b][5]) bs.seek(mshInfo2[b][3], NOESEEK_ABS) idxList = [[0, 0, 0, 0, 0, 0, 0, 0]] for c in range(0, mshInfo2[b][2]): idxList[0][c] = bs.readInt() bs.seek(mshInfo2[b][4], NOESEEK_ABS) #print(idxList) for c in range(0, mshInfo2[b][0]): mshId2 = bs.readInt() vertCount = bs.readInt() vertStart = bs.tell() + bs.readInt() mshInfo3.append([mshId2, vertCount, vertStart]) #print(mshInfo3) for c in range(0, len(mshInfo3)): #print(mshInfo3[c]) bs.seek(mshInfo3[c][2], NOESEEK_ABS) rapi.rpgSetName(meshList[a][0]) #rapi.rpgSetName(meshList[a][0] + "_" + str(b) + "_" + str(c) + "_" + str(mshInfo2[b][1])) vertStride = 0 if mshInfo2[b][1] == 7: vertStride = 0x18 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0xC) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x8, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0) elif mshInfo2[b][1] == 24: vertStride = 0x1C vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x10) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0xC, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x4) elif mshInfo2[b][1] == 25: vertStride = 0x1C vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x10) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0xC, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x4) elif mshInfo2[b][1] == 26: vertStride = 0x20 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x14) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x10, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x8) elif mshInfo2[b][1] == 27: vertStride = 0x20 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x14) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x10, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x8) elif mshInfo2[b][1] == 28: vertStride = 0x24 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x18) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x14, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0xC) elif mshInfo2[b][1] == 29: vertStride = 0x24 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x18) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x14, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0xC) elif mshInfo2[b][1] == 30: vertStride = 0x28 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x1C) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x18, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x10) elif mshInfo2[b][1] == 23: vertStride = 0x28 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x1C) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x18, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x10) else: print(bs.tell()) print("unknown found " + str(mshInfo2[b][1])) vs = NoeBitStream(vertBuff) tmp = [] tmp2 = [] weight = [] index = [] if vertStride == 0x18: for d in range(0, mshInfo3[c][1]): w1, w2, w3, w4, w5, w6, w7, w8 = [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] index.append(idxList[0][0]); index.append(idxList[0][1]); index.append(idxList[0][2]); index.append(idxList[0][3]) index.append(idxList[0][4]); index.append(idxList[0][5]); index.append(idxList[0][6]); index.append(idxList[0][7]) weight.append(w1); weight.append(w2); weight.append(w3); weight.append(w4); weight.append(w5); weight.append(w6); weight.append(w7); weight.append(w8) vs.readBytes(0xC) tmp.append([vs.readUInt(), vs.readUInt(), vs.readUInt()]) elif vertStride == 0x1C: for d in range(0, mshInfo3[c][1]): w1, w2, w3, w4, w5, w6, w7, w8 = [vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] index.append(idxList[0][0]); index.append(idxList[0][1]); index.append(idxList[0][2]); index.append(idxList[0][3]) index.append(idxList[0][4]); index.append(idxList[0][5]); index.append(idxList[0][6]); index.append(idxList[0][7]) weight.append(w1); weight.append(w2); weight.append(w3); weight.append(w4); weight.append(w5); weight.append(w6); weight.append(w7); weight.append(w8) vs.readBytes(0xC) tmp.append([vs.readUInt(), vs.readUInt(), vs.readUInt()]) elif vertStride == 0x20: for d in range(0, mshInfo3[c][1]): w1, w2, w3, w4, w5, w6, w7, w8 = [vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, 0.0, 0.0, 0.0, 0.0] index.append(idxList[0][0]); index.append(idxList[0][1]); index.append(idxList[0][2]); index.append(idxList[0][3]) index.append(idxList[0][4]); index.append(idxList[0][5]); index.append(idxList[0][6]); index.append(idxList[0][7]) weight.append(w1); weight.append(w2); weight.append(w3); weight.append(w4); weight.append(w5); weight.append(w6); weight.append(w7); weight.append(w8) vs.readBytes(0xC) tmp.append([vs.readUInt(), vs.readUInt(), vs.readUInt()]) elif vertStride == 0x24: for d in range(0, mshInfo3[c][1]): w1, w2, w3, w4, w5, w6, w7, w8 = [vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, 0.0, 0.0] index.append(idxList[0][0]); index.append(idxList[0][1]); index.append(idxList[0][2]); index.append(idxList[0][3]) index.append(idxList[0][4]); index.append(idxList[0][5]); index.append(idxList[0][6]); index.append(idxList[0][7]) weight.append(w1); weight.append(w2); weight.append(w3); weight.append(w4); weight.append(w5); weight.append(w6); weight.append(w7); weight.append(w8) vs.readBytes(0xC) tmp.append([vs.readUInt(), vs.readUInt(), vs.readUInt()]) elif vertStride == 0x28: for d in range(0, mshInfo3[c][1]): w1, w2, w3, w4, w5, w6, w7, w8 = [vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF] index.append(idxList[0][0]); index.append(idxList[0][1]); index.append(idxList[0][2]); index.append(idxList[0][3]) index.append(idxList[0][4]); index.append(idxList[0][5]); index.append(idxList[0][6]); index.append(idxList[0][7]) weight.append(w1); weight.append(w2); weight.append(w3); weight.append(w4); weight.append(w5); weight.append(w6); weight.append(w7); weight.append(w8) vs.readBytes(0xC) tmp.append([vs.readUInt(), vs.readUInt(), vs.readUInt()]) indexBuff = struct.pack('B'*len(index), *index) weightBuff = struct.pack('f'*len(weight), *weight) rapi.rpgBindBoneIndexBuffer(indexBuff, noesis.RPGEODATA_BYTE, 8, 8) rapi.rpgBindBoneWeightBuffer(weightBuff, noesis.RPGEODATA_FLOAT, 0x20, 8) flip = 0 step = 1 if mshInfo3[c][0] == 0: step = 3 for d in range(0, mshInfo3[c][1] - 2, step): if (tmp[d] != tmp[(d + 1)]) and (tmp[d] != tmp[(d + 2)]) and (tmp[d + 1] != tmp[(d + 2)]): tmp2.append(d) tmp2.append(d + 1 + flip) tmp2.append(d + 2 - flip) if mshInfo3[c][0] != 0: flip = 1 - flip else: flip = 0 #print(d) faceBuff = struct.pack('H'*len(tmp2), *tmp2) if len(faceBuff) > 3: rapi.rpgCommitTriangles(faceBuff, noesis.RPGEODATA_USHORT, len(tmp2), noesis.RPGEO_TRIANGLE, 1) rapi.rpgClearBufferBinds() mdl = rapi.rpgConstructModel() mdl.setModelMaterials(NoeModelMaterials(texList, matList)) mdlList.append(mdl) mdl.setBones(boneList) return 1
def __init__(self,data): fName=rapi.getInputName().split('\\')[-1][:-4] self.data = NoeBitStream(data) self.magix = noeStrFromBytes(self.data.readBytes(4)) self.version = self.data.readUShort() print("Version:",self.version) self.matList = [] if self.version != 120: self.padding = self.data.readUShort() if self.padding >0: self.data.seek(self.padding,1) while not self.data.checkEOF(): current = self.data.tell() chunkID = self.data.readUShort() cSize = self.data.readUInt() if chunkID == 47066: self.skeleton = WZMSkeleton(self.data,self.version) if self.data.tell() != current + cSize:self.data.seek(current + cSize - self.data.tell(),1) elif chunkID == 47057: if self.version <=112: print("Skeleton won't show up correctly") mesh = WZMmesh112(self.data,self) elif self.version == 113 or self.version == 114: mesh = WZMmesh112(self.data,self) elif self.version == 117: mesh = WZMmesh117(self.data,self) elif self.version in [118,119]: mesh = WZMmesh118(self.data,self) elif self.version == 120: mesh = WZMmesh120(self.data,self) else:print("###\nUnknown mesh format\n###\nVersion: %d\n###"%self.version);self.data.seek(cSize - 6,1) elif chunkID == 47058: if cSize == 8:self.data.seek(2,1);maxWeight = 1 else: count = self.data.readUShort() maxWeight = 0 extraWeight = [] for i in range(count): extraWeight.append(WZMBoneWeight(self.data)) if extraWeight[-1].count > maxWeight:maxWeight = extraWeight[-1].count else: try:self.data.seek(cSize - 6,1) except: print(self.data.tell(),cSize) break for subMesh in mesh.subMesh: vertBuffer = b'' for i in range(subMesh.numVert): vert = subMesh.vertBuff[i] vertBuffer += mesh.posBuffer[vert.vertID] vertBuffer += vert.normal vertBuffer += vert.tangent vertBuffer += vert.uv rapi.rpgBindPositionBufferOfs(vertBuffer, noesis.RPGEODATA_FLOAT, 44, 0) if self.version == 112: rapi.rpgSetPosScaleBias((1,-1,1),(0,0,-5)) rapi.rpgBindNormalBufferOfs(vertBuffer, noesis.RPGEODATA_FLOAT, 44, 12) rapi.rpgBindTangentBufferOfs(vertBuffer, noesis.RPGEODATA_FLOAT, 44, 24) rapi.rpgBindUV1BufferOfs(vertBuffer, noesis.RPGEODATA_FLOAT, 44, 36) wB = NoeBitStream() weightLength = maxWeight * 6 for i in range(subMesh.numVert): vert = subMesh.vertBuff[i] if vert.boneID >= 0: wB.writeUShort(vert.boneID) for n in range(maxWeight - 1): wB.writeUShort(0) wB.writeFloat(1) for n in range(maxWeight - 1): wB.writeFloat(0) else: ID = abs(vert.boneID)-1 weight = extraWeight[ID] for bID in weight.boneID: wB.writeUShort(bID) for n in range(maxWeight - len(weight.boneID)): wB.writeUShort(0) for bW in weight.weight: wB.writeFloat(bW) for n in range(maxWeight - len(weight.weight)): wB.writeFloat(0) weightBuffer = wB.getBuffer() rapi.rpgBindBoneIndexBufferOfs(weightBuffer, noesis.RPGEODATA_USHORT, weightLength, 0, maxWeight) rapi.rpgBindBoneWeightBufferOfs(weightBuffer, noesis.RPGEODATA_FLOAT, weightLength, maxWeight*2, maxWeight) material = NoeMaterial(subMesh.diffuse,subMesh.diffuse) material.setSpecularTexture(subMesh.specular) self.matList.append(material) rapi.rpgSetMaterial(subMesh.diffuse) rapi.rpgSetName(fName) rapi.rpgCommitTriangles(subMesh.idxBuffer,noesis.RPGEODATA_UINT, subMesh.numIdx*3, noesis.RPGEO_TRIANGLE, 1)
def psaLoadModel(data, mdlList): ctx = rapi.rpgCreateContext() bs = NoeBitStream(data) bs.setEndian(NOE_BIGENDIAN) rapi.rpgSetOption(noesis.RPGOPT_BIGENDIAN, 1) rapi.rpgSetOption(noesis.RPGOPT_TRIWINDBACKWARD, 1) IdMagic = bs.readBytes(4).decode("ASCII") version = bs.readUInt() modelCount = bs.readUInt() fvfTableOffset = bs.readUInt() bs.seek(fvfTableOffset, NOESEEK_ABS) for i in range(0, modelCount): bs.seek(fvfTableOffset + (0x80 * i), NOESEEK_ABS) bs.seek(0x08, NOESEEK_REL) vertexCount = bs.readUShort() indexCount = bs.readUShort() #print('Index Count: ' + str(indexCount)) bs.seek(0x04, NOESEEK_REL) indexOffset = bs.readUInt() #print('Index Offset: ' + str(indexOffset)) indexSize = bs.readUShort() unk01 = bs.readUShort() vertexOffset = bs.readUInt() unkown01Offset = bs.readUInt() vertexSize = bs.readUShort() bs.seek(0x5E, NOESEEK_REL) bs.seek(indexOffset, NOESEEK_ABS) # read EDGE indices header numIndices = bs.readUShort() #print('Num Indices: ' + str(numIndices)) indexBase = bs.readUShort() #print('Base Index: ' + str(indexBase)) sequenceSize = bs.readUShort() #print('Sequence Size: ' + str(sequenceSize)) indexBitSize = bs.readUByte() #print('Index Bit Size: ' + str(indexBitSize)) bs.readUByte() # padding # setup sequence bit stream sequenceCount = sequenceSize * 8 #print('Sequence Count: ' + str(sequenceCount)) sequenceBytes = bs.readBytes(sequenceSize) spec = ['data', {"count" : sequenceCount, "spec" : ["value", 1]}] reader = BitReader(spec, BitReader.BIG_ENDIAN) sequenceStream = reader.read(sequenceBytes) # setup triangle bit stream triangleCount = indexCount // 3 #print('Triangle Count: ' + str(triangleCount)) triangleSize = ((triangleCount * 2) + 7) // 8 #print('Trangle Size: ' + str(triangleSize)) triangleBytes = bs.readBytes(triangleSize) spec = ['data', {"count" : triangleCount, "spec" : ["value", 2]}] reader = BitReader(spec, BitReader.BIG_ENDIAN) triangleStream = reader.read(triangleBytes) # setup indices bit stream indicesSize = ((numIndices * indexBitSize) + 7) // 8 #print('Indices Size: ' + str(indicesSize)) #print('Indices Offset: ' + str(bs.getOffset())) indicesBytes = bs.readBytes(indicesSize) spec = ['data', {"count" : numIndices, "spec" : ["value", indexBitSize]}] reader = BitReader(spec, BitReader.BIG_ENDIAN) indicesStream = reader.read(indicesBytes) # indicesStream = NoeBitStream(indicesBytes) # indicesStream.setEndian(NOE_BIGENDIAN) # read delta compressed indices deltaIndices = array('H') for i in range(0, numIndices): value = indicesStream.data[i].value if i == 1: pass #print('Index Bit Value: ' + str(value) + ' Index: ' + str(i)) value -= indexBase if i > 7: value += deltaIndices[i - 8] deltaIndices.append(value) # create sequence indices inputIndices = array('H') sequencedIndex = 0 unorderedIndex = 0 for i in range(0, sequenceCount): value = sequenceStream.data[i].value if value == 0: inputIndices.append(sequencedIndex) sequencedIndex += 1 else: inputIndices.append(deltaIndices[unorderedIndex]) unorderedIndex += 1 # create triangle indices outputIndices = array('H') currentIndex = 0 triangleIndices = [0, 0, 0] # triangleIndices = {0:0, 1:0, 2:0} for i in range(0, triangleCount): value = triangleStream.data[i].value if value == 0: triangleIndices[1] = triangleIndices[2] triangleIndices[2] = inputIndices[currentIndex] currentIndex += 1 elif value == 1: triangleIndices[0] = triangleIndices[2] triangleIndices[2] = inputIndices[currentIndex] currentIndex += 1 elif value == 2: tempIndex = triangleIndices[0] triangleIndices[0] = triangleIndices[1] triangleIndices[1] = tempIndex triangleIndices[2] = inputIndices[currentIndex] currentIndex += 1 else: # value == 3: triangleIndices[0] = inputIndices[currentIndex] currentIndex += 1 triangleIndices[1] = inputIndices[currentIndex] currentIndex += 1 triangleIndices[2] = inputIndices[currentIndex] currentIndex += 1 outputIndices.append(triangleIndices[0]) outputIndices.append(triangleIndices[1]) outputIndices.append(triangleIndices[2]) bs.seek(vertexOffset, NOESEEK_ABS) vertexSize = 16 * vertexCount vertbuff = bs.readBytes(vertexSize) rapi.rpgBindPositionBufferOfs(vertbuff, noesis.RPGEODATA_FLOAT, 16, 0) faceBuff = struct.pack(">" + 'h'*len(outputIndices), *outputIndices) #print(outputIndices[len(outputIndices) - 1]) #print(outputIndices) rapi.rpgSetName(str(i)) #rapi.rpgCommitTriangles(None, noesis.RPGEODATA_USHORT, (vertexSize // 16), noesis.RPGEO_POINTS, 1) rapi.rpgCommitTriangles(faceBuff, noesis.RPGEODATA_USHORT, len(outputIndices), noesis.RPGEO_TRIANGLE, 1) mdl = rapi.rpgConstructModel() mdlList.append(mdl) rapi.rpgClearBufferBinds() return 1
def noepyLoadModel(data, mdlList): LOADANIM = 0 ExportSkin = 1 VertexBool = 0 #Vertex Bool = 1 is Vertex Tint Channel Vertex Bool = 0 is Material Layers #Remember Vertex Colors are BGRA ctx = rapi.rpgCreateContext() bs = NoeBitStream(data) rapi.rpgSetOption(noesis.RPGOPT_MORPH_RELATIVEPOSITIONS, 1) rapi.rpgSetOption(noesis.RPGOPT_MORPH_RELATIVENORMALS, 1) #IDSig = bs.readUInt() #Blank1 = bs.readUInt() #BSphereX = bs.readFloat() #BSphereY = bs.readFloat() #BSphereZ = bs.readFloat() #BSphereThing = bs.readFloat() #UNK1 = bs.readFloat() #BBoxX1 = bs.readFloat() #BBoxY1 = bs.readFloat() #BBoxZ1 = bs.readFloat() #BBoxX2 = bs.readFloat() #BBoxY2 = bs.readFloat() #BBoxZ2 = bs.readFloat() #BBoxScaleX1 = bs.readFloat() #BBoxScaleY1 = bs.readFloat() #BBoxScaleZ1 = bs.readFloat() #BBoxScaleX2 = bs.readFloat() #BBoxScaleY2 = bs.readFloat() #BBoxScaleZ2 = bs.readFloat() #MipConstantUV0 = bs.readFloat() #MipConstantUV1 = bs.readFloat() bs.seek(84, NOESEEK_ABS) posAli = 0 #MTRL STUFF #MatSig = bs.readUInt() MatCount = bs.read("L") MatNames = [] pos = bs.tell() print(MatCount, pos) #MTRL LOOP for i in range(0, MatCount[0]): #MatCharCount = bs.readUInt() #print(MatCharCount) #MatNames.append (bs.readBytes(MatCharCount).decode("ASCII").rstrip("\0")) bs.seek(4, NOESEEK_REL) MatNames.append(bs.readString()) #STBS LOOP print(MatNames) subMeshCount = bs.readUInt() print(subMeshCount) MatID = [] VertCount = [] VertBuffType = [] FaceCount = [] FaceType = [] BoneIDS = [] BIXD = [] BoneIDLOC = [] BoneIDS = [] mdl = [] VertID = [] MorphVertPOS = [] MorphVertNorm = [] MorphFrameCountID = [] MDLWritten = rapi.getInputName() MDLWrite = NoeBitStream() topname = rapi.getExtensionlessName( rapi.getExtensionlessName(rapi.getInputName())) for i in range(0, subMeshCount): BoneIDSPre = [] print("Sub Mesh", i) tsbsSig = bs.readUInt() print(tsbsSig) MatID.append(bs.readUInt()) Blank2 = bs.readUInt() BVXD = bs.readUInt() VertCount.append(bs.readUInt()) VertBuffType.append(bs.readUShort()) print(VertBuffType[i]) MorphFrameCount = bs.readUInt() MorphFrameCountID.append(MorphFrameCount) if MorphFrameCount is 0: print(MorphFrameCount, "Morph Frame Count is 0") if MorphFrameCount is not 0: print(MorphFrameCount, "Morph Frame Count is not 0") n = 0 MorphVertCountList = [] FrameLOC = [] FrameOrder = [] for m in range(0, MorphFrameCount): pos = bs.tell() FrameLOC.append(pos) MorphVertCount = bs.readUInt() MorphVertCountList.append(MorphVertCount) #print("MorphVertCount", MorphVertCount) #n = 0 FrameName = ("Frame_" + str(n)) n = (n + 1) Frame = [] for mv in range(0, MorphVertCount): VertID.append(bs.readUInt()) VertX = bs.readUShort() #pos = bs.tell() #VertX = (VertX / 32767) VertY = bs.readUShort() #pos = bs.tell() #VertY = (VertY / 32767) VertZ = bs.readUShort() #pos = bs.tell() #VertZ = (VertZ / 32767) VertNormX = bs.readUShort() VertNormY = bs.readUShort() VertNormZ = bs.readUShort() bs.seek(8, NOESEEK_REL) #pos = bs.tell() for mc in range(0, MorphFrameCount): FrameOrder.append(bs.readUShort()) FinalMorphCount = bs.readUShort() MorphCharCount = bs.readUInt() MorphName = bs.readString() print(MorphName) if VertBuffType[i] == int(768) or VertBuffType[i] == int(256): bs.seek(3, NOESEEK_REL) pos = bs.tell() BIXD.append(pos) BIXDSig = bs.readUInt() Blank2 = bs.readUInt() FaceCount.append(bs.readUInt()) FaceType.append(bs.readUInt()) pos = bs.tell() BoneIDLOC.append(pos) BoneIDCount = bs.readUByte() for bi in range(0, BoneIDCount): BoneIDSPre.append(bs.readUByte()) BoneIDS.append(BoneIDSPre) bs.seek(56, NOESEEK_REL) if VertBuffType[i] == (1280, ): crap = bs.readUShort() VertBuffType[i] = (1024, ) print("MaterialIDS", MatID) #RigStuff if VertBuffType[0] == int(1024) or VertBuffType[0] == int(768): boneReList = RigStuff(VertBuffType, topname) #MDLSourceStuff MeshExists = rapi.checkFileExists(topname + str(".Mesh")) if MeshExists: MDLFile = rapi.loadIntoByteArray(topname + str(".Mesh")) else: MDLFile = rapi.loadPairedFile("Brutal Legend", ".Mesh") MDL = NoeBitStream(MDLFile) MeshStarts = [] MeshFaceStarts = [] BONINDBUFF = [] #print("MeshStarts", MeshStarts, "MeshFaceStarts", MeshFaceStarts) print("MDL AT ", MDL.tell()) for s in range(0, subMeshCount): Face = [] POS, NORM, TAN, UV1, UV2, COL1, COL2, BI, BW = VertStuff( MDL, VertCount[s], VertBuffType[s]) POS = struct.pack('B' * len(POS), *POS) NORM = struct.pack('B' * len(NORM), *NORM) TAN = struct.pack('B' * len(TAN), *TAN) UV1 = struct.pack('B' * len(UV1), *UV1) UV2 = struct.pack('B' * len(UV2), *UV2) if VertBuffType[s] == int(1024) or VertBuffType[s] == int(512): rapi.rpgBindPositionBuffer(POS, noesis.RPGEODATA_HALFFLOAT, 8) rapi.rpgBindNormalBuffer(NORM, noesis.RPGEODATA_HALFFLOAT, 8) rapi.rpgBindTangentBuffer(TAN, noesis.RPGEODATA_HALFFLOAT, 8) rapi.rpgBindUV1Buffer(UV1, noesis.RPGEODATA_HALFFLOAT, 4) rapi.rpgBindUV2Buffer(UV2, noesis.RPGEODATA_HALFFLOAT, 4) if VertBuffType[s] == int(768) or VertBuffType[s] == int(256): rapi.rpgBindPositionBuffer(POS, noesis.RPGEODATA_FLOAT, 12) rapi.rpgBindNormalBuffer(NORM, noesis.RPGEODATA_FLOAT, 12) #rapi.rpgBindTangentBuffer(TAN, noesis.RPGEODATA_FLOAT, 16) rapi.rpgBindUV1Buffer(UV1, noesis.RPGEODATA_FLOAT, 8) rapi.rpgBindUV2Buffer(UV2, noesis.RPGEODATA_FLOAT, 8) if VertexBool: COL = COL2 else: COL = COL1 COL = struct.pack('B' * len(COL), *COL) #VertColor = BGRA rapi.rpgBindColorBuffer(COL, noesis.RPGEODATA_UBYTE, 4, 4) if VertBuffType[s] == int(1024) or VertBuffType[s] == int(768): rapi.rpgSetBoneMap(BoneIDS[s]) IDS = struct.pack('B' * len(BI), *BI) WEIGHTS = struct.pack('B' * len(BW), *BW) if ExportSkin: print("Bind Skin") rapi.rpgBindBoneIndexBuffer(IDS, noesis.RPGEODATA_BYTE, 4, 4) rapi.rpgBindBoneWeightBuffer(WEIGHTS, noesis.RPGEODATA_UBYTE, 4, 4) FaceBuff = MDL.readBytes(FaceCount[s] * 2) # FaceBuff = struct.pack('H'*len(Face), *Face) if MorphFrameCountID[s] is not 0: ## RETURN = bs.tell() for mf in range(0, MorphFrameCountID[s]): bs.seek(FrameLOC[mf], NOESEEK_ABS) # print(FrameLOC[mf], FlexNames[FrameOrder[mf]]) MorphVertCount = bs.readUInt() FramePOS = [] FrameNorm = [] FrameTan = [] FrameIDS = [] MorphPOS = [] MorphNorm = [] MorphTan = [] for mm in range(0, MorphVertCount): FrameIDS.append(bs.readUInt()) MPOSX = (((bs.readShort() / 32767) * 2)) MPOSY = (((bs.readShort() / 32767) * 2)) MPOSZ = (((bs.readShort() / 32767) * 2)) MNORMX = (((bs.readShort() / 32767) * 2)) MNORMY = (((bs.readShort() / 32767) * 2)) MNORMZ = (((bs.readShort() / 32767) * 2)) MTANX = (((bs.readShort() / 32767) * 2)) MTANY = (((bs.readShort() / 32767) * 2)) MTANZ = (((bs.readShort() / 32767) * 2)) MTANW = (((bs.readShort() / 32767) * 2)) FramePOS.append((float(MPOSX), float(MPOSY), float(MPOSZ))) FrameNorm.append( (float(MNORMX), float(MNORMY), float(MNORMZ))) FrameTan.append((float(MTANX), float(MTANY), float(MTANZ), float(MTANW))) for mv in range(0, VertCount[s]): if mv in FrameIDS: ID = FrameIDS.index(mv) MorphPOS.append(FramePOS[ID]) MorphNorm.append(FrameNorm[ID]) MorphTan.append(FrameTan[ID]) else: MorphPOS.append((float(0.0), float(0.0), float(0.0))) MorphNorm.append((float(0.0), float(0.0), float(0.0))) MorphTan.append( (float(0.0), float(0.0), float(0.0), float(0.0))) MPOSBUFF3 = list(itertools.chain.from_iterable(MorphPOS)) MNORMBUFF = list(itertools.chain.from_iterable(MorphNorm)) MTANBUFF = list(itertools.chain.from_iterable(MorphTan)) #rapi.rpgSetName(MeshName) MPOS = struct.pack('f' * len(MPOSBUFF3), *MPOSBUFF3) MNORM = struct.pack('f' * len(MNORMBUFF), *MNORMBUFF) MTAN = struct.pack('f' * len(MTANBUFF), *MTANBUFF) rapi.rpgFeedMorphTargetPositions(MPOS, noesis.RPGEODATA_FLOAT, 12) rapi.rpgFeedMorphTargetNormals(MNORM, noesis.RPGEODATA_FLOAT, 12) rapi.rpgCommitMorphFrame(VertCount[s]) MPOSBUFF = [] MNORMBUFF = [] MTANBUFF = [] MPOS = None MNORM = None MTAN = None rapi.rpgCommitMorphFrameSet() Mesh = ("Mesh_" + str(s)) MeshName = str(Mesh) rapi.rpgSetName(MeshName) print(MatNames[MatID[s]]) CurrentMaterial = MatNames[MatID[s]] CurrentMaterial = CurrentMaterial.replace('/', '_') rapi.rpgSetMaterial(CurrentMaterial) rapi.rpgSmoothTangents() if FaceType[s] == 2: rapi.rpgCommitTriangles(FaceBuff, noesis.RPGEODATA_USHORT, FaceCount[s], noesis.RPGEO_TRIANGLE, 1) else: rapi.rpgCommitTriangles(FaceBuff, noesis.RPGEODATA_USHORT, FaceCount[s], noesis.RPGEO_TRIANGLE_STRIP, 1) rapi.rpgClearBufferBinds() mdl = rapi.rpgConstructModel() if LOADANIM == (0): print("No Anim") if VertBuffType[0] == int(1024) or VertBuffType[0] == int(768): mdl.setBones(boneReList) mdlList.append( mdl ) #important, don't forget to put your loaded model in the mdlList return 1
def noepyLoadModel(data, mdlList): ctx = rapi.rpgCreateContext() bs = NoeBitStream(data) bs.setEndian(NOE_BIGENDIAN) rapi.rpgSetOption(noesis.RPGOPT_BIGENDIAN, 1) fvfInto = [] texList = [] matList = [] header = bs.readBytes(4).decode("ASCII") version1 = bs.readInt() version2 = bs.readInt() modelSize = bs.readInt() unk01 = bs.readUShort() sceneName = bs.readBytes(30).decode("ASCII").rstrip("\0") offset00 = bs.readInt() #Bone Matrix / Parent / 0x80 count00 = bs.readInt() offset01 = bs.readInt() #info related to section before last? / 0x40 count01 = bs.readInt() faceInfoOff = bs.readInt() #Face Info /0x40 faceInfoSize = bs.readInt() materialOff = bs.readInt() materialCount = bs.readInt() offset04 = bs.readInt() #? / 0x10 count04 = bs.readInt() offset05 = bs.readInt() #Some Matrix / 0x40 count05 = bs.readInt() vertInfoOff = bs.readInt() #Vertex Info / 0x20 vertInfoSize = bs.readInt() vertOff = bs.readInt() #Vertex Start / 1 vertOffSize = bs.readInt() texOff = bs.readInt() #Some Names / 0x20 texCount = bs.readInt() offset09 = bs.readInt() #Some Names / 0x20 count09 = bs.readInt() offset10 = bs.readInt() #Bone Names / 0x20 count10 = bs.readInt() faceOff = bs.readInt() #Some Face Info / 2 faceOffSize = bs.readInt() offset12 = bs.readInt() #? / 1 count12 = bs.readInt() offset13 = bs.readInt() #? / 1 count13 = bs.readInt() texName = [] bs.seek(texOff, NOESEEK_ABS) for i in range(0, texCount): id = bs.readUShort() tmp = bs.readBytes(30).decode("ASCII").rstrip("\0") texName.append(tmp) bs.seek(materialOff, NOESEEK_ABS) for i in range(0, materialCount): matInfo = bs.read(">" + "h" * 32) matInfo2 = bs.read(">" + "f" * 16) material = NoeMaterial((str(i)), "") if matInfo[17] != -1: material.setTexture(texName[matInfo[17]] + ".dds") matList.append(material) #print(matInfo) faceInfo = [] bs.seek(faceInfoOff, NOESEEK_ABS) for i in range(0, faceInfoSize): faceInfoTmp = bs.read(">iiiiiiiiiiiiiiii") #print(faceInfoTmp) faceInfo.append(faceInfoTmp) #for i in range(0, faceInfoSize): # print(faceInfo[i]) from operator import itemgetter faceInfo = sorted(faceInfo, key=itemgetter(2, 1)) #for i in range(0, faceInfoSize): #print(faceInfo[i]) faceInfo2 = [] for i in range(0, vertInfoSize): tmp = [] for a in range(0, faceInfoSize): if faceInfo[a][2] == i: tmp.append(faceInfo[a]) faceInfo2.append(tmp) #print(faceInfo2) bs.seek(vertInfoOff, NOESEEK_ABS) for i in range(0, vertInfoSize): meshID = bs.readInt() vertCount = bs.readInt() fvf00 = bs.readUByte() fvf01 = bs.readUByte() fvf02 = bs.readUByte() fvf03 = bs.readUByte() fvf04 = bs.readUByte() fvf05 = bs.readUByte() fvf06 = bs.readUByte() fvf07 = bs.readUByte() vertStart = bs.readInt() vertDataSize = bs.readInt() vertSize = bs.readInt() null = bs.readInt() fvfInto.append([ meshID, vertCount, vertStart, vertDataSize, vertSize, fvf00, fvf01, fvf02, fvf03, fvf04, fvf05, fvf06, fvf07 ]) print(fvfInto) for i in range(0, vertInfoSize): bs.seek((vertOff + fvfInto[i][2]), NOESEEK_ABS) VertBuff = bs.readBytes(fvfInto[i][3]) rapi.rpgBindPositionBufferOfs(VertBuff, noesis.RPGEODATA_FLOAT, fvfInto[i][4], 0) if fvfInto[i][8] == 4: rapi.rpgBindUV1BufferOfs(VertBuff, noesis.RPGEODATA_HALFFLOAT, fvfInto[i][4], (fvfInto[i][4] - 4)) if fvfInto[i][8] == 0x44: rapi.rpgBindUV1BufferOfs(VertBuff, noesis.RPGEODATA_HALFFLOAT, fvfInto[i][4], (fvfInto[i][4] - 8)) for a in range(0, len(faceInfo2[i])): rapi.rpgSetName(str(faceInfo2[i][a][1])) rapi.rpgSetMaterial(str(faceInfo2[i][a][1])) bs.seek(faceOff + (2 * faceInfo2[i][a][5]), NOESEEK_ABS) FaceBuff = bs.readBytes(faceInfo2[i][a][4] * 2) rapi.rpgCommitTriangles(FaceBuff, noesis.RPGEODATA_USHORT, faceInfo2[i][a][4], noesis.RPGEO_TRIANGLE, 1) bs.seek(faceOff + (2 * faceInfo2[i][a][7]), NOESEEK_ABS) FaceBuff = bs.readBytes(faceInfo2[i][a][6] * 2) rapi.rpgCommitTriangles(FaceBuff, noesis.RPGEODATA_USHORT, faceInfo2[i][a][6], noesis.RPGEO_TRIANGLE_STRIP, 1) bs.seek(faceOff + (2 * faceInfo2[i][a][9]), NOESEEK_ABS) FaceBuff = bs.readBytes(faceInfo2[i][a][8] * 2) rapi.rpgCommitTriangles(FaceBuff, noesis.RPGEODATA_USHORT, faceInfo2[i][a][8], noesis.RPGEO_TRIANGLE_STRIP, 1) mdl = rapi.rpgConstructModel() mdl.setModelMaterials(NoeModelMaterials(texList, matList)) mdlList.append(mdl) rapi.rpgClearBufferBinds() return 1
def noepyLoadModel(data, mdlList): ctx = rapi.rpgCreateContext() bs = NoeBitStream(data) #rapi.rpgSetPosScaleBias((-1,-1,1),(0,0,0)) boneList = [] boneCount = bs.readInt() boneOffset = bs.tell() + bs.readInt() texCount = bs.readInt() texOffset = bs.tell() + bs.readInt() matCount = bs.readInt() matOffset = bs.tell() + bs.readInt() meshCount = bs.readInt() meshOffset = bs.tell() + bs.readInt() bs.seek(boneOffset, NOESEEK_ABS) for i in range(0, boneCount): boneName = bs.readBytes(0x20).decode("ASCII").rstrip("\0") boneMtx = NoeMat44.fromBytes(bs.readBytes(0x40)).toMat43() bs.readBytes(0x40) boneParent = bs.readInt() bs.readBytes(0x8) pos = NoeVec3.fromBytes(bs.readBytes(12)) bs.readBytes(0x8) quat = NoeQuat.fromBytes(bs.readBytes(16)) NoeVec3.fromBytes(bs.readBytes(12)) bs.readBytes(0x14) boneMtx = quat.toMat43() boneMtx[3] = pos newBone = NoeBone(i, boneName, boneMtx, None, boneParent) boneList.append(newBone) boneList = rapi.multiplyBones(boneList) texInfo = [] texList = [] bs.seek(texOffset, NOESEEK_ABS) for i in range(0, texCount): texName = bs.readBytes(0x20).decode("ASCII").rstrip("\0") texStart = bs.tell() + bs.readInt() bs.readBytes(0xC) texInfo.append([texName, texStart]) #print(texInfo) for i in range(0, texCount): bs.seek(texInfo[i][1], NOESEEK_ABS) bs.readBytes(0xC) palOff = bs.tell() + bs.readInt() texType, unk02, pixWidth, pixHeight, unk03, unk04 = bs.read("6H") texSize = bs.readInt() texOff = bs.tell() + bs.readInt() bs.seek(texOff, NOESEEK_ABS) texData = bs.readBytes(texSize) bs.seek(palOff, NOESEEK_ABS) unk11, unk22 = bs.read("2H") palSize, Null = bs.read("2I") palStart = bs.tell() + bs.readInt() bs.seek(palStart, NOESEEK_ABS) palData = [] for a in range(0, palSize // 4): pR, pG, pB, pA = bs.read("4B") if pR == 0 and pG == 255 and pB == 0 and pA == 255: pG = 0 pA = 0 palData.append(pR) palData.append(pG) palData.append(pB) palData.append(pA) palData = struct.pack("<" + 'B' * len(palData), *palData) if texType == 5: pix = rapi.imageUntwiddlePSP(texData, pixWidth, pixHeight, 8) pix = rapi.imageDecodeRawPal(pix, palData, pixWidth, pixHeight, 8, "r8g8b8a8") elif texType == 4: pix = rapi.imageUntwiddlePSP(texData, pixWidth, pixHeight, 4) pix = rapi.imageDecodeRawPal(pix, palData, pixWidth, pixHeight, 4, "r8g8b8a8") texList.append( NoeTexture(texInfo[i][0], pixWidth, pixHeight, pix, noesis.NOESISTEX_RGBA32)) matList = [] bs.seek(matOffset, NOESEEK_ABS) for i in range(0, matCount): matName = bs.readBytes(0x20).decode("ASCII").rstrip("\0") bs.readBytes(0xC) texID = bs.readInt() unk01, unk02, unk03, unk04 = bs.read("4B") bs.readBytes(0x8) material = NoeMaterial(matName, "") if texID >= 0: material.setTexture(texInfo[texID][0]) #material.setOpacityTexture(texInfo[texID][0]) matList.append(material) meshList = [] bs.seek(meshOffset, NOESEEK_ABS) for i in range(0, meshCount): meshName = bs.readBytes(0x20).decode("ASCII").rstrip("\0") mshCount = bs.readInt() unk11 = bs.readInt() meshStart = bs.tell() + bs.readInt() bs.readBytes(0xC) meshList.append([meshName, meshStart, mshCount, unk11]) #print(meshList) for a in range(0, len(meshList)): mshInfo = [] #print(meshList[a][0]) bs.seek(meshList[a][1], NOESEEK_ABS) for b in range(0, meshList[a][2]): unk20 = bs.readInt() matID = bs.readInt() mshC = bs.readInt() MshOff = bs.tell() + bs.readInt() mshInfo.append([matID, mshC, MshOff]) #print(mshInfo) mshInfo2 = [] for b in range(0, len(mshInfo)): bs.seek(mshInfo[b][2], NOESEEK_ABS) for c in range(0, mshInfo[b][1]): meshPc = bs.readInt() vType = bs.readInt() meshPc2 = bs.readInt() mshPo = bs.tell() + bs.readInt() mshPo2 = bs.tell() + bs.readInt() mshInfo2.append([ meshPc, vType, meshPc2, mshPo, mshPo2, matList[(mshInfo[b][0])].name ]) #print(mshInfo2) for b in range(0, len(mshInfo2)): mshInfo3 = [] rapi.rpgSetMaterial(mshInfo2[b][5]) bs.seek(mshInfo2[b][3], NOESEEK_ABS) idxList = [[0, 0, 0, 0, 0, 0, 0, 0]] for c in range(0, mshInfo2[b][2]): idxList[0][c] = bs.readInt() bs.seek(mshInfo2[b][4], NOESEEK_ABS) #print(idxList) for c in range(0, mshInfo2[b][0]): mshId2 = bs.readInt() vertCount = bs.readInt() vertStart = bs.tell() + bs.readInt() mshInfo3.append([mshId2, vertCount, vertStart]) #print(mshInfo3) for c in range(0, len(mshInfo3)): #print(mshInfo3[c]) bs.seek(mshInfo3[c][2], NOESEEK_ABS) rapi.rpgSetName(meshList[a][0]) #rapi.rpgSetName(meshList[a][0] + "_" + str(b) + "_" + str(c) + "_" + str(mshInfo2[b][1])) vertStride = 0 if mshInfo2[b][1] == 7: vertStride = 0x18 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0xC) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x8, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0) elif mshInfo2[b][1] == 24: vertStride = 0x1C vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x10) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0xC, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x4) elif mshInfo2[b][1] == 25: vertStride = 0x1C vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x10) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0xC, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x4) elif mshInfo2[b][1] == 26: vertStride = 0x20 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x14) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x10, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x8) elif mshInfo2[b][1] == 27: vertStride = 0x20 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x14) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x10, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x8) elif mshInfo2[b][1] == 28: vertStride = 0x24 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x18) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x14, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0xC) elif mshInfo2[b][1] == 29: vertStride = 0x24 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x18) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x14, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0xC) elif mshInfo2[b][1] == 30: vertStride = 0x28 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x1C) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x18, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x10) elif mshInfo2[b][1] == 23: vertStride = 0x28 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x1C) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x18, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x10) else: print(bs.tell()) print("unknown found " + str(mshInfo2[b][1])) vs = NoeBitStream(vertBuff) tmp = [] tmp2 = [] weight = [] index = [] if vertStride == 0x18: for d in range(0, mshInfo3[c][1]): w1, w2, w3, w4, w5, w6, w7, w8 = [ 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ] index.append(idxList[0][0]) index.append(idxList[0][1]) index.append(idxList[0][2]) index.append(idxList[0][3]) index.append(idxList[0][4]) index.append(idxList[0][5]) index.append(idxList[0][6]) index.append(idxList[0][7]) weight.append(w1) weight.append(w2) weight.append(w3) weight.append(w4) weight.append(w5) weight.append(w6) weight.append(w7) weight.append(w8) vs.readBytes(0xC) tmp.append( [vs.readUInt(), vs.readUInt(), vs.readUInt()]) elif vertStride == 0x1C: for d in range(0, mshInfo3[c][1]): w1, w2, w3, w4, w5, w6, w7, w8 = [ vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ] index.append(idxList[0][0]) index.append(idxList[0][1]) index.append(idxList[0][2]) index.append(idxList[0][3]) index.append(idxList[0][4]) index.append(idxList[0][5]) index.append(idxList[0][6]) index.append(idxList[0][7]) weight.append(w1) weight.append(w2) weight.append(w3) weight.append(w4) weight.append(w5) weight.append(w6) weight.append(w7) weight.append(w8) vs.readBytes(0xC) tmp.append( [vs.readUInt(), vs.readUInt(), vs.readUInt()]) elif vertStride == 0x20: for d in range(0, mshInfo3[c][1]): w1, w2, w3, w4, w5, w6, w7, w8 = [ vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, 0.0, 0.0, 0.0, 0.0 ] index.append(idxList[0][0]) index.append(idxList[0][1]) index.append(idxList[0][2]) index.append(idxList[0][3]) index.append(idxList[0][4]) index.append(idxList[0][5]) index.append(idxList[0][6]) index.append(idxList[0][7]) weight.append(w1) weight.append(w2) weight.append(w3) weight.append(w4) weight.append(w5) weight.append(w6) weight.append(w7) weight.append(w8) vs.readBytes(0xC) tmp.append( [vs.readUInt(), vs.readUInt(), vs.readUInt()]) elif vertStride == 0x24: for d in range(0, mshInfo3[c][1]): w1, w2, w3, w4, w5, w6, w7, w8 = [ vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, 0.0, 0.0 ] index.append(idxList[0][0]) index.append(idxList[0][1]) index.append(idxList[0][2]) index.append(idxList[0][3]) index.append(idxList[0][4]) index.append(idxList[0][5]) index.append(idxList[0][6]) index.append(idxList[0][7]) weight.append(w1) weight.append(w2) weight.append(w3) weight.append(w4) weight.append(w5) weight.append(w6) weight.append(w7) weight.append(w8) vs.readBytes(0xC) tmp.append( [vs.readUInt(), vs.readUInt(), vs.readUInt()]) elif vertStride == 0x28: for d in range(0, mshInfo3[c][1]): w1, w2, w3, w4, w5, w6, w7, w8 = [ vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF ] index.append(idxList[0][0]) index.append(idxList[0][1]) index.append(idxList[0][2]) index.append(idxList[0][3]) index.append(idxList[0][4]) index.append(idxList[0][5]) index.append(idxList[0][6]) index.append(idxList[0][7]) weight.append(w1) weight.append(w2) weight.append(w3) weight.append(w4) weight.append(w5) weight.append(w6) weight.append(w7) weight.append(w8) vs.readBytes(0xC) tmp.append( [vs.readUInt(), vs.readUInt(), vs.readUInt()]) indexBuff = struct.pack('B' * len(index), *index) weightBuff = struct.pack('f' * len(weight), *weight) rapi.rpgBindBoneIndexBuffer(indexBuff, noesis.RPGEODATA_BYTE, 8, 8) rapi.rpgBindBoneWeightBuffer(weightBuff, noesis.RPGEODATA_FLOAT, 0x20, 8) flip = 0 step = 1 if mshInfo3[c][0] == 0: step = 3 for d in range(0, mshInfo3[c][1] - 2, step): if (tmp[d] != tmp[(d + 1)]) and (tmp[d] != tmp[ (d + 2)]) and (tmp[d + 1] != tmp[(d + 2)]): tmp2.append(d) tmp2.append(d + 1 + flip) tmp2.append(d + 2 - flip) if mshInfo3[c][0] != 0: flip = 1 - flip else: flip = 0 #print(d) faceBuff = struct.pack('H' * len(tmp2), *tmp2) if len(faceBuff) > 3: rapi.rpgCommitTriangles(faceBuff, noesis.RPGEODATA_USHORT, len(tmp2), noesis.RPGEO_TRIANGLE, 1) rapi.rpgClearBufferBinds() mdl = rapi.rpgConstructModel() mdl.setModelMaterials(NoeModelMaterials(texList, matList)) mdlList.append(mdl) mdl.setBones(boneList) return 1
def __init__(self, bs, offset, mesh, boneSect, brntre, impl): bs.seekAbs(offset) if bs.readString() != "GPR": raise ValueError("GPR section expected to be second") # calculate offset for far section bs.readBytes(0xC) self.farOffset = bs.tell() bs.readBytes(0x18) self.farOffset += bs.readInt() # go into GPR descriptors bs.seekAbs(offset + 0x40) # read HEAP if bs.readFixedString(4) != "HEAP": raise ValueError("HEAP data expected") bs.readInt() bs.readInt() gprDesSize = bs.readInt() bs.readInt() heapSize = bs.readInt() bs.readInt() gprDesCount = bs.readInt() self.descriptors = [] for _ in range(gprDesCount): self.descriptors.append( GprDes(bs.readFixedString(4), bs.readInt(), bs.readInt(), bs.readInt(), bs.readInt(), bs.readInt(), bs.readInt(), bs.readInt())) bs.readBytes(heapSize) modelName = bs.readString() log("Model name: " + modelName) bs.seekAlign(0x10) self.nearOffset = bs.tell() dlog("GPR near offset: " + hex(self.nearOffset)) dlog("GPR far offset: " + hex(self.farOffset)) # Collect IXBF, VXBF, VXST ixbfList = [] vxbfList = [] vxstList = [] for _, des in enumerate(self.descriptors): if des.name == "IXBF": ixbfList.append(des) if des.name == "VXBF": vxbfList.append(des) if des.name == "VXST": vxstList.append(des) vxstEntryCount = [] for _, des in enumerate(vxstList): bs.seek(des.offset + self.nearOffset, NOESEEK_ABS) bs.readBytes(impl.getVxstEntryCountOffset()) vxstEntryCount.append(bs.readInt()) vxbfEntryCount = [] vxbfEntryLen = [] for _, des in enumerate(vxbfList): bs.seek(des.offset + self.nearOffset, NOESEEK_ABS) bs.readBytes(0x8) vxbfEntryCount.append(bs.readInt()) vxbfEntryLen.append(bs.readInt()) # ddump(vxstEntryCount) # ddump(vxbfEntryCount) # ddump(vxbfEntryLen) if len(vxbfList) > len(ixbfList): warn("VXBF count > IXBF count, some data not processed") # not sure if this will work for Link idxToRemove = [] for i, length in enumerate(vxbfEntryLen): if length <= 16: idxToRemove.append(i) for idx in sorted(idxToRemove, reverse=True): del vxbfList[idx] del vxbfEntryCount[idx] del vxbfEntryLen[idx] elif len(vxbfList) < len(ixbfList): warn("VXBF count < IXBF count, some data not processed") for i, des in enumerate(vxbfList): rapi.rpgSetName(mesh.stringBank[mesh.primInfo[i].meshGeomNameSid]) bs.seek(des.farOffset + self.farOffset, NOESEEK_ABS) vertStride = vxbfEntryLen[i] dlog("Parse verts at " + hex(bs.tell()) + " with stride " + str(vertStride)) vertBuff = bs.readBytes(des.farSize) def bindBones(boneOffset, weightOffset, stride): VertexBones(boneOffset, weightOffset, stride) class VertexBones: def __init__(self, boneOffset, weightOffset, stride): if boneSect is None: return self.boneOffset = boneOffset self.weightOffset = weightOffset self.stride = stride self.boneData = [] self.weightData = [] self.collectBones() self.collectWeights() self.mapBones() flatten = lambda l: [ item for sublist in l for item in sublist ] boneBuf = struct.pack("B" * (vxbfEntryCount[i] * 4), *flatten(self.boneData)) rapi.rpgBindBoneIndexBuffer(boneBuf, noesis.RPGEODATA_BYTE, 0x4, 4) weightBuf = struct.pack("f" * (vxbfEntryCount[i] * 4), *flatten(self.weightData)) rapi.rpgBindBoneWeightBuffer(weightBuf, noesis.RPGEODATA_FLOAT, 0x10, 4) def collectBones(self): bsi = NoeBitStream(vertBuff) for _ in range(vxbfEntryCount[i]): bsi.readBytes(self.boneOffset) b1 = bsi.readUByte() b2 = bsi.readUByte() b3 = bsi.readUByte() b4 = bsi.readUByte() bsi.readBytes(self.stride - self.boneOffset - 0x4) self.boneData.append([b1, b2, b3, b4]) def collectWeights(self): wsi = NoeBitStream(vertBuff) for _ in range(vxbfEntryCount[i]): wsi.readBytes(self.weightOffset) w1 = wsi.readUByte() / 255.0 w2 = wsi.readUByte() / 255.0 w3 = wsi.readUByte() / 255.0 w4 = wsi.readUByte() / 255.0 wsi.readBytes(self.stride - self.weightOffset - 0x4) self.weightData.append((w1, w2, w3, w4)) def mapBones(self): for b, w in zip(self.boneData, self.weightData): for i, (bv, wv) in enumerate(zip(b, w)): if wv != 0: try: b[i] = brntre.boneMeshToSkelMap[bv] except KeyError: #warn("Missing mapping for mesh bone " + str(bv)) pass impl.bindVertStride(modelName, rapi, des, vertBuff, vertStride, bindBones) bs.seek(ixbfList[i].farOffset + self.farOffset, NOESEEK_ABS) faceList = impl.getFaceList(bs, vxstEntryCount[i]) faceBuff = struct.pack('H' * len(faceList), *faceList) rapi.rpgSetMaterial(mesh.materials[mesh.primInfo[i].matId].name) if impl.needsUVFlip(): rapi.rpgSetUVScaleBias(NoeVec3((1.0, -1.0, 1.0)), NoeVec3((1.0, 1.0, 1.0))) rapi.rpgCommitTriangles(faceBuff, noesis.RPGEODATA_USHORT, len(faceList), noesis.RPGEO_TRIANGLE, 1) if impl.needsOptimize(): rapi.rpgOptimize() rapi.rpgClearBufferBinds()