'''Noesis import plugin. Written by Tsukihime''' from inc_noesis import * import noesis import rapi import os def registerNoesisTypes(): '''Register the plugin. Just change the Game name and extension.''' handle = noesis.register("Yi Jian Xiang", ".fak") noesis.setHandlerTypeCheck(handle, noepyCheckType) noesis.setHandlerLoadModel(handle, noepyLoadModel) return 1 def noepyCheckType(data): '''Verify that the format is supported by this plugin. Default yes''' if len(data) < 4: return 0 try: bs = NoeBitStream(data) if noeStrFromBytes(bs.readBytes(4)) != "AKK": return 0 return 1 except: return 0 def noepyLoadModel(data, mdlList): '''Build the model, set materials, bones, and animations. You do not need all of them as long as they are empty lists (they are by default)''' ctx = rapi.rpgCreateContext() parser = SanaeParser(data) parser.parse_file() #build meshes for pose in parser.vertGroups.keys(): print(pose, len(parser.vertGroups[pose])) vertBuffs = parser.vertGroups["walk"] for i in range(len(vertBuffs)): idxBuff, numIdx, matNum = parser.idxBuffs[i%len(parser.idxBuffs)] vertBuff = vertBuffs[i] rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 32, 0) rapi.rpgBindNormalBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 32, 12) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 32, 24) matName = parser.matList[matNum].name rapi.rpgSetMaterial(matName) rapi.rpgSetOption(noesis.RPGOPT_TRIWINDBACKWARD, 1) rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_USHORT, numIdx, noesis.RPGEO_TRIANGLE, 1) mdl = rapi.rpgConstructModel() mdl.setModelMaterials(NoeModelMaterials(parser.texList, parser.matList)) mdl.setBones(parser.boneList) mdl.setAnims(parser.animList) mdlList.append(mdl) return 1 class SanaeParser(object): def __init__(self, data): '''Initialize some data. Refer to Sanae.py to see what is already initialized''' self.inFile = NoeBitStream(data) self.idxBuffs = [] self.animList = [] self.texList = [] self.matList = [] self.boneList = [] self.vertGroups = {} def read_name(self, n=4): return noeStrFromBytes(self.inFile.readBytes(n)) def parse_faces(self, numIdx): return self.inFile.readBytes(numIdx*2) def parse_vertices(self, numVerts): return self.inFile.readBytes(32*numVerts) def parse_unk(self, count): self.inFile.readBytes(count*36) def parse_materials(self, numMat): for i in range(numMat): matNum = self.inFile.readUInt() self.inFile.read('16f') self.inFile.readFloat() self.inFile.read('3b') texPath = self.read_name(1057) texName = os.path.basename(texPath) matName = "material[%d]" %matNum material = NoeMaterial(matName, texName) self.matList.append(material) def parse_file(self): idstring = self.inFile.read('4s') null, numVerts, numFaceGroups, faceOfs, numMat, matOfs, numVertGroups, \ vertOfs = self.inFile.read('8L') self.inFile.read('6f') self.inFile.seek(256, 1) for i in range(numFaceGroups): unk, matNum, unk, numVerts = self.inFile.read('4H') self.inFile.read('6f') numIdx = self.inFile.readUInt() * 3 idxBuff = self.parse_faces(numIdx) self.inFile.seek(20, 1) self.idxBuffs.append([idxBuff, numIdx, matNum]) for i in range(numVertGroups): meshName = self.read_name() self.inFile.readFloat() numVerts = self.inFile.readUInt() vertBuff = self.parse_vertices(numVerts) count = self.inFile.readUInt() self.parse_unk(count) if not meshName in self.vertGroups: self.vertGroups[meshName] = [] self.vertGroups[meshName].append(vertBuff) self.parse_materials(numMat)