diff options
| author | Luke Street <luke@street.dev> | 2026-03-01 15:35:36 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-03-01 14:35:36 -0800 |
| commit | 9649319ec4926457ef85e6094f8207474c977c2d (patch) | |
| tree | 1c5cd4c7cc4c1aee03f28921213da47f2775444d /libs/JSystem/src/J3DGraphLoader/J3DModelLoader.cpp | |
| parent | 6e149819e13b1f70ecbf8a4c66b030c17ffed2bb (diff) | |
Reorganize library code into `libs/` (#3119)
* Reorganize files into libs/{dolphin,JSystem,PowerPC_EABI_Support,revolution,TRK_MINNOW_DOLPHIN}
* Update configure.py and project.py for new libs structure
* Refactor `#include <dolphin/x.h>` -> `<x.h>`
* Remove `__REVOLUTION_SDK__` forwards from dolphin
* Fix dolphin/ references in revolution
* Wrap `#include <dolphin.h>` in `!__REVOLUTION_SDK__`
* Always build TRK against dolphin headers
* Resolve revolution SDK header resolution issues
Diffstat (limited to 'libs/JSystem/src/J3DGraphLoader/J3DModelLoader.cpp')
| -rw-r--r-- | libs/JSystem/src/J3DGraphLoader/J3DModelLoader.cpp | 672 |
1 files changed, 672 insertions, 0 deletions
diff --git a/libs/JSystem/src/J3DGraphLoader/J3DModelLoader.cpp b/libs/JSystem/src/J3DGraphLoader/J3DModelLoader.cpp new file mode 100644 index 0000000000..68622ff346 --- /dev/null +++ b/libs/JSystem/src/J3DGraphLoader/J3DModelLoader.cpp @@ -0,0 +1,672 @@ +#include "JSystem/JSystem.h" // IWYU pragma: keep + +#include "JSystem/J3DGraphLoader/J3DModelLoader.h" +#include "JSystem/J3DGraphAnimator/J3DAnimation.h" +#include "JSystem/J3DGraphAnimator/J3DShapeTable.h" +#include "JSystem/J3DGraphAnimator/J3DJointTree.h" +#include "JSystem/J3DGraphAnimator/J3DJoint.h" +#include "JSystem/J3DGraphLoader/J3DJointFactory.h" +#include "JSystem/J3DGraphLoader/J3DMaterialFactory.h" +#include "JSystem/J3DGraphLoader/J3DMaterialFactory_v21.h" +#include "JSystem/J3DGraphLoader/J3DShapeFactory.h" +#include "JSystem/J3DGraphAnimator/J3DModelData.h" +#include "JSystem/J3DGraphBase/J3DMaterial.h" +#include "JSystem/JUtility/JUTNameTab.h" +#include "JSystem/JKernel/JKRHeap.h" +#include "JSystem/JSupport/JSupport.h" + +J3DModelLoader::J3DModelLoader() : + mpModelData(NULL), + mpMaterialTable(NULL), + mpShapeBlock(NULL), + mpMaterialBlock(NULL), + mpModelHierarchy(NULL), + field_0x18(0), + mEnvelopeSize(0) { + /* empty function */ +} + +J3DModelData* J3DModelLoaderDataBase::load(void const* i_data, u32 i_flags) { + J3D_ASSERT_NULLPTR(52, i_data); + const J3DModelFileData* header = (const J3DModelFileData*)i_data; + if (i_data == NULL) { + return NULL; + } + if (header->mMagic1 == 'J3D1' && header->mMagic2 == 'bmd1') { + JUT_PANIC(64, "Error : version error."); + return NULL; + } + if (header->mMagic1 == 'J3D2' && header->mMagic2 == 'bmd2') { + J3DModelLoader_v21 loader; + return loader.load(i_data, i_flags); + } + if (header->mMagic1 == 'J3D2' && header->mMagic2 == 'bmd3') { + J3DModelLoader_v26 loader; + return loader.load(i_data, i_flags); + } + JUT_PANIC(89, "Error : version error."); + return NULL; +} + +J3DModelData* J3DModelLoaderDataBase::loadBinaryDisplayList(const void* i_data, u32 flags) { + J3D_ASSERT_NULLPTR(138, i_data); + const J3DModelFileData* header = (const J3DModelFileData*)i_data; + if (!i_data) { + return NULL; + } + if (header->mMagic1 == 'J3D2' && (header->mMagic2 == 'bdl3' || header->mMagic2 == 'bdl4')) { + J3DModelLoader_v26 loader; + return loader.loadBinaryDisplayList(i_data, flags); + } + JUT_PANIC(157, "Error : version error."); + return NULL; +} + +J3DModelData* J3DModelLoader::load(void const* i_data, u32 i_flags) { + s32 freeSize = JKRGetCurrentHeap()->getTotalFreeSize(); + mpModelData = new J3DModelData(); + J3D_ASSERT_ALLOCMEM(177, mpModelData); + mpModelData->clear(); + mpModelData->mpRawData = i_data; + mpModelData->setModelDataType(0); + mpMaterialTable = &mpModelData->mMaterialTable; + J3DModelFileData const* data = (J3DModelFileData*)i_data; + J3DModelBlock const* block = data->mBlocks; + for (u32 block_no = 0; block_no < data->mBlockNum; block_no++) { + switch (block->mBlockType) { + case 'INF1': + readInformation((J3DModelInfoBlock*)block, (s32)i_flags); + break; + case 'VTX1': + readVertex((J3DVertexBlock*)block); + break; + case 'EVP1': + readEnvelop((J3DEnvelopeBlock*)block); + break; + case 'DRW1': + readDraw((J3DDrawBlock*)block); + break; + case 'JNT1': + readJoint((J3DJointBlock*)block); + break; + case 'MAT3': + readMaterial((J3DMaterialBlock*)block, (s32)i_flags); + break; + case 'MAT2': + readMaterial_v21((J3DMaterialBlock_v21*)block, (s32)i_flags); + break; + case 'SHP1': + readShape((J3DShapeBlock*)block, (s32)i_flags); + break; + case 'TEX1': + readTexture((J3DTextureBlock*)block); + break; + default: + OSReport("Unknown data block\n"); + break; + } + block = (J3DModelBlock*)((uintptr_t)block + block->mBlockSize); + } + J3DModelHierarchy const* hierarchy = mpModelData->getHierarchy(); + mpModelData->makeHierarchy(NULL, &hierarchy); + mpModelData->getShapeTable()->sortVcdVatCmd(); + mpModelData->getJointTree().findImportantMtxIndex(); + setupBBoardInfo(); + if (mpModelData->getFlag() & 0x100) { + for (u16 shape_no = 0; shape_no < mpModelData->getShapeNum(); shape_no++) { + mpModelData->getShapeNodePointer(shape_no)->onFlag(0x200); + } + } + return mpModelData; +} + + +J3DMaterialTable* J3DModelLoader::loadMaterialTable(void const* i_data) { + int flags = 0x51100000; + mpMaterialTable = new J3DMaterialTable(); + J3D_ASSERT_ALLOCMEM(279, mpMaterialTable); + mpMaterialTable->clear(); + J3DModelFileData const* data = (J3DModelFileData*)i_data; + J3DModelBlock const* block = data->mBlocks; + for (u32 block_no = 0; block_no < data->mBlockNum; block_no++) { + switch (block->mBlockType) { + case 'MAT3': + readMaterialTable((J3DMaterialBlock*)block, flags); + break; + case 'MAT2': + readMaterialTable_v21((J3DMaterialBlock_v21*)block, flags); + break; + case 'TEX1': + readTextureTable((J3DTextureBlock*)block); + break; + default: + OSReport("Unknown data block\n"); + break; + } + block = (J3DModelBlock*)((uintptr_t)block + block->mBlockSize); + } + if (mpMaterialTable->mTexture == NULL) { + mpMaterialTable->mTexture = new J3DTexture(0, NULL); + J3D_ASSERT_ALLOCMEM(319, mpMaterialTable->mTexture); + } + return mpMaterialTable; +} + +inline u32 getBdlFlag_MaterialType(u32 flags) { + return flags & (J3DMLF_13 | J3DMLF_DoBdlMaterialCalc); +} + +J3DModelData* J3DModelLoader::loadBinaryDisplayList(void const* i_data, u32 i_flags) { + mpModelData = new J3DModelData(); + J3D_ASSERT_ALLOCMEM(338, mpModelData); + mpModelData->clear(); + mpModelData->mpRawData = i_data; + mpModelData->setModelDataType(1); + mpMaterialTable = &mpModelData->mMaterialTable; + J3DModelFileData const* data = (J3DModelFileData*)i_data; + J3DModelBlock const* block = data->mBlocks; + for (u32 block_no = 0; block_no < data->mBlockNum; block_no++) { + s32 flags; + u32 materialType; + switch (block->mBlockType) { + case 'INF1': + flags = i_flags; + readInformation((J3DModelInfoBlock*)block, flags); + break; + case 'VTX1': + readVertex((J3DVertexBlock*)block); + break; + case 'EVP1': + readEnvelop((J3DEnvelopeBlock*)block); + break; + case 'DRW1': + readDraw((J3DDrawBlock*)block); + break; + case 'JNT1': + readJoint((J3DJointBlock*)block); + break; + case 'SHP1': + readShape((J3DShapeBlock*)block, i_flags); + break; + case 'TEX1': + readTexture((J3DTextureBlock*)block); + break; + case 'MDL3': + readMaterialDL((J3DMaterialDLBlock*)block, i_flags); + modifyMaterial(i_flags); + break; + case 'MAT3': + flags = 0x50100000; + flags |= (i_flags & 0x3000000); + mpMaterialBlock = (J3DMaterialBlock*)block; + materialType = getBdlFlag_MaterialType(i_flags); + if (materialType == 0) { + readMaterial((J3DMaterialBlock*)block, flags); + } else if (materialType == 0x2000) { + readPatchedMaterial((J3DMaterialBlock*)block, flags); + } + break; + default: + OSReport("Unknown data block\n"); + break; + } + block = (J3DModelBlock*)((uintptr_t)block + block->mBlockSize); + } + J3DModelHierarchy const* hierarchy = mpModelData->getHierarchy(); + mpModelData->makeHierarchy(NULL, &hierarchy); + mpModelData->getShapeTable()->sortVcdVatCmd(); + mpModelData->getJointTree().findImportantMtxIndex(); + setupBBoardInfo(); + mpModelData->indexToPtr(); + return mpModelData; +} + +void J3DModelLoader::setupBBoardInfo() { + for (u16 i = 0; i < mpModelData->getJointNum(); i++) { + J3DMaterial* mesh = mpModelData->getJointNodePointer(i)->getMesh(); + if (mesh != NULL) { + u32 shape_index = mesh->getShape()->getIndex(); + u16* index_table = JSUConvertOffsetToPtr<u16>(mpShapeBlock, + (uintptr_t)mpShapeBlock->mpIndexTable); + J3DShapeInitData* shape_init_data = + JSUConvertOffsetToPtr<J3DShapeInitData>(mpShapeBlock, + (uintptr_t)mpShapeBlock->mpShapeInitData); + J3DShapeInitData* r26 = &shape_init_data[index_table[shape_index]]; + switch (r26->mShapeMtxType) { + case 0: + mpModelData->getJointNodePointer(i)->setMtxType(0); + break; + case 1: + mpModelData->getJointNodePointer(i)->setMtxType(1); + mpModelData->mbHasBillboard = true; + break; + case 2: + mpModelData->getJointNodePointer(i)->setMtxType(2); + mpModelData->mbHasBillboard = true; + break; + case 3: + mpModelData->getJointNodePointer(i)->setMtxType(0); + break; + default: + OSReport("WRONG SHAPE MATRIX TYPE (__FILE__)\n"); + break; + } + } + } +} + +void J3DModelLoader::readInformation(J3DModelInfoBlock const* i_block, u32 i_flags) { + J3D_ASSERT_NULLPTR(506, i_block); + mpModelData->mFlags = i_flags | i_block->mFlags; + mpModelData->getJointTree().setFlag(mpModelData->mFlags); + J3DMtxCalc* mtx_calc = NULL; + switch (mpModelData->mFlags & 0xf) { + case 0: + mtx_calc = new J3DMtxCalcNoAnm<J3DMtxCalcCalcTransformBasic,J3DMtxCalcJ3DSysInitBasic>(); + break; + case 1: + mtx_calc = new J3DMtxCalcNoAnm<J3DMtxCalcCalcTransformSoftimage,J3DMtxCalcJ3DSysInitSoftimage>(); + break; + case 2: + mtx_calc = new J3DMtxCalcNoAnm<J3DMtxCalcCalcTransformMaya,J3DMtxCalcJ3DSysInitMaya>(); + break; + default: + JUT_PANIC(529, "Error : Invalid MtxCalcType."); + break; + } + J3D_ASSERT_ALLOCMEM(532, mtx_calc); + mpModelData->setBasicMtxCalc(mtx_calc); + mpModelData->getVertexData().mPacketNum = i_block->mPacketNum; + mpModelData->getVertexData().mVtxNum = i_block->mVtxNum; + mpModelData->setHierarchy(JSUConvertOffsetToPtr<J3DModelHierarchy>(i_block, i_block->mpHierarchy)); +} + +static _GXCompType getFmtType(_GXVtxAttrFmtList* i_fmtList, _GXAttr i_attr) { + for (; i_fmtList->attr != GX_VA_NULL; i_fmtList++) { + if (i_fmtList->attr == i_attr) { + return i_fmtList->type; + } + } + return GX_F32; +} + +void J3DModelLoader::readVertex(J3DVertexBlock const* i_block) { + J3D_ASSERT_NULLPTR(577, i_block); + J3DVertexData& vertex_data = mpModelData->getVertexData(); + vertex_data.mVtxAttrFmtList = + JSUConvertOffsetToPtr<GXVtxAttrFmtList>(i_block, i_block->mpVtxAttrFmtList); + vertex_data.mVtxPosArray = JSUConvertOffsetToPtr<void>(i_block, i_block->mpVtxPosArray); + vertex_data.mVtxNrmArray = JSUConvertOffsetToPtr<void>(i_block, i_block->mpVtxNrmArray); + vertex_data.mVtxNBTArray = JSUConvertOffsetToPtr<void>(i_block, i_block->mpVtxNBTArray); + for (int i = 0; i < 2; i++) { + vertex_data.mVtxColorArray[i] = + (GXColor*)JSUConvertOffsetToPtr<void>(i_block, i_block->mpVtxColorArray[i]); + } + for (int i = 0; i < 8; i++) { + vertex_data.mVtxTexCoordArray[i] = + JSUConvertOffsetToPtr<void>(i_block, i_block->mpVtxTexCoordArray[i]); + } + + u32 nrm_size = 12; + if (getFmtType(vertex_data.mVtxAttrFmtList, GX_VA_NRM) == GX_F32) { + nrm_size = 12; + } else { + nrm_size = 6; + } + + void* nrm_end = NULL; + if (vertex_data.mVtxNBTArray != NULL) { + nrm_end = vertex_data.mVtxNBTArray; + } else if (vertex_data.mVtxColorArray[0] != NULL) { + nrm_end = vertex_data.mVtxColorArray[0]; + } else if (vertex_data.mVtxTexCoordArray[0] != NULL) { + nrm_end = vertex_data.mVtxTexCoordArray[0]; + } + + if (vertex_data.mVtxNrmArray == NULL) { + vertex_data.mNrmNum = 0; + } else if (nrm_end != NULL) { + vertex_data.mNrmNum = ((uintptr_t)nrm_end - (uintptr_t)vertex_data.mVtxNrmArray) / nrm_size + 1; + } else { + vertex_data.mNrmNum = (i_block->mBlockSize - (uintptr_t)i_block->mpVtxNrmArray) / nrm_size + 1; + } + + void* color0_end = NULL; + if (vertex_data.mVtxColorArray[1] != NULL) { + color0_end = vertex_data.mVtxColorArray[1]; + } else if (vertex_data.mVtxTexCoordArray[0] != NULL) { + color0_end = vertex_data.mVtxTexCoordArray[0]; + } + + if (vertex_data.mVtxColorArray[0] == NULL) { + vertex_data.mColNum = 0; + } else if (color0_end != NULL) { + vertex_data.mColNum = ((uintptr_t)color0_end - (uintptr_t)vertex_data.mVtxColorArray[0]) / 4 + 1; + } else { + vertex_data.mColNum = (i_block->mBlockSize - (uintptr_t)i_block->mpVtxColorArray[0]) / 4 + 1; + } + + int local_28 = 0; + if (vertex_data.mVtxTexCoordArray[1]) { + color0_end = vertex_data.mVtxTexCoordArray[1]; + } + + if (vertex_data.mVtxTexCoordArray[0] == NULL) { + vertex_data.mTexCoordNum = 0; + return; + } + if (local_28) { + vertex_data.mTexCoordNum = (local_28 - (uintptr_t)vertex_data.mVtxTexCoordArray[0]) / 8 + 1; + } else { + vertex_data.mTexCoordNum = (i_block->mBlockSize - (uintptr_t)i_block->mpVtxTexCoordArray[0]) / 8 + 1; + } +} + +void J3DModelLoader::readEnvelop(J3DEnvelopeBlock const* i_block) { + J3D_ASSERT_NULLPTR(724, i_block); + mpModelData->getJointTree().mWEvlpMtxNum = i_block->mWEvlpMtxNum; + mpModelData->getJointTree().mWEvlpMixMtxNum = + JSUConvertOffsetToPtr<u8>(i_block, i_block->mpWEvlpMixMtxNum); + mpModelData->getJointTree().mWEvlpMixMtxIndex = + JSUConvertOffsetToPtr<u16>(i_block, i_block->mpWEvlpMixIndex); + mpModelData->getJointTree().mWEvlpMixWeight = + JSUConvertOffsetToPtr<f32>(i_block, i_block->mpWEvlpMixWeight); + mpModelData->getJointTree().mInvJointMtx = + JSUConvertOffsetToPtr<Mtx>(i_block, i_block->mpInvJointMtx); +} + +void J3DModelLoader::readDraw(J3DDrawBlock const* i_block) { + J3D_ASSERT_NULLPTR(747, i_block); + J3DDrawMtxData* drawMtxData = mpModelData->getDrawMtxData(); + drawMtxData->mEntryNum = i_block->mMtxNum - mpModelData->getWEvlpMtxNum(); + drawMtxData->mDrawMtxFlag = JSUConvertOffsetToPtr<u8>(i_block, i_block->mpDrawMtxFlag); + drawMtxData->mDrawMtxIndex = JSUConvertOffsetToPtr<u16>(i_block, i_block->mpDrawMtxIndex); + u16 i; + for (i = 0; i < drawMtxData->mEntryNum; i++) { + if (drawMtxData->mDrawMtxFlag[i] == 1) { + break; + } + } + drawMtxData->mDrawFullWgtMtxNum = i; + mpModelData->getJointTree().mWEvlpImportantMtxIdx = new u16[drawMtxData->mEntryNum]; + J3D_ASSERT_ALLOCMEM(767, mpModelData->getJointTree().mWEvlpImportantMtxIdx); +} + +void J3DModelLoader::readJoint(J3DJointBlock const* i_block) { + J3D_ASSERT_NULLPTR(781, i_block); + J3DJointFactory factory(*i_block); + mpModelData->getJointTree().mJointNum = i_block->mJointNum; + if (i_block->mpNameTable != NULL) { + mpModelData->getJointTree().mJointName = + new JUTNameTab(JSUConvertOffsetToPtr<ResNTAB>(i_block, i_block->mpNameTable)); + J3D_ASSERT_ALLOCMEM(791, mpModelData->getJointTree().mJointName); + } else { + mpModelData->getJointTree().mJointName = NULL; + } + mpModelData->getJointTree().mJointNodePointer = + new J3DJoint*[mpModelData->getJointTree().mJointNum]; + J3D_ASSERT_ALLOCMEM(797, mpModelData->getJointTree().mJointNodePointer); + for (u16 i = 0; i < mpModelData->getJointNum(); i++) { + mpModelData->getJointTree().mJointNodePointer[i] = factory.create(i); + } +} + +void J3DModelLoader_v26::readMaterial(J3DMaterialBlock const* i_block, u32 i_flags) { + J3D_ASSERT_NULLPTR(817, i_block); + J3DMaterialFactory factory(*i_block); + mpMaterialTable->mMaterialNum = i_block->mMaterialNum; + mpMaterialTable->mUniqueMatNum = factory.countUniqueMaterials(); + if (i_block->mpNameTable != NULL) { + mpMaterialTable->mMaterialName = + new JUTNameTab(JSUConvertOffsetToPtr<ResNTAB>(i_block, i_block->mpNameTable)); + J3D_ASSERT_ALLOCMEM(832, mpMaterialTable->mMaterialName); + } else { + mpMaterialTable->mMaterialName = NULL; + } + mpMaterialTable->mMaterialNodePointer = new J3DMaterial*[mpMaterialTable->mMaterialNum]; + J3D_ASSERT_ALLOCMEM(841, mpMaterialTable->mMaterialNodePointer); + if (i_flags & 0x200000) { + mpMaterialTable->field_0x10 = new (0x20) J3DMaterial[mpMaterialTable->mUniqueMatNum]; + J3D_ASSERT_ALLOCMEM(846, mpMaterialTable->field_0x10); + } else { + mpMaterialTable->field_0x10 = NULL; + } + if (i_flags & 0x200000) { + for (u16 i = 0; i < mpMaterialTable->mUniqueMatNum; i++) { + factory.create(&mpMaterialTable->field_0x10[i], + J3DMaterialFactory::MATERIAL_TYPE_NORMAL, i, i_flags); + mpMaterialTable->field_0x10[i].mDiffFlag = (uintptr_t)&mpMaterialTable->field_0x10[i] >> 4; + } + } + for (u16 i = 0; i < mpMaterialTable->mMaterialNum; i++) { + mpMaterialTable->mMaterialNodePointer[i] = + factory.create(NULL, J3DMaterialFactory::MATERIAL_TYPE_NORMAL, i, i_flags); + } + if (i_flags & 0x200000) { + for (u16 i = 0; i < mpMaterialTable->mMaterialNum; i++) { + mpMaterialTable->mMaterialNodePointer[i]->mDiffFlag = + (uintptr_t)&mpMaterialTable->field_0x10[factory.getMaterialID(i)] >> 4; + mpMaterialTable->mMaterialNodePointer[i]->mpOrigMaterial = + &mpMaterialTable->field_0x10[factory.getMaterialID(i)]; + } + } else { + for (u16 i = 0; i < mpMaterialTable->mMaterialNum; i++) { + mpMaterialTable->mMaterialNodePointer[i]->mDiffFlag = + ((uintptr_t)mpMaterialTable->mMaterialNodePointer >> 4) + factory.getMaterialID(i); + } + } +} + +void J3DModelLoader_v21::readMaterial_v21(J3DMaterialBlock_v21 const* i_block, u32 i_flags) { + J3D_ASSERT_NULLPTR(913, i_block); + J3DMaterialFactory_v21 factory(*i_block); + mpMaterialTable->mMaterialNum = i_block->mMaterialNum; + mpMaterialTable->mUniqueMatNum = factory.countUniqueMaterials(); + if (i_block->mpNameTable != NULL) { + mpMaterialTable->mMaterialName = + new JUTNameTab(JSUConvertOffsetToPtr<ResNTAB>(i_block, i_block->mpNameTable)); + J3D_ASSERT_ALLOCMEM(930, mpMaterialTable->mMaterialName); + } else { + mpMaterialTable->mMaterialName = NULL; + } + mpMaterialTable->mMaterialNodePointer = new J3DMaterial*[mpMaterialTable->mMaterialNum]; + J3D_ASSERT_ALLOCMEM(940, mpMaterialTable->mMaterialNodePointer); + if (i_flags & 0x200000) { + mpMaterialTable->field_0x10 = new (0x20) J3DMaterial[mpMaterialTable->mUniqueMatNum]; + J3D_ASSERT_ALLOCMEM(945, mpMaterialTable->field_0x10); + } else { + mpMaterialTable->field_0x10 = NULL; + } + if (i_flags & 0x200000) { + for (u16 i = 0; i < mpMaterialTable->mUniqueMatNum; i++) { + factory.create(&mpMaterialTable->field_0x10[i], i, i_flags); + mpMaterialTable->field_0x10[i].mDiffFlag = (uintptr_t)&mpMaterialTable->field_0x10[i] >> 4; + } + } + for (u16 i = 0; i < mpMaterialTable->mMaterialNum; i++) { + mpMaterialTable->mMaterialNodePointer[i] = factory.create(NULL, i, i_flags); + } + if (i_flags & 0x200000) { + for (u16 i = 0; i < mpMaterialTable->mMaterialNum; i++) { + mpMaterialTable->mMaterialNodePointer[i]->mDiffFlag = + (uintptr_t)&mpMaterialTable->field_0x10[factory.getMaterialID(i)] >> 4; + mpMaterialTable->mMaterialNodePointer[i]->mpOrigMaterial = + &mpMaterialTable->field_0x10[factory.getMaterialID(i)]; + } + } else { + for (u16 i = 0; i < mpMaterialTable->mMaterialNum; i++) { + mpMaterialTable->mMaterialNodePointer[i]->mDiffFlag = 0xc0000000; + } + } +} + +void J3DModelLoader::readShape(J3DShapeBlock const* i_block, u32 i_flags) { + J3D_ASSERT_NULLPTR(1009, i_block); + mpShapeBlock = i_block; + J3DShapeTable* shape_table = mpModelData->getShapeTable(); + J3DShapeFactory factory(*i_block); + shape_table->mShapeNum = i_block->mShapeNum; + if (i_block->mpNameTable != NULL) { + shape_table->mShapeName = + new JUTNameTab(JSUConvertOffsetToPtr<ResNTAB>(i_block, i_block->mpNameTable)); + J3D_ASSERT_ALLOCMEM(1026, shape_table->mShapeName); + } else { + shape_table->mShapeName = NULL; + } + shape_table->mShapeNodePointer = new J3DShape*[shape_table->mShapeNum]; + J3D_ASSERT_ALLOCMEM(1034, shape_table->mShapeNodePointer); + factory.allocVcdVatCmdBuffer(shape_table->mShapeNum); + J3DModelHierarchy const* hierarchy_entry = mpModelData->getHierarchy(); + GXVtxDescList* vtx_desc_list = NULL; + for (; hierarchy_entry->mType != 0; hierarchy_entry++) { + if (hierarchy_entry->mType == 0x12) { + shape_table->mShapeNodePointer[hierarchy_entry->mValue] = + factory.create(hierarchy_entry->mValue, i_flags, vtx_desc_list); + vtx_desc_list = factory.getVtxDescList(hierarchy_entry->mValue); + } + } +} + +void J3DModelLoader::readTexture(J3DTextureBlock const* i_block) { + J3D_ASSERT_NULLPTR(1067, i_block); + u16 texture_num = i_block->mTextureNum; + ResTIMG* texture_res = JSUConvertOffsetToPtr<ResTIMG>(i_block, i_block->mpTextureRes); + if (i_block->mpNameTable != NULL) { + mpMaterialTable->mTextureName = + new JUTNameTab(JSUConvertOffsetToPtr<ResNTAB>(i_block, i_block->mpNameTable)); + J3D_ASSERT_ALLOCMEM(1077, mpMaterialTable->mTextureName); + } else { + mpMaterialTable->mTextureName = NULL; + } + mpMaterialTable->mTexture = new J3DTexture(texture_num, texture_res); + J3D_ASSERT_ALLOCMEM(1084, mpMaterialTable->mTexture); +} + +void J3DModelLoader_v26::readMaterialTable(J3DMaterialBlock const* i_block, u32 i_flags) { + J3D_ASSERT_NULLPTR(1101, i_block); + J3DMaterialFactory factory(*i_block); + mpMaterialTable->mMaterialNum = i_block->mMaterialNum; + if (i_block->mpNameTable != NULL) { + mpMaterialTable->mMaterialName = + new JUTNameTab(JSUConvertOffsetToPtr<ResNTAB>(i_block, i_block->mpNameTable)); + J3D_ASSERT_ALLOCMEM(1114, mpMaterialTable->mMaterialName); + } else { + mpMaterialTable->mMaterialName = NULL; + } + mpMaterialTable->mMaterialNodePointer = new J3DMaterial*[mpMaterialTable->mMaterialNum]; + J3D_ASSERT_ALLOCMEM(1121, mpMaterialTable->mMaterialNodePointer); + for (u16 i = 0; i < mpMaterialTable->mMaterialNum; i++) { + mpMaterialTable->mMaterialNodePointer[i] = + factory.create(NULL, J3DMaterialFactory::MATERIAL_TYPE_NORMAL, i, i_flags); + } + for (u16 i = 0; i < mpMaterialTable->mMaterialNum; i++) { + mpMaterialTable->mMaterialNodePointer[i]->mDiffFlag = + (uintptr_t)mpMaterialTable->mMaterialNodePointer + factory.getMaterialID(i); + } +} + +void J3DModelLoader_v21::readMaterialTable_v21(J3DMaterialBlock_v21 const* i_block, u32 i_flags) { + J3D_ASSERT_NULLPTR(1152, i_block); + J3DMaterialFactory_v21 factory(*i_block); + mpMaterialTable->mMaterialNum = i_block->mMaterialNum; + if (i_block->mpNameTable != NULL) { + mpMaterialTable->mMaterialName = + new JUTNameTab(JSUConvertOffsetToPtr<ResNTAB>(i_block, i_block->mpNameTable)); + J3D_ASSERT_ALLOCMEM(1165, mpMaterialTable->mMaterialName); + } else { + mpMaterialTable->mMaterialName = NULL; + } + mpMaterialTable->mMaterialNodePointer = new J3DMaterial*[mpMaterialTable->mMaterialNum]; + J3D_ASSERT_ALLOCMEM(1172, mpMaterialTable->mMaterialNodePointer); + for (u16 i = 0; i < mpMaterialTable->mMaterialNum; i++) { + mpMaterialTable->mMaterialNodePointer[i] = + factory.create(NULL, i, i_flags); + } + for (u16 i = 0; i < mpMaterialTable->mMaterialNum; i++) { + mpMaterialTable->mMaterialNodePointer[i]->mDiffFlag = + ((uintptr_t)mpMaterialTable->mMaterialNodePointer >> 4) + factory.getMaterialID(i); + } +} + +void J3DModelLoader::readTextureTable(J3DTextureBlock const* i_block) { + J3D_ASSERT_NULLPTR(1200, i_block); + u16 texture_num = i_block->mTextureNum; + ResTIMG* texture_res = JSUConvertOffsetToPtr<ResTIMG>(i_block, i_block->mpTextureRes); + if (i_block->mpNameTable != NULL) { + mpMaterialTable->mTextureName = + new JUTNameTab(JSUConvertOffsetToPtr<ResNTAB>(i_block, i_block->mpNameTable)); + J3D_ASSERT_ALLOCMEM(1211, mpMaterialTable->mTextureName); + } else { + mpMaterialTable->mTextureName = NULL; + } + mpMaterialTable->mTexture = new J3DTexture(texture_num, texture_res); + J3D_ASSERT_ALLOCMEM(1218, mpMaterialTable->mTexture); +} + +void J3DModelLoader::readPatchedMaterial(J3DMaterialBlock const* i_block, u32 i_flags) { + J3D_ASSERT_NULLPTR(1234, i_block); + J3DMaterialFactory factory(*i_block); + mpMaterialTable->mMaterialNum = i_block->mMaterialNum; + mpMaterialTable->mUniqueMatNum = factory.countUniqueMaterials(); + if (i_block->mpNameTable != NULL) { + mpMaterialTable->mMaterialName = + new JUTNameTab(JSUConvertOffsetToPtr<ResNTAB>(i_block, i_block->mpNameTable)); + J3D_ASSERT_ALLOCMEM(1251, mpMaterialTable->mMaterialName); + } else { + mpMaterialTable->mMaterialName = NULL; + } + mpMaterialTable->mMaterialNodePointer = new J3DMaterial*[mpMaterialTable->mMaterialNum]; + J3D_ASSERT_ALLOCMEM(1260, mpMaterialTable->mMaterialNodePointer); + mpMaterialTable->field_0x10 = NULL; + for (u16 i = 0; i < mpMaterialTable->mMaterialNum; i++) { + mpMaterialTable->mMaterialNodePointer[i] = + factory.create(NULL, J3DMaterialFactory::MATERIAL_TYPE_PATCHED, i, i_flags); + mpMaterialTable->mMaterialNodePointer[i]->mDiffFlag = + ((uintptr_t)mpMaterialTable->mMaterialNodePointer >> 4) + factory.getMaterialID(i); + } +} + +void J3DModelLoader::readMaterialDL(J3DMaterialDLBlock const* i_block, u32 i_flags) { + J3D_ASSERT_NULLPTR(1290, i_block); + J3DMaterialFactory factory(*i_block); + s32 flags; + if (mpMaterialTable->mMaterialNum == 0) { + mpMaterialTable->field_0x1c = 1; + mpMaterialTable->mMaterialNum = i_block->mMaterialNum; + mpMaterialTable->mUniqueMatNum = i_block->mMaterialNum; + if (i_block->mpNameTable != NULL) { + mpMaterialTable->mMaterialName = + new JUTNameTab(JSUConvertOffsetToPtr<ResNTAB>(i_block, i_block->mpNameTable)); + J3D_ASSERT_ALLOCMEM(1312, mpMaterialTable->mMaterialName); + } else { + mpMaterialTable->mMaterialName = NULL; + } + mpMaterialTable->mMaterialNodePointer = new J3DMaterial*[mpMaterialTable->mMaterialNum]; + J3D_ASSERT_ALLOCMEM(1320, mpMaterialTable->mMaterialNodePointer); + mpMaterialTable->field_0x10 = NULL; + for (u16 i = 0; i < mpMaterialTable->mMaterialNum; i++) { + flags = i_flags; + mpMaterialTable->mMaterialNodePointer[i] = + factory.create(NULL, J3DMaterialFactory::MATERIAL_TYPE_LOCKED, i, flags); + } + for (u16 i = 0; i < mpMaterialTable->mMaterialNum; i++) { + mpMaterialTable->mMaterialNodePointer[i]->mDiffFlag = 0xc0000000; + } + } else { + for (u16 i = 0; i < mpMaterialTable->mMaterialNum; i++) { + flags = i_flags; + mpMaterialTable->mMaterialNodePointer[i] = + factory.create(mpMaterialTable->mMaterialNodePointer[i], + J3DMaterialFactory::MATERIAL_TYPE_LOCKED, i, flags); + } + } +} + +void J3DModelLoader::modifyMaterial(u32 i_flags) { + if (i_flags & 0x2000) { + J3DMaterialFactory factory(*mpMaterialBlock); + for (u16 i = 0; i < mpMaterialTable->mMaterialNum; i++) { + factory.modifyPatchedCurrentMtx(mpMaterialTable->mMaterialNodePointer[i], i); + } + } +} |
