def parse_textures(self): basename = rapi.getExtensionlessName(self.filename) basepath = rapi.getDirForFilePath(rapi.getInputName()) Tex_Basename = basename.replace('Mesh', 'Tex') diffTex = basepath + Tex_Basename + "_diff.dds" normTex = basepath + Tex_Basename + "_norm.dds" specTex = basepath + Tex_Basename + "_spec.dds" if rapi.checkFileExists(diffTex): material = NoeMaterial(basename + "_diffuse", diffTex) material.setFlags(noesis.NMATFLAG_TWOSIDED) self.TextureFiles.append('Diffuse: ' + diffTex) if (rapi.checkFileExists(normTex)): material.setNormalTexture(normTex) self.TextureFiles.append('Normal: ' + normTex) if (rapi.checkFileExists(specTex)): material.setSpecularTexture(specTex) self.TextureFiles.append('Specular: ' + specTex) self.matList.append(material) # Read Textures Block if self.TextureFilesCnt > 0: for i in range(self.TextureFilesCnt): TexFile = self.inFile.readString() TexFilePath = rapi.getDirForFilePath( rapi.getInputName()) + "/" + TexFile if (rapi.checkFileExists(TexFilePath)): self.TextureFiles.append(TexFile) material = NoeMaterial('mat' + str(i), str(TexFile)) material.setFlags(noesis.NMATFLAG_TWOSIDED) self.matList.append(material)
def getTexPath(extension): texPath = self.stringBank[sstv.texPathSid] texNormalizedName = path.splitext( path.basename(texPath))[0] texFinalPath = rapi.getDirForFilePath( rapi.getInputName()) + texNormalizedName + extension if rapi.checkFileExists( texFinalPath): # check in current dir first dlog("Tex in current: " + texFinalPath) return texFinalPath, texNormalizedName # resource/target/win baseResFolder = path.dirname( path.abspath( rapi.getDirForFilePath(rapi.getInputName()))) texFinalPath = path.join( path.join(baseResFolder, "mdltex"), texNormalizedName) + extension if rapi.checkFileExists(texFinalPath): dlog("Tex from ../mdltex: " + texFinalPath) return texFinalPath, texNormalizedName dlog("Tex not found: " + texFinalPath) return None, None
def parse_texture(self, template): token = template.get_token() if token: texName = os.path.basename(token.get_value()) ext = os.path.splitext(texName)[1] texPath = self.dirpath + texName if rapi.checkFileExists(texPath): f = open(texPath, 'rb') tex = rapi.loadTexByHandler(f.read(), ext) print(texName, ext) if tex is not None: tex.name = texName self.texList.append(tex) self.matList[-1].setTexture(texName) f.close()
def LoadTexture(texName, file): if MODPATH != None: name = MODPATH +'\\'+ texName else: name = rapi.getDirForFilePath(rapi.getInputName()) + texName.split('\\')[-1] print(rapi.getDirForFilePath(rapi.getInputName())) if not rapi.checkFileExists(name): print("Texture not found: %s" %name) else: tex = open(name,'rb').read() noepyLoadRGBA(tex,file.texList) file.texList[-1].name = name return file.texList[-1]
def LoadArmature(self): if not rapi.checkFileExists(self.dirPath+'/rig.ast'): data = rapi.loadPairedFileOptional('Path of Exile armature','ast') if data == None: return data = NoeBitStream(data) else: data = NoeBitStream(open(self.dirPath + '/rig.ast','rb').read()) data.seek(1,1) numBones = data.readUByte() data.seek(1,1) numAnim = data.readUShort() data.seek(3,1) bones = [] parent = [] for i in range(numBones): parent.append( data.read('2B') ) bone = data.read('16f') length = data.readUByte() name = noeStrFromBytes( data.readBytes(length) ) mat = NoeMat44() mat.__setitem__(0, NoeVec4(bone[0 :4 ])) mat.__setitem__(1, NoeVec4(bone[4 :8 ])) mat.__setitem__(2, NoeVec4(bone[8 :12])) mat.__setitem__(3, NoeVec4(bone[12: ])) mat = mat.toMat43() bones.append(NoeBone(i,name,mat,None,-1)) Parent = { 0:{'parent':-1} } for i in range(len(parent)): mod=parent[i] if mod[0] !=255: Parent[mod[0]] = {'parent':Parent[i]['parent']} if mod[1] !=255: Parent[mod[1]] = {'parent':i} for i in range(len(bones)): bone = bones[i] bone.parentIndex = Parent[i]['parent'] animation={} animL=[] for i in range(numAnim): nBones = data.readUByte() data.seek(3,1) length = data.readUByte() name = noeStrFromBytes(data.readBytes(length)) animation[i] = {'name':name,'data':[]} for t in range(nBones): data.seek(1,1) boneID = data.readUShort() dID=data.tell() data.seek(2,1) mod = data.readUShort() mods= data.read('12B') data.seek(12,1) numFrames = data.readUShort() data.seek(12,1) if mod == 3: numFrames=data.readUShort() data.seek(12,1) rot={} pos={} printing=[] for f in range(numFrames+1): try: ID=data.readUShort() rot[ID]=data.read('4f') if ID >=numFrames:break except: print("animation:",i,"\nbone:",t,"total:",nBones,"\nframe:",f,"ID:",ID) raise for f in range(numFrames+1): ID=data.readUShort() pos[ID]=data.read('3f') printing.append(ID) if ID >=numFrames:break animation[i]['data'].append((boneID,(rot,pos),numFrames+1)) data.seek(14*mods[8],1) if t == nBones: print(data.tell()) animL.append(numFrames+1) anims=[] pLine='' for i in range(numAnim): anim = animation[i] name = anim['name'] data = anim['data'] frameMat=[] for b in range(len(data)): frameMat.append([]) bone = data[b] rot = bone[1][0] pos = bone[1][1] for f in range(bone[2]): if f in rot: mat = NoeQuat((rot[f][0],rot[f][1],rot[f][2],rot[f][3])) mat = mat.toMat43() else: mat = frameMat[b][-1] if f in pos: mat.__setitem__(3,NoeVec3((pos[f]))) else: mat.__setitem__(3,frameMat[b][-1][3]) if b == 0 and f==0: rotate = NoeMat43(((-1,0,0),(0,0,-1),(0,-1,0),(0,0,0))) frameMat[b].append(mat) matFrame=[] for f in range(animL[i]): mat = NoeMat43() for b in range(len(data)): try:matFrame.append(frameMat[b][f]) except:print("%d %d"%(f,b)) anims.append(NoeAnim(name,bones,animL[i],matFrame,1)) bones = rapi.multiplyBones(bones) self.bones = bones self.anims = anims
def RigStuff(VertBuffType, topname): #print("Loading Rig") RigExists = rapi.checkFileExists(topname + str(".Rig.header")) if RigExists: rigFile = rapi.loadIntoByteArray(topname + str(".Rig.header")) else: rigFile = rapi.loadPairedFile("Brutal Legend", ".Rig.header") rig = NoeBitStream(rigFile) Blank2 = rig.readUInt() Float1 = rig.readHalfFloat() Float2 = rig.readHalfFloat() Float3 = rig.readHalfFloat() Float4 = rig.readHalfFloat() BoneNameSize = rig.readUInt() BoneCount = rig.read("L") rig.seek(-4, NOESEEK_REL) BoneCount2 = rig.readUInt() parentIndicesSize = rig.readUInt() FlexCount = rig.readUInt() UNK5 = rig.readUInt() UNK6 = rig.readUInt() UNK7 = rig.readUInt() UNK8 = rig.readUInt() UNK9 = rig.readUInt() UNK10 = rig.readUInt() UNK11 = rig.readUInt() Float6 = rig.readFloat() UNK12 = rig.readUInt() UNK13 = rig.readUInt() UNK14 = rig.readUInt() rig.seek(76, NOESEEK_ABS) Offset1 = rig.readUInt() Offset2 = rig.readUInt() Offset3 = rig.readUInt() Offset4 = rig.readUInt() Offset5 = rig.readUInt() Offset6 = rig.readUInt() Offset7 = rig.readUInt() Blank2 = rig.readUInt() RigSig = rig.readUInt() BoneNames = [] BoneParent = [] BoneID = [] boneList = [] BoneXROTList = [] BoneYROTList = [] BoneZROTList = [] BoneXSCAList = [] BoneYSCAList = [] BoneZSCAList = [] BoneWSCAList = [] BoneXPOSList = [] BoneYPOSList = [] BoneZPOSList = [] BoneWPOSList = [] FlexNames = [] RigSourceExists = rapi.checkFileExists(topname + str(".Rig")) if RigSourceExists: rigSource = rapi.loadIntoByteArray(topname + str(".Rig")) else: rigSource = rapi.loadPairedFile("Brutal Legend", ".Rig") rigsource = NoeBitStream(rigSource) for i in range(0, BoneCount2): BoneNames.append(rigsource.readString()) #rigsource.seek(0, NOESEEK_ABS) for i in range(0, FlexCount): FlexNames.append(rigsource.readString()) print(FlexNames) rigsource.seek(Offset2, NOESEEK_ABS) for i in range(0, BoneCount[0]): BoneParent.append(rigsource.readShort()) rigsource.seek(Offset6, NOESEEK_ABS) boneReList = [] quat = NoeQuat([0, 0, 0, 0]) turn = NoeQuat([0, 0, 0, 1]) SCAINV = NoeVec3([0, 0, 0]) SCA = NoeVec3([0, 0, 0]) POS = NoeVec3([0, 0, 0]) #print("BoneParent", BoneParent) for i in range(0, (BoneCount[0])): boneMat = NoeMat44.fromBytes(rigsource.readBytes(64)) boneMat = boneMat.toMat43() boneMat = boneMat.inverse() boneReList.append( NoeBone(i, BoneNames[i], boneMat, None, BoneParent[i])) return boneReList
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 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 noepyLoadModel(data, mdlList): bones = [] dirPath = rapi.getDirForFilePath(rapi.getInputName()) if(rapi.checkFileExists(dirPath+"tpose.xskt")): xsktData = rapi.loadIntoByteArray(dirPath+"tpose.xskt") xsktData = NoeBitStream(xsktData) bones = LoadSkeleton(xsktData) bs = NoeBitStream(data) EndFile = bs.getSize() MHeader = noeAsciiFromBytes(bs.readBytes(4)) Version = bs.readInt() Unk1 = bs.readInt() NumObj = bs.readInt() FnameSize = bs.readInt() Fname = noeAsciiFromBytes(bs.readBytes(FnameSize)) Unk3 = bs.readInt() Num1 = bs.readInt() bs.seek(0x1C, NOESEEK_REL) Unk2 = bs.readInt() mesh = [] for obj in range(NumObj): ModelNameSize = bs.readInt() ModelName = noeAsciiFromBytes(bs.readBytes(ModelNameSize)) Num2 = bs.readInt() Type1 = bs.readShort() Type2 = bs.readShort() bs.seek(0x44, NOESEEK_REL) SubCount = bs.readInt() for sub in range(SubCount): vertArray = [] normArray = [] Facearray = [] UV_array = [] Weight_array = [] BoneMap = [] BoneNamePosArray = [] TexArray = [] MNameSize = bs.readInt() MName = noeAsciiFromBytes(bs.readBytes(MNameSize)) ModelId = bs.readInt() Unk4 = bs.readInt() VertexCount = bs.readInt() #mesh type 1 if Type1 == 4101: curOffSet = bs.getOffset() bs.seek(VertexCount*32, NOESEEK_REL) uv = True if bs.readInt() > 65000: uv = False bs.setOffset(curOffSet) for x in range(VertexCount): vertArray.append(NoeVec3.fromBytes(bs.readBytes(12))) normArray.append(NoeVec3.fromBytes(bs.readBytes(12))) if uv: UV_array.append(NoeVec3([bs.readFloat(), bs.readFloat(), 0.0])) #mesh type 2 if Type1 == 5381: for x in range(VertexCount): getPos = bs.getOffset() + 56 vertArray.append(NoeVec3.fromBytes(bs.readBytes(12))) normArray.append(NoeVec3.fromBytes(bs.readBytes(12))) bi = NoeVec3.fromBytes(bs.readBytes(12)) t = NoeVec3.fromBytes(bs.readBytes(12)) UV_array.append(NoeVec3([bs.readFloat(), bs.readFloat(), 0.0])) unk = bs.readFloat() bs.seek(getPos, NOESEEK_ABS) #mesh type 3 if Type1 == 5397: for x in range(VertexCount): getPos = bs.getOffset() + 60 vertArray.append(NoeVec3.fromBytes(bs.readBytes(12))) normArray.append(NoeVec3.fromBytes(bs.readBytes(12))) bi = NoeVec3.fromBytes(bs.readBytes(12)) t = NoeVec3.fromBytes(bs.readBytes(12)) UV_array.append(NoeVec3([bs.readFloat(), bs.readFloat(), 0.0])) bs.seek(getPos, NOESEEK_ABS) #face FaceCount = bs.readInt() Facearray = [bs.readUShort() for x in range(FaceCount)] #weight if EndFile-bs.getOffset() > VertexCount*32: WeightsStart = bs.getOffset() bs.seek(VertexCount*32, NOESEEK_REL) BoneMapSize = bs.readInt() BoneMap = noeAsciiFromBytes(bs.readBytes(BoneMapSize)).split('\0') if bones: BoneNamePosArray = [0] for x in BoneMap[:-1]: offset = BoneNamePosArray[-1] if BoneNamePosArray else 0 BoneNamePosArray.append(len(x) + offset+1) bs.seek(WeightsStart, NOESEEK_ABS) for i in range(VertexCount): bone1Off = bs.readInt() B1Offset = (bone1Off) for i in range(len(BoneNamePosArray)): if BoneNamePosArray[i] == B1Offset: B1Offset = i Bone1 = B1Offset weight1 = bs.readFloat() bone2Off = bs.readInt() B2Offset = (bone2Off) for i in range(len(BoneNamePosArray)): if BoneNamePosArray[i] == B2Offset: B2Offset = i Bone2 = int(B2Offset) weight2 = bs.readFloat() bone3Off = bs.readInt() B3Offset = (bone3Off) for i in range(len(BoneNamePosArray)): if BoneNamePosArray[i] == B3Offset: B3Offset = i Bone3 = int(B3Offset) weight3 = bs.readFloat() bone4Off = bs.readInt() B4Offset = (bone4Off) for i in range(len(BoneNamePosArray)): if BoneNamePosArray[i] == B4Offset: B4Offset = i Bone4 = int(B4Offset) weight4 = bs.readFloat() weights = ([],[]) maxweight = 0 if weight1 != 0: maxweight = maxweight + weight1 if weight2 != 0: maxweight = maxweight + weight2 if weight3 != 0: maxweight = maxweight + weight3 if weight4 != 0: maxweight = maxweight + weight4 if maxweight != 0: if bone1Off != -1: w1 = float(weight1) if len(BoneMap) < len(bones): weights[0].append(IDfromName(bones,BoneMap[Bone1])) else: weights[0].append(Bone1) weights[1].append(w1) if bone2Off != -1: w2 = float(weight2) if len(BoneMap) < len(bones): weights[0].append(IDfromName(bones,BoneMap[Bone2])) else: weights[0].append(Bone2) weights[1].append(w2) if bone3Off != -1: w3 = float(weight3) if len(BoneMap) < len(bones): weights[0].append(IDfromName(bones,BoneMap[Bone3])) else: weights[0].append(Bone3) weights[1].append(w3) if bone4Off != -1: w4 = float(weight4) if len(BoneMap) < len(bones): weights[0].append(IDfromName(bones,BoneMap[Bone4])) else: weights[0].append(Bone4) weights[1].append(w4) Weight_array.append(NoeVertWeight(weights[0],weights[1])) if SubCount > 1: bs.seek(0x18, NOESEEK_REL) bs.seek(bs.readInt(), NOESEEK_REL) bs.seek(bs.readInt(), NOESEEK_REL) msh = NoeMesh(Facearray, vertArray, ModelName, "mat_0") msh.setUVs(UV_array) msh.setNormals(normArray) msh.setWeights(Weight_array) mesh.append(msh) mdl = NoeModel(mesh) mdl.setModelMaterials(NoeModelMaterials([], [NoeMaterial("mat_0","")])) mdl.setBones(bones) mdlList.append(mdl) rapi.setPreviewOption("setAngOfs", "0 90 90") return 1