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 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): 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): 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 __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 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()