Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "main.h"
- #include "glwrap.h"
- #include "cnt_pgeo.h"
- //is it a sc4 model?
- bool Model_IsSC4(BYTE *fileBuffer, int bufferLen)
- {
- if (bufferLen < sizeof(int)*2)
- {
- return false;
- }
- int numEntries = GetBigIntRaw(fileBuffer);
- if (numEntries < 1 || (int)sizeof(int)*(numEntries+1) > bufferLen)
- {
- return false;
- }
- int firstEntry = GetBigIntRaw(fileBuffer+4);
- if (firstEntry <= 4 || firstEntry > (bufferLen-4))
- {
- return false;
- }
- BYTE *testData = fileBuffer+firstEntry;
- if (memcmp(testData, "NMD.", 4))
- {
- if (memcmp(testData, "NDXR", 4) && memcmp(testData, "NTXR", 4))
- {
- return false;
- }
- }
- return true;
- }
- //native format structures
- typedef struct nmdHdr_s
- {
- BYTE id[8];
- //int unknownA;
- WORD unknownWA;
- short numBones;
- int unknownB;
- int unknownC;
- int unknownD;
- int matOfs;
- int decDatOfs;
- int padOfs;
- int unknownE;
- int unknownOfsB;
- int unknownF;
- int unknownG;
- short numBonesB;
- short unknownH;
- int unknownI[2];
- } nmdHdr_t;
- typedef struct nmdBoneEntry_s
- {
- float unknownA[8];
- float unknownB[3];
- int decOfs;
- float unknownC[4];
- int unknownD[3];
- short parentIdx;
- short idx;
- } nmdBoneEntry_t;
- typedef struct tkBoneHdr_s
- {
- BYTE id[4];
- int unknownA;
- int unknownB; //A&B maybe version?
- WORD unknownC;
- WORD unknownD;
- int numBones;
- float unknownE;
- int hieOfs;
- int transOfs;
- int rotOfs;
- int ofs3;
- int ofs4;
- int nameOfs;
- int ofs5;
- int pad[3];
- } tkBoneHdr_t;
- typedef struct ntxrHdr_s
- {
- BYTE id[4];
- short unknownA;
- short numTex;
- int unknownB;
- int unknownC;
- } ntxrHdr_t;
- typedef struct ntxrTexHdr_s
- {
- int ofsToNext;
- int unknownA;
- int dataSize;
- WORD ofsToImg;
- WORD unknownB;
- WORD numMips;
- WORD imgFmt;
- WORD width;
- WORD height;
- } ntxrTexHdr_t;
- typedef struct ndxrHdr_s
- {
- BYTE id[4];
- int dataSize;
- WORD unknownWA;
- WORD numDrawSurfs;
- // BYTE unknownA[4];
- // int unknownA;
- short unknownWC;
- short unknownWD;
- // int numUnknown;
- int idxOfs;
- int idxSize;
- int clrUVSize;
- int vertSize;
- float unknownC[4];
- } ndxrHdr_t;
- typedef struct ndxrDraw_s
- {
- float unknownA[8];
- int nameOfs;
- int unknownC;
- short baseBone;
- WORD numAtOfs;
- int dofs;
- } ndxrDraw_t;
- typedef struct ndxrSubDraw_s
- {
- int idxStartOfs;
- int colorUVStartOfs;
- int vertStartOfs;
- WORD unknownG;
- WORD vertType;
- int dofs[4];
- short numIdx;
- short unknownH;
- int unknownI[3];
- } ndxrSubDraw_t;
- //interpreted structures
- typedef struct nmdBone_s
- {
- char *objName;
- BYTE *decDat;
- modelMatrix_t boneMat;
- int parentIdx;
- bool didTrans;
- modelMatrix_t postTransMat;
- } nmdBone_t;
- typedef struct ndxrInMemSubDraw_s
- {
- ndxrSubDraw_t hdr;
- int vertOfs;
- int idxOfs;
- int clrUVOfs;
- BYTE *dptr[4];
- } ndxrInMemSubDraw_t;
- typedef struct ndxrInMemDraw_s
- {
- ndxrDraw_t hdr;
- char *objName;
- ndxrInMemSubDraw_t *subDraws;
- int numSubDraws;
- } ndxrInMemDraw_t;
- typedef struct ndxrInMemBuf_s
- {
- ndxrHdr_t hdr;
- ndxrInMemDraw_t *draws;
- int numDraws;
- BYTE *dataPtr;
- BYTE *idxPtr;
- BYTE *vertPtr;
- BYTE *clrUVPtr;
- } ndxrInMemBuf_t;
- typedef struct ndxrVInfo_s
- {
- int vertSize;
- int posOfs;
- rpgeoDataType_e posType;
- int nrmOfs;
- rpgeoDataType_e nrmType;
- int uvOfs;
- rpgeoDataType_e uvType;
- int bidxOfs;
- rpgeoDataType_e bidxType;
- int bwgtOfs;
- rpgeoDataType_e bwgtType;
- } ndxrVInfo_t;
- //load NMD
- static void Model_SC4_LoadNMD(BYTE *data, CArrayList<nmdBone_t> &nmdBones)
- {
- nmdHdr_t hdr = *((nmdHdr_t *)data);
- LITTLE_BIG_SWAP(hdr.unknownWA);
- LITTLE_BIG_SWAP(hdr.numBones);
- LITTLE_BIG_SWAP(hdr.unknownB);
- LITTLE_BIG_SWAP(hdr.unknownC);
- LITTLE_BIG_SWAP(hdr.unknownD);
- LITTLE_BIG_SWAP(hdr.matOfs);
- LITTLE_BIG_SWAP(hdr.decDatOfs);
- LITTLE_BIG_SWAP(hdr.padOfs);
- LITTLE_BIG_SWAP(hdr.unknownE);
- LITTLE_BIG_SWAP(hdr.unknownOfsB);
- LITTLE_BIG_SWAP(hdr.unknownF);
- LITTLE_BIG_SWAP(hdr.unknownG);
- LITTLE_BIG_SWAP(hdr.numBonesB);
- LITTLE_BIG_SWAP(hdr.unknownH);
- LITTLE_BIG_SWAP(hdr.unknownI[0]);
- LITTLE_BIG_SWAP(hdr.unknownI[1]);
- BYTE *boneDat = data+sizeof(hdr);
- for (int i = 0; i < hdr.numBones; i++)
- {
- nmdBoneEntry_t nmdBone = *((nmdBoneEntry_t *)(boneDat+i*sizeof(nmdBoneEntry_t)));
- LITTLE_BIG_SWAP(nmdBone.unknownA[0]);
- LITTLE_BIG_SWAP(nmdBone.unknownA[1]);
- LITTLE_BIG_SWAP(nmdBone.unknownA[2]);
- LITTLE_BIG_SWAP(nmdBone.unknownA[3]);
- LITTLE_BIG_SWAP(nmdBone.unknownA[4]);
- LITTLE_BIG_SWAP(nmdBone.unknownA[5]);
- LITTLE_BIG_SWAP(nmdBone.unknownA[6]);
- LITTLE_BIG_SWAP(nmdBone.unknownA[7]);
- LITTLE_BIG_SWAP(nmdBone.unknownB[0]);
- LITTLE_BIG_SWAP(nmdBone.unknownB[1]);
- LITTLE_BIG_SWAP(nmdBone.unknownB[2]);
- LITTLE_BIG_SWAP(nmdBone.decOfs);
- LITTLE_BIG_SWAP(nmdBone.unknownC[0]);
- LITTLE_BIG_SWAP(nmdBone.unknownC[1]);
- LITTLE_BIG_SWAP(nmdBone.unknownC[2]);
- LITTLE_BIG_SWAP(nmdBone.unknownC[3]);
- LITTLE_BIG_SWAP(nmdBone.unknownD[0]);
- LITTLE_BIG_SWAP(nmdBone.unknownD[1]);
- LITTLE_BIG_SWAP(nmdBone.unknownD[2]);
- LITTLE_BIG_SWAP(nmdBone.parentIdx);
- LITTLE_BIG_SWAP(nmdBone.idx);
- float *matData = (float *)(data + hdr.matOfs + i*sizeof(float)*16);
- nmdBone_t dst;
- memset(&dst, 0, sizeof(dst));
- dst.parentIdx = nmdBone.parentIdx;
- dst.decDat = (nmdBone.decOfs > 0) ? data + nmdBone.decOfs : NULL;
- float mat[16];
- memcpy(mat, matData, sizeof(mat));
- for (int j = 0; j < 16; j++)
- {
- LITTLE_BIG_SWAP(mat[j]);
- }
- Math_4x4ToModelMat((fourxMatrix_t *)mat, &dst.boneMat);
- nmdBones.Append(dst);
- }
- }
- //transform a bone
- static void Model_SC4_TransformBone(CArrayList<nmdBone_t> &nmdBones, nmdBone_t &bone)
- {
- if (bone.didTrans)
- {
- return;
- }
- bone.didTrans = true;
- if (bone.parentIdx >= 0)
- {
- Model_SC4_TransformBone(nmdBones, bone);
- }
- if (bone.parentIdx >= 0)
- {
- Math_MatrixMultiply(&nmdBones[bone.parentIdx].postTransMat, &bone.boneMat, &bone.postTransMat);
- }
- else
- {
- bone.postTransMat = bone.boneMat;
- }
- }
- //load BONE (used in tekken, also little endian even for 360)
- static void Model_SC4_LoadBONE(BYTE *data, CArrayList<nmdBone_t> &nmdBones)
- {
- tkBoneHdr_t *hdr = (tkBoneHdr_t *)data;
- for (int i = 0; i < hdr->numBones; i++)
- {
- int *hieData = (int *)(data + hdr->hieOfs);
- nmdBone_t nb;
- memset(&nb, 0, sizeof(nb));
- nb.objName = (char *)(data + hdr->nameOfs + i*32);
- nb.decDat = NULL;
- nb.parentIdx = hieData[i];
- float *pos = (float *)(data + hdr->transOfs + i*12);
- float *ang = (float *)(data + hdr->rotOfs + i*12);
- fourxMatrix_t fm = g_identityMatrix4x4;
- Math_TranslateMatrix4x4(&fm, pos);
- Math_RotateMatrix4x4(&fm, ang[2]*57.295779514f, 0.0f, 0.0f, 1.0f);
- Math_RotateMatrix4x4(&fm, -ang[1]*57.295779514f, 0.0f, 1.0f, 0.0f);
- Math_RotateMatrix4x4(&fm, ang[0]*57.295779514f, 1.0f, 0.0f, 0.0f);
- Math_4x4ToModelMat(&fm, &nb.boneMat);
- nmdBones.Append(nb);
- }
- //transform all of the bones after loading
- for (int i = 0; i < nmdBones.Num(); i++)
- {
- Model_SC4_TransformBone(nmdBones, nmdBones[i]);
- }
- }
- //load ntxr segment
- static void Model_SC4_LoadNTXR(BYTE *data, CArrayList<noesisTex_t *> &textures, CArrayList<noesisMaterial_t *> &materials)
- {
- ntxrHdr_t hdr = *((ntxrHdr_t *)data);
- LITTLE_BIG_SWAP(hdr.unknownA);
- LITTLE_BIG_SWAP(hdr.numTex);
- LITTLE_BIG_SWAP(hdr.unknownB);
- LITTLE_BIG_SWAP(hdr.unknownC);
- BYTE *imgPtr = data + sizeof(ntxrHdr_t);
- for (int i = 0; i < hdr.numTex; i++)
- {
- ntxrTexHdr_t texHdr = *((ntxrTexHdr_t *)imgPtr);
- LITTLE_BIG_SWAP(texHdr.ofsToNext);
- LITTLE_BIG_SWAP(texHdr.unknownA);
- LITTLE_BIG_SWAP(texHdr.dataSize);
- LITTLE_BIG_SWAP(texHdr.ofsToImg);
- LITTLE_BIG_SWAP(texHdr.unknownB);
- LITTLE_BIG_SWAP(texHdr.numMips);
- LITTLE_BIG_SWAP(texHdr.imgFmt);
- LITTLE_BIG_SWAP(texHdr.width);
- LITTLE_BIG_SWAP(texHdr.height);
- int globalIdx = -1;
- BYTE *imgData = imgPtr + texHdr.ofsToImg;
- if (!memcmp(imgData-16, "GIDX", 4))
- { //grab the global index
- globalIdx = GetBigWordRaw(imgData-16+10);
- }
- int dxFmt = NOESISTEX_DXT1;
- bool isDXT = true;
- int bytesPP = 1;
- if (texHdr.imgFmt == 0)
- {
- dxFmt = NOESISTEX_DXT1;
- }
- else if (texHdr.imgFmt == 1)
- {
- dxFmt = NOESISTEX_DXT3;
- }
- else if (texHdr.imgFmt == 2)
- {
- dxFmt = NOESISTEX_DXT5;
- }
- else if (texHdr.imgFmt == 19)
- {
- dxFmt = NOESISTEX_RGB24;
- isDXT = false;
- bytesPP = 3;
- }
- else if (texHdr.imgFmt == 20)
- {
- dxFmt = NOESISTEX_RGBA32;
- isDXT = false;
- bytesPP = 4;
- }
- else
- {
- richprintf("WARNING: Unknown texture format %i.\n", texHdr.imgFmt);
- }
- char fname[8192];
- GetDirForFilePath(fname, g_outFileName);
- char nameStr[512];
- sprintf(nameStr, ".\\%sntxr%03i", g_mo.texNamePrep, i);
- strcat(fname, nameStr);
- if (isDXT)
- {
- strcat(fname, ".dds");
- }
- else
- {
- strcat(fname, ".png");
- }
- BYTE *swapData = (BYTE *)malloc(texHdr.dataSize);
- memcpy(swapData, imgData, texHdr.dataSize);
- //now perform endian swap on the whole thing
- int swapCount = (isDXT) ? 2 : bytesPP;
- for (int i = 0; i < texHdr.dataSize; i += swapCount)
- {
- LittleBigSwap(swapData+i, swapCount);
- }
- noesisTex_t *nt = Noesis_TextureAlloc(fname, texHdr.width, texHdr.height, swapData, dxFmt);
- nt->shouldFreeData = true;
- nt->globalIdx = globalIdx;
- textures.Append(nt);
- noesisMaterial_t *mat = Noesis_GetMaterialList(1);
- mat->texIdx = textures.Num()-1;
- sprintf(nameStr, ".\\%sntxr%03i", g_mo.texNamePrep, mat->texIdx);
- mat->name = Noesis_PooledString(nameStr);
- //mat->noDefaultBlend = true;
- materials.Append(mat);
- imgPtr += texHdr.ofsToNext;
- }
- }
- //load ndxr segment
- static void Model_SC4_LoadNDXR(BYTE *data, CArrayList<ndxrInMemBuf_t> &ndBuffers, CArrayList<nmdBone_t> &nmdBones)
- {
- ndxrHdr_t hdr = *((ndxrHdr_t *)data);
- LITTLE_BIG_SWAP(hdr.dataSize);
- LITTLE_BIG_SWAP(hdr.unknownWA);
- LITTLE_BIG_SWAP(hdr.numDrawSurfs);
- //LITTLE_BIG_SWAP(hdr.unknownA);
- LITTLE_BIG_SWAP(hdr.unknownWC);
- LITTLE_BIG_SWAP(hdr.unknownWD);
- LITTLE_BIG_SWAP(hdr.idxOfs);
- LITTLE_BIG_SWAP(hdr.idxSize);
- LITTLE_BIG_SWAP(hdr.clrUVSize);
- LITTLE_BIG_SWAP(hdr.vertSize);
- LITTLE_BIG_SWAP(hdr.unknownC[0]);
- LITTLE_BIG_SWAP(hdr.unknownC[1]);
- LITTLE_BIG_SWAP(hdr.unknownC[2]);
- LITTLE_BIG_SWAP(hdr.unknownC[3]);
- char *objNames = (char *)(data + sizeof(hdr) + hdr.idxOfs + hdr.idxSize + hdr.vertSize + hdr.clrUVSize);
- ndxrInMemBuf_t nbuf;
- memset(&nbuf, 0, sizeof(nbuf));
- nbuf.hdr = hdr;
- nbuf.dataPtr = data;
- nbuf.idxPtr = data + hdr.idxOfs + sizeof(hdr);
- nbuf.vertPtr = nbuf.idxPtr + hdr.idxSize;
- if (hdr.vertSize > 0)
- {
- nbuf.clrUVPtr = nbuf.vertPtr;
- nbuf.vertPtr += hdr.clrUVSize;
- }
- nbuf.numDraws = hdr.numDrawSurfs;
- nbuf.draws = (ndxrInMemDraw_t *)rcmalloc(sizeof(ndxrInMemDraw_t)*nbuf.numDraws);
- memset(nbuf.draws, 0, sizeof(ndxrInMemDraw_t)*nbuf.numDraws);
- BYTE *dsMem = data+sizeof(hdr);
- for (int i = 0; i < hdr.numDrawSurfs; i++)
- {
- ndxrDraw_t nd = *((ndxrDraw_t *)(dsMem+i*sizeof(ndxrDraw_t)));
- for (int j = 0; j < 8; j++) { LITTLE_BIG_SWAP(nd.unknownA[j]); }
- LITTLE_BIG_SWAP(nd.nameOfs);
- LITTLE_BIG_SWAP(nd.unknownC);
- LITTLE_BIG_SWAP(nd.baseBone);
- LITTLE_BIG_SWAP(nd.numAtOfs);
- LITTLE_BIG_SWAP(nd.dofs);
- BYTE *ofsDat = data + nd.dofs;
- nbuf.draws[i].hdr = nd;
- nbuf.draws[i].objName = objNames + nd.nameOfs;
- nbuf.draws[i].numSubDraws = nd.numAtOfs;
- nbuf.draws[i].subDraws = (ndxrInMemSubDraw_t *)rcmalloc(sizeof(ndxrInMemSubDraw_t)*nd.numAtOfs);
- memset(nbuf.draws[i].subDraws, 0, sizeof(ndxrInMemSubDraw_t)*nd.numAtOfs);
- for (int j = 0; j < nd.numAtOfs; j++)
- {
- ndxrSubDraw_t sd = *((ndxrSubDraw_t *)(ofsDat+j*sizeof(ndxrSubDraw_t)));
- LITTLE_BIG_SWAP(sd.idxStartOfs);
- LITTLE_BIG_SWAP(sd.colorUVStartOfs);
- LITTLE_BIG_SWAP(sd.vertStartOfs);
- LITTLE_BIG_SWAP(sd.numIdx);
- LITTLE_BIG_SWAP(sd.vertType);
- LITTLE_BIG_SWAP(sd.dofs[0]);
- LITTLE_BIG_SWAP(sd.dofs[1]);
- LITTLE_BIG_SWAP(sd.dofs[2]);
- LITTLE_BIG_SWAP(sd.dofs[3]);
- LITTLE_BIG_SWAP(sd.unknownG);
- LITTLE_BIG_SWAP(sd.unknownH);
- LITTLE_BIG_SWAP(sd.unknownI[0]);
- LITTLE_BIG_SWAP(sd.unknownI[1]);
- LITTLE_BIG_SWAP(sd.unknownI[2]);
- ndxrInMemSubDraw_t *sdDst = &nbuf.draws[i].subDraws[j];
- sdDst->dptr[0] = (sd.dofs[0] > 0) ? data + sd.dofs[0] : NULL;
- sdDst->dptr[1] = (sd.dofs[1] > 0) ? data + sd.dofs[1] : NULL;
- sdDst->dptr[2] = (sd.dofs[2] > 0) ? data + sd.dofs[2] : NULL;
- sdDst->dptr[3] = (sd.dofs[3] > 0) ? data + sd.dofs[3] : NULL;
- sdDst->hdr = sd;
- sdDst->idxOfs = sd.idxStartOfs;
- //sdDst->vertOfs = (hdr.unknownWC == -1) ? sd.vertStartOfs : sd.colorUVStartOfs;
- sdDst->vertOfs = sd.vertStartOfs;
- sdDst->clrUVOfs = sd.colorUVStartOfs;
- if (!nbuf.clrUVPtr)
- {
- sdDst->clrUVOfs = -1;
- sdDst->vertOfs = sd.colorUVStartOfs;
- }
- }
- }
- ndBuffers.Append(nbuf);
- }
- //convert bones
- static modelBone_t *Model_SC4_CreateBones(CArrayList<nmdBone_t> &nmdBones, int &numBones)
- {
- numBones = 0;
- if (nmdBones.Num() <= 0)
- {
- return NULL;
- }
- numBones = nmdBones.Num();
- modelBone_t *bones = (modelBone_t *)rcmalloc(sizeof(modelBone_t)*numBones);
- memset(bones, 0, sizeof(modelBone_t)*numBones);
- for (int i = 0; i < numBones; i++)
- {
- nmdBone_t &src = nmdBones[i];
- int idx = i;//src.hdr.idx;
- modelBone_t *bone = &bones[idx];
- char boneName[1024];
- if (src.objName)
- {
- sprintf(boneName, "bone%i_%s", idx, src.objName);
- }
- else
- {
- sprintf(boneName, "bone%i", idx);
- }
- boneName[30] = 0;
- strcpy(bone->name, boneName);
- bone->index = idx;
- bone->eData.parent = NULL;
- if (src.parentIdx >= 0 && src.parentIdx < numBones)
- {
- bone->eData.parent = &bones[src.parentIdx];
- }
- if (src.didTrans)
- { //tekken 6 type
- bone->mat = src.postTransMat;
- }
- else
- {
- Math_MatrixInverse(&src.boneMat, &bone->mat);
- }
- }
- for (int i = 0; i < numBones; i++)
- { //assign parent names
- modelBone_t *bone = &bones[i];
- if (bone->eData.parent)
- {
- strcpy(bone->parentName, bone->eData.parent->name);
- }
- }
- return bones;
- }
- //get vertex info
- static void Model_SC4_GetVertInfo(ndxrInMemSubDraw_t *sd, ndxrVInfo_t *vi, bool noColors)
- {
- memset(vi, 0, sizeof(ndxrVInfo_t));
- WORD t = (sd->hdr.vertType>>8);
- if (t == 17) //4370
- {
- vi->vertSize = 64;
- vi->posOfs = 0;
- vi->posType = RPGEODATA_FLOAT;
- vi->nrmOfs = 16;
- vi->nrmType = RPGEODATA_FLOAT;
- vi->uvOfs = -1;
- vi->bidxOfs = 32;
- vi->bidxType = RPGEODATA_INT;
- vi->bwgtOfs = 48;
- vi->bwgtType = RPGEODATA_FLOAT;
- }
- else if (t == 19) //4882
- {
- vi->vertSize = 96;
- vi->posOfs = 0;
- vi->posType = RPGEODATA_FLOAT;
- vi->nrmOfs = 16;
- vi->nrmType = RPGEODATA_FLOAT;
- vi->uvOfs = -1;
- vi->bidxOfs = 64;
- vi->bidxType = RPGEODATA_INT;
- vi->bwgtOfs = 80;
- vi->bwgtType = RPGEODATA_FLOAT;
- }
- else if (t == 16) //4112
- {
- vi->vertSize = 48;
- vi->posOfs = 0;
- vi->posType = RPGEODATA_FLOAT;
- vi->nrmOfs = -1;//16;
- vi->nrmType = RPGEODATA_FLOAT;
- vi->uvOfs = -1;
- vi->bidxOfs = 16;
- vi->bidxType = RPGEODATA_INT;
- vi->bwgtOfs = 32;
- vi->bwgtType = RPGEODATA_FLOAT;
- }
- else if (t == 6) //1554
- {
- if (noColors)
- {
- vi->vertSize = 24;
- vi->posOfs = 0;
- vi->posType = RPGEODATA_FLOAT;
- vi->nrmOfs = 12;
- vi->nrmType = RPGEODATA_HALFFLOAT;
- vi->uvOfs = 20;
- vi->uvType = RPGEODATA_HALFFLOAT;
- vi->bidxOfs = -1;
- vi->bwgtOfs = -1;
- }
- else
- {
- vi->vertSize = 28;
- vi->posOfs = 0;
- vi->posType = RPGEODATA_FLOAT;
- vi->nrmOfs = 12;
- vi->nrmType = RPGEODATA_HALFFLOAT;
- vi->uvOfs = 24;
- vi->uvType = RPGEODATA_HALFFLOAT;
- vi->bidxOfs = -1;
- vi->bwgtOfs = -1;
- }
- }
- else if (t == 7) //1810
- {
- if (noColors)
- {
- vi->vertSize = 40;
- vi->posOfs = 0;
- vi->posType = RPGEODATA_FLOAT;
- vi->nrmOfs = 12;
- vi->nrmType = RPGEODATA_HALFFLOAT;
- vi->uvOfs = 36;
- vi->uvType = RPGEODATA_HALFFLOAT;
- vi->bidxOfs = -1;
- vi->bwgtOfs = -1;
- }
- else
- {
- vi->vertSize = 44;
- vi->posOfs = 0;
- vi->posType = RPGEODATA_FLOAT;
- vi->nrmOfs = 12;
- vi->nrmType = RPGEODATA_HALFFLOAT;
- vi->uvOfs = 40;
- vi->uvType = RPGEODATA_HALFFLOAT;
- vi->bidxOfs = -1;
- vi->bwgtOfs = -1;
- }
- }
- else if (t == 0) //18
- {
- vi->vertSize = 24;
- vi->posOfs = 0;
- vi->posType = RPGEODATA_FLOAT;
- vi->nrmOfs = 12;
- vi->nrmType = RPGEODATA_HALFFLOAT;
- vi->uvOfs = 20;
- vi->uvType = RPGEODATA_HALFFLOAT;
- vi->bidxOfs = -1;
- vi->bwgtOfs = -1;
- }
- else
- {
- richprintf("WARNING: vertex type %i is unknown.\n", t);
- }
- }
- //iterate through the god damn thing and find a texture index
- static int Model_SC4_GetTexFromCommandList(BYTE *cmdBuf, CArrayList<noesisTex_t *> &textures)
- {
- while (1)
- {
- if (cmdBuf[0] == 8)
- { //direct texture index
- return GetBigWordRaw(cmdBuf+34);
- //cmdBuf += 56;
- }
- else if (cmdBuf[0] == 18)
- {
- cmdBuf += 32;
- }
- else if (cmdBuf[0] == 16 || cmdBuf[0] == 20)
- {
- int gidx = GetBigWordRaw(cmdBuf+2);
- for (int i = 0; i < textures.Num(); i++)
- {
- noesisTex_t *tex = textures[i];
- if (tex->globalIdx == gidx)
- {
- return i;
- }
- }
- cmdBuf += 24;
- }
- else if (cmdBuf[0] == 0)
- {
- cmdBuf += 4;
- }
- else if (cmdBuf[0] == 63)
- {
- cmdBuf += 4;
- }
- else if (cmdBuf[0] == 65 || cmdBuf[0] == 255)
- { //seems to indicate the end
- //cmdBuf += 16;
- break;
- }
- else
- {
- break;
- }
- }
- return 0;
- }
- //load model
- noesisModel_t *Model_LoadSC4(BYTE *fileBuffer, int bufferLen, int &numMdl)
- {
- if (!Model_IsSC4(fileBuffer, bufferLen))
- {
- return NULL;
- }
- CArrayList<ndxrInMemBuf_t> ndBuffers;
- CArrayList<nmdBone_t> nmdBones;
- CArrayList<noesisTex_t *> textures;
- CArrayList<noesisMaterial_t *> materials;
- int numEntries = GetBigIntRaw(fileBuffer);
- for (int i = 0; i < numEntries; i++)
- {
- int ofs = GetBigIntRaw(fileBuffer+sizeof(int) + i*sizeof(int));
- if (ofs <= 0 || ofs >= bufferLen)
- {
- continue;
- }
- BYTE *data = fileBuffer+ofs;
- if (!memcmp(data, "NMD.", 4))
- { //skeleton data
- Model_SC4_LoadNMD(data, nmdBones);
- }
- else if (!memcmp(data, "BONE", 4))
- { //tekken skeleton data
- Model_SC4_LoadBONE(data, nmdBones);
- }
- else if (!memcmp(data, "NTXR", 4))
- { //texture chunk
- Model_SC4_LoadNTXR(data, textures, materials);
- }
- else if (!memcmp(data, "NDXR", 4))
- { //draw+face+vertex data
- Model_SC4_LoadNDXR(data, ndBuffers, nmdBones);
- }
- }
- if (ndBuffers.Num() <= 0)
- {
- if (textures.Num() > 0)
- {
- CArrayList<noesisMaterial_t *> matList;
- noesisMatData_t *md = Noesis_GetMatDataFromLists(matList, textures);
- matList.Clear();
- numMdl = 1;
- return Noesis_AllocModel(NULL, NULL, NULL, md, NULL);
- }
- return NULL;
- }
- RichPGeo *pgeo = RichPGeo_Alloc();
- pgeo->SetEndian(true);
- rpgeoFinishData_t fn;
- memset(&fn, 0, sizeof(fn));
- fn.bones = Model_SC4_CreateBones(nmdBones, fn.numBones);
- fn.matData = Noesis_GetMatDataFromLists(materials, textures);
- for (int i = 0; i < ndBuffers.Num(); i++)
- {
- ndxrInMemBuf_t *b = &ndBuffers[i];
- for (int j = 0; j < b->numDraws; j++)
- {
- ndxrInMemDraw_t *d = &b->draws[j];
- for (int k = 0; k < d->numSubDraws; k++)
- {
- ndxrInMemSubDraw_t *sd = &d->subDraws[k];
- ndxrVInfo_t vi;
- bool noColors = ((sd->hdr.vertType & 255) == 16);
- Model_SC4_GetVertInfo(sd, &vi, noColors);
- if (vi.vertSize <= 0)
- {
- continue;
- }
- int texIdx = Model_SC4_GetTexFromCommandList(sd->dptr[0], textures);
- if (texIdx < 0 || texIdx >= textures.Num())
- {
- texIdx = -1;
- }
- pgeo->SetMaterialIndex(texIdx);
- int vertOfs = sd->vertOfs;
- if (vi.posOfs >= 0)
- {
- pgeo->BindPositionBuffer(b->vertPtr+vertOfs+vi.posOfs, vi.posType, vi.vertSize);
- }
- if (vi.nrmOfs >= 0)
- {
- pgeo->BindNormalBuffer(b->vertPtr+vertOfs+vi.nrmOfs, vi.nrmType, vi.vertSize);
- }
- if (vi.uvOfs >= 0)
- {
- pgeo->BindUV1Buffer(b->vertPtr+vertOfs+vi.uvOfs, vi.uvType, vi.vertSize);
- }
- else if (b->clrUVPtr)
- {
- if (noColors)
- {
- pgeo->BindUV1Buffer(b->clrUVPtr+sd->clrUVOfs+0, RPGEODATA_HALFFLOAT, 4);
- }
- else
- {
- pgeo->BindUV1Buffer(b->clrUVPtr+sd->clrUVOfs+4, RPGEODATA_HALFFLOAT, 8);
- //pgeo->BindColorBuffer(b->clrUVPtr+sd->clrUVOfs, RPGEODATA_BYTE, 8, 4);
- }
- }
- if (vi.bidxOfs >= 0 && vi.bwgtOfs >= 0)
- {
- pgeo->BindBoneIndexBuffer(b->vertPtr+vertOfs+vi.bidxOfs, vi.bidxType, vi.vertSize, 4);
- pgeo->BindBoneWeightBuffer(b->vertPtr+vertOfs+vi.bwgtOfs, vi.bwgtType, vi.vertSize, 4);
- }
- else if (nmdBones.Num() > 0)
- { //default skin weighted to base bone
- int idx = (d->hdr.baseBone >= 0 && d->hdr.baseBone < nmdBones.Num()) ? d->hdr.baseBone : 0;
- pgeo->VertBoneIndexI(&idx, 1);
- float wgt = 1.0f;
- pgeo->VertBoneWeightF(&wgt, 1);
- }
- pgeo->CommitTriangles(b->idxPtr+sd->idxOfs, RPGEODATA_USHORT, sd->hdr.numIdx, RPGEO_TRIANGLE_STRIP);
- pgeo->ClearBufferBinds();
- pgeo->SetTransform(NULL);
- }
- }
- }
- noesisModel_t *mdl = pgeo->ConstructModel(&fn);
- if (mdl)
- {
- richprintf("Successfully loaded SC4 model.\n");
- numMdl = 1;
- }
- RichPGeo_Free(pgeo);
- ndBuffers.Clear();
- nmdBones.Clear();
- textures.Clear();
- materials.Clear();
- return mdl;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement