def CreateModel(self): for n in range(self.numMesh): rapi.rpgBindPositionBufferOfs(self.vertBuff[n], noesis.RPGEODATA_HALFFLOAT, 64, 0) rapi.rpgBindUV1BufferOfs(self.vertBuff[n], noesis.RPGEODATA_SHORT, 64, 16) rapi.rpgBindUV2BufferOfs(self.vertBuff[n], noesis.RPGEODATA_SHORT, 64, 16) idxBuffer = self.idxBuff[n][:] for i in range(self.numDrawCall[n]): numDrawFace = self.drawCallFace[n][i] idxBuff = idxBuffer[:numDrawFace * 6] idxBuffer = idxBuffer[numDrawFace * 6:] rapi.rpgSetMaterial(self.matList[self.matID[n][i]].name) if self.matID[n][i] in self.matEmis: #rapi.rpgSetLightmap(self.matEmis[self.matID[n][i]].name) self.matList[self.matID[n][i]].setNextPass( self.matEmis[self.matID[n][i]]) rapi.rpgSetOption(noesis.RPGOPT_TRIWINDBACKWARD, 1) if SKIPTOID: rapi.rpgBindBoneIndexBufferOfs(self.boneBuff[n], noesis.RPGEODATA_UBYTE, 4, 0, 4) else: rapi.rpgBindBoneIndexBufferOfs(self.vertBuff[n], noesis.RPGEODATA_UBYTE, 64, 44, 4) rapi.rpgBindBoneWeightBufferOfs(self.vertBuff[n], noesis.RPGEODATA_FLOAT, 64, 28, 4) rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_USHORT, numDrawFace * 3, noesis.RPGEO_TRIANGLE, 1)
def LoadModel(self): self.data = NoeBitStream( open(self.dirPath + self.model,'rb').read() ) self.data.seek(1,1) self.numIdx = self.data.readUInt() self.numVert = self.data.readUInt() prop = self.data.read('3B') totalStringLength = self.data.readUInt() boundingBox = self.data.read('6f') meshNames = [] stringLengths = [] idxGroups = [] for i in range(prop[1]): stringLengths.append(self.data.readUInt()) idxGroups.append (self.data.readUInt()) for i in range(prop[1]): meshNames.append (noeStrFromBytes(self.data.readBytes(stringLengths[i]))) self.meshNames = meshNames self.idxBuffer = self.data.readBytes(self.numIdx * 6) self.vertBuffer = self.data.readBytes(self.numVert * 64) for i in range(prop[1]): name = ''.join(meshNames[i].split('\x00')) meshNames[i] = name.split('Shape')[0] idxG = [] idxGroups.append(self.numIdx) for i in range(prop[1]): idxG.append(idxGroups[i+1] - idxGroups[i]) for i in range(prop[1]): rapi.rpgBindPositionBufferOfs (self.vertBuffer, noesis.RPGEODATA_FLOAT, 64, 0) rapi.rpgBindUV1BufferOfs (self.vertBuffer, noesis.RPGEODATA_FLOAT, 64, 40) rapi.rpgBindNormalBufferOfs (self.vertBuffer, noesis.RPGEODATA_FLOAT, 64, 12) #rapi.rpgBindColorBufferOfs (self.vertBuffer, noesis.RPGEODATA_FLOAT, 64, 24, 4) rapi.rpgBindBoneIndexBufferOfs (self.vertBuffer, noesis.RPGEODATA_UBYTE, 64, 48, 4) rapi.rpgBindBoneWeightBufferOfs (self.vertBuffer, noesis.RPGEODATA_FLOAT, 64, 52, 3) self.CreateMaterial(i) rapi.rpgSetMaterial(self.meshNames[i]) min = idxGroups[i] * 6 max = idxGroups[i+1] * 6 rapi.rpgCommitTriangles(self.idxBuffer[min:max], noesis.RPGEODATA_USHORT,idxG[i]*3, noesis.RPGEO_TRIANGLE, 1)
def Textures(self): self.data.seek(4,1) numShader = self.data.readUInt() for i in range( numShader): name = noeStrFromBytes(self.data.readBytes(self.data.readUInt())) numTex = self.data.readUInt() material = NoeMaterial(name, "") for n in range( numTex): typeName = noeStrFromBytes(self.data.readBytes(self.data.readUInt())) typeID = self.data.readUInt() if typeID ==7: #BaseTexture, Bump if MODPATH == None:texName = noeStrFromBytes(self.data.readBytes(self.data.readUInt())).split('\\')[-1] else: texName = noeStrFromBytes(self.data.readBytes(self.data.readUInt())) if typeName == 'baseTexture': tex = LoadTexture(texName, self) if tex != None: material.setTexture(tex.name) elif typeName == 'bumpTexture': tex = LoadTexture(texName, self) if tex != None: material.setNormalTexture(tex.name) elif typeID ==8: self.data.read('2f') elif typeID ==9: #Color (specular, ..) temp = self.data.read('3f') if typeName == 'specularColor': material.setSpecularColor((temp[0], temp[1], temp[2], 8.0)) elif typeID ==10: #Power, Effects, ... self.data.read('f') self.matList.append(material) for draw in self.drawCallInfo: idxBuff = self.idxBuffer[ draw['faceStart'] * 6 : ] numIdx = draw['faceCount'] rapi.rpgSetMaterial(self.matList[draw['matID']].name) if len(self.boneList) >0: rapi.rpgSetBoneMap( draw['boneMap']) rapi.rpgBindBoneIndexBufferOfs (self.vertBuff, noesis.RPGEODATA_UBYTE, self.vertLength, self.boneIndexOffset, 4) rapi.rpgBindBoneWeightBufferOfs (self.vertBuff, noesis.RPGEODATA_FLOAT, self.vertLength, self.boneWeightOffset, 4) rapi.rpgSetOption(noesis.RPGOPT_TRIWINDBACKWARD, 1) rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_USHORT, numIdx*3, noesis.RPGEO_TRIANGLE, 1) return
def CreateModel(self): for n in range(self.numMesh): rapi.rpgBindPositionBufferOfs (self.vertBuff[n], noesis.RPGEODATA_HALFFLOAT, 64, 0) rapi.rpgBindUV1BufferOfs (self.vertBuff[n], noesis.RPGEODATA_SHORT, 64, 16) rapi.rpgBindUV2BufferOfs (self.vertBuff[n], noesis.RPGEODATA_SHORT, 64, 16) idxBuffer = self.idxBuff[n][:] for i in range(self.numDrawCall[n]): numDrawFace = self.drawCallFace[n][i] idxBuff = idxBuffer[:numDrawFace*6] idxBuffer=idxBuffer[numDrawFace*6:] rapi.rpgSetMaterial(self.matList[self.matID[n][i]].name) if self.matID[n][i] in self.matEmis: #rapi.rpgSetLightmap(self.matEmis[self.matID[n][i]].name) self.matList[self.matID[n][i]].setNextPass(self.matEmis[self.matID[n][i]]) rapi.rpgSetOption(noesis.RPGOPT_TRIWINDBACKWARD, 1) if SKIPTOID: rapi.rpgBindBoneIndexBufferOfs(self.boneBuff[n], noesis.RPGEODATA_UBYTE, 4, 0, 4) else: rapi.rpgBindBoneIndexBufferOfs(self.vertBuff[n], noesis.RPGEODATA_UBYTE, 64, 44, 4) rapi.rpgBindBoneWeightBufferOfs(self.vertBuff[n], noesis.RPGEODATA_FLOAT, 64, 28, 4) rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_USHORT, numDrawFace*3, noesis.RPGEO_TRIANGLE, 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 __init__(self, data): self.meshInfo = [] self.bufferInfo = [] self.vertexBuffer = [] self.indexBuffer = [] self.matList = [] self.texList = [] self.lightMapList = {} self.data = NoeBitStream(data) self.findMODL() self.parseMaterials() self.findGEOM() self.header = ANetPfChunkHeader(self.data) self.numMesh = self.data.readUInt() if self.numMesh == 0: print("numMesh = 0, animation file") meshInfoOffsetTableOffset = self.data.readUInt() self.data.seek(meshInfoOffsetTableOffset - 4, 1) meshInfoOffsetTable = self.data.read('%di' % self.numMesh) for i in range(self.numMesh): self.meshInfo.append(ANetModelMeshInfo(self.data)) for mesh in self.meshInfo: self.data.seek(mesh.pos + mesh.bufferInfoOffset) self.bufferInfo.append(ANetModelBufferInfo(self.data)) self.data.seek(mesh.matpos + mesh.materialNameOffset) self.bufferInfo[-1].materialName = self.data.readString() self.bufferInfo[-1].materialIndex = mesh.materialIndex for buffer in self.bufferInfo: Format = self.vertexSize(buffer) LOGGING = 0 if LOGGING == 1: print("[*] Mesh") for var in vars(Format): val = getattr(Format, var) if val != -1: print(" %s: %d" % (var, val)) self.data.seek(buffer.vertexPos + buffer.vertexBufferOffset) vertexBuffer = self.data.readBytes(buffer.vertexBufferSize) self.data.seek(buffer.indexPos + buffer.indexBufferOffset) indexBuffer = self.data.readBytes(buffer.indexCount * 2) self.data.seek(buffer.boneMapPos + buffer.boneMapOffset) boneMap = self.data.read('%di' % buffer.boneMapCount) try: material = self.matList[buffer.materialIndex] except: print(buffer.materialIndex) raise material.name = buffer.materialName rapi.rpgSetMaterial(buffer.materialName) self.matList[buffer.materialIndex] = material if buffer.materialIndex in self.lightMapList: material = self.lightMapList[buffer.materialIndex] material.name = buffer.materialName + "_LM" rapi.rpgSetLightmap(material.name) self.matList.append(material) if Format.position != -1: rapi.rpgBindPositionBufferOfs(vertexBuffer, noesis.RPGEODATA_FLOAT, Format.vertexSize, Format.position) if Format.uv32Mask != -1: rapi.rpgBindUV1BufferOfs(vertexBuffer, noesis.RPGEODATA_FLOAT, Format.vertexSize, Format.uv32Mask) if Format.uv16Mask != -1: rapi.rpgBindUV1BufferOfs(vertexBuffer, noesis.RPGEODATA_HALFFLOAT, Format.vertexSize, Format.uv16Mask) if Format.uv16Count >= 3: rapi.rpgBindUV2BufferOfs(vertexBuffer, noesis.RPGEODATA_HALFFLOAT, Format.vertexSize, Format.uv16Mask + 8) rapi.rpgBindBoneIndexBufferOfs(vertexBuffer, noesis.RPGEODATA_UBYTE, Format.vertexSize, Format.group, 4) rapi.rpgBindBoneWeightBufferOfs(vertexBuffer, noesis.RPGEODATA_UBYTE, Format.vertexSize, Format.weights, 4) rapi.rpgSetBoneMap(boneMap) rapi.rpgCommitTriangles(indexBuffer, noesis.RPGEODATA_USHORT, buffer.indexCount, noesis.RPGEO_TRIANGLE, 1) self.Bones = [] self.ParseBones()
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 noepyLoadFMOD(data, mdlList): bs = NoeBitStream(data) if bs.readInt() != FMOD_HEADER: return 0 if bs.readInt() != FMOD_VERSION: return 0 pos = 0 filesize = bs.readUInt() # total typeBlock = bs.readInt() countBlock = bs.readInt() sizeBlock = bs.readInt() processBlock(typeBlock, countBlock, sizeBlock, bs) while pos < filesize: for i in range(countBlock): pos = bs.tell() if pos < filesize: typeBlock = bs.readInt() countBlock = bs.readInt() sizeBlock = bs.readInt() processBlock(typeBlock, countBlock, sizeBlock, bs) ctx = rapi.rpgCreateContext() global textureOff, textureCount, materialOff, materialCount texList, matList = createMaterialTexList(bs,textureOff,textureCount,materialOff,materialCount) for meshi in range(objectcount): # Add vertices bs.seek(vertexoffsets[meshi]) vertexbuffer = bs.readBytes(vertexcounts[meshi] * 12) rapi.rpgBindPositionBufferOfs(vertexbuffer, noesis.RPGEODATA_FLOAT, 12, 0) # Add normals global normalsoffsets bs.seek(normalsoffsets[meshi] - 8) normalscount = bs.readInt() bs.readInt() # skip normalsbuffer = bs.readBytes(normalscount * 12) rapi.rpgBindNormalBufferOfs(normalsbuffer, noesis.RPGEODATA_FLOAT, 12, 0) # Add tangents (is it necessary?) global tanoffsets if len(tanoffsets) > 0: bs.seek(tanoffsets[meshi] - 8) tangentcount = bs.readInt() bs.readInt() #blocksize tangentbuffer = bs.readBytes(tangentcount*16) rapi.rpgBindTangentBuffer(tangentbuffer, noesis.RPGEODATA_FLOAT, 16) # Add UVs bs.seek(uvoffsets[meshi] - 8) uvcount = bs.readInt() bs.readInt() # skip uvbuffer = bs.readBytes(uvcount * 8) rapi.rpgBindUV1BufferOfs(uvbuffer, noesis.RPGEODATA_FLOAT, 8, 0) # Add Vertex Color (possible) global coloroffsets bs.seek(coloroffsets[meshi] - 8) colorcount = bs.readUInt() bs.readUInt() #blocksize colorbuffer = bs.readBytes(colorcount*16) rapi.rpgBindColorBuffer(colorbuffer, noesis.RPGEODATA_FLOAT, 16, 4) # Add Bone Remap global boneoffsets if(len(boneoffsets) > 0): bs.seek(boneoffsets[meshi] - 8) boneCount = bs.readInt() bs.readInt() #blockSize bones = list() for i in range(boneCount): bone = bs.readInt() bones.append(bone) rapi.rpgSetBoneMap(bones) else: #there's no bone remap dummy = 1+1 #just to please noesis # Add Weights global weightoffsets if len(weightoffsets) > 0: weightValues = bytes() weightBones = bytes() bs.seek(weightoffsets[meshi] - 8) weightcount = bs.readInt() bs.readInt() #blocksize for i in range(weightcount): paircount = bs.readInt() for j in range(paircount): weightBone = bs.readUInt() weightValue = bs.readFloat() weightBones += noePack("i", weightBone) weightValues += noePack("f", weightValue/100) for k in range(4-paircount): weightBone = 0 weightValue = 0.0 weightBones += noePack("i", weightBone) weightValues += noePack("f", weightValue) rapi.rpgBindBoneIndexBufferOfs(weightBones,noesis.RPGEODATA_UINT, 16, 0, 4) rapi.rpgBindBoneWeightBufferOfs(weightValues,noesis.RPGEODATA_FLOAT, 16, 0, 4) # Add skeleton bins = [] for root, dirnames, filenames in os.walk(noesis.getSelectedDirectory()): for filename in fnmatch.filter(filenames, '*.fskl'): bins.append(os.path.join(root, filename)) boneList = [] if len(bins) > 0: dataSkl = [] with open(bins[0], mode='rb') as file: dataSkl = file.read() bsSkl = NoeBitStream(dataSkl) if bsSkl.readUInt() == FSKL_HEADER: # slightly adapted from https://github.com/m2jean/mhfu-ios-pmo-plugin blockCount = bsSkl.readUInt() - 1 #print("Skeleton file with {} sections found.".format(blockCount)) filesizeSkl = bsSkl.readUInt() blockType = bsSkl.readUInt() blockCount1 = bsSkl.readUInt() blockLen = bsSkl.readUInt() for i in range(blockCount1): dummy = bsSkl.readUInt() sklidxList = [] posList = [] for i in range(blockCount): blockTyp = bsSkl.readUInt() assert blockTyp == 0x40000001 or 0x40000002 assert bsSkl.readUInt() == 0x1 assert bsSkl.readUInt() == 0x10C nodei = bsSkl.readInt() parent = bsSkl.readInt() lchild = bsSkl.readInt() rsibling = bsSkl.readInt() bsSkl.readBytes(4*8) mat43 = [] for _ in range(3): mat43.append(bsSkl.readFloat()) bsSkl.readFloat() bsSkl.readBytes(16*12) if parent == -1: pos = (0,0,0) else: pos = posList[parent].vec3 sklidxList += (nodei, parent, parent) transform = list(pos) transform[0] += mat43[0] transform[1] += mat43[1] transform[2] += mat43[2] #print(mat43, transform) posList.append(NoeVec3(transform)) finMatrix = NoeQuat().toMat43() finMatrix[3] = NoeVec3(transform) boneList.append(NoeBone(i, "Bone.%03i"%i, finMatrix, None, parent)) #create material remap and material map global materialoffsets, matmapoffsets bs.seek(materialoffsets[meshi]-8) matRemap = [] remapCount = bs.readUInt() bs.readUInt() for _ in range(remapCount): matRemap.append(bs.readUInt()) matMap = [] bs.seek(matmapoffsets[meshi]-8) stripCount = bs.readUInt() bs.readUInt() for _ in range(stripCount): matMap.append(matRemap[bs.readUInt()]) # Add faces bs.seek(faceoffsets[meshi]) stripIndex = 0 for j in range(faceblockcounts[meshi]): faceblocktype = bs.readInt() facesubblockcount = bs.readInt() blocksize = bs.readInt() for i in range(facesubblockcount): rapi.rpgSetMaterial("Material.%03i"%matMap[stripIndex]) facecount = bs.readUInt() # not sure what's up with these counts i.e. wf521, em098 if facecount > 0x80000000: #print("WARNING: Face count is abnormal with {}. Fake adjusted.".format(facecount)) facecount = facecount - 0x80000000 #print("Mesh {} face index {} block count: {} at offset 0x{:X}".format(meshi, i, facecount, bs.tell())) facebuffer = bs.readBytes(facecount * 4) rapi.rpgCommitTriangles(facebuffer, noesis.RPGEODATA_UINT, facecount, noesis.RPGEO_TRIANGLE_STRIP, 1) stripIndex += 1 matRemap = [] matMap = [] mdl = rapi.rpgConstructModel() mdl.setModelMaterials(NoeModelMaterials(texList, matList)) mdl.setBones(boneList) mdlList.append(mdl) rapi.rpgReset() rapi.rpgClearBufferBinds() # reset global variables rapi.rpgOptimize() global objectcount global vertexoffsets; global vertexcounts global faceoffsets; global faceblocksubcounts; global faceblockcounts global uvoffsets; global tanoffsets objectcount = 0 vertexoffsets = list(); vertexcounts = list() faceoffsets = list(); faceblockcounts = list(); faceblocksubcounts = list() uvoffsets = list(); normalsoffsets = list(); tanoffsets = list() weightoffsets = list(); boneoffsets = list() materialoffsets =list(); matmapoffsets = list() matoffsets = list(); texoffsets = list() coloroffsets = list() materialOff = 0 materialCount = 0 textureOff = 0 textureCount = 0 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): self.meshInfo = [] self.bufferInfo = [] self.vertexBuffer = [] self.indexBuffer = [] self.matList = [] self.texList = [] self.lightMapList = {} self.data = NoeBitStream(data) self.findMODL() self.parseMaterials() self.findGEOM() self.header = ANetPfChunkHeader(self.data) self.numMesh = self.data.readUInt() if self.numMesh == 0:print("numMesh = 0, animation file") meshInfoOffsetTableOffset = self.data.readUInt() self.data.seek(meshInfoOffsetTableOffset-4,1) meshInfoOffsetTable = self.data.read('%di'%self.numMesh) for i in range(self.numMesh): self.meshInfo.append(ANetModelMeshInfo(self.data)) for mesh in self.meshInfo: self.data.seek(mesh.pos+mesh.bufferInfoOffset) self.bufferInfo.append(ANetModelBufferInfo(self.data)) self.data.seek(mesh.matpos+mesh.materialNameOffset) self.bufferInfo[-1].materialName = self.data.readString() self.bufferInfo[-1].materialIndex= mesh.materialIndex for buffer in self.bufferInfo: Format = self.vertexSize(buffer) LOGGING = 0 if LOGGING == 1: print("[*] Mesh") for var in vars(Format): val = getattr(Format,var) if val != -1:print(" %s: %d"%(var,val)) self.data.seek(buffer.vertexPos + buffer.vertexBufferOffset) vertexBuffer = self.data.readBytes(buffer.vertexBufferSize) self.data.seek(buffer.indexPos + buffer.indexBufferOffset) indexBuffer = self.data.readBytes(buffer.indexCount*2) self.data.seek(buffer.boneMapPos + buffer.boneMapOffset) boneMap = self.data.read('%di'%buffer.boneMapCount) try:material = self.matList[buffer.materialIndex] except: print(buffer.materialIndex) raise material.name = buffer.materialName rapi.rpgSetMaterial(buffer.materialName) self.matList[buffer.materialIndex] = material if buffer.materialIndex in self.lightMapList: material = self.lightMapList[buffer.materialIndex] material.name = buffer.materialName + "_LM" rapi.rpgSetLightmap(material.name) self.matList.append(material) if Format.position != -1: rapi.rpgBindPositionBufferOfs(vertexBuffer, noesis.RPGEODATA_FLOAT, Format.vertexSize, Format.position) if Format.uv32Mask != -1: rapi.rpgBindUV1BufferOfs(vertexBuffer, noesis.RPGEODATA_FLOAT, Format.vertexSize, Format.uv32Mask) if Format.uv16Mask != -1: rapi.rpgBindUV1BufferOfs(vertexBuffer, noesis.RPGEODATA_HALFFLOAT, Format.vertexSize, Format.uv16Mask) if Format.uv16Count >=3: rapi.rpgBindUV2BufferOfs(vertexBuffer, noesis.RPGEODATA_HALFFLOAT, Format.vertexSize, Format.uv16Mask+8) rapi.rpgBindBoneIndexBufferOfs(vertexBuffer, noesis.RPGEODATA_UBYTE, Format.vertexSize ,Format.group, 4) rapi.rpgBindBoneWeightBufferOfs(vertexBuffer, noesis.RPGEODATA_UBYTE, Format.vertexSize, Format.weights, 4) rapi.rpgSetBoneMap(boneMap) rapi.rpgCommitTriangles(indexBuffer, noesis.RPGEODATA_USHORT, buffer.indexCount, noesis.RPGEO_TRIANGLE, 1) self.Bones = [] self.ParseBones()