home *** CD-ROM | disk | FTP | other *** search
/ Xentax forum attachments archive / xentax.7z / 12191 / fmt_KnightsConract_hxt_bone_test.7z / fmt_KnightsConract_hxt.py
Encoding:
Python Source  |  2017-01-09  |  11.6 KB  |  312 lines

  1. #Script by chrrox
  2.  
  3. from inc_noesis import *
  4.  
  5. def registerNoesisTypes():
  6.     handle = noesis.register("Knights Contract", ".hxt")
  7.     noesis.setHandlerTypeCheck(handle, kcCheckType)
  8.     noesis.setHandlerLoadModel(handle, kcLoadModel)
  9.     #noesis.logPopup()
  10.     return 1
  11.  
  12. def kcCheckType(data):
  13.     td = NoeBitStream(data)
  14.     return 1
  15.  
  16.  
  17. def dataAlign(pos,pad):
  18.     if (pos % pad) > 0:
  19.         return((pad - (pos) % pad))
  20.     else:
  21.         return(0)
  22.  
  23. class hxtFile: 
  24.          
  25.     def __init__(self, bs):
  26.         self.bs = bs
  27.         self.texList   = []
  28.         self.vtxList   = []
  29.         self.matList   = []
  30.         self.boneList  = []
  31.  
  32.     def loadAll(self, bs):
  33.         bs.seek(0x80, NOESEEK_ABS)
  34.         #Texture
  35.         unk00,unk01,unk02,texCount,unk03 = bs.read(">5i")
  36.         #print(unk00,unk01,unk02,texCount,unk03)
  37.         bs.seek(0xA4, NOESEEK_ABS)
  38.         folderBaseNameSize =  bs.read(">i")[0]
  39.         folderBaseName = bs.readBytes(folderBaseNameSize).decode("ASCII").rstrip("\0")
  40.         #print(folderBaseName)
  41.         bs.seek(0x6C, NOESEEK_REL)
  42.         baseName = rapi.getExtensionlessName(rapi.getLocalFileName(rapi.getLastCheckedName()))
  43.         txbFile = None
  44.         if( rapi.checkFileExists( rapi.getDirForFilePath( rapi.getLastCheckedName() ) + baseName + ".txb" ) ):
  45.             txbFile = rapi.loadIntoByteArray( rapi.getDirForFilePath( rapi.getLastCheckedName() ) + baseName + ".txb" )
  46.         for a in range(0,texCount):
  47.             texNameSize =  bs.read(">i")[0]
  48.             texName = bs.readBytes(texNameSize).decode("ASCII").rstrip("\0")
  49.             #print(texName)
  50.             bs.seek(0x2A, NOESEEK_REL)
  51.             texType, texUnk = bs.read(">2b")
  52.             texPreLoadSize =  bs.read(">i")[0]
  53.             texPreLoadData = bs.readBytes(texPreLoadSize)
  54.             tunk00,tunk01,tunk02 = bs.read(">3i")
  55.             width,height,one,mips,tunk06,picsize = bs.read(">6i")
  56.             texLod01 = bs.read(">6i")
  57.             texLod02 = bs.read(">6i")
  58.             texLod03 = bs.read(">6i")
  59.             offset,totalsize,size,zsize = bs.read(">4i")
  60.             texLodInfo01 = bs.read(">4i")
  61.             texLodInfo02 = bs.read(">4i")
  62.             tunk03,tunk04,tunk05 = bs.read(">3i")
  63.             #bs.seek(0xA8, NOESEEK_REL)
  64.             if txbFile:
  65.                 texData = b''
  66.                 #print("YES")
  67.                 #print(width,height,one,mips,tunk06,picsize)
  68.                 #print(offset,totalsize,size,zsize)
  69.                 #print(texType)
  70.                 cmpData = txbFile[offset:offset + zsize]
  71.                 if size == 0:
  72.                     size = totalsize
  73.                     texData += rapi.decompInflate(cmpData, size, -15)
  74.                 else:
  75.                     texData += rapi.decompInflate(cmpData, size, -15)
  76.                     while totalsize != 0:
  77.                         #print(offset,zsize,totalsize)
  78.                         totalsize -= size
  79.                         if totalsize > 0:
  80.                             offset += zsize
  81.                             size,zsize = noeUnpack(">ii", txbFile[offset:offset + 8])
  82.                             offset += 8
  83.                             cmpData = txbFile[offset:offset + zsize]
  84.                             texData += rapi.decompInflate(cmpData, size, -15)
  85.                 
  86.                 #print(len(texData))
  87.                 texFmt = 0
  88.                 if texType == 71:
  89.                     texFmt = noesis.NOESISTEX_DXT1
  90.                 #DXT5
  91.                 elif texType == 78:
  92.                     texFmt = noesis.NOESISTEX_DXT5
  93.  
  94.                 tex1 = NoeTexture(rapi.getLocalFileName(texName), width, height, texData, texFmt)
  95.                 self.texList.append(tex1)
  96.         #print(bs.tell())
  97.         #ddm
  98.         ddmBase = (bs.tell() + 4)
  99.         bs.seek(0xAC, NOESEEK_REL)
  100.         bonetype ,boneCount = bs.read(">ii")
  101.         #print(hex(bonetype) ,hex(boneCount))
  102.         boneMap = {}
  103.         for a in range(0,boneCount):
  104.             bid = bs.read("B")[0]
  105.             boneMap[bid] = a
  106.         boneParrent = bs.readBytes(boneCount * 1)
  107.         #print(bs.tell())
  108.         bs.seek(dataAlign((bs.tell() - ddmBase) , 8), NOESEEK_REL)
  109.         if bonetype == 0x13:
  110.             #boneData2 = bs.readBytes(16 * boneCount)
  111.             for a in range(0,boneCount):
  112.                 px,py,pz,pw = bs.read(">4f")
  113.                 boneMtx = NoeQuat([0,0,0,1]).toMat43()
  114.                 boneMtx[3] = [px,py,pz]
  115.                 newBone = NoeBone(a, str(a), boneMtx, None, -1)
  116.                 self.boneList.append(newBone)
  117.             #print(bs.tell())
  118.             boneData4 = bs.readBytes(4 * boneCount)
  119.             #print(bs.tell())
  120.             boneCount2 = bs.read(">i")[0]
  121.             boneData5 = bs.readBytes(48 * boneCount2)
  122.             #print(bs.tell())
  123.         elif bonetype == 0x17:
  124.             #boneData2 = bs.readBytes(16 * boneCount)
  125.             for a in range(0,boneCount):
  126.                 px,py,pz,pw = bs.read(">4f")
  127.                 boneMtx = NoeQuat([0,0,0,1]).toMat43()
  128.                 boneMtx[3] = [px,py,pz]
  129.                 newBone = NoeBone(a, str(a), boneMtx, None, -1)
  130.                 self.boneList.append(newBone)
  131.             #print(bs.tell())
  132.             boneData3 = bs.readBytes(16 * boneCount)
  133.             #print(bs.tell())
  134.             boneData4 = bs.readBytes(4 * boneCount)
  135.             #print(bs.tell())
  136.             boneCount2 = bs.read(">i")[0]
  137.             boneData5 = bs.readBytes(48 * boneCount2)
  138.             #print(bs.tell())
  139.         elif bonetype == 0x1B:
  140.             #boneData2 = bs.readBytes(16 * boneCount)
  141.             for a in range(0,boneCount):
  142.                 px,py,pz,pw = bs.read(">4f")
  143.                 boneMtx = NoeQuat([0,0,0,1]).toMat43()
  144.                 boneMtx[3] = [px,py,pz]
  145.                 newBone = NoeBone(a, str(a), boneMtx, None, -1)
  146.                 self.boneList.append(newBone)
  147.             #print(bs.tell())
  148.             boneData3 = bs.readBytes(16 * boneCount)
  149.             #print(bs.tell())
  150.             boneData4 = bs.readBytes(4 * boneCount)
  151.             #print(bs.tell())
  152.             boneCount2 = bs.read(">i")[0]
  153.             boneData5 = bs.readBytes(48 * boneCount2)
  154.             #print(bs.tell())
  155.         elif bonetype == 0x1F:
  156.             #boneData2 = bs.readBytes(16 * boneCount)
  157.             for a in range(0,boneCount):
  158.                 px,py,pz,pw = bs.read(">4f")
  159.                 boneMtx = NoeQuat([0,0,0,1]).toMat43()
  160.                 boneMtx[3] = [px,py,pz]
  161.                 newBone = NoeBone(a, str(a), boneMtx, None, -1)
  162.                 self.boneList.append(newBone)
  163.             #print(bs.tell())
  164.             boneData3 = bs.readBytes(16 * boneCount)
  165.             #print(bs.tell())
  166.             boneData4 = bs.readBytes(16 * boneCount)
  167.             #print(bs.tell())
  168.             boneData4 = bs.readBytes(4 * boneCount)
  169.             #print(bs.tell())
  170.             boneCount2 = bs.read(">i")[0]
  171.             boneData5 = bs.readBytes(48 * boneCount2)
  172.             #print(bs.tell())
  173.         else:
  174.             return 0
  175.         unk10,unkCount,unk12 = bs.read(">3i")
  176.         for a in range(0,unkCount):
  177.             unkDataSize =  bs.read(">i")[0]
  178.             unkData = bs.readBytes(unkDataSize)
  179.         #print(bs.tell())
  180.         #materials
  181.         matCount = bs.read(">i")[0]
  182.         for a in range(0,matCount):
  183.             matNameSize =  bs.read(">i")[0]
  184.             matName = bs.readBytes(matNameSize).decode("ASCII").rstrip("\0")
  185.             material = NoeMaterial(matName, "")
  186.             emissiveMaterial = NoeMaterial(matName + "_emissive", "")
  187.             emissiveMaterial.setBlendMode("GL_SRC_ALPHA","GL_ONE")
  188.             #material.setFlags(noesis.NMATFLAG_TWOSIDED, 1)
  189.             #material.setDefaultBlend(0)
  190.             #print(matName)
  191.             for b in range(0,4):
  192.                 matTexNameSize =  bs.read(">i")[0]
  193.                 matTexName = bs.readBytes(matTexNameSize).decode("ASCII").rstrip("\0")
  194.                 bs.seek(0x20, NOESEEK_REL)
  195.                 #print(matTexName)
  196.                 if b == 0:
  197.                     material.setTexture(matTexName)
  198.                 elif b == 1:
  199.                     time = 1.0
  200.                     pulseRate = 0.005
  201.                     emissiveMaterial.setTexture(matTexName)
  202.                     emissiveMaterial.setDiffuseColor([1, 1, 1, 1])
  203.                     emissiveMaterial.setExpr_diffuse_r("0.75 + sin(time * %f) * 0.25"%pulseRate)
  204.                     emissiveMaterial.setExpr_diffuse_g("0.75 + sin(time * %f) * 0.25"%pulseRate)
  205.                     emissiveMaterial.setExpr_diffuse_b("0.75 + sin(time * %f) * 0.25"%pulseRate)
  206.                     if matTexName != "":
  207.                         for c in range(0,len(self.texList)):
  208.                             if self.texList[c].name == matTexName:
  209.                                 if len(self.texList[c].pixelData) > 56:
  210.                                     material.setNextPass(emissiveMaterial)
  211.                 elif b == 2:
  212.                     material.setNormalTexture(matTexName)
  213.                     emissiveMaterial.setNormalTexture(matTexName)
  214.                 elif b == 3:
  215.                     material.setSpecularTexture(matTexName)
  216.             self.matList.append(material)
  217.             bs.seek(0xA8, NOESEEK_REL)
  218.         #print(bs.tell())
  219.         #mesh
  220.         meshCount = bs.read(">i")[0]
  221.         for a in range(0,meshCount):
  222.  
  223.             #print(str(a))
  224.             #rapi.rpgSetMaterial(rsiString.split(':')[1])
  225.             subMeshCount,meshType,vtxCount,bidCount,faceCount = bs.read(">5i")
  226.             faceBuff = bs.readBytes(2 * faceCount)
  227.             #print(subMeshCount,meshType,vtxCount,bidCount,faceCount)
  228.             if meshType == 8:
  229.                 vtxStride = 0x2C
  230.                 vertBuff = bs.readBytes(vtxStride * vtxCount)
  231.             elif meshType == 7:
  232.                 vtxStride = 0x28
  233.                 vertBuff = bs.readBytes(vtxStride * vtxCount)
  234.             elif meshType == 3:
  235.                 vtxStride = 0x30
  236.                 vertBuff = bs.readBytes(vtxStride * vtxCount)
  237.             else:
  238.                 return 0
  239.             print("Mesh " + str(bs.tell()))
  240.             usedBones = bs.read(">" + bidCount * "i")
  241.             print(usedBones)
  242.             bMap = []
  243.             for b in range(0,bidCount):
  244.                 bMap.append(boneMap[usedBones[b]])
  245.             print(bMap)
  246.             meshInfo2 = ()
  247.             for b in range(0,subMeshCount):
  248.                 print(str(b))
  249.                 meshInfo1 = bs.read(">" + 14 * "i")
  250.                 subUsedBonesCount =  bs.read(">i")[0]
  251.                 meshInfo2 += bs.read(">" + subUsedBonesCount * "i")
  252.                 meshInfo3 = bs.read(">" + 11 * "f")
  253.                 rapi.rpgSetName(self.matList[meshInfo1[4]].name)
  254.                 rapi.rpgSetMaterial(self.matList[meshInfo1[4]].name)
  255.                 rapi.rpgSetBoneMap(bMap)
  256.                 #print(meshInfo1)
  257.                 print(meshInfo2)
  258.                 #print(meshInfo3)
  259.                 #print("meshType ",str(meshType))
  260.                 posBuff = (vertBuff[(meshInfo1[2] * vtxStride):(meshInfo1[2] * vtxStride) + (meshInfo1[3] * vtxStride)])
  261.                 idxBuff = (faceBuff[(meshInfo1[12] * 2):(meshInfo1[12] * 2) + (meshInfo1[13] * 2)])
  262.                 if meshType == 8:
  263.                     rapi.rpgBindPositionBufferOfs(posBuff, noesis.RPGEODATA_FLOAT, vtxStride, 0)
  264.                     decodedNormals = rapi.decodeNormals32(posBuff[12:], vtxStride, -11, -11, -10, NOE_BIGENDIAN)
  265.                     decodedNormals = rapi.swapEndianArray(decodedNormals, 4)
  266.                     rapi.rpgBindNormalBuffer(decodedNormals, noesis.RPGEODATA_FLOAT, 12)
  267.                     rapi.rpgBindColorBufferOfs(posBuff, noesis.RPGEODATA_UBYTE, vtxStride, 0x18, 4)
  268.                     rapi.rpgBindUV1BufferOfs(posBuff, noesis.RPGEODATA_HALFFLOAT, vtxStride, 0x1C)
  269.                     #rapi.rpgBindUV2BufferOfs(posBuff, noesis.RPGEODATA_HALFFLOAT, vtxStride, 0x20)
  270.                     rapi.rpgBindBoneIndexBufferOfs(posBuff, noesis.RPGEODATA_UBYTE, vtxStride, 0x24, 4)
  271.                     rapi.rpgBindBoneWeightBufferOfs(posBuff, noesis.RPGEODATA_UBYTE, vtxStride, 0x28, 4)
  272.                 elif meshType == 7:
  273.                     rapi.rpgBindPositionBufferOfs(posBuff, noesis.RPGEODATA_FLOAT, vtxStride, 0)
  274.                     decodedNormals = rapi.decodeNormals32(posBuff[12:], vtxStride, -11, -11, -10, NOE_BIGENDIAN)
  275.                     decodedNormals = rapi.swapEndianArray(decodedNormals, 4)
  276.                     rapi.rpgBindNormalBuffer(decodedNormals, noesis.RPGEODATA_FLOAT, 12)
  277.                     rapi.rpgBindColorBufferOfs(posBuff, noesis.RPGEODATA_UBYTE, vtxStride, 0x18, 4)
  278.                     rapi.rpgBindUV1BufferOfs(posBuff, noesis.RPGEODATA_HALFFLOAT, vtxStride, 0x1C)
  279.                     rapi.rpgBindBoneIndexBufferOfs(posBuff, noesis.RPGEODATA_UBYTE, vtxStride, 0x20, 4)
  280.                     rapi.rpgBindBoneWeightBufferOfs(posBuff, noesis.RPGEODATA_UBYTE, vtxStride, 0x24, 4)
  281.                 elif meshType == 3:
  282.                     rapi.rpgBindPositionBufferOfs(posBuff, noesis.RPGEODATA_FLOAT, vtxStride, 0)
  283.                     decodedNormals = rapi.decodeNormals32(posBuff[12:], vtxStride, -11, -11, -10, NOE_BIGENDIAN)
  284.                     decodedNormals = rapi.swapEndianArray(decodedNormals, 4)
  285.                     rapi.rpgBindNormalBuffer(decodedNormals, noesis.RPGEODATA_FLOAT, 12)
  286.                     rapi.rpgBindColorBufferOfs(posBuff, noesis.RPGEODATA_UBYTE, vtxStride, 0x18, 4)
  287.                     rapi.rpgBindUV1BufferOfs(posBuff, noesis.RPGEODATA_HALFFLOAT, vtxStride, 0x1C)
  288.                     rapi.rpgBindBoneIndexBufferOfs(posBuff, noesis.RPGEODATA_USHORT, vtxStride, 0x20, 4)
  289.                     rapi.rpgBindBoneWeightBufferOfs(posBuff, noesis.RPGEODATA_UBYTE, vtxStride, 0x2C, 4)
  290.                 if meshInfo1[0] == 3:
  291.                     rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_USHORT, meshInfo1[13], noesis.RPGEO_TRIANGLE, 1)
  292.                 elif meshInfo1[0] == 4:
  293.                     rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_USHORT, meshInfo1[13], noesis.RPGEO_TRIANGLE_STRIP, 1)
  294.                 rapi.rpgClearBufferBinds()
  295.  
  296.     def loadMeshNames(self, bs):
  297.         pass
  298.  
  299. def kcLoadModel(data, mdlList):
  300.     ctx = rapi.rpgCreateContext()
  301.     rapi.rpgSetOption(noesis.RPGOPT_BIGENDIAN, 1)
  302.     hxt = hxtFile(NoeBitStream(data, NOE_BIGENDIAN))
  303.     hxt.loadAll(hxt.bs)
  304.     try:
  305.         mdl = rapi.rpgConstructModel()
  306.     except:
  307.         mdl = NoeModel()
  308.     mdl.setModelMaterials(NoeModelMaterials(hxt.texList, hxt.matList))
  309.     mdlList.append(mdl); mdl.setBones(hxt.boneList)    
  310.     return 1
  311.  
  312.