Advertisement
Guest User

JX3

a guest
Oct 16th, 2019
575
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.38 KB | None | 0 0
  1. from inc_noesis import *
  2. import noesis
  3. import rapi
  4. import os
  5.  
  6. def registerNoesisTypes():
  7.     '''Register the plugin. Just change the Game name and extension.'''
  8.    
  9.     handle = noesis.register("xin", ".ksw")
  10.     noesis.setHandlerTypeCheck(handle, noepyCheckType)
  11.     noesis.setHandlerLoadModel(handle, noepyLoadModel)
  12.     return 1
  13.  
  14. def noepyCheckType(data):
  15.     '''Verify that the format is supported by this plugin. Default yes'''
  16.    
  17.     if len(data) < 6:
  18.         return 0
  19.    
  20.     return 1
  21.  
  22. def noepyLoadModel(data, mdlList):
  23.     '''Build the model, set materials, bones, and animations. You do not
  24.    need all of them as long as they are empty lists (they are by default)'''
  25.    
  26.     ctx = rapi.rpgCreateContext()
  27.     parser = SanaeParser(data)
  28.     parser.parse_file()
  29.     mdl = rapi.rpgConstructModel()
  30.     mdl.setModelMaterials(NoeModelMaterials(parser.texList, parser.matList))
  31.     mdl.setBones(parser.boneList)
  32.     mdl.setAnims(parser.animList)
  33.     mdlList.append(mdl)
  34.     #rapi.setPreviewOption("setAngOfs", "90 0 0")
  35.     return 1
  36.  
  37. class SanaeParser(object):
  38.    
  39.     def __init__(self, data):    
  40.        
  41.         self.inFile = NoeBitStream(data)
  42.         self.texList = []
  43.         self.matList = []    
  44.         self.boneList = []
  45.         self.animList = []
  46.        
  47.     def read_ustring(self, n):
  48.            
  49.         s = bytes()
  50.         for i in range(n):
  51.             s += self.inFile.readBytes(1)
  52.             self.inFile.readBytes(1)
  53.         return noeStrFromBytes(s)        
  54.    
  55.     def invert_faces(self):
  56.         '''Negates the x-coord of all vertices in the mesh'''
  57.        
  58.         trans = NoeMat43((NoeVec3((-1, 0, 0)),
  59.                          NoeVec3((0, 1, 0)),
  60.                          NoeVec3((0, 0, 1)),
  61.                          NoeVec3((0, 0, 0))))
  62.         rapi.rpgSetTransform(trans)    
  63.    
  64.     def parse_material(self, matName):
  65.        
  66.         self.inFile.read('16f')
  67.         self.inFile.readFloat()
  68.         self.inFile.readUShort()
  69.         self.inFile.readShort()
  70.         diffTex = self.read_ustring(768)
  71.         normTex = self.read_ustring(256)
  72.         normTex2 = self.read_ustring(256)
  73.        
  74.         texName = os.path.basename(diffTex)
  75.         material = NoeMaterial(matName, texName)
  76.         self.matList.append(material)
  77.        
  78.     def parse_faces(self, numIdx):
  79.        
  80.         return self.inFile.readBytes(4*numIdx)
  81.    
  82.     def parse_vertices(self, numVerts):
  83.        
  84.             vertBuff = self.inFile.readBytes(numVerts*12)
  85.             rapi.rpgBindPositionBuffer(vertBuff, noesis.RPGEODATA_FLOAT, 12)
  86.             self.invert_faces()
  87.  
  88.     def parse_normals(self, numVerts):
  89.        
  90.             normBuff = self.inFile.readBytes(numVerts*12)
  91.             rapi.rpgBindNormalBuffer(normBuff, noesis.RPGEODATA_FLOAT, 12)
  92.  
  93.     def parse_uvs(self, numVerts):
  94.        
  95.             uvBuff = self.inFile.readBytes(numVerts*12)
  96.             rapi.rpgBindUV1Buffer(uvBuff, noesis.RPGEODATA_FLOAT, 12)          
  97.  
  98.            
  99.     def parse_tri(self, triStripLen):
  100.        
  101.             idxBuff = self.inFile.readBytes(triStripLen*4)
  102.             rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_INT, triStripLen, noesis.RPGEO_TRIANGLE_STRIP, 1)
  103.  
  104.     def parse_bone(self, boneOff):
  105.         # seek to bone offset with absolute address
  106.         self.inFile.seek(boneOff, NOESEEK_ABS)
  107.         # read the number of bones
  108.         boneCount = self.inFile.readUInt()
  109.         # read bones loop
  110.         for i in range(0, boneCount):
  111.             # read bone name
  112.             boneName = self.inFile.readBytes(30).decode('utf-8', 'ignore').replace('\x00','').replace('\xCD','')
  113.             # read parent name of the current bone
  114.             parentBoneName = self.inFile.readBytes(30).decode('utf-8', 'ignore').replace('\x00','').replace('\xCD','')
  115.             # read the number of child bone
  116.             numChildren = self.inFile.readUInt()
  117.             # read child bone name
  118.             for j in range(0, numChildren):
  119.                 childBoneName = self.inFile.readBytes(30).decode('utf-8', 'ignore').replace('\x00','').replace('\xCD','')
  120.             # read 4x4 bone matrix
  121.             boneMat = NoeMat44.fromBytes( self.inFile.readBytes(0x40), NOE_LITTLEENDIAN )
  122.             # convert and inverse to 4x3 matrix
  123.             boneMat43 = boneMat.toMat43().inverse()
  124.             # read 4x4 parent bone matrix
  125.             parentMat = NoeMat44.fromBytes( self.inFile.readBytes(0x40), NOE_LITTLEENDIAN )
  126.             # convert and inverse to 4x3 matrix
  127.             parentMat43 = parentMat.toMat43().inverse()
  128.             # read the number of vertices deformed by this bone
  129.             numVertices = self.inFile.readUInt()
  130.             if numVertices > 0:
  131.                 vwList = []
  132.                 bidx = []
  133.                 bwgt = []
  134.                 # read vertex IDs
  135.                 for j in range(0, numVertices):
  136.                     vertexID = self.inFile.readUInt()
  137.                     bidx.append(vertexID)
  138.                 # read weights correspondent to vertex IDs
  139.                 for j in range(0, numVertices):
  140.                     weight = self.inFile.readFloat()
  141.                     bwgt.append(weight)
  142.                 vwList.append(NoeVertWeight(bidx, bwgt))
  143.    
  144.                 fw = NoeFlatWeights(vwList)
  145.                 rapi.rpgBindBoneIndexBuffer(fw.flatW[:fw.weightValOfs], noesis.RPGEODATA_UINT, 4*fw.weightsPerVert, fw.weightsPerVert)
  146.                 rapi.rpgBindBoneWeightBuffer(fw.flatW[fw.weightValOfs:], noesis.RPGEODATA_FLOAT, 4*fw.weightsPerVert, fw.weightsPerVert)  
  147.                
  148.             # set bones for Noesis to display      
  149.             self.boneList.append(NoeBone(i, boneName, boneMat43, parentBoneName, parentIndex = -1))        
  150.  
  151.  
  152.     def parse_file(self):
  153.         '''Main parser method'''
  154.         self.inFile.seek(140)
  155.         numMesh, numVerts, triStripLen, unk1, vertOff, normOff, \
  156.             unk2, UVOff, unk3, unk4, triSTripOff, unk5, boneOff = self.inFile.read('13L')
  157.         self.inFile.seek(vertOff)
  158.         self.parse_vertices(numVerts)
  159.         self.inFile.read('1L')
  160.         self.parse_normals(numVerts)
  161.         self.inFile.read('1L')
  162.         self.parse_uvs(numVerts)
  163.         self.inFile.seek(triSTripOff)
  164.         numIdx = triStripLen *3
  165.         idxBuff = self.parse_faces(numIdx)
  166.         rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_INT, numIdx, noesis.RPGEO_TRIANGLE, 1)
  167.         self.parse_bone(boneOff)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement