def parse_file(self): headerSize = self.inFile.readUInt() width, height = self.inFile.read('2L') self.inFile.readUInt() self.inFile.readUInt() pixSize = self.inFile.readUInt() self.inFile.read("2L") numColors = self.inFile.readUInt() self.inFile.readUInt() if numColors: palette = self.inFile.readBytes(numColors * 4) pixMap = self.inFile.readBytes(width * height) pixData = rapi.imageDecodeRawPal(pixMap, palette, height, width, 8, "b8g8r8p8") else: if pixSize == 0: pixSize = width * height * 3 pixData = self.inFile.readBytes(pixSize) pixData = rapi.imageDecodeRaw(pixData, width, height, 'b8g8r8') pixData = rapi.imageFlipRGBA32(pixData, width, height, 0, 1) tex = NoeTexture("tex", width, height, pixData, noesis.NOESISTEX_RGBA32) self.texList.append(tex)
def parseTexture(self): texWidth = self.reader.readUShort() texHeight = self.reader.readUShort() texType = self.reader.readShort() texMips = self.reader.readShort() texUnknown = self.reader.readShort() texFlag1 = self.reader.readUByte() texFlag2 = self.reader.readUByte() texFlag3 = self.reader.readUByte() texFlag4 = self.reader.readUByte() if texType == 1: # P8 palMap = self.reader.readBytes(256*4) pixMap = self.reader.readBytes(texWidth * texHeight) pixData = rapi.imageDecodeRawPal(pixMap, palMap, texWidth, texHeight, 8, "b8g8r8p8") if texType == 14: # PA8 palMap = self.reader.readBytes(256*4) pixMap = self.reader.readBytes(texWidth * texHeight) pixData = rapi.imageDecodeRawPal(pixMap, palMap, texWidth, texHeight, 8, "b8g8r8a8") if texType == 15: # P4_MC palMap = self.reader.readBytes(16*4) pixMap = self.reader.readBytes(int(texWidth * texHeight / 2)) pixData = rapi.imageDecodeRawPal(pixMap, palMap, texWidth, texHeight, 4, "b8g8r8p8") if texType == 16: # PA4_MC palMap = self.reader.readBytes(16*4) pixMap = self.reader.readBytes(int(texWidth * texHeight / 2)) pixData = rapi.imageDecodeRawPal(pixMap, palMap, texWidth, texHeight, 4, "b8g8r8a8") if texType == 17: # RGB888 pixMap = self.reader.readBytes(texWidth * texHeight * 3) pixData = rapi.imageDecodeRaw(pixMap, texWidth, texHeight, "r8g8b8") if texType == 18: # RGBA8888 pixMap = self.reader.readBytes(texWidth * texHeight * 4) pixData = rapi.imageDecodeRaw(pixMap, texWidth, texHeight, "r8g8b8a8") # Midnight Club 2 support (textype 26 not fully functional) if texType == 22: # DXT1 pixMap = self.reader.readBytes(int(texWidth * texHeight * 4 / 8)) pixData = rapi.imageDecodeDXT(pixMap, texWidth, texHeight, noesis.NOESISTEX_DXT1) if texType == 26: # DXT5 pixMap = self.reader.readBytes(int(texWidth * texHeight * 4 / 4)) pixData = rapi.imageDecodeDXT(pixMap, texWidth, texHeight, noesis.NOESISTEX_DXT5) #pixData = rapi.imageFlipRGBA32(pixData, texWidth, texHeight, 0, 1) return NoeTexture("tex", texWidth, texHeight, pixData, noesis.NOESISTEX_RGBA32)
def parse_file(self): headerSize = self.inFile.readUInt() width, height = self.inFile.read('2L') self.inFile.readUInt() self.inFile.readUInt() pixSize = self.inFile.readUInt() self.inFile.read("2L") numColors = self.inFile.readUInt() self.inFile.readUInt() if numColors: palette = self.inFile.readBytes(numColors*4) pixMap = self.inFile.readBytes(width*height) pixData = rapi.imageDecodeRawPal(pixMap, palette, height, width, 8, "b8g8r8p8") else: if pixSize == 0: pixSize = width * height * 3 pixData = self.inFile.readBytes(pixSize) pixData = rapi.imageDecodeRaw(pixData, width, height, 'b8g8r8') pixData = rapi.imageFlipRGBA32(pixData, width, height, 0, 1) tex = NoeTexture("tex", width, height, pixData, noesis.NOESISTEX_RGBA32) self.texList.append(tex)
def Bio1LoadRGBA(data, texList): textcount = 1 bs = NoeBitStream(data) filesize = bs.getSize() filesizeDiv4 = filesize//4 for i in range(0, filesizeDiv4-1): Temp = bs.readInt() # Texture headers if (Temp == 0x004F61C8) or (Temp == 0x004F8288) or (Temp == 0x004F5110) or (Temp == 0x004F9260) or (Temp == 0x004FD320) or (Temp == 0x004FF504) or (Temp == 0x004F7218) or (Temp == 0x00543B28) or (Temp == 0x004F8298) or (Temp == 0x004F8280) or (Temp == 0x004F92D0) or (Temp == 0x00543B28) or (Temp == 0x004F5130) or (Temp == 0x00567760): offset = bs.tell() bs.seek(0x09, NOESEEK_REL) palPosition = bs.readByte() bitDepth = bs.readByte() # Accomdation for wad version 101 if (Temp == 0x00543B28): bs.seek(0x5, NOESEEK_REL) off2pal = bs.readInt() bs.seek(0x10, NOESEEK_REL) value1 = bs.readInt() value2 = bs.readInt() width = bs.readInt() height = bs.readInt() else: bs.seek(0x19, NOESEEK_REL) off2pal = bs.readInt() bs.seek(0x04, NOESEEK_REL) value1 = bs.readInt() value2 = bs.readInt() width = bs.readInt() height = bs.readInt() if (width > 2048) or (height > 2048): continue print (textcount) print('Found a texture at {0}, width - {1}, height - {2}'.format(hex(offset - 0x4), width, height)) textcount+=1 # Accomdation for wad version 101 if (Temp == 0x00543B28): bs.seek(0x28, NOESEEK_REL) else: bs.seek(0x30, NOESEEK_REL) off2raw = bs.tell() bs.seek(off2pal, NOESEEK_ABS) print('Found a palette at {0}'.format(hex(off2pal))) bs.seek(0x50, NOESEEK_REL) palSize = 0x400 pal = bs.readBytes(palSize) f0 = io.BytesIO(pal) f1 = io.BytesIO(pal) count = 0 swapCount = 0 block0 = [] block1 = [] # Unswizzle palette block while count != 0x100: color = struct.unpack('i', f0.read(4))[0] f1.write(struct.pack("i", color)) count += 1 swapCount += 1 if count == 8 or swapCount == 16: for i in range(0,8): color = struct.unpack('i', f0.read(4))[0] block0+=[color] for i in range(0,8): color = struct.unpack('i', f0.read(4))[0] block1+=[color] for i in range(0,8): f1.write(struct.pack("i", block1[i])) for i in range(0,8): f1.write(struct.pack("i", block0[i])) block0=[] block1=[] count += 16 swapCount = 0 f1.seek(0x00, io.SEEK_SET) # Seek to correct palette in palette block if texture has a bit depth of 4 # Else, read the whole palette block if bitDepth == 0x14: newpalPosition = palPosition * 0x40 f1.seek(newpalPosition, io.SEEK_SET) thepal = f1.read(0x40) else: thepal = f1.read() newpal = bytearray(thepal) bs.seek(off2raw, NOESEEK_ABS) # 0x14: 16 color palette, 0x13: 256 color palette, 0x00: No palette # Accomdation for wad version 136 swizzling if bitDepth == 0x14: if (value1 != value2) and Temp == 0x00567760: width = width*2 height = height*2 img = rapi.imageUntwiddlePS2(bs.readBytes(width*height*4), width, height,4) img = rapi.imageDecodeRawPal(img, newpal, width, height, 4, "r8g8b8a8") else: img = rapi.imageDecodeRawPal(bs.readBytes(width*height), newpal, width, height, 4, "r8g8b8a8") if bitDepth == 0x13: if (value1 != value2) and Temp == 0x00567760: width = width*2 height = height*2 img = rapi.imageUntwiddlePS2(bs.readBytes(width*height*4), width, height,8) img = rapi.imageDecodeRawPal(img, newpal, width, height, 8, "r8g8b8a8") else: img = rapi.imageDecodeRawPal(bs.readBytes(width*height), newpal, width, height, 8, "r8g8b8a8") if bitDepth == 0x00: img = rapi.imageDecodeRaw(bs.readBytes(width*height*4), width, height, "r8g8b8a8") texList.append(NoeTexture(str(i), width, height, img, noesis.NOESISTEX_RGBA32)) bs.seek(offset, NOESEEK_ABS) # Texture package headers if (Temp == 0x004F5124) or (Temp == 0x004F92E4) or (Temp == 0x004F722C) or (Temp == 0x004FF518) or (Temp == 0x004F61DC) or (Temp == 0x004F829C): offset = bs.tell() bs.seek(0x09, NOESEEK_REL) palPosition = bs.readByte() bitDepth = bs.readByte() bs.seek(0x05, NOESEEK_REL) off2pal = bs.readInt() bs.seek(0x20, NOESEEK_REL) numTex = bs.readShort() print('Found a texture package at {0}, number of textures - {1}'.format(hex(offset - 0x4), numTex)) bs.seek(0x2, NOESEEK_REL) off2inf = bs.readInt() bs.seek(off2inf, NOESEEK_ABS) for j in range(0, numTex): bs.seek(0x8, NOESEEK_REL) width = bs.readInt() height = bs.readInt() off2tex = bs.readInt() bs.seek(0x4, NOESEEK_REL) print (textcount) print('Found a texture at {0}, width - {1}, height - {2}'.format(hex(off2tex), width, height)) textcount+=1 bs.seek(off2pal, NOESEEK_ABS) print('Found a palette at {0}'.format(hex(off2pal))) bs.seek(0x50, NOESEEK_REL) palSize = 0x400 pal = bs.readBytes(palSize) f0 = io.BytesIO(pal) f1 = io.BytesIO(pal) count = 0 swapCount = 0 block0 = [] block1 = [] # Unswizzle palette block while count != 0x100: color = struct.unpack('i', f0.read(4))[0] f1.write(struct.pack("i", color)) count += 1 swapCount += 1 if count == 8 or swapCount == 16: for i in range(0,8): color = struct.unpack('i', f0.read(4))[0] block0+=[color] for i in range(0,8): color = struct.unpack('i', f0.read(4))[0] block1+=[color] for i in range(0,8): f1.write(struct.pack("i", block1[i])) for i in range(0,8): f1.write(struct.pack("i", block0[i])) block0=[] block1=[] count += 16 swapCount = 0 f1.seek(0x00, io.SEEK_SET) # Seek to correct palette in palette block if texture has a bit depth of 4 # Else, read the whole palette block if bitDepth == 0x14: newpalPosition = palPosition * 0x40 f1.seek(newpalPosition, io.SEEK_SET) thepal = f1.read(0x40) else: thepal = f1.read() newpal = bytearray(thepal) bs.seek(off2tex + 0x20, NOESEEK_ABS) # 0x14: 16 color palette, 0x13: 256 color palette, 0x00: No palette if bitDepth == 0x14: img = rapi.imageDecodeRawPal(bs.readBytes(width*height), newpal, width, height, 4, "r8g8b8a8") if bitDepth == 0x13: img = rapi.imageDecodeRawPal(bs.readBytes(width*height), newpal, width, height, 8, "r8g8b8a8") if bitDepth == 0x00: img = rapi.imageDecodeRaw(bs.readBytes(width*height*4), width, height, "r8g8b8a8") texList.append(NoeTexture(str(i+j), width, height, img, noesis.NOESISTEX_RGBA32)) bs.seek(off2inf + (j + 1)*0x18, NOESEEK_ABS) bs.seek(offset, NOESEEK_ABS) 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