Advertisement
Guest User

SC4/Tekken6 Loader

a guest
May 28th, 2010
1,632
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 21.25 KB | None | 0 0
  1. #include "main.h"
  2. #include "glwrap.h"
  3. #include "cnt_pgeo.h"
  4.  
  5. //is it a sc4 model?
  6. bool Model_IsSC4(BYTE *fileBuffer, int bufferLen)
  7. {
  8.     if (bufferLen < sizeof(int)*2)
  9.     {
  10.         return false;
  11.     }
  12.     int numEntries = GetBigIntRaw(fileBuffer);
  13.     if (numEntries < 1 || (int)sizeof(int)*(numEntries+1) > bufferLen)
  14.     {
  15.         return false;
  16.     }
  17.     int firstEntry = GetBigIntRaw(fileBuffer+4);
  18.     if (firstEntry <= 4 || firstEntry > (bufferLen-4))
  19.     {
  20.         return false;
  21.     }
  22.     BYTE *testData = fileBuffer+firstEntry;
  23.     if (memcmp(testData, "NMD.", 4))
  24.     {
  25.         if (memcmp(testData, "NDXR", 4) && memcmp(testData, "NTXR", 4))
  26.         {
  27.             return false;
  28.         }
  29.     }
  30.     return true;
  31. }
  32.  
  33. //native format structures
  34. typedef struct nmdHdr_s
  35. {
  36.     BYTE            id[8];
  37.     //int               unknownA;
  38.     WORD            unknownWA;
  39.     short           numBones;
  40.     int             unknownB;
  41.     int             unknownC;
  42.     int             unknownD;
  43.     int             matOfs;
  44.     int             decDatOfs;
  45.     int             padOfs;
  46.     int             unknownE;
  47.     int             unknownOfsB;
  48.     int             unknownF;
  49.     int             unknownG;
  50.     short           numBonesB;
  51.     short           unknownH;
  52.     int             unknownI[2];
  53. } nmdHdr_t;
  54. typedef struct nmdBoneEntry_s
  55. {
  56.     float           unknownA[8];
  57.     float           unknownB[3];
  58.     int             decOfs;
  59.     float           unknownC[4];
  60.     int             unknownD[3];
  61.     short           parentIdx;
  62.     short           idx;
  63. } nmdBoneEntry_t;
  64. typedef struct tkBoneHdr_s
  65. {
  66.     BYTE            id[4];
  67.     int             unknownA;
  68.     int             unknownB; //A&B maybe version?
  69.  
  70.     WORD            unknownC;
  71.     WORD            unknownD;
  72.  
  73.     int             numBones;
  74.     float           unknownE;
  75.  
  76.     int             hieOfs;
  77.     int             transOfs;
  78.     int             rotOfs;
  79.     int             ofs3;
  80.     int             ofs4;
  81.     int             nameOfs;
  82.     int             ofs5;
  83.  
  84.     int             pad[3];
  85. } tkBoneHdr_t;
  86. typedef struct ntxrHdr_s
  87. {
  88.     BYTE            id[4];
  89.     short           unknownA;
  90.     short           numTex;
  91.     int             unknownB;
  92.     int             unknownC;
  93. } ntxrHdr_t;
  94. typedef struct ntxrTexHdr_s
  95. {
  96.     int             ofsToNext;
  97.     int             unknownA;
  98.     int             dataSize;
  99.     WORD            ofsToImg;
  100.     WORD            unknownB;
  101.  
  102.     WORD            numMips;
  103.     WORD            imgFmt;
  104.  
  105.     WORD            width;
  106.     WORD            height;
  107. } ntxrTexHdr_t;
  108. typedef struct ndxrHdr_s
  109. {
  110.     BYTE            id[4];
  111.     int             dataSize;
  112.     WORD            unknownWA;
  113.     WORD            numDrawSurfs;
  114. //  BYTE            unknownA[4];
  115. //  int             unknownA;
  116.     short           unknownWC;
  117.     short           unknownWD;
  118. //  int             numUnknown;
  119.     int             idxOfs;
  120.     int             idxSize;
  121.     int             clrUVSize;
  122.     int             vertSize;
  123.     float           unknownC[4];
  124. } ndxrHdr_t;
  125. typedef struct ndxrDraw_s
  126. {
  127.     float           unknownA[8];
  128.     int             nameOfs;
  129.     int             unknownC;
  130.     short           baseBone;
  131.     WORD            numAtOfs;
  132.     int             dofs;
  133. } ndxrDraw_t;
  134. typedef struct ndxrSubDraw_s
  135. {
  136.     int             idxStartOfs;
  137.     int             colorUVStartOfs;
  138.     int             vertStartOfs;
  139.     WORD            unknownG;
  140.     WORD            vertType;
  141.     int             dofs[4];
  142.     short           numIdx;
  143.     short           unknownH;
  144.     int             unknownI[3];
  145. } ndxrSubDraw_t;
  146.  
  147. //interpreted structures
  148. typedef struct nmdBone_s
  149. {
  150.     char            *objName;
  151.     BYTE            *decDat;
  152.     modelMatrix_t   boneMat;
  153.     int             parentIdx;
  154.  
  155.     bool            didTrans;
  156.     modelMatrix_t   postTransMat;
  157. } nmdBone_t;
  158. typedef struct ndxrInMemSubDraw_s
  159. {
  160.     ndxrSubDraw_t   hdr;
  161.     int             vertOfs;
  162.     int             idxOfs;
  163.     int             clrUVOfs;
  164.     BYTE            *dptr[4];
  165. } ndxrInMemSubDraw_t;
  166. typedef struct ndxrInMemDraw_s
  167. {
  168.     ndxrDraw_t          hdr;
  169.     char                *objName;
  170.     ndxrInMemSubDraw_t  *subDraws;
  171.     int                 numSubDraws;
  172. } ndxrInMemDraw_t;
  173. typedef struct ndxrInMemBuf_s
  174. {
  175.     ndxrHdr_t       hdr;
  176.     ndxrInMemDraw_t *draws;
  177.     int             numDraws;
  178.     BYTE            *dataPtr;
  179.     BYTE            *idxPtr;
  180.     BYTE            *vertPtr;
  181.     BYTE            *clrUVPtr;
  182. } ndxrInMemBuf_t;
  183. typedef struct ndxrVInfo_s
  184. {
  185.     int             vertSize;
  186.  
  187.     int             posOfs;
  188.     rpgeoDataType_e posType;
  189.     int             nrmOfs;
  190.     rpgeoDataType_e nrmType;
  191.     int             uvOfs;
  192.     rpgeoDataType_e uvType;
  193.  
  194.     int             bidxOfs;
  195.     rpgeoDataType_e bidxType;
  196.     int             bwgtOfs;
  197.     rpgeoDataType_e bwgtType;
  198. } ndxrVInfo_t;
  199.  
  200. //load NMD
  201. static void Model_SC4_LoadNMD(BYTE *data, CArrayList<nmdBone_t> &nmdBones)
  202. {
  203.     nmdHdr_t hdr = *((nmdHdr_t *)data);
  204.     LITTLE_BIG_SWAP(hdr.unknownWA);
  205.     LITTLE_BIG_SWAP(hdr.numBones);
  206.     LITTLE_BIG_SWAP(hdr.unknownB);
  207.     LITTLE_BIG_SWAP(hdr.unknownC);
  208.     LITTLE_BIG_SWAP(hdr.unknownD);
  209.     LITTLE_BIG_SWAP(hdr.matOfs);
  210.     LITTLE_BIG_SWAP(hdr.decDatOfs);
  211.     LITTLE_BIG_SWAP(hdr.padOfs);
  212.     LITTLE_BIG_SWAP(hdr.unknownE);
  213.     LITTLE_BIG_SWAP(hdr.unknownOfsB);
  214.     LITTLE_BIG_SWAP(hdr.unknownF);
  215.     LITTLE_BIG_SWAP(hdr.unknownG);
  216.     LITTLE_BIG_SWAP(hdr.numBonesB);
  217.     LITTLE_BIG_SWAP(hdr.unknownH);
  218.     LITTLE_BIG_SWAP(hdr.unknownI[0]);
  219.     LITTLE_BIG_SWAP(hdr.unknownI[1]);
  220.     BYTE *boneDat = data+sizeof(hdr);
  221.     for (int i = 0; i < hdr.numBones; i++)
  222.     {
  223.         nmdBoneEntry_t nmdBone = *((nmdBoneEntry_t *)(boneDat+i*sizeof(nmdBoneEntry_t)));
  224.         LITTLE_BIG_SWAP(nmdBone.unknownA[0]);
  225.         LITTLE_BIG_SWAP(nmdBone.unknownA[1]);
  226.         LITTLE_BIG_SWAP(nmdBone.unknownA[2]);
  227.         LITTLE_BIG_SWAP(nmdBone.unknownA[3]);
  228.         LITTLE_BIG_SWAP(nmdBone.unknownA[4]);
  229.         LITTLE_BIG_SWAP(nmdBone.unknownA[5]);
  230.         LITTLE_BIG_SWAP(nmdBone.unknownA[6]);
  231.         LITTLE_BIG_SWAP(nmdBone.unknownA[7]);
  232.         LITTLE_BIG_SWAP(nmdBone.unknownB[0]);
  233.         LITTLE_BIG_SWAP(nmdBone.unknownB[1]);
  234.         LITTLE_BIG_SWAP(nmdBone.unknownB[2]);
  235.         LITTLE_BIG_SWAP(nmdBone.decOfs);
  236.         LITTLE_BIG_SWAP(nmdBone.unknownC[0]);
  237.         LITTLE_BIG_SWAP(nmdBone.unknownC[1]);
  238.         LITTLE_BIG_SWAP(nmdBone.unknownC[2]);
  239.         LITTLE_BIG_SWAP(nmdBone.unknownC[3]);
  240.         LITTLE_BIG_SWAP(nmdBone.unknownD[0]);
  241.         LITTLE_BIG_SWAP(nmdBone.unknownD[1]);
  242.         LITTLE_BIG_SWAP(nmdBone.unknownD[2]);
  243.         LITTLE_BIG_SWAP(nmdBone.parentIdx);
  244.         LITTLE_BIG_SWAP(nmdBone.idx);
  245.         float *matData = (float *)(data + hdr.matOfs + i*sizeof(float)*16);
  246.         nmdBone_t dst;
  247.         memset(&dst, 0, sizeof(dst));
  248.         dst.parentIdx = nmdBone.parentIdx;
  249.         dst.decDat = (nmdBone.decOfs > 0) ? data + nmdBone.decOfs : NULL;
  250.         float mat[16];
  251.         memcpy(mat, matData, sizeof(mat));
  252.         for (int j = 0; j < 16; j++)
  253.         {
  254.             LITTLE_BIG_SWAP(mat[j]);
  255.         }
  256.         Math_4x4ToModelMat((fourxMatrix_t *)mat, &dst.boneMat);
  257.         nmdBones.Append(dst);
  258.     }
  259. }
  260.  
  261. //transform a bone
  262. static void Model_SC4_TransformBone(CArrayList<nmdBone_t> &nmdBones, nmdBone_t &bone)
  263. {
  264.     if (bone.didTrans)
  265.     {
  266.         return;
  267.     }
  268.     bone.didTrans = true;
  269.     if (bone.parentIdx >= 0)
  270.     {
  271.         Model_SC4_TransformBone(nmdBones, bone);
  272.     }
  273.  
  274.     if (bone.parentIdx >= 0)
  275.     {
  276.         Math_MatrixMultiply(&nmdBones[bone.parentIdx].postTransMat, &bone.boneMat, &bone.postTransMat);
  277.     }
  278.     else
  279.     {
  280.         bone.postTransMat = bone.boneMat;
  281.     }
  282. }
  283.  
  284. //load BONE (used in tekken, also little endian even for 360)
  285. static void Model_SC4_LoadBONE(BYTE *data, CArrayList<nmdBone_t> &nmdBones)
  286. {
  287.     tkBoneHdr_t *hdr = (tkBoneHdr_t *)data;
  288.     for (int i = 0; i < hdr->numBones; i++)
  289.     {
  290.         int *hieData = (int *)(data + hdr->hieOfs);
  291.         nmdBone_t nb;
  292.         memset(&nb, 0, sizeof(nb));
  293.         nb.objName = (char *)(data + hdr->nameOfs + i*32);
  294.         nb.decDat = NULL;
  295.         nb.parentIdx = hieData[i];
  296.         float *pos = (float *)(data + hdr->transOfs + i*12);
  297.         float *ang = (float *)(data + hdr->rotOfs + i*12);
  298.         fourxMatrix_t fm = g_identityMatrix4x4;
  299.         Math_TranslateMatrix4x4(&fm, pos);
  300.         Math_RotateMatrix4x4(&fm, ang[2]*57.295779514f, 0.0f, 0.0f, 1.0f);
  301.         Math_RotateMatrix4x4(&fm, -ang[1]*57.295779514f, 0.0f, 1.0f, 0.0f);
  302.         Math_RotateMatrix4x4(&fm, ang[0]*57.295779514f, 1.0f, 0.0f, 0.0f);
  303.         Math_4x4ToModelMat(&fm, &nb.boneMat);
  304.         nmdBones.Append(nb);
  305.     }
  306.  
  307.     //transform all of the bones after loading
  308.     for (int i = 0; i < nmdBones.Num(); i++)
  309.     {
  310.         Model_SC4_TransformBone(nmdBones, nmdBones[i]);
  311.     }
  312. }
  313.  
  314. //load ntxr segment
  315. static void Model_SC4_LoadNTXR(BYTE *data, CArrayList<noesisTex_t *> &textures, CArrayList<noesisMaterial_t *> &materials)
  316. {
  317.     ntxrHdr_t hdr = *((ntxrHdr_t *)data);
  318.     LITTLE_BIG_SWAP(hdr.unknownA);
  319.     LITTLE_BIG_SWAP(hdr.numTex);
  320.     LITTLE_BIG_SWAP(hdr.unknownB);
  321.     LITTLE_BIG_SWAP(hdr.unknownC);
  322.  
  323.     BYTE *imgPtr = data + sizeof(ntxrHdr_t);
  324.     for (int i = 0; i < hdr.numTex; i++)
  325.     {
  326.         ntxrTexHdr_t texHdr = *((ntxrTexHdr_t *)imgPtr);
  327.         LITTLE_BIG_SWAP(texHdr.ofsToNext);
  328.         LITTLE_BIG_SWAP(texHdr.unknownA);
  329.         LITTLE_BIG_SWAP(texHdr.dataSize);
  330.         LITTLE_BIG_SWAP(texHdr.ofsToImg);
  331.         LITTLE_BIG_SWAP(texHdr.unknownB);
  332.         LITTLE_BIG_SWAP(texHdr.numMips);
  333.         LITTLE_BIG_SWAP(texHdr.imgFmt);
  334.         LITTLE_BIG_SWAP(texHdr.width);
  335.         LITTLE_BIG_SWAP(texHdr.height);
  336.  
  337.         int globalIdx = -1;
  338.         BYTE *imgData = imgPtr + texHdr.ofsToImg;
  339.         if (!memcmp(imgData-16, "GIDX", 4))
  340.         { //grab the global index
  341.             globalIdx = GetBigWordRaw(imgData-16+10);
  342.         }
  343.         int dxFmt = NOESISTEX_DXT1;
  344.         bool isDXT = true;
  345.         int bytesPP = 1;
  346.         if (texHdr.imgFmt == 0)
  347.         {
  348.             dxFmt = NOESISTEX_DXT1;
  349.         }
  350.         else if (texHdr.imgFmt == 1)
  351.         {
  352.             dxFmt = NOESISTEX_DXT3;
  353.         }
  354.         else if (texHdr.imgFmt == 2)
  355.         {
  356.             dxFmt = NOESISTEX_DXT5;
  357.         }
  358.         else if (texHdr.imgFmt == 19)
  359.         {
  360.             dxFmt = NOESISTEX_RGB24;
  361.             isDXT = false;
  362.             bytesPP = 3;
  363.         }
  364.         else if (texHdr.imgFmt == 20)
  365.         {
  366.             dxFmt = NOESISTEX_RGBA32;
  367.             isDXT = false;
  368.             bytesPP = 4;
  369.         }
  370.         else
  371.         {
  372.             richprintf("WARNING: Unknown texture format %i.\n", texHdr.imgFmt);
  373.         }
  374.  
  375.         char fname[8192];
  376.         GetDirForFilePath(fname, g_outFileName);
  377.         char nameStr[512];
  378.         sprintf(nameStr, ".\\%sntxr%03i", g_mo.texNamePrep, i);
  379.         strcat(fname, nameStr);
  380.  
  381.         if (isDXT)
  382.         {
  383.             strcat(fname, ".dds");
  384.         }
  385.         else
  386.         {
  387.             strcat(fname, ".png");
  388.         }
  389.  
  390.         BYTE *swapData = (BYTE *)malloc(texHdr.dataSize);
  391.         memcpy(swapData, imgData, texHdr.dataSize);
  392.         //now perform endian swap on the whole thing
  393.         int swapCount = (isDXT) ? 2 : bytesPP;
  394.         for (int i = 0; i < texHdr.dataSize; i += swapCount)
  395.         {
  396.             LittleBigSwap(swapData+i, swapCount);
  397.         }
  398.  
  399.         noesisTex_t *nt = Noesis_TextureAlloc(fname, texHdr.width, texHdr.height, swapData, dxFmt);
  400.         nt->shouldFreeData = true;
  401.         nt->globalIdx = globalIdx;
  402.         textures.Append(nt);
  403.  
  404.         noesisMaterial_t *mat = Noesis_GetMaterialList(1);
  405.         mat->texIdx = textures.Num()-1;
  406.         sprintf(nameStr, ".\\%sntxr%03i", g_mo.texNamePrep, mat->texIdx);
  407.         mat->name = Noesis_PooledString(nameStr);
  408.         //mat->noDefaultBlend = true;
  409.         materials.Append(mat);
  410.  
  411.         imgPtr += texHdr.ofsToNext;
  412.     }
  413. }
  414.  
  415. //load ndxr segment
  416. static void Model_SC4_LoadNDXR(BYTE *data, CArrayList<ndxrInMemBuf_t> &ndBuffers, CArrayList<nmdBone_t> &nmdBones)
  417. {
  418.     ndxrHdr_t hdr = *((ndxrHdr_t *)data);
  419.     LITTLE_BIG_SWAP(hdr.dataSize);
  420.     LITTLE_BIG_SWAP(hdr.unknownWA);
  421.     LITTLE_BIG_SWAP(hdr.numDrawSurfs);
  422.     //LITTLE_BIG_SWAP(hdr.unknownA);
  423.     LITTLE_BIG_SWAP(hdr.unknownWC);
  424.     LITTLE_BIG_SWAP(hdr.unknownWD);
  425.     LITTLE_BIG_SWAP(hdr.idxOfs);
  426.     LITTLE_BIG_SWAP(hdr.idxSize);
  427.     LITTLE_BIG_SWAP(hdr.clrUVSize);
  428.     LITTLE_BIG_SWAP(hdr.vertSize);
  429.     LITTLE_BIG_SWAP(hdr.unknownC[0]);
  430.     LITTLE_BIG_SWAP(hdr.unknownC[1]);
  431.     LITTLE_BIG_SWAP(hdr.unknownC[2]);
  432.     LITTLE_BIG_SWAP(hdr.unknownC[3]);
  433.     char *objNames = (char *)(data + sizeof(hdr) + hdr.idxOfs + hdr.idxSize + hdr.vertSize + hdr.clrUVSize);
  434.     ndxrInMemBuf_t nbuf;
  435.     memset(&nbuf, 0, sizeof(nbuf));
  436.     nbuf.hdr = hdr;
  437.     nbuf.dataPtr = data;
  438.     nbuf.idxPtr = data + hdr.idxOfs + sizeof(hdr);
  439.     nbuf.vertPtr = nbuf.idxPtr + hdr.idxSize;
  440.     if (hdr.vertSize > 0)
  441.     {
  442.         nbuf.clrUVPtr = nbuf.vertPtr;
  443.         nbuf.vertPtr += hdr.clrUVSize;
  444.     }
  445.     nbuf.numDraws = hdr.numDrawSurfs;
  446.     nbuf.draws = (ndxrInMemDraw_t *)rcmalloc(sizeof(ndxrInMemDraw_t)*nbuf.numDraws);
  447.     memset(nbuf.draws, 0, sizeof(ndxrInMemDraw_t)*nbuf.numDraws);
  448.     BYTE *dsMem = data+sizeof(hdr);
  449.     for (int i = 0; i < hdr.numDrawSurfs; i++)
  450.     {
  451.         ndxrDraw_t nd = *((ndxrDraw_t *)(dsMem+i*sizeof(ndxrDraw_t)));
  452.         for (int j = 0; j < 8; j++) { LITTLE_BIG_SWAP(nd.unknownA[j]); }
  453.         LITTLE_BIG_SWAP(nd.nameOfs);
  454.         LITTLE_BIG_SWAP(nd.unknownC);
  455.         LITTLE_BIG_SWAP(nd.baseBone);
  456.         LITTLE_BIG_SWAP(nd.numAtOfs);
  457.         LITTLE_BIG_SWAP(nd.dofs);
  458.  
  459.         BYTE *ofsDat = data + nd.dofs;
  460.         nbuf.draws[i].hdr = nd;
  461.         nbuf.draws[i].objName = objNames + nd.nameOfs;
  462.         nbuf.draws[i].numSubDraws = nd.numAtOfs;
  463.         nbuf.draws[i].subDraws = (ndxrInMemSubDraw_t *)rcmalloc(sizeof(ndxrInMemSubDraw_t)*nd.numAtOfs);
  464.         memset(nbuf.draws[i].subDraws, 0, sizeof(ndxrInMemSubDraw_t)*nd.numAtOfs);
  465.         for (int j = 0; j < nd.numAtOfs; j++)
  466.         {
  467.             ndxrSubDraw_t sd = *((ndxrSubDraw_t *)(ofsDat+j*sizeof(ndxrSubDraw_t)));
  468.             LITTLE_BIG_SWAP(sd.idxStartOfs);
  469.             LITTLE_BIG_SWAP(sd.colorUVStartOfs);
  470.             LITTLE_BIG_SWAP(sd.vertStartOfs);
  471.             LITTLE_BIG_SWAP(sd.numIdx);
  472.             LITTLE_BIG_SWAP(sd.vertType);
  473.             LITTLE_BIG_SWAP(sd.dofs[0]);
  474.             LITTLE_BIG_SWAP(sd.dofs[1]);
  475.             LITTLE_BIG_SWAP(sd.dofs[2]);
  476.             LITTLE_BIG_SWAP(sd.dofs[3]);
  477.             LITTLE_BIG_SWAP(sd.unknownG);
  478.             LITTLE_BIG_SWAP(sd.unknownH);
  479.             LITTLE_BIG_SWAP(sd.unknownI[0]);
  480.             LITTLE_BIG_SWAP(sd.unknownI[1]);
  481.             LITTLE_BIG_SWAP(sd.unknownI[2]);
  482.             ndxrInMemSubDraw_t *sdDst = &nbuf.draws[i].subDraws[j];
  483.             sdDst->dptr[0] = (sd.dofs[0] > 0) ? data + sd.dofs[0] : NULL;
  484.             sdDst->dptr[1] = (sd.dofs[1] > 0) ? data + sd.dofs[1] : NULL;
  485.             sdDst->dptr[2] = (sd.dofs[2] > 0) ? data + sd.dofs[2] : NULL;
  486.             sdDst->dptr[3] = (sd.dofs[3] > 0) ? data + sd.dofs[3] : NULL;
  487.             sdDst->hdr = sd;
  488.             sdDst->idxOfs = sd.idxStartOfs;
  489.             //sdDst->vertOfs = (hdr.unknownWC == -1) ? sd.vertStartOfs : sd.colorUVStartOfs;
  490.             sdDst->vertOfs = sd.vertStartOfs;
  491.             sdDst->clrUVOfs = sd.colorUVStartOfs;
  492.             if (!nbuf.clrUVPtr)
  493.             {
  494.                 sdDst->clrUVOfs = -1;
  495.                 sdDst->vertOfs = sd.colorUVStartOfs;
  496.             }
  497.         }
  498.     }
  499.     ndBuffers.Append(nbuf);
  500. }
  501.  
  502. //convert bones
  503. static modelBone_t *Model_SC4_CreateBones(CArrayList<nmdBone_t> &nmdBones, int &numBones)
  504. {
  505.     numBones = 0;
  506.     if (nmdBones.Num() <= 0)
  507.     {
  508.         return NULL;
  509.     }
  510.  
  511.     numBones = nmdBones.Num();
  512.     modelBone_t *bones = (modelBone_t *)rcmalloc(sizeof(modelBone_t)*numBones);
  513.     memset(bones, 0, sizeof(modelBone_t)*numBones);
  514.  
  515.     for (int i = 0; i < numBones; i++)
  516.     {
  517.         nmdBone_t &src = nmdBones[i];
  518.         int idx = i;//src.hdr.idx;
  519.         modelBone_t *bone = &bones[idx];
  520.         char boneName[1024];
  521.         if (src.objName)
  522.         {
  523.             sprintf(boneName, "bone%i_%s", idx, src.objName);
  524.         }
  525.         else
  526.         {
  527.             sprintf(boneName, "bone%i", idx);
  528.         }
  529.         boneName[30] = 0;
  530.         strcpy(bone->name, boneName);
  531.         bone->index = idx;
  532.         bone->eData.parent = NULL;
  533.         if (src.parentIdx >= 0 && src.parentIdx < numBones)
  534.         {
  535.             bone->eData.parent = &bones[src.parentIdx];
  536.         }
  537.         if (src.didTrans)
  538.         { //tekken 6 type
  539.             bone->mat = src.postTransMat;
  540.         }
  541.         else
  542.         {
  543.             Math_MatrixInverse(&src.boneMat, &bone->mat);
  544.         }
  545.     }
  546.     for (int i = 0; i < numBones; i++)
  547.     { //assign parent names
  548.         modelBone_t *bone = &bones[i];
  549.         if (bone->eData.parent)
  550.         {
  551.             strcpy(bone->parentName, bone->eData.parent->name);
  552.         }
  553.     }
  554.  
  555.     return bones;
  556. }
  557.  
  558. //get vertex info
  559. static void Model_SC4_GetVertInfo(ndxrInMemSubDraw_t *sd, ndxrVInfo_t *vi, bool noColors)
  560. {
  561.     memset(vi, 0, sizeof(ndxrVInfo_t));
  562.     WORD t = (sd->hdr.vertType>>8);
  563.     if (t == 17) //4370
  564.     {
  565.         vi->vertSize = 64;
  566.         vi->posOfs = 0;
  567.         vi->posType = RPGEODATA_FLOAT;
  568.         vi->nrmOfs = 16;
  569.         vi->nrmType = RPGEODATA_FLOAT;
  570.         vi->uvOfs = -1;
  571.         vi->bidxOfs = 32;
  572.         vi->bidxType = RPGEODATA_INT;
  573.         vi->bwgtOfs = 48;
  574.         vi->bwgtType = RPGEODATA_FLOAT;
  575.     }
  576.     else if (t == 19) //4882
  577.     {
  578.         vi->vertSize = 96;
  579.         vi->posOfs = 0;
  580.         vi->posType = RPGEODATA_FLOAT;
  581.         vi->nrmOfs = 16;
  582.         vi->nrmType = RPGEODATA_FLOAT;
  583.         vi->uvOfs = -1;
  584.         vi->bidxOfs = 64;
  585.         vi->bidxType = RPGEODATA_INT;
  586.         vi->bwgtOfs = 80;
  587.         vi->bwgtType = RPGEODATA_FLOAT;
  588.     }
  589.     else if (t == 16) //4112
  590.     {
  591.         vi->vertSize = 48;
  592.         vi->posOfs = 0;
  593.         vi->posType = RPGEODATA_FLOAT;
  594.         vi->nrmOfs = -1;//16;
  595.         vi->nrmType = RPGEODATA_FLOAT;
  596.         vi->uvOfs = -1;
  597.         vi->bidxOfs = 16;
  598.         vi->bidxType = RPGEODATA_INT;
  599.         vi->bwgtOfs = 32;
  600.         vi->bwgtType = RPGEODATA_FLOAT;
  601.     }
  602.     else if (t == 6) //1554
  603.     {
  604.         if (noColors)
  605.         {
  606.             vi->vertSize = 24;
  607.             vi->posOfs = 0;
  608.             vi->posType = RPGEODATA_FLOAT;
  609.             vi->nrmOfs = 12;
  610.             vi->nrmType = RPGEODATA_HALFFLOAT;
  611.             vi->uvOfs = 20;
  612.             vi->uvType = RPGEODATA_HALFFLOAT;
  613.             vi->bidxOfs = -1;
  614.             vi->bwgtOfs = -1;
  615.         }
  616.         else
  617.         {
  618.             vi->vertSize = 28;
  619.             vi->posOfs = 0;
  620.             vi->posType = RPGEODATA_FLOAT;
  621.             vi->nrmOfs = 12;
  622.             vi->nrmType = RPGEODATA_HALFFLOAT;
  623.             vi->uvOfs = 24;
  624.             vi->uvType = RPGEODATA_HALFFLOAT;
  625.             vi->bidxOfs = -1;
  626.             vi->bwgtOfs = -1;
  627.         }
  628.     }
  629.     else if (t == 7) //1810
  630.     {
  631.         if (noColors)
  632.         {
  633.             vi->vertSize = 40;
  634.             vi->posOfs = 0;
  635.             vi->posType = RPGEODATA_FLOAT;
  636.             vi->nrmOfs = 12;
  637.             vi->nrmType = RPGEODATA_HALFFLOAT;
  638.             vi->uvOfs = 36;
  639.             vi->uvType = RPGEODATA_HALFFLOAT;
  640.             vi->bidxOfs = -1;
  641.             vi->bwgtOfs = -1;
  642.         }
  643.         else
  644.         {
  645.             vi->vertSize = 44;
  646.             vi->posOfs = 0;
  647.             vi->posType = RPGEODATA_FLOAT;
  648.             vi->nrmOfs = 12;
  649.             vi->nrmType = RPGEODATA_HALFFLOAT;
  650.             vi->uvOfs = 40;
  651.             vi->uvType = RPGEODATA_HALFFLOAT;
  652.             vi->bidxOfs = -1;
  653.             vi->bwgtOfs = -1;
  654.         }
  655.     }
  656.     else if (t == 0) //18
  657.     {
  658.         vi->vertSize = 24;
  659.         vi->posOfs = 0;
  660.         vi->posType = RPGEODATA_FLOAT;
  661.         vi->nrmOfs = 12;
  662.         vi->nrmType = RPGEODATA_HALFFLOAT;
  663.         vi->uvOfs = 20;
  664.         vi->uvType = RPGEODATA_HALFFLOAT;
  665.         vi->bidxOfs = -1;
  666.         vi->bwgtOfs = -1;
  667.     }
  668.     else
  669.     {
  670.         richprintf("WARNING: vertex type %i is unknown.\n", t);
  671.     }
  672. }
  673.  
  674. //iterate through the god damn thing and find a texture index
  675. static int Model_SC4_GetTexFromCommandList(BYTE *cmdBuf, CArrayList<noesisTex_t *> &textures)
  676. {
  677.     while (1)
  678.     {
  679.         if (cmdBuf[0] == 8)
  680.         { //direct texture index
  681.             return GetBigWordRaw(cmdBuf+34);
  682.             //cmdBuf += 56;
  683.         }
  684.         else if (cmdBuf[0] == 18)
  685.         {
  686.             cmdBuf += 32;
  687.         }
  688.         else if (cmdBuf[0] == 16 || cmdBuf[0] == 20)
  689.         {
  690.             int gidx = GetBigWordRaw(cmdBuf+2);
  691.             for (int i = 0; i < textures.Num(); i++)
  692.             {
  693.                 noesisTex_t *tex = textures[i];
  694.                 if (tex->globalIdx == gidx)
  695.                 {
  696.                     return i;
  697.                 }
  698.             }
  699.             cmdBuf += 24;
  700.         }
  701.         else if (cmdBuf[0] == 0)
  702.         {
  703.             cmdBuf += 4;
  704.         }
  705.         else if (cmdBuf[0] == 63)
  706.         {
  707.             cmdBuf += 4;
  708.         }
  709.         else if (cmdBuf[0] == 65 || cmdBuf[0] == 255)
  710.         { //seems to indicate the end
  711.             //cmdBuf += 16;
  712.             break;
  713.         }
  714.         else
  715.         {
  716.             break;
  717.         }
  718.     }
  719.     return 0;
  720. }
  721.  
  722. //load model
  723. noesisModel_t *Model_LoadSC4(BYTE *fileBuffer, int bufferLen, int &numMdl)
  724. {
  725.     if (!Model_IsSC4(fileBuffer, bufferLen))
  726.     {
  727.         return NULL;
  728.     }
  729.  
  730.     CArrayList<ndxrInMemBuf_t> ndBuffers;
  731.     CArrayList<nmdBone_t> nmdBones;
  732.     CArrayList<noesisTex_t *> textures;
  733.     CArrayList<noesisMaterial_t *> materials;
  734.  
  735.     int numEntries = GetBigIntRaw(fileBuffer);
  736.     for (int i = 0; i < numEntries; i++)
  737.     {
  738.         int ofs = GetBigIntRaw(fileBuffer+sizeof(int) + i*sizeof(int));
  739.         if (ofs <= 0 || ofs >= bufferLen)
  740.         {
  741.             continue;
  742.         }
  743.         BYTE *data = fileBuffer+ofs;
  744.         if (!memcmp(data, "NMD.", 4))
  745.         { //skeleton data
  746.             Model_SC4_LoadNMD(data, nmdBones);
  747.         }
  748.         else if (!memcmp(data, "BONE", 4))
  749.         { //tekken skeleton data
  750.             Model_SC4_LoadBONE(data, nmdBones);
  751.         }
  752.         else if (!memcmp(data, "NTXR", 4))
  753.         { //texture chunk
  754.             Model_SC4_LoadNTXR(data, textures, materials);
  755.         }
  756.         else if (!memcmp(data, "NDXR", 4))
  757.         { //draw+face+vertex data
  758.             Model_SC4_LoadNDXR(data, ndBuffers, nmdBones);
  759.         }
  760.     }
  761.  
  762.     if (ndBuffers.Num() <= 0)
  763.     {
  764.         if (textures.Num() > 0)
  765.         {
  766.             CArrayList<noesisMaterial_t *> matList;
  767.             noesisMatData_t *md = Noesis_GetMatDataFromLists(matList, textures);
  768.             matList.Clear();
  769.             numMdl = 1;
  770.             return Noesis_AllocModel(NULL, NULL, NULL, md, NULL);
  771.         }
  772.         return NULL;
  773.     }
  774.  
  775.     RichPGeo *pgeo = RichPGeo_Alloc();
  776.     pgeo->SetEndian(true);
  777.  
  778.     rpgeoFinishData_t fn;
  779.     memset(&fn, 0, sizeof(fn));
  780.     fn.bones = Model_SC4_CreateBones(nmdBones, fn.numBones);
  781.     fn.matData = Noesis_GetMatDataFromLists(materials, textures);
  782.  
  783.     for (int i = 0; i < ndBuffers.Num(); i++)
  784.     {
  785.         ndxrInMemBuf_t *b = &ndBuffers[i];
  786.         for (int j = 0; j < b->numDraws; j++)
  787.         {
  788.             ndxrInMemDraw_t *d = &b->draws[j];
  789.             for (int k = 0; k < d->numSubDraws; k++)
  790.             {
  791.                 ndxrInMemSubDraw_t *sd = &d->subDraws[k];
  792.                 ndxrVInfo_t vi;
  793.                 bool noColors = ((sd->hdr.vertType & 255) == 16);
  794.                 Model_SC4_GetVertInfo(sd, &vi, noColors);
  795.                 if (vi.vertSize <= 0)
  796.                 {
  797.                     continue;
  798.                 }
  799.  
  800.                 int texIdx = Model_SC4_GetTexFromCommandList(sd->dptr[0], textures);
  801.                 if (texIdx < 0 || texIdx >= textures.Num())
  802.                 {
  803.                     texIdx = -1;
  804.                 }
  805.                 pgeo->SetMaterialIndex(texIdx);
  806.  
  807.                 int vertOfs = sd->vertOfs;
  808.                 if (vi.posOfs >= 0)
  809.                 {
  810.                     pgeo->BindPositionBuffer(b->vertPtr+vertOfs+vi.posOfs, vi.posType, vi.vertSize);
  811.                 }
  812.                 if (vi.nrmOfs >= 0)
  813.                 {
  814.                     pgeo->BindNormalBuffer(b->vertPtr+vertOfs+vi.nrmOfs, vi.nrmType, vi.vertSize);
  815.                 }
  816.                 if (vi.uvOfs >= 0)
  817.                 {
  818.                     pgeo->BindUV1Buffer(b->vertPtr+vertOfs+vi.uvOfs, vi.uvType, vi.vertSize);
  819.                 }
  820.                 else if (b->clrUVPtr)
  821.                 {
  822.                     if (noColors)
  823.                     {
  824.                         pgeo->BindUV1Buffer(b->clrUVPtr+sd->clrUVOfs+0, RPGEODATA_HALFFLOAT, 4);
  825.                     }
  826.                     else
  827.                     {
  828.                         pgeo->BindUV1Buffer(b->clrUVPtr+sd->clrUVOfs+4, RPGEODATA_HALFFLOAT, 8);
  829.                         //pgeo->BindColorBuffer(b->clrUVPtr+sd->clrUVOfs, RPGEODATA_BYTE, 8, 4);
  830.                     }
  831.                 }
  832.                 if (vi.bidxOfs >= 0 && vi.bwgtOfs >= 0)
  833.                 {
  834.                     pgeo->BindBoneIndexBuffer(b->vertPtr+vertOfs+vi.bidxOfs, vi.bidxType, vi.vertSize, 4);
  835.                     pgeo->BindBoneWeightBuffer(b->vertPtr+vertOfs+vi.bwgtOfs, vi.bwgtType, vi.vertSize, 4);
  836.                 }
  837.                 else if (nmdBones.Num() > 0)
  838.                 { //default skin weighted to base bone
  839.                     int idx = (d->hdr.baseBone >= 0 && d->hdr.baseBone < nmdBones.Num()) ? d->hdr.baseBone : 0;
  840.                     pgeo->VertBoneIndexI(&idx, 1);
  841.                     float wgt = 1.0f;
  842.                     pgeo->VertBoneWeightF(&wgt, 1);
  843.                 }
  844.  
  845.                 pgeo->CommitTriangles(b->idxPtr+sd->idxOfs, RPGEODATA_USHORT, sd->hdr.numIdx, RPGEO_TRIANGLE_STRIP);
  846.                 pgeo->ClearBufferBinds();
  847.                 pgeo->SetTransform(NULL);
  848.             }
  849.         }
  850.     }
  851.  
  852.     noesisModel_t *mdl = pgeo->ConstructModel(&fn);
  853.     if (mdl)
  854.     {
  855.         richprintf("Successfully loaded SC4 model.\n");
  856.         numMdl = 1;
  857.     }
  858.  
  859.     RichPGeo_Free(pgeo);
  860.  
  861.     ndBuffers.Clear();
  862.     nmdBones.Clear();
  863.     textures.Clear();
  864.     materials.Clear();
  865.     return mdl;
  866. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement