from inc_noesis import * import noesis import rapi import os def registerNoesisTypes(): '''Register the plugin''' handle = noesis.register("League of Legends", ".skn;.skl") noesis.setHandlerTypeCheck(handle, noepyCheckType) noesis.setHandlerLoadModel(handle, noepyLoadModel) return 1 def noepyCheckType(data): '''Verify that the format is supported by this plugin.''' return 1 def noepyLoadModel(data, mdlList): '''Load the model''' 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 SklParser(object): def __init__(self, data): self.inFile = NoeBitStream(data) self.animList = [] self.texList = [] self.matList = [] self.boneList = [] def read_name(self, n): return noeStrFromBytes(self.inFile.readBytes(n)) def make_bone(self): pass def make_bone_parent(self): pass def make_bone_position(self): pass def parse_bones(self, numBones): for i in range(numBones): boneName = self.read_name(32) self.inFile.readUInt() self.inFile.readFloat() self.inFile.read('12f') def parse_file(self): idstring = self.read_name(8) self.inFile.readUInt() self.inFile.readUInt() numBones = self.inFile.readUInt() self.parse_bones(numBones) print(self.inFile.tell()) class SanaeParser(object): def __init__(self, data): self.inFile = NoeBitStream(data) self.animList = [] self.texList = [] self.matList = [] self.boneList = [] self.dirpath = rapi.getDirForFilePath(rapi.getInputName()) self.basename = rapi.getExtensionlessName(rapi.getInputName()) def read_name(self, n): return noeStrFromBytes(self.inFile.readBytes(n)) def parse_skeleton(self): sklFile = self.dirpath + self.basename + ".skl" f = open(sklFile, 'rb') skl = SklParser(f.read()) f.close() skl.parse_file() def parse_vertices(self, numVerts): vertBuff = self.inFile.readBytes(52*numVerts) rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 52, 0) rapi.rpgBindNormalBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 52, 32) rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 52, 44) def parse_faces(self, numIdx, matName): return self.inFile.readBytes(numIdx*2) def get_texture_name(self): '''Search current directory for any texture that contains the basename of this file''' filename = os.path.basename(self.basename).lower() base_model = False if filename.find("_") == -1: filename_base = filename + "_base" base_model = True dirList = [file for file in os.listdir(self.dirpath) if file.lower().endswith(".dds")] for name in dirList: if base_model: if filename_base in name.lower(): return name if filename in name.lower(): return name return "" def parse_texture(self): texName = self.get_texture_name() if texName: f = open(self.dirpath + texName, 'rb') tex = rapi.loadTexByHandler(f.read(), ".dds") f.close() if tex is not None: tex.name = texName self.texList.append(tex) return texName else: return "" def parse_material(self): matName = "material" texName = self.parse_texture() material = NoeMaterial(matName, texName) self.matList.append(material) return matName def parse_file(self): idstring = self.inFile.readUInt() hasMat, numMesh = self.inFile.read('2H') if hasMat: numMat = self.inFile.readUInt() for i in range(numMat): name = self.read_name(64) self.inFile.read('4L') #just hardcode matName for now matName = self.parse_material() numIdx = self.inFile.readUInt() numVerts = self.inFile.readUInt() else: matName = self.parse_material() numIdx, numVerts = self.inFile.read('2L') idxBuff = self.parse_faces(numIdx, matName) self.parse_vertices(numVerts) rapi.rpgSetMaterial(matName) rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_USHORT, numIdx, noesis.RPGEO_TRIANGLE, 1) #load skeleton #self.parse_skeleton()