'''rapi model template''' from inc_noesis import * import noesis import rapi def registerNoesisTypes(): '''Register the plugin. Just change the Game name and extension.''' handle = noesis.register("Twelve Sky 2 - Motion model", ".mobject") noesis.setHandlerTypeCheck(handle, noepyCheckType) noesis.setHandlerLoadModel(handle, noepyLoadModel) return 1 def noepyCheckType(data): '''Verify that the format is supported by this plugin. Default yes''' return 1 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 Mesh(object): def __init__(self): self.numVerts = 0 self.vertBuff = bytes() self.idxBuff = bytes() self.numIdx = 0 class ModelParser(object): def __init__(self, data): self.inFile = NoeBitStream(data) self.animList = [] self.texList = [] self.matList = [] self.boneList = [] def parse_vertices(self, numVerts): return self.inFile.readBytes(numVerts * 32) def parse_animations(self, numAnims): self.inFile.readBytes(64 * numAnims) def parse_bones(self, numBones): self.inFile.readBytes(32 * numBones) def parse_faces(self, numIdx): return self.inFile.readBytes(numIdx * 2) def parse_file(self): mesh = Mesh() type, unk = self.inFile.read('2L') print("type %d" %type) if type == 0: self.inFile.read('9f') self.inFile.readBytes(76) numBones, mesh.numVerts, numUnk = self.inFile.read('3L') mesh.numIdx = self.inFile.readUInt() * 3 self.inFile.read('40B') mesh.vertBuff = self.parse_vertices(mesh.numVerts) self.parse_bones(numBones) mesh.idxBuff = self.parse_faces(mesh.numIdx) else: print("mobject") self.inFile.read('9f') self.inFile.read('76B') numAnims, mesh.numVerts, numUnk = self.inFile.read('3L') mesh.numIdx = self.inFile.readUInt() * 3 #self.parse_animations(numAnims) mesh.vertBuff = self.parse_vertices(mesh.numVerts) return mesh class SanaeParser(object): def __init__(self, data): '''Initialize some data''' self.inFile = NoeBitStream(data) self.meshList = [] self.animList = [] self.texList = [] self.matList = [] self.boneList = [] def build_mesh(self): for i in range(len(self.meshList)): mesh = self.meshList[i] print(mesh.numIdx, len(mesh.idxBuff)) rapi.rpgBindPositionBufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 32, 0) rapi.rpgBindNormalBufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 32, 12) rapi.rpgBindUV1BufferOfs(mesh.vertBuff, noesis.RPGEODATA_FLOAT, 32, 24) meshName = "Mesh%d" %i rapi.rpgSetName(meshName) mat = self.matList[i] rapi.rpgSetMaterial(mat.name) rapi.rpgCommitTriangles(mesh.idxBuff, noesis.RPGEODATA_USHORT, mesh.numIdx, noesis.RPGEO_TRIANGLE, 1) def decompData(self, size, compSize): compData = self.inFile.readBytes(compSize) return rapi.decompInflate(compData, size) def parse_model(self, data): parser = ModelParser(data) mesh = parser.parse_file() self.meshList.append(mesh) def parse_texture(self, data): matNum = len(self.matList) mat = NoeMaterial("material%d" %matNum, "") texture = rapi.loadTexByHandler(data, ".dds") if texture: texture.name = "texture%d" %(len(self.texList)) self.texList.append(texture) mat.setTexture(texture.name) self.matList.append(mat) def parse_file(self): '''Main parser method''' numFiles = self.inFile.readUInt() for i in range(numFiles): unk, size, compSize = self.inFile.read('3L') data = self.decompData(size, compSize) self.parse_model(data) unk = self.inFile.readUInt() if unk > 0: size, compSize = self.inFile.read('2L') data = self.decompData(size, compSize) self.parse_texture(data) self.inFile.read('2L') self.build_mesh()