home *** CD-ROM | disk | FTP | other *** search
/ Xentax forum attachments archive / xentax.7z / 6434 / Imageepoch.7z / fmt_brs_mdl.py
Encoding:
Python Source  |  2013-05-18  |  5.5 KB  |  167 lines

  1. from inc_noesis import *
  2. import noesis
  3. import rapi
  4.  
  5. def registerNoesisTypes():
  6.     handle = noesis.register("Black Rock Shooter", ".mdl")
  7.     noesis.setHandlerTypeCheck(handle, brsCheckType)
  8.     noesis.setHandlerLoadModel(handle, brsLoadModel)
  9.     #noesis.logPopup()
  10.     return 1
  11.  
  12. #check if it's this type based on the data
  13.  
  14. def brsCheckType(data):
  15.     bs = NoeBitStream(data)
  16.     idMagic = bs.readInt()
  17.     if idMagic != 0x4D534E49:
  18.         return 0
  19.     return 1       
  20.  
  21. #load the model
  22. def brsLoadModel(data, mdlList):
  23.     ctx = rapi.rpgCreateContext()
  24.     bs = NoeBitStream(data)
  25.     idMagic = bs.readInt()
  26.     unk00, texCount, matCount, unk01, boneCount, count2, count3, unk02, meshCount = bs.read("8BI")
  27.     matOffset, meshOffset, boneOffset, unk00Offset, meshGOffset, texOffset, vertOffset, size00, size01, texOffset2 = bs.read("10I")
  28.  
  29.     matInfo = []
  30.     bs.seek(matOffset)
  31.     for i in range(0, matCount):
  32.         matInfo.append(bs.read("4B8I"))
  33.  
  34.     bs.seek(meshOffset)
  35.     meshInfo = []
  36.     meshInfoEnd = []
  37.     for i in range(0, meshCount):
  38.         info1 = bs.read("4BI")
  39.         meshInfo.append(info1)
  40.         meshInfoEnd.append(info1[4])
  41.     meshInfoEnd.append(matInfo[0][4])
  42.     #print("meshInfo", meshInfo)
  43.     #print("meshInfoEnd", meshInfoEnd)
  44.     
  45.     bs.seek(boneOffset)
  46.     boneSize = (unk00Offset - boneOffset) // boneCount
  47.     #print(boneSize)
  48.     boneList = []
  49.     for i in range(0, boneCount):
  50.         boneName = str(i)
  51.         if boneSize == 0x20:
  52.             info = bs.read("4b")
  53.             pos = NoeVec3.fromBytes(bs.readBytes(12))
  54.             quat = NoeQuat.fromBytes(bs.readBytes(16))
  55.             quat[3] = -quat[3]
  56.             boneMtx = quat.toMat43()
  57.             boneMtx[3] = pos
  58.             newBone = NoeBone(i, boneName, boneMtx, None, info[2])
  59.             boneList.append(newBone)
  60.         elif boneSize == 0x34:
  61.             info = bs.read("4b")
  62.             boneMtx = NoeMat43.fromBytes(bs.readBytes(48))
  63.             newBone = NoeBone(i, boneName, boneMtx, None, info[2])
  64.             boneList.append(newBone)
  65.     if boneSize == 0x20:
  66.         boneList = rapi.multiplyBones(boneList)
  67.  
  68.     bs.seek(unk00Offset)
  69.     info3 = []
  70.     for i in range(0, count2):
  71.         info3.append(bs.read("2H2I"))
  72.     #print("info3", info3)
  73.     info31 = []
  74.     for i in range(0, count2):
  75.         bs.seek(info3[i][2], NOESEEK_ABS)
  76.         info31.append(bs.read(str(info3[i][0]) + "I"))
  77.     #print(info31)
  78.  
  79.     bs.seek(meshGOffset)
  80.  
  81.     texList = []
  82.     matList = []
  83.     bs.seek(texOffset)
  84.     tdata = bs.readBytes(len(data) - texOffset)
  85.     td = NoeBitStream(tdata)
  86.     palArray = []
  87.     for i in range(0, len(tdata) // 4):
  88.         if td.readUInt() == 0x444D5450:
  89.             palArray.append(td.tell() - 4)
  90.     palArray.append(len(tdata))
  91.     for i in range(0, texCount):
  92.         td.seek(palArray[i])
  93.         texInfo = td.read("4H4BI")
  94.         texData = td.readBytes(texInfo[8] - 16)
  95.         palData = []
  96.         palSize = palArray[i + 1] - td.tell()
  97.         palData = td.readBytes(palSize)
  98.         pixWidth = 2 ** ((texInfo[3] & 0xF000) // 0x1000)
  99.         pixHeight = (texInfo[3] & 0xFFF)
  100.         #print(texInfo[5])
  101.         if texInfo[4] == 5:
  102.             pix = rapi.imageUntwiddlePSP(texData, pixWidth, pixHeight, 8)
  103.             if texInfo[5] == 0x30:
  104.                 pix = rapi.imageDecodeRawPal(pix, palData, pixWidth, pixHeight, 8, "r8g8b8a8")
  105.             elif texInfo[5] == 0:
  106.                 pix = rapi.imageDecodeRawPal(pix, palData, pixWidth, pixHeight, 8, "r5g6b5")
  107.             elif texInfo[5] == 16:
  108.                 pix = rapi.imageDecodeRawPal(pix, palData, pixWidth, pixHeight, 8, "r5g5b5a1")
  109.         elif texInfo[4] == 4:
  110.             pix = rapi.imageUntwiddlePSP(texData, pixWidth, pixHeight, 4)
  111.             if texInfo[5] == 0x30:
  112.                 pix = rapi.imageDecodeRawPal(pix, palData, pixWidth, pixHeight, 4, "r8g8b8a8")
  113.             elif texInfo[5] == 0:
  114.                 pix = rapi.imageDecodeRawPal(pix, palData, pixWidth, pixHeight, 4, "r5g6b5")
  115.             elif texInfo[5] == 16:
  116.                 pix = rapi.imageDecodeRawPal(pix, palData, pixWidth, pixHeight, 4, "r5g5b5a1")
  117.         elif texInfo[4] == 3:
  118.             pix = rapi.imageUntwiddlePSP(texData, pixWidth, pixHeight, 4)
  119.         texList.append(NoeTexture(str(i), pixWidth, pixHeight, pix, noesis.NOESISTEX_RGBA32))
  120.  
  121.     matList = []
  122.     for i in range(0, matCount):
  123.         matName = str(i)
  124.         material = NoeMaterial(matName, "")
  125.         material.setTexture(str(matInfo[i][1]))
  126.         material.setFlags(0, 1)
  127.         matList.append(material)
  128.  
  129.     bs.seek(vertOffset)
  130.     for a in range(0, meshCount):
  131.         #rapi.rpgSetName(str(a))
  132.         rapi.rpgSetName(str(meshInfo[a][2]))
  133.         rapi.rpgSetMaterial(str(meshInfo[a][2]))
  134.         bs.seek(meshInfo[a][4], NOESEEK_ABS)
  135.         stripCount = (((meshInfoEnd[a + 1] - meshInfo[a][4]) - 12) // 16)
  136.         #print(stripCount)
  137.         #print(meshInfo[a][4])
  138.         stripInfo = []
  139.         tag1, tag2 = bs.read("2I")
  140.         for b in range(0, stripCount):
  141.             s = bs.read("I4BI4B"); s = [s[0], s[4], (s[5] & 0xFFFFFF), s[6], s[8], s[9]]
  142.             stripInfo.append(s)
  143.             #print(s)
  144.         for b in range(0, stripCount):
  145.             #print(stripInfo[b], str(a))
  146.             bs.seek(meshInfo[a][4] + stripInfo[b][2], NOESEEK_ABS)
  147.             pspVert = rapi.decodePSPVert(stripInfo[b][0])
  148.             #print(bs.tell())
  149.             #print(pspVert.weightType, pspVert.numWeights, pspVert.indexType)
  150.             #print(pspVert.uvOfs, pspVert.uvType, pspVert.colorOfs, pspVert.colorType, pspVert.normalOfs, pspVert.normalType)
  151.             if pspVert.uvType == 2:
  152.                 rapi.rpgSetUVScaleBias(NoeVec3 ((2.0, 2.0, 1.0)), NoeVec3 ((0.0, 0.0, 0.0)))
  153.             elif pspVert.uvType == 3:
  154.                 rapi.rpgSetUVScaleBias(NoeVec3 ((1.0, 1.0, 1.0)), NoeVec3 ((0.0, 0.0, 0.0)))
  155.             vertData = bs.readBytes(pspVert.vertexSize * stripInfo[b][3])
  156.             if vertData is not None and len(vertData) > 0:
  157.                 pspVert.bindBuffers(vertData)
  158.                 rapi.rpgCommitTriangles(None, noesis.RPGEODATA_SHORT, stripInfo[b][3], noesis.RPGEO_TRIANGLE_STRIP, 1)
  159.     rapi.rpgClearBufferBinds()
  160.     try:
  161.         mdl = rapi.rpgConstructModel()
  162.     except:
  163.         mdl = NoeModel()
  164.     mdl.setModelMaterials(NoeModelMaterials(texList, matList))
  165.     mdlList.append(mdl)
  166.     mdl.setBones(boneList)
  167.     return 1