home *** CD-ROM | disk | FTP | other *** search
- from inc_noesis import *
-
- def registerNoesisTypes():
- handle = noesis.register("Folklore", ".bi5_")
- noesis.setHandlerTypeCheck(handle, flCheckType)
- noesis.setHandlerLoadModel(handle, flLoadModel)
- #noesis.logPopup()
- return 1
-
-
- def flCheckType(data):
- bs = NoeBitStream(data)
- return 1
-
-
- class folkloreFile:
-
- def __init__(self, bs):
- self.bs = bs
- rapi.rpgSetOption(noesis.RPGOPT_BIGENDIAN, 1)
- self.texList = []
- self.matList = []
- self.boneList = []
- self.boneMap = []
- self.offsetList = []
- self.meshOffsets = []
-
- def loadAll(self, bs):
- fileSize, fileCount, tableOffset, nameOffset = bs.read(">" + 4 * "i")
- bs.seek(tableOffset, NOESEEK_ABS)
- bi5Off = bs.read(">" + (fileCount + 1) * "i")
- bs.seek(nameOffset, NOESEEK_ABS)
- for i in range(0, fileCount):
- fileName = bs.readBytes(0x18).decode("ASCII").rstrip("\0")
- if (bi5Off[i + 1] - bi5Off[i]) != 0:
- self.offsetList.append([fileName, bi5Off[i], (bi5Off[i + 1] - bi5Off[i])])
- for i in range(0, len(self.offsetList)):
- bs.seek(self.offsetList[i][1], NOESEEK_ABS)
- chunkType = bs.readUInt()
- if chunkType in flObjectLoaderDict:
- flObjectLoaderDict[chunkType](self, bs, i)
- else:
- #print("NO :", chunkType)
- self.loadTXT(bs, self.offsetList[i])
-
- def loadAM2(self, bs, fname):
- am2Header = bs.read(">" + "i2H5i")
- bs.seek(am2Header[7] - 32, NOESEEK_REL)
- boneParenting = []
- for i in range(0, am2Header[1]):
- null, id = bs.read(">" + 2 * "B")
- bs.seek(0x16, NOESEEK_REL)
- boneParenting.append(bs.read(">" + 2 * "h"))
- bs.seek(4, NOESEEK_REL)
- BonePos = NoeVec3.fromBytes(bs.readBytes(12), NOE_BIGENDIAN)
- boneMtx = NoeQuat([0.0, 0.0, 0.0, 1.0]).toMat43()
- boneMtx[3] = BonePos
- bs.seek(0x24, NOESEEK_REL)
- newBone = NoeBone(id, (self.offsetList[fname][0] + "_bone_" + str(id)), boneMtx, None, -1)
- self.boneList.append(newBone)
- for i in range(0, am2Header[1]):
- p = self.boneList[i]
- cidx = boneParenting[i][0]
- while cidx != -1:
- b = self.boneList[cidx]
- b.parentIndex = p.index
- cidx = boneParenting[cidx][1]
- self.boneList = rapi.multiplyBones(self.boneList)
-
- def loadCMD(self, bs, fname):
- cmdHeader = bs.read(">" + "i2H5i")
- meshInfo = []
- for i in range(0, cmdHeader[1]):
- bs.seek(0x7C, NOESEEK_REL)
- meshInfo.append(bs.read(">" + "7i"))
- bs.seek(0x18, NOESEEK_REL)
- self.loadMaterial(bs, cmdHeader, meshInfo, fname)
- self.loadBonePallet(bs, cmdHeader, meshInfo, fname)
- self.loadMesh(bs, cmdHeader, meshInfo, fname)
-
- def loadBonePallet(self, bs, cmdHeader, meshInfo, fname):
- for i in range(0, cmdHeader[1]):
- #print(meshInfo[i])
- bs.seek(self.offsetList[fname][1] + meshInfo[i][6], NOESEEK_ABS)
- #print(bs.tell())
- pallet = []
- for a in range(0, 0x100):
- bid = bs.readUByte()
- if bid != 255:
- pallet.append(bid)
- self.boneMap.append(pallet)
-
- def loadMesh(self, bs, cmdHeader, meshInfo, fname):
- for i in range(0, cmdHeader[1]):
- bs.seek(self.offsetList[fname][1] + meshInfo[i][3], NOESEEK_ABS)
- faceBuff = bs.readBytes(4 * meshInfo[i][1])
- bs.seek(self.offsetList[fname][1] + meshInfo[i][4], NOESEEK_ABS)
- vertBuff = bs.readBytes(0x40 * meshInfo[i][2])
- if meshInfo[i][0] == 0:
- pass
- else:
- rapi.rpgSetBoneMap(self.boneMap[i])
- rapi.rpgSetMaterial(self.matList[i].name)
- rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 0x40, 0)
- rapi.rpgBindNormalBufferOfs(vertBuff, noesis.RPGEODATA_HALFFLOAT, 0x40, 12)
- #rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, 0x40, 24, 4)
- rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_HALFFLOAT, 0x40, 32)
- rapi.rpgBindUV2BufferOfs(vertBuff, noesis.RPGEODATA_HALFFLOAT, 0x40, 36)
- rapi.rpgBindBoneWeightBufferOfs(vertBuff, noesis.RPGEODATA_HALFFLOAT, 0x40, 48, 4)
- rapi.rpgBindBoneIndexBufferOfs(vertBuff, noesis.RPGEODATA_HALFFLOAT, 0x40, 56, 4)
- rapi.rpgCommitTriangles(faceBuff, noesis.RPGEODATA_INT, meshInfo[i][1], noesis.RPGEO_TRIANGLE_STRIP, 1)
- def loadMaterial(self, bs, cmdHeader, meshInfo, fname):
- texNames = []
- bs.seek(self.offsetList[fname][1] + cmdHeader[5], NOESEEK_ABS)
- for i in range(0, cmdHeader[2]):
- texNames.append(bs.readBytes(0x20).decode("ASCII").rstrip("\0"))
- for i in range(0, cmdHeader[1]):
- bs.seek(self.offsetList[fname][1] + meshInfo[i][5], NOESEEK_ABS)
- matInfo = bs.read(">" + 3 * "h")
- bs.seek(0x1E, NOESEEK_REL)
- matInfo2 = bs.read(">" + 6 * "b")
- bs.seek(6, NOESEEK_REL)
- material = NoeMaterial("material_" + str(fname) + "_" + str(i), "")
- if matInfo2[1] != -1:
- material.setTexture(texNames[matInfo2[1] - 1])
- if matInfo2[2] != -1:
- material.setBumpTexture(texNames[matInfo2[2] - 1])
- material.setFlags(0, 1)
- self.matList.append(material)
-
- def loadTXT(self, bs, fname):
- pass
-
- def loadDDS(self, bs, fname):
- ddsHeader = bs.read(">" + "4i")
- bs.seek(0x40, NOESEEK_REL)
- type = bs.readUInt()
- bs.seek(0x28, NOESEEK_REL)
- texData = bs.readBytes(self.offsetList[fname][2] - 0x80)
- texFmt = noesis.NOESISTEX_DXT1
- if type == 0x31545844:
- texFmt = noesis.NOESISTEX_DXT1
- elif type == 0x33545844:
- texFmt = noesis.NOESISTEX_DXT3
- elif type == 0x35545844:
- texFmt = noesis.NOESISTEX_DXT5
- self.texList.append(NoeTexture(self.offsetList[fname][0], ddsHeader[3], ddsHeader[2], texData, texFmt))
-
- flObjectLoaderDict = {
- 0x414D3200 : folkloreFile.loadAM2,
- 0x434D4400 : folkloreFile.loadCMD,
- 0x20534444 : folkloreFile.loadDDS,
- }
-
- def flLoadModel(data, mdlList):
- ctx = rapi.rpgCreateContext()
- bi5 = folkloreFile(NoeBitStream(data, NOE_BIGENDIAN))
- bi5.loadAll(bi5.bs)
- rapi.rpgSmoothNormals()
- try:
- mdl = rapi.rpgConstructModel()
- except:
- mdl = NoeModel()
- mdl.setModelMaterials(NoeModelMaterials(bi5.texList, bi5.matList))
- mdlList.append(mdl); mdl.setBones(bi5.boneList)
- return 1