from inc_noesis import * import noesis import rapi def registerNoesisTypes(): '''Register the plugin. Just change the Game name and extension.''' handle = noesis.register("Loong", ".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) idstring = noeStrFromBytes(bs.readBytes(8), 'utf-16') if idstring == "AKK": return 1 return 0 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() 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.vertBuffs = [] self.idxBuffs = [] self.animList = [] self.texList = [] self.matList = [] self.boneList = [] def invert_faces(self): '''Negates the x-coord of all vertices in the mesh''' trans = NoeMat43((NoeVec3((-1, 0, 0)), NoeVec3((0, 1, 0)), NoeVec3((0, 0, 1)), NoeVec3((0, 0, 0)))) rapi.rpgSetTransform(trans) def read_ustring(self, n): s = bytes() for i in range(n): s += self.inFile.readBytes(1) self.inFile.readBytes(1) return noeStrFromBytes(s) def build_meshes(self): for i in range(len(self.idxBuffs)): idxBuff, numIdx, matNum = self.idxBuffs[i] vertBuff, vertType = self.vertBuffs[i] if matNum != -1: matName = self.matList[matNum].name rapi.rpgSetMaterial(matName) if vertType == 0.125: rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_HALFFLOAT, 16, 0) rapi.rpgBindNormalBufferOfs(vertBuff, noesis.RPGEODATA_HALFFLOAT, 16, 6) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_HALFFLOAT, 16, 12) elif vertType in [0.0333, 0.0335]: rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_HALFFLOAT, 22, 0) rapi.rpgBindNormalBufferOfs(vertBuff, noesis.RPGEODATA_HALFFLOAT, 22, 6) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_HALFFLOAT, 22, 18) rapi.rpgSetOption(noesis.RPGOPT_TRIWINDBACKWARD, 1) rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_USHORT, numIdx, noesis.RPGEO_TRIANGLE, 1) def parse_materials(self, numMat): for i in range(numMat): matId = self.inFile.readUInt() self.inFile.read('17f') self.inFile.read('4b') texName = self.read_ustring(768) normName = self.read_ustring(528) matName = "material[%d]" %matId material = NoeMaterial(matName, texName) self.matList.append(material) def parse_faces(self, numIdx, matNum): idxBuff = self.inFile.readBytes(numIdx * 2) self.idxBuffs.append([idxBuff, numIdx, matNum]) def parse_vertices(self, numVerts, vertType, vertGroups): print(vertType) for vertCount in vertGroups: if vertType == 0.125: vertBuff = self.inFile.readBytes(vertCount*16) elif vertType in [0.0333, 0.0335]: vertBuff = self.inFile.readBytes(vertCount*22) self.vertBuffs.append([vertBuff, vertType]) def parse_file(self): '''Main parser method''' idstring = self.read_ustring(4) self.inFile.readUInt() vertType, numVerts, numFaceGroups, faceOfs, numMat, matOfs, numVertGroups, vertOfs = \ self.inFile.read('8L') self.inFile.read('6f') self.inFile.seek(256, 1) #face section start vertGroups = [] for i in range(numFaceGroups): vertStart = self.inFile.readUInt() matNum = self.inFile.readShort() vertCount = self.inFile.readUShort() self.inFile.read('6f') numIdx = self.inFile.readUInt() * 3 self.parse_faces(numIdx, matNum) self.inFile.read('5L') vertGroups.append(vertCount) #vert section start idstring = self.inFile.readBytes(4) vertType = round(self.inFile.readFloat(), 4) count = self.inFile.readUInt() self.inFile.seek(count, 1) size = self.inFile.readUInt() self.parse_vertices(numVerts, vertType, vertGroups) #skip rest of data, go straight to materials self.inFile.seek(matOfs) self.parse_materials(numMat) self.build_meshes()