def __init__(self, bs, offset): bs.seekAbs(offset) if bs.readFixedString(4) != "60SE": raise ValueError("Expected bone section to start with '60SE'") bs.readBytes(0xC) boneCount = bs.readInt() bs.readInt() matrixOffset = bs.tell() + bs.readInt() bs.readBytes(0x14) boneNamesHeaderOffset = bs.tell() + bs.readInt() bs.readInt() bs.readInt() parentMap = {} parentRelCount = bs.readInt() bs.readInt() bs.readInt() for _ in range(parentRelCount): child = bs.readUByte() bs.readUByte() parent = bs.readUByte() bs.readUByte() if child != parent: parentMap[child] = parent boneNames = [] bs.seekAbs(boneNamesHeaderOffset) bs.readBytes(0x1C) bs.seekAbs(bs.tell() + bs.readInt()) for _ in range(boneCount): boneNames.append(bs.readString()) boneMatrixes = [] bs.seekAbs(matrixOffset) for _ in range(boneCount): qx, qy, qz, qw = bs.readFloat(), bs.readFloat(), bs.readFloat( ), bs.readFloat() x, y, z = bs.readFloat(), bs.readFloat(), bs.readFloat() bs.readBytes(0x14) quat = NoeQuat((qx, qy, qz, qw)) mat = quat.toMat43(transposed=1) mat[3] = NoeVec3((x, y, z)) boneMatrixes.append(mat) self.noeBones = [] for i in range(boneCount): self.noeBones.append( NoeBone(i, boneNames[i], boneMatrixes[i], None, parentMap.get(i, -1))) self.noeBones = rapi.multiplyBones(self.noeBones)
def noepyLoadModel(data,mdlList): ctx = rapi.rpgCreateContext() pfFile = PFfile(data) rapi.setPreviewOption('setAngOfs',"0 90 180") try: pfFile.Bones = rapi.multiplyBones(pfFile.Bones) mdl = rapi.rpgConstructModel() mdl.setModelMaterials(NoeModelMaterials(pfFile.texList, pfFile.matList)) mdl.setBones(pfFile.Bones) mdlList.append(mdl) except:pass rapi.rpgClearBufferBinds() return 1
def GetBones(self): try: boneFile = open(self.path+"/"+self.name+".skeleton","rb").read() bs = NoeBitStream(boneFile) bs.seek(21,1) boneData = [] parentData = {} i=0 while bs.tell() != bs.dataSize: chunk = bs.readUShort() if chunk == 0x2000: bs.seek(4,1) name = b'' char = bs.readBytes(1) while char != b'\x0a': name+=char char = bs.readBytes(1) name = noeStrFromBytes(name) bs.seek(2,1) data=bs.read('7f') bone=NoeMat43() bone.__setitem__(3,(data[0],data[2],data[1])) rot = NoeVec3((data[3],data[4],data[5])) rot = rot.toMat43() if i == 53: print(rot.mat43[0]) print(rot.mat43[1]) print(rot.mat43[2]) print(rot.mat43[3]) #bone.__setitem__(0,NoeVec3(data[3],0,0)) #bone.__setitem__(1,NoeVec3(0,data[4],0)) #bone.__setitem__(2,NoeVec3(0,0,data[5])) boneData.append((name,bone)) i+=1 elif chunk == 0x3000: bs.seek(4,1) p = bs.read('2H') parentData[p[0]] = p[1] else: size = bs.readUInt() bs.seek(size-6,1) for i in range(len(boneData)): name = boneData[i][0] bone = boneData[i][1] if i == len(boneData)-1:parent = -1 else:parent = parentData[i] self.boneList.append(NoeBone(i,name,bone,None,parent)) self.boneList = rapi.multiplyBones(self.boneList) except: print("[*] Skeleton not found.", );raise;return 0
def noepyLoadModel(data,mdlList): ctx = rapi.rpgCreateContext() wzm = WZM(data) mdl = rapi.rpgConstructModel() texList = [] Bones = [] Anims = [] matList = wzm.matList Bones = rapi.multiplyBones(wzm.skeleton.Bones) Anims = wzm.ParseAnims() mdl.setModelMaterials(NoeModelMaterials(texList, matList)) mdl.setBones(Bones) mdl.setAnims(Anims) mdlList.append(mdl) return 1
def noepyLoadModel(data, mdlList): ctx = rapi.rpgCreateContext() pfFile = PFfile(data) rapi.setPreviewOption('setAngOfs', "0 90 180") try: pfFile.Bones = rapi.multiplyBones(pfFile.Bones) mdl = rapi.rpgConstructModel() mdl.setModelMaterials(NoeModelMaterials(pfFile.texList, pfFile.matList)) mdl.setBones(pfFile.Bones) mdlList.append(mdl) except: pass rapi.rpgClearBufferBinds() return 1
def noepyLoadModel(data, mdlList): ctx = rapi.rpgCreateContext() wzm = WZM(data) mdl = rapi.rpgConstructModel() texList = [] Bones = [] Anims = [] matList = wzm.matList Bones = rapi.multiplyBones(wzm.skeleton.Bones) Anims = wzm.ParseAnims() mdl.setModelMaterials(NoeModelMaterials(texList, matList)) mdl.setBones(Bones) mdl.setAnims(Anims) mdlList.append(mdl) return 1
def ReadBones(self): self.SearchChunk("353020") self.data.seek(7, 1) self.numBones = self.data.readUInt() tempBone = [] for i in range(self.numBones): self.data.seek(10, 1) x, y, z = self.data.read('3f') self.data.seek(12, 1) r = self.data.read('4f') rotate = NoeQuat((r[0], r[1], r[2], -r[3])) bone = rotate.toMat43() bone.__setitem__(3, (x, y, z)) tempBone.append(bone) self.data.seek(1, 1) self.data.seek(15, 1) tag = self.data.read('3b') if tag[0] == 16: self.data.seek(1, 1) parent = [] for i in range(self.numBones): parent.append(self.data.readShort()) self.data.seek(11, 1) nameCount = self.data.readUInt() if nameCount > 0: boneName = 1 boneNames = [] for i in range(nameCount): self.data.seek(9, 1) boneNames.append( noeStrFromBytes(self.data.readBytes( self.data.readUByte()))[2:]) self.data.seek(1, 1) else: boneName = 0 self.data.seek(2, 1) for i in range(self.numBones): if boneName == 1: self.boneList.append( NoeBone(i, boneNames[i], tempBone[i], None, parent[i])) else: self.boneList.append( NoeBone(i, str(i), tempBone[i], None, parent[i])) self.boneList = rapi.multiplyBones(self.boneList)
def ReadBones(self): self.SearchChunk("353020") self.data.seek(7,1) self.numBones = self.data.readUInt() tempBone = [] for i in range(self.numBones): self.data.seek(10,1) x,y,z = self.data.read('3f') self.data.seek(12,1) r = self.data.read('4f') rotate = NoeQuat((r[0],r[1],r[2],-r[3])) bone = rotate.toMat43() bone.__setitem__(3,(x,y,z)) tempBone.append(bone) self.data.seek(1,1) self.data.seek(15,1) tag = self.data.read('3b') if tag[0] == 16:self.data.seek(1,1) parent = [] for i in range(self.numBones): parent.append( self.data.readShort()) self.data.seek(11,1) nameCount = self.data.readUInt() if nameCount> 0: boneName = 1 boneNames = [] for i in range(nameCount): self.data.seek(9,1) boneNames.append(noeStrFromBytes(self.data.readBytes( self.data.readUByte()))[2:]) self.data.seek(1, 1) else: boneName = 0 self.data.seek(2,1) for i in range(self.numBones): if boneName == 1: self.boneList.append(NoeBone(i,boneNames[i],tempBone[i],None,parent[i])) else: self.boneList.append(NoeBone(i,str(i),tempBone[i],None,parent[i])) self.boneList = rapi.multiplyBones(self.boneList)
def build_skeleton(self): if self.boneList: self.boneList = rapi.multiplyBones(self.boneList)
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 parseBlockMesh(self, blockHeader): bs = self.bs bs.seek(BLOCKHEADERSIZE, NOESEEK_REL) # todo: unknown data print(bs.readInt(), bs.readInt()) # boneCount boneCount = bs.readShort() if boneCount == 0: return # todo: unknown data t = bs.readShort() shifts = { 'bones': bs.readInt(), 'junk': bs.readInt(), 's1': bs.readInt( ), # almost always boneCount * 64 bytes (almost == static/skeletal?) 's2': bs.readInt(), # meshCount * 18 bytes 'boneInfo': bs.readInt(), 's4': bs.readInt(), # not always 0 bytes (int8) 'junk': bs.readInt(), 'm1': bs.readInt(), # 32 bytes 'meshInfo': bs.readInt() } ################################## BONES ################################## # Reading bones bs.seek(blockHeader['shift'] + shifts['bones'], NOESEEK_ABS) bones = [] for y in range(boneCount): p = { 'rot': NoeAngles.fromBytes(bs.readBytes(12)), 'trans': NoeVec3.fromBytes(bs.readBytes(12)), 'scale': NoeVec3.fromBytes(bs.readBytes(12)) } p['rot'][0], p['rot'][1], p['rot'][2] = -p['rot'][0], p['rot'][ 2], p['rot'][1] bones.append(p) # Reading bone hierarchy bs.seek(blockHeader['shift'] + shifts['boneInfo'], NOESEEK_ABS) boneInfo = [] for j in range(boneCount): t0 = [ bs.readByte() for x in range(6) ] # parent, 255 for 1st | 0 otherwise, bone index, ? some index , 0, 0 boneInfo.append({"parent": t0[0], "index": t0[2], "other": t0[3]}) # Building bones boneMatrices = [] socketIndex = 0 for j in range(boneCount): trans = NoeMat43().translate(bones[j]['trans']) rot = NoeMat43() scale = NoeMat43() if boneInfo[j]["parent"] != -1: rot = bones[boneInfo[j]["parent"]]['rot'].toMat43() scale = (NoeVec3((bones[j]['scale'][0], 0.0, 0.0)), NoeVec3((0.0, bones[j]['scale'][1], 0.0)), NoeVec3((0.0, 0.0, bones[j]['scale'][2])), NoeVec3((0.0, 0.0, 0.0))) if boneInfo[j]["index"] != -1: boneInfo[j]["name"] = "bone{0:03}".format(boneInfo[j]["index"]) else: boneInfo[j]["name"] = "socket{0:03}".format(socketIndex) socketIndex += 1 bone = trans * scale * rot boneMatrices.append(bone) noeBones = [ NoeBone(j, boneInfo[j]["name"], boneMatrices[j], parentIndex=boneInfo[j]["parent"]) for j in range(boneCount) ] noeBones = rapi.multiplyBones(noeBones) for j in range(boneCount): noeBones[j].setMatrix(bones[j]['rot'].toMat43() * noeBones[j].getMatrix()) self.objects[blockHeader['objectname']]['bones'] = noeBones ################################# MESHES ################################## bs.seek(blockHeader['shift'] + shifts['meshInfo'], NOESEEK_ABS) meshCount = bs.readInt() totalVertexCount = bs.readInt() # todo: unknown data bs.seek(16, NOESEEK_REL) meshInfo = [] meshBones = [] for j in range(meshCount): meshInfo.append([bs.readInt() for k in range(8)]) meshBones.append([bs.readShort() for k in range(32)]) meshDataShift = bs.tell() # meshDataShift = blockHeader['shift'] + meshInfoShift + 24 + 96 * meshCount self.objects[blockHeader['objectname']]['meshes'] = [] for j in range(meshCount): bs.seek(meshDataShift, NOESEEK_ABS) wmesh = WSXMesh(j, bs, boneInfo, meshInfo[j], meshBones[j], meshDataShift, blockHeader['recordtype'] == 0, blockHeader['objectname'] + "_" + str(j)) # todo: move this to mesh parser?? matList = self.objects[blockHeader['objectname']].get( 'materials', []) try: wmesh.mesh.setMaterial(matList[meshInfo[j][0]].name) except IndexError: print("> Missing texture {0}".format(meshInfo[j][0])) self.objects[blockHeader['objectname']]['meshes'].append( wmesh.mesh) return 1
def noepyLoadModel(data, mdlList): ctx = rapi.rpgCreateContext() bs = NoeBitStream(data) #rapi.rpgSetPosScaleBias((-1,-1,1),(0,0,0)) boneList = [] boneCount = bs.readInt() boneOffset = bs.tell() + bs.readInt() texCount = bs.readInt() texOffset = bs.tell() + bs.readInt() matCount = bs.readInt() matOffset = bs.tell() + bs.readInt() meshCount = bs.readInt() meshOffset = bs.tell() + bs.readInt() bs.seek(boneOffset, NOESEEK_ABS) for i in range(0, boneCount): boneName = bs.readBytes(0x20).decode("ASCII").rstrip("\0") boneMtx = NoeMat44.fromBytes(bs.readBytes(0x40)).toMat43() bs.readBytes(0x40) boneParent = bs.readInt() bs.readBytes(0x8) pos = NoeVec3.fromBytes(bs.readBytes(12)) bs.readBytes(0x8) quat = NoeQuat.fromBytes(bs.readBytes(16)) NoeVec3.fromBytes(bs.readBytes(12)) bs.readBytes(0x14) boneMtx = quat.toMat43() boneMtx[3] = pos newBone = NoeBone(i, boneName, boneMtx, None, boneParent) boneList.append(newBone) boneList = rapi.multiplyBones(boneList) texInfo = [] texList = [] bs.seek(texOffset, NOESEEK_ABS) for i in range(0, texCount): texName = bs.readBytes(0x20).decode("ASCII").rstrip("\0") texStart = bs.tell() + bs.readInt() bs.readBytes(0xC) texInfo.append([texName, texStart]) #print(texInfo) for i in range(0, texCount): bs.seek(texInfo[i][1], NOESEEK_ABS) bs.readBytes(0xC) palOff = bs.tell() + bs.readInt() texType, unk02, pixWidth, pixHeight, unk03, unk04 = bs.read("6H") texSize = bs.readInt() texOff = bs.tell() + bs.readInt() bs.seek(texOff, NOESEEK_ABS) texData = bs.readBytes(texSize) bs.seek(palOff, NOESEEK_ABS) unk11, unk22 = bs.read("2H") palSize, Null = bs.read("2I") palStart = bs.tell() + bs.readInt() bs.seek(palStart, NOESEEK_ABS) palData = [] for a in range(0, palSize // 4): pR, pG, pB, pA = bs.read("4B") if pR == 0 and pG == 255 and pB == 0 and pA == 255: pG = 0 pA = 0 palData.append(pR) palData.append(pG) palData.append(pB) palData.append(pA) palData = struct.pack("<" + 'B' * len(palData), *palData) if texType == 5: pix = rapi.imageUntwiddlePSP(texData, pixWidth, pixHeight, 8) pix = rapi.imageDecodeRawPal(pix, palData, pixWidth, pixHeight, 8, "r8g8b8a8") elif texType == 4: pix = rapi.imageUntwiddlePSP(texData, pixWidth, pixHeight, 4) pix = rapi.imageDecodeRawPal(pix, palData, pixWidth, pixHeight, 4, "r8g8b8a8") texList.append( NoeTexture(texInfo[i][0], pixWidth, pixHeight, pix, noesis.NOESISTEX_RGBA32)) matList = [] bs.seek(matOffset, NOESEEK_ABS) for i in range(0, matCount): matName = bs.readBytes(0x20).decode("ASCII").rstrip("\0") bs.readBytes(0xC) texID = bs.readInt() unk01, unk02, unk03, unk04 = bs.read("4B") bs.readBytes(0x8) material = NoeMaterial(matName, "") if texID >= 0: material.setTexture(texInfo[texID][0]) #material.setOpacityTexture(texInfo[texID][0]) matList.append(material) meshList = [] bs.seek(meshOffset, NOESEEK_ABS) for i in range(0, meshCount): meshName = bs.readBytes(0x20).decode("ASCII").rstrip("\0") mshCount = bs.readInt() unk11 = bs.readInt() meshStart = bs.tell() + bs.readInt() bs.readBytes(0xC) meshList.append([meshName, meshStart, mshCount, unk11]) #print(meshList) for a in range(0, len(meshList)): mshInfo = [] #print(meshList[a][0]) bs.seek(meshList[a][1], NOESEEK_ABS) for b in range(0, meshList[a][2]): unk20 = bs.readInt() matID = bs.readInt() mshC = bs.readInt() MshOff = bs.tell() + bs.readInt() mshInfo.append([matID, mshC, MshOff]) #print(mshInfo) mshInfo2 = [] for b in range(0, len(mshInfo)): bs.seek(mshInfo[b][2], NOESEEK_ABS) for c in range(0, mshInfo[b][1]): meshPc = bs.readInt() vType = bs.readInt() meshPc2 = bs.readInt() mshPo = bs.tell() + bs.readInt() mshPo2 = bs.tell() + bs.readInt() mshInfo2.append([ meshPc, vType, meshPc2, mshPo, mshPo2, matList[(mshInfo[b][0])].name ]) #print(mshInfo2) for b in range(0, len(mshInfo2)): mshInfo3 = [] rapi.rpgSetMaterial(mshInfo2[b][5]) bs.seek(mshInfo2[b][3], NOESEEK_ABS) idxList = [[0, 0, 0, 0, 0, 0, 0, 0]] for c in range(0, mshInfo2[b][2]): idxList[0][c] = bs.readInt() bs.seek(mshInfo2[b][4], NOESEEK_ABS) #print(idxList) for c in range(0, mshInfo2[b][0]): mshId2 = bs.readInt() vertCount = bs.readInt() vertStart = bs.tell() + bs.readInt() mshInfo3.append([mshId2, vertCount, vertStart]) #print(mshInfo3) for c in range(0, len(mshInfo3)): #print(mshInfo3[c]) bs.seek(mshInfo3[c][2], NOESEEK_ABS) rapi.rpgSetName(meshList[a][0]) #rapi.rpgSetName(meshList[a][0] + "_" + str(b) + "_" + str(c) + "_" + str(mshInfo2[b][1])) vertStride = 0 if mshInfo2[b][1] == 7: vertStride = 0x18 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0xC) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x8, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0) elif mshInfo2[b][1] == 24: vertStride = 0x1C vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x10) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0xC, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x4) elif mshInfo2[b][1] == 25: vertStride = 0x1C vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x10) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0xC, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x4) elif mshInfo2[b][1] == 26: vertStride = 0x20 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x14) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x10, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x8) elif mshInfo2[b][1] == 27: vertStride = 0x20 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x14) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x10, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x8) elif mshInfo2[b][1] == 28: vertStride = 0x24 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x18) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x14, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0xC) elif mshInfo2[b][1] == 29: vertStride = 0x24 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x18) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x14, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0xC) elif mshInfo2[b][1] == 30: vertStride = 0x28 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x1C) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x18, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x10) elif mshInfo2[b][1] == 23: vertStride = 0x28 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x1C) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x18, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x10) else: print(bs.tell()) print("unknown found " + str(mshInfo2[b][1])) vs = NoeBitStream(vertBuff) tmp = [] tmp2 = [] weight = [] index = [] if vertStride == 0x18: for d in range(0, mshInfo3[c][1]): w1, w2, w3, w4, w5, w6, w7, w8 = [ 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ] index.append(idxList[0][0]) index.append(idxList[0][1]) index.append(idxList[0][2]) index.append(idxList[0][3]) index.append(idxList[0][4]) index.append(idxList[0][5]) index.append(idxList[0][6]) index.append(idxList[0][7]) weight.append(w1) weight.append(w2) weight.append(w3) weight.append(w4) weight.append(w5) weight.append(w6) weight.append(w7) weight.append(w8) vs.readBytes(0xC) tmp.append( [vs.readUInt(), vs.readUInt(), vs.readUInt()]) elif vertStride == 0x1C: for d in range(0, mshInfo3[c][1]): w1, w2, w3, w4, w5, w6, w7, w8 = [ vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ] index.append(idxList[0][0]) index.append(idxList[0][1]) index.append(idxList[0][2]) index.append(idxList[0][3]) index.append(idxList[0][4]) index.append(idxList[0][5]) index.append(idxList[0][6]) index.append(idxList[0][7]) weight.append(w1) weight.append(w2) weight.append(w3) weight.append(w4) weight.append(w5) weight.append(w6) weight.append(w7) weight.append(w8) vs.readBytes(0xC) tmp.append( [vs.readUInt(), vs.readUInt(), vs.readUInt()]) elif vertStride == 0x20: for d in range(0, mshInfo3[c][1]): w1, w2, w3, w4, w5, w6, w7, w8 = [ vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, 0.0, 0.0, 0.0, 0.0 ] index.append(idxList[0][0]) index.append(idxList[0][1]) index.append(idxList[0][2]) index.append(idxList[0][3]) index.append(idxList[0][4]) index.append(idxList[0][5]) index.append(idxList[0][6]) index.append(idxList[0][7]) weight.append(w1) weight.append(w2) weight.append(w3) weight.append(w4) weight.append(w5) weight.append(w6) weight.append(w7) weight.append(w8) vs.readBytes(0xC) tmp.append( [vs.readUInt(), vs.readUInt(), vs.readUInt()]) elif vertStride == 0x24: for d in range(0, mshInfo3[c][1]): w1, w2, w3, w4, w5, w6, w7, w8 = [ vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, 0.0, 0.0 ] index.append(idxList[0][0]) index.append(idxList[0][1]) index.append(idxList[0][2]) index.append(idxList[0][3]) index.append(idxList[0][4]) index.append(idxList[0][5]) index.append(idxList[0][6]) index.append(idxList[0][7]) weight.append(w1) weight.append(w2) weight.append(w3) weight.append(w4) weight.append(w5) weight.append(w6) weight.append(w7) weight.append(w8) vs.readBytes(0xC) tmp.append( [vs.readUInt(), vs.readUInt(), vs.readUInt()]) elif vertStride == 0x28: for d in range(0, mshInfo3[c][1]): w1, w2, w3, w4, w5, w6, w7, w8 = [ vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF ] index.append(idxList[0][0]) index.append(idxList[0][1]) index.append(idxList[0][2]) index.append(idxList[0][3]) index.append(idxList[0][4]) index.append(idxList[0][5]) index.append(idxList[0][6]) index.append(idxList[0][7]) weight.append(w1) weight.append(w2) weight.append(w3) weight.append(w4) weight.append(w5) weight.append(w6) weight.append(w7) weight.append(w8) vs.readBytes(0xC) tmp.append( [vs.readUInt(), vs.readUInt(), vs.readUInt()]) indexBuff = struct.pack('B' * len(index), *index) weightBuff = struct.pack('f' * len(weight), *weight) rapi.rpgBindBoneIndexBuffer(indexBuff, noesis.RPGEODATA_BYTE, 8, 8) rapi.rpgBindBoneWeightBuffer(weightBuff, noesis.RPGEODATA_FLOAT, 0x20, 8) flip = 0 step = 1 if mshInfo3[c][0] == 0: step = 3 for d in range(0, mshInfo3[c][1] - 2, step): if (tmp[d] != tmp[(d + 1)]) and (tmp[d] != tmp[ (d + 2)]) and (tmp[d + 1] != tmp[(d + 2)]): tmp2.append(d) tmp2.append(d + 1 + flip) tmp2.append(d + 2 - flip) if mshInfo3[c][0] != 0: flip = 1 - flip else: flip = 0 #print(d) faceBuff = struct.pack('H' * len(tmp2), *tmp2) if len(faceBuff) > 3: rapi.rpgCommitTriangles(faceBuff, noesis.RPGEODATA_USHORT, len(tmp2), noesis.RPGEO_TRIANGLE, 1) rapi.rpgClearBufferBinds() mdl = rapi.rpgConstructModel() mdl.setModelMaterials(NoeModelMaterials(texList, matList)) mdlList.append(mdl) mdl.setBones(boneList) return 1
def noepyLoadModel(data, mdlList): ctx = rapi.rpgCreateContext() bs = NoeBitStream(data) #rapi.rpgSetPosScaleBias((-1,-1,1),(0,0,0)) boneList = [] boneCount = bs.readInt() boneOffset = bs.tell() + bs.readInt() texCount = bs.readInt() texOffset = bs.tell() + bs.readInt() matCount = bs.readInt() matOffset = bs.tell() + bs.readInt() meshCount = bs.readInt() meshOffset = bs.tell() + bs.readInt() bs.seek(boneOffset, NOESEEK_ABS) for i in range(0, boneCount): boneName = bs.readBytes(0x20).decode("ASCII").rstrip("\0") boneMtx = NoeMat44.fromBytes(bs.readBytes(0x40)).toMat43() bs.readBytes(0x40) boneParent = bs.readInt() bs.readBytes(0x8) pos = NoeVec3.fromBytes(bs.readBytes(12)) bs.readBytes(0x8) quat = NoeQuat.fromBytes(bs.readBytes(16)) NoeVec3.fromBytes(bs.readBytes(12)) bs.readBytes(0x14) boneMtx = quat.toMat43() boneMtx[3] = pos newBone = NoeBone(i, boneName, boneMtx, None, boneParent) boneList.append(newBone) boneList = rapi.multiplyBones(boneList) texInfo = [] texList = [] bs.seek(texOffset, NOESEEK_ABS) for i in range(0, texCount): texName = bs.readBytes(0x20).decode("ASCII").rstrip("\0") texStart = bs.tell() + bs.readInt() bs.readBytes(0xC) texInfo.append([texName,texStart]) #print(texInfo) for i in range(0, texCount): bs.seek(texInfo[i][1], NOESEEK_ABS) bs.readBytes(0xC) palOff = bs.tell() + bs.readInt() texType, unk02, pixWidth, pixHeight, unk03, unk04 = bs.read("6H") texSize = bs.readInt() texOff = bs.tell() + bs.readInt() bs.seek(texOff, NOESEEK_ABS) texData = bs.readBytes(texSize) bs.seek(palOff, NOESEEK_ABS) unk11, unk22 = bs.read("2H") palSize, Null = bs.read("2I") palStart = bs.tell() + bs.readInt() bs.seek(palStart, NOESEEK_ABS) palData = [] for a in range(0, palSize // 4): pR, pG, pB, pA = bs.read("4B") if pR == 0 and pG == 255 and pB == 0 and pA == 255: pG = 0 pA = 0 palData.append(pR) palData.append(pG) palData.append(pB) palData.append(pA) palData = struct.pack("<" + 'B'*len(palData), *palData) if texType == 5: pix = rapi.imageUntwiddlePSP(texData, pixWidth, pixHeight, 8) pix = rapi.imageDecodeRawPal(pix, palData, pixWidth, pixHeight, 8, "r8g8b8a8") elif texType == 4: pix = rapi.imageUntwiddlePSP(texData, pixWidth, pixHeight, 4) pix = rapi.imageDecodeRawPal(pix, palData, pixWidth, pixHeight, 4, "r8g8b8a8") texList.append(NoeTexture(texInfo[i][0], pixWidth, pixHeight, pix, noesis.NOESISTEX_RGBA32)) matList = [] bs.seek(matOffset, NOESEEK_ABS) for i in range(0, matCount): matName = bs.readBytes(0x20).decode("ASCII").rstrip("\0") bs.readBytes(0xC) texID = bs.readInt() unk01, unk02, unk03, unk04 = bs.read("4B") bs.readBytes(0x8) material = NoeMaterial(matName, "") if texID >= 0: material.setTexture(texInfo[texID][0]) #material.setOpacityTexture(texInfo[texID][0]) matList.append(material) meshList = [] bs.seek(meshOffset, NOESEEK_ABS) for i in range(0, meshCount): meshName = bs.readBytes(0x20).decode("ASCII").rstrip("\0") mshCount = bs.readInt() unk11 = bs.readInt() meshStart = bs.tell() + bs.readInt() bs.readBytes(0xC) meshList.append([meshName, meshStart, mshCount, unk11]) #print(meshList) for a in range(0, len(meshList)): mshInfo = [] #print(meshList[a][0]) bs.seek(meshList[a][1], NOESEEK_ABS) for b in range(0, meshList[a][2]): unk20 = bs.readInt() matID = bs.readInt() mshC = bs.readInt() MshOff = bs.tell() + bs.readInt() mshInfo.append([matID, mshC, MshOff]) #print(mshInfo) mshInfo2 = [] for b in range(0, len(mshInfo)): bs.seek(mshInfo[b][2], NOESEEK_ABS) for c in range(0, mshInfo[b][1]): meshPc = bs.readInt() vType = bs.readInt() meshPc2 = bs.readInt() mshPo = bs.tell() + bs.readInt() mshPo2 = bs.tell() + bs.readInt() mshInfo2.append([meshPc, vType, meshPc2, mshPo, mshPo2, matList[(mshInfo[b][0])].name]) #print(mshInfo2) for b in range(0, len(mshInfo2)): mshInfo3 = [] rapi.rpgSetMaterial(mshInfo2[b][5]) bs.seek(mshInfo2[b][3], NOESEEK_ABS) idxList = [[0, 0, 0, 0, 0, 0, 0, 0]] for c in range(0, mshInfo2[b][2]): idxList[0][c] = bs.readInt() bs.seek(mshInfo2[b][4], NOESEEK_ABS) #print(idxList) for c in range(0, mshInfo2[b][0]): mshId2 = bs.readInt() vertCount = bs.readInt() vertStart = bs.tell() + bs.readInt() mshInfo3.append([mshId2, vertCount, vertStart]) #print(mshInfo3) for c in range(0, len(mshInfo3)): #print(mshInfo3[c]) bs.seek(mshInfo3[c][2], NOESEEK_ABS) rapi.rpgSetName(meshList[a][0]) #rapi.rpgSetName(meshList[a][0] + "_" + str(b) + "_" + str(c) + "_" + str(mshInfo2[b][1])) vertStride = 0 if mshInfo2[b][1] == 7: vertStride = 0x18 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0xC) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x8, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0) elif mshInfo2[b][1] == 24: vertStride = 0x1C vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x10) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0xC, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x4) elif mshInfo2[b][1] == 25: vertStride = 0x1C vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x10) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0xC, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x4) elif mshInfo2[b][1] == 26: vertStride = 0x20 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x14) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x10, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x8) elif mshInfo2[b][1] == 27: vertStride = 0x20 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x14) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x10, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x8) elif mshInfo2[b][1] == 28: vertStride = 0x24 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x18) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x14, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0xC) elif mshInfo2[b][1] == 29: vertStride = 0x24 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x18) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x14, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0xC) elif mshInfo2[b][1] == 30: vertStride = 0x28 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x1C) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x18, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x10) elif mshInfo2[b][1] == 23: vertStride = 0x28 vertBuff = bs.readBytes(mshInfo3[c][1] * vertStride) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x1C) rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, vertStride, 0x18, 4) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, vertStride, 0x10) else: print(bs.tell()) print("unknown found " + str(mshInfo2[b][1])) vs = NoeBitStream(vertBuff) tmp = [] tmp2 = [] weight = [] index = [] if vertStride == 0x18: for d in range(0, mshInfo3[c][1]): w1, w2, w3, w4, w5, w6, w7, w8 = [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] index.append(idxList[0][0]); index.append(idxList[0][1]); index.append(idxList[0][2]); index.append(idxList[0][3]) index.append(idxList[0][4]); index.append(idxList[0][5]); index.append(idxList[0][6]); index.append(idxList[0][7]) weight.append(w1); weight.append(w2); weight.append(w3); weight.append(w4); weight.append(w5); weight.append(w6); weight.append(w7); weight.append(w8) vs.readBytes(0xC) tmp.append([vs.readUInt(), vs.readUInt(), vs.readUInt()]) elif vertStride == 0x1C: for d in range(0, mshInfo3[c][1]): w1, w2, w3, w4, w5, w6, w7, w8 = [vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] index.append(idxList[0][0]); index.append(idxList[0][1]); index.append(idxList[0][2]); index.append(idxList[0][3]) index.append(idxList[0][4]); index.append(idxList[0][5]); index.append(idxList[0][6]); index.append(idxList[0][7]) weight.append(w1); weight.append(w2); weight.append(w3); weight.append(w4); weight.append(w5); weight.append(w6); weight.append(w7); weight.append(w8) vs.readBytes(0xC) tmp.append([vs.readUInt(), vs.readUInt(), vs.readUInt()]) elif vertStride == 0x20: for d in range(0, mshInfo3[c][1]): w1, w2, w3, w4, w5, w6, w7, w8 = [vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, 0.0, 0.0, 0.0, 0.0] index.append(idxList[0][0]); index.append(idxList[0][1]); index.append(idxList[0][2]); index.append(idxList[0][3]) index.append(idxList[0][4]); index.append(idxList[0][5]); index.append(idxList[0][6]); index.append(idxList[0][7]) weight.append(w1); weight.append(w2); weight.append(w3); weight.append(w4); weight.append(w5); weight.append(w6); weight.append(w7); weight.append(w8) vs.readBytes(0xC) tmp.append([vs.readUInt(), vs.readUInt(), vs.readUInt()]) elif vertStride == 0x24: for d in range(0, mshInfo3[c][1]): w1, w2, w3, w4, w5, w6, w7, w8 = [vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, 0.0, 0.0] index.append(idxList[0][0]); index.append(idxList[0][1]); index.append(idxList[0][2]); index.append(idxList[0][3]) index.append(idxList[0][4]); index.append(idxList[0][5]); index.append(idxList[0][6]); index.append(idxList[0][7]) weight.append(w1); weight.append(w2); weight.append(w3); weight.append(w4); weight.append(w5); weight.append(w6); weight.append(w7); weight.append(w8) vs.readBytes(0xC) tmp.append([vs.readUInt(), vs.readUInt(), vs.readUInt()]) elif vertStride == 0x28: for d in range(0, mshInfo3[c][1]): w1, w2, w3, w4, w5, w6, w7, w8 = [vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF, vs.readUShort() / 0x7FFF] index.append(idxList[0][0]); index.append(idxList[0][1]); index.append(idxList[0][2]); index.append(idxList[0][3]) index.append(idxList[0][4]); index.append(idxList[0][5]); index.append(idxList[0][6]); index.append(idxList[0][7]) weight.append(w1); weight.append(w2); weight.append(w3); weight.append(w4); weight.append(w5); weight.append(w6); weight.append(w7); weight.append(w8) vs.readBytes(0xC) tmp.append([vs.readUInt(), vs.readUInt(), vs.readUInt()]) indexBuff = struct.pack('B'*len(index), *index) weightBuff = struct.pack('f'*len(weight), *weight) rapi.rpgBindBoneIndexBuffer(indexBuff, noesis.RPGEODATA_BYTE, 8, 8) rapi.rpgBindBoneWeightBuffer(weightBuff, noesis.RPGEODATA_FLOAT, 0x20, 8) flip = 0 step = 1 if mshInfo3[c][0] == 0: step = 3 for d in range(0, mshInfo3[c][1] - 2, step): if (tmp[d] != tmp[(d + 1)]) and (tmp[d] != tmp[(d + 2)]) and (tmp[d + 1] != tmp[(d + 2)]): tmp2.append(d) tmp2.append(d + 1 + flip) tmp2.append(d + 2 - flip) if mshInfo3[c][0] != 0: flip = 1 - flip else: flip = 0 #print(d) faceBuff = struct.pack('H'*len(tmp2), *tmp2) if len(faceBuff) > 3: rapi.rpgCommitTriangles(faceBuff, noesis.RPGEODATA_USHORT, len(tmp2), noesis.RPGEO_TRIANGLE, 1) rapi.rpgClearBufferBinds() mdl = rapi.rpgConstructModel() mdl.setModelMaterials(NoeModelMaterials(texList, matList)) mdlList.append(mdl) mdl.setBones(boneList) return 1