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/J3DGraphAnimator/J3DModel.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/J3DGraphAnimator/J3DModel.cpp')
| -rw-r--r-- | libs/JSystem/src/J3DGraphAnimator/J3DModel.cpp | 555 |
1 files changed, 555 insertions, 0 deletions
diff --git a/libs/JSystem/src/J3DGraphAnimator/J3DModel.cpp b/libs/JSystem/src/J3DGraphAnimator/J3DModel.cpp new file mode 100644 index 0000000000..f423f1db2f --- /dev/null +++ b/libs/JSystem/src/J3DGraphAnimator/J3DModel.cpp @@ -0,0 +1,555 @@ +#include "JSystem/JSystem.h" // IWYU pragma: keep + +#include "JSystem/J3DGraphAnimator/J3DModel.h" +#include "JSystem/J3DGraphAnimator/J3DJoint.h" +#include "JSystem/J3DGraphAnimator/J3DMaterialAnm.h" +#include "JSystem/J3DGraphAnimator/J3DShapeTable.h" +#include "JSystem/J3DGraphBase/J3DMaterial.h" +#include "JSystem/J3DGraphBase/J3DShapeMtx.h" +#include "JSystem/J3DGraphBase/J3DSys.h" + +#define J3D_ASSERTMSG(LINE, COND, MSG) JUT_ASSERT_MSG(LINE, (COND) != 0, MSG) +#define J3D_WARN1(LINE, MSG, ARG1) JUT_WARN(LINE, MSG, ARG1) + +void J3DModel::initialize() { + mModelData = NULL; + mFlags = 0; + mDiffFlag = 0; + mCalcCallBack = NULL; + mUserArea = 0; + + mBaseScale.x = 1.0f; + mBaseScale.y = 1.0f; + mBaseScale.z = 1.0f; + + MTXIdentity(mBaseTransformMtx); + MTXIdentity(mInternalView); + + mMtxBuffer = NULL; + mMatPacket = NULL; + mShapePacket = NULL; + mDeformData = NULL; + mSkinDeform = NULL; + mVtxColorCalc = NULL; + mUnkCalc1 = NULL; + mUnkCalc2 = NULL; +} + +s32 J3DModel::entryModelData(J3DModelData* pModelData, u32 mdlFlags, u32 mtxNum) { + J3D_ASSERTMSG(83, pModelData != NULL, "Error : null pointer."); + J3D_ASSERTMSG(84, mtxNum != 0, "Error : non-zero argument is specified 0."); + int ret = kJ3DError_Success; + + mModelData = pModelData; + mMtxBuffer = new J3DMtxBuffer(); + + if (mMtxBuffer == NULL) { + return kJ3DError_Alloc; + } + + ret = mMtxBuffer->create(pModelData, mtxNum); + if (ret != kJ3DError_Success) { + return ret; + } + + ret = createShapePacket(pModelData); + if (ret != kJ3DError_Success) { + return ret; + } + + ret = createMatPacket(pModelData, mdlFlags); + if (ret != kJ3DError_Success) { + return ret; + } + + mVertexBuffer.setVertexData(&pModelData->getVertexData()); + prepareShapePackets(); + + if (mdlFlags & J3DMdlFlag_Unk1) { + onFlag(J3DMdlFlag_Unk1); + } + if (mdlFlags & J3DMdlFlag_UseDefaultJ3D) { + onFlag(J3DMdlFlag_UseDefaultJ3D); + } + if (mdlFlags & J3DMdlFlag_EnableLOD) { + onFlag(J3DMdlFlag_EnableLOD); + } + if (mdlFlags & J3DMdlFlag_UseSharedDL) { + onFlag(J3DMdlFlag_UseSharedDL); + } + if (mdlFlags & J3DMdlFlag_UseSingleDL) { + onFlag(J3DMdlFlag_UseSingleDL); + } + if (mdlFlags & J3DMdlFlag_DifferedDLBuffer) { + onFlag(J3DMdlFlag_DifferedDLBuffer); + } + if (mdlFlags & J3DMdlFlag_SkinPosCpu) { + J3D_WARN1(149, "%s", "Don't forget to call J3DModel::setSkinDeform\n if you set J3DMdlFlag_SkinPosCpu."); + onFlag(J3DMdlFlag_SkinPosCpu); + } + if (mdlFlags & J3DMdlFlag_SkinNrmCpu) { + J3D_WARN1(154, "%s", "Don't forget to call J3DModel::setSkinDeform\n if you set J3DMdlFlag_SkinNrmCpu."); + onFlag(J3DMdlFlag_SkinNrmCpu); + } + + return kJ3DError_Success; +} + +s32 J3DModel::createShapePacket(J3DModelData* pModelData) { + J3D_ASSERTMSG(173, pModelData != NULL, "Error : null pointer."); + + if (pModelData->getShapeNum() != 0) { + mShapePacket = new J3DShapePacket[pModelData->getShapeNum()]; + + if (mShapePacket == NULL) { + return kJ3DError_Alloc; + } + + for (int i = 0; i < pModelData->getShapeNum(); i++) { + mShapePacket[i].setShape(pModelData->getShapeNodePointer(i)); + mShapePacket[i].setModel(this); + } + } + + return kJ3DError_Success; +} + +s32 J3DModel::createMatPacket(J3DModelData* pModelData, u32 mdlFlags) { + J3D_ASSERTMSG(207, pModelData != NULL, "Error : null pointer."); + s32 ret = 0; + + if (pModelData->getMaterialNum() != 0) { + mMatPacket = new J3DMatPacket[pModelData->getMaterialNum()]; + + if (mMatPacket == NULL) { + return kJ3DError_Alloc; + } + } + + u16 matNum = pModelData->getMaterialNum(); + for (u16 i = 0; i < matNum; i++) { + J3DMaterial* materialNode = pModelData->getMaterialNodePointer(i); + J3DMatPacket* matPacket = mMatPacket + i; + J3DShapePacket* shapePacket = mShapePacket + materialNode->getShape()->getIndex(); + + matPacket->setMaterial(materialNode); + matPacket->setInitShapePacket(shapePacket); + matPacket->addShapePacket(shapePacket); + matPacket->setTexture(pModelData->getTexture()); + matPacket->setMaterialID(materialNode->mDiffFlag); + + if (pModelData->getModelDataType() == 1) { + matPacket->lock(); + } + + if (mdlFlags & J3DMdlFlag_DifferedDLBuffer) { + J3DDisplayListObj* dlobj = materialNode->getSharedDisplayListObj(); + J3D_ASSERTMSG(253, dlobj != NULL, "Error : User need to call J3DModelData::newSharedDisplayList() before using DifferedDLBuffer."); + matPacket->setDisplayListObj(dlobj); + } else { + if (pModelData->getModelDataType() == 1) { + if (mdlFlags & J3DMdlFlag_UseSingleDL) { + J3DDisplayListObj* dlobj = materialNode->getSharedDisplayListObj(); + matPacket->setDisplayListObj(dlobj); + } else { + J3DDisplayListObj* dlobj = materialNode->getSharedDisplayListObj(); + ret = dlobj->single_To_Double(); + if (ret != kJ3DError_Success) + return ret; + + matPacket->setDisplayListObj(dlobj); + } + } else if (mdlFlags & J3DMdlFlag_UseSharedDL) { + if (mdlFlags & J3DMdlFlag_UseSingleDL) { + ret = materialNode->newSingleSharedDisplayList(materialNode->countDLSize()); + if (ret != kJ3DError_Success) + return ret; + + J3DDisplayListObj* dlobj = materialNode->getSharedDisplayListObj(); + matPacket->setDisplayListObj(dlobj); + } else { + ret = materialNode->newSharedDisplayList(materialNode->countDLSize()); + if (ret != kJ3DError_Success) + return ret; + + J3DDisplayListObj* dlobj = materialNode->getSharedDisplayListObj(); + ret = dlobj->single_To_Double(); + if (ret != kJ3DError_Success) + return ret; + + matPacket->setDisplayListObj(dlobj); + } + } else { + if (mdlFlags & J3DMdlFlag_UseSingleDL) { + ret = matPacket->newSingleDisplayList(materialNode->countDLSize()); + if (ret != kJ3DError_Success) + return ret; + } else { + ret = matPacket->newDisplayList(materialNode->countDLSize()); + if (ret != kJ3DError_Success) + return ret; + } + } + } + } + + return kJ3DError_Success; +} + +s32 J3DModel::newDifferedDisplayList(u32 diffFlags) { + mDiffFlag = diffFlags; + + u16 shapeNum = getModelData()->getShapeNum(); + for (u16 i = 0; i < shapeNum; i++) { + s32 ret = getShapePacket(i)->newDifferedDisplayList(diffFlags); + if (ret != kJ3DError_Success) + return ret; + } + + return kJ3DError_Success; +} + +void J3DModel::ptrToIndex() { + j3dSys.setModel(this); + j3dSys.setTexture(mModelData->getTexture()); + + u16 matNum = mModelData->getMaterialNum(); + for (u16 i = 0; i < matNum; i++) { + J3DMatPacket* matPacket = getMatPacket(i); + + GDLObj dlobj; + GDInitGDLObj(&dlobj, matPacket->getDisplayList(0), matPacket->getDisplayListSize()); + GDSetCurrent(&dlobj); + + mModelData->getMaterialNodePointer(i)->getTevBlock()->ptrToIndex(); + + GDSetCurrent(NULL); + } +} + +void J3DModel::lock() { + int matNum = mModelData->getMaterialNum(); + for (int i = 0; i < matNum; i++) { + mMatPacket[i].lock(); + } +} + +void J3DModel::unlock() { + int matNum = mModelData->getMaterialNum(); + for (int i = 0; i < matNum; i++) { + mMatPacket[i].unlock(); + } +} + +void J3DModel::makeDL() { + j3dSys.setModel(this); + j3dSys.setTexture(mModelData->getTexture()); + + u16 matNum = mModelData->getMaterialNum(); + for (u16 i = 0; i < matNum; i++) { + j3dSys.setMatPacket(&mMatPacket[i]); + mModelData->getMaterialNodePointer(i)->makeDisplayList(); + } +} + +void J3DModel::calcMaterial() { + j3dSys.setModel(this); + + if (checkFlag(J3DMdlFlag_SkinPosCpu)) { + j3dSys.onFlag(4); + } else { + j3dSys.offFlag(4); + } + + if (checkFlag(J3DMdlFlag_SkinNrmCpu)) { + j3dSys.onFlag(8); + } else { + j3dSys.offFlag(8); + } + + mModelData->syncJ3DSysFlags(); + j3dSys.setTexture(mModelData->getTexture()); + + u16 matNum = mModelData->getMaterialNum(); + for (u16 i = 0; i < matNum; i++) { + j3dSys.setMatPacket(&mMatPacket[i]); + + J3DMaterial* material = mModelData->getMaterialNodePointer(i); + if (material->getMaterialAnm() != NULL) { + material->getMaterialAnm()->calc(material); + } + + material->calc(getAnmMtx(material->getJoint()->getJntNo())); + } +} + +void J3DModel::calcDiffTexMtx() { + j3dSys.setModel(this); + + u16 matNum = mModelData->getMaterialNum(); + for (u16 i = 0; i < matNum; i++) { + j3dSys.setMatPacket(&mMatPacket[i]); + J3DMaterial* materialNode = mModelData->getMaterialNodePointer(i); + materialNode->calcDiffTexMtx(getAnmMtx(materialNode->getJoint()->getJntNo())); + } + + u16 shapeNum = getModelData()->getShapeNum(); + for (u16 i = 0; i < shapeNum; i++) { + J3DShapePacket* shapePacket = getShapePacket(i); + J3DTexGenBlock* texGenBlock = mModelData->getShapeNodePointer(i)->getMaterial()->getTexGenBlock(); + + for (u16 j = 0; (int)j < 8; j++) { + J3DTexMtx* texMtxNode = texGenBlock->getTexMtx(j); + J3DTexMtxObj* texMtxObj = shapePacket->getTexMtxObj(); + if (texMtxNode != NULL && texMtxObj != NULL) { + texMtxObj->setMtx(j, texMtxNode->getMtx()); + } + } + } +} + +void J3DModel::diff() { + u16 matNum = mModelData->getMaterialNum(); + for (u16 i = 0; i < matNum; i++) { + j3dSys.setMatPacket(&mMatPacket[i]); + mModelData->getMaterialNodePointer(i)->diff(mDiffFlag); + } +} + +s32 J3DModel::setDeformData(J3DDeformData* p_deformData, u32 param_1) { + mDeformData = p_deformData; + + if (p_deformData == NULL) { + return kJ3DError_Success; + } + + s32 ret = mVertexBuffer.copyLocalVtxArray(param_1); + if (ret) { + return ret; + } + + if (param_1 & 4) { + p_deformData->offAllFlag(1); + } + + return kJ3DError_Success; +} + +s32 J3DModel::setSkinDeform(J3DSkinDeform* p_skinDeform, u32 flags) { + mSkinDeform = p_skinDeform; + + if (p_skinDeform == NULL) { + offFlag(J3DMdlFlag_SkinPosCpu); + offFlag(J3DMdlFlag_SkinNrmCpu); + return 5; + } + + mSkinDeform->initMtxIndexArray(mModelData); + + if (mModelData->checkFlag(0x100)) { + mSkinDeform->changeFastSkinDL(mModelData); + flags &= ~2; + flags &= ~4; + mSkinDeform->transformVtxPosNrm(mModelData); + mSkinDeform->initSkinInfo(mModelData); + } + + s32 ret = kJ3DError_Success; + if ((~flags & 2)) { + ret = mVertexBuffer.allocTransformedVtxPosArray(); + if (ret != kJ3DError_Success) { + offFlag(J3DMdlFlag_SkinPosCpu); + return ret; + } + onFlag(J3DMdlFlag_SkinPosCpu); + } else { + offFlag(J3DMdlFlag_SkinPosCpu); + } + + if ((~flags & 4)) { + ret = mVertexBuffer.allocTransformedVtxNrmArray(); + if (ret != kJ3DError_Success) { + offFlag(J3DMdlFlag_SkinNrmCpu); + return ret; + } + onFlag(J3DMdlFlag_SkinNrmCpu); + } else { + offFlag(J3DMdlFlag_SkinNrmCpu); + } + + return ret; +} + +void J3DModel::calcAnmMtx() { + j3dSys.setModel(this); + + if (checkFlag(J3DMdlFlag_UseDefaultJ3D)) { + getModelData()->getJointTree().calc(mMtxBuffer, j3dDefaultScale, j3dDefaultMtx); + } else { + getModelData()->getJointTree().calc(mMtxBuffer, mBaseScale, mBaseTransformMtx); + } +} + +void J3DModel::calcWeightEnvelopeMtx() { + if (getModelData()->getWEvlpMtxNum() != 0 && !checkFlag(J3DMdlFlag_EnableLOD)) { + if (!getModelData()->checkFlag(0x100)) { + mMtxBuffer->calcWeightEnvelopeMtx(); + } + } +} + +void J3DModel::update() { + calc(); + entry(); +} + +void J3DModel::calc() { + j3dSys.setModel(this); + + if (checkFlag(J3DMdlFlag_SkinPosCpu)) { + j3dSys.onFlag(J3DSysFlag_SkinPosCpu); + } else { + j3dSys.offFlag(J3DSysFlag_SkinPosCpu); + } + + if (checkFlag(J3DMdlFlag_SkinNrmCpu)) { + j3dSys.onFlag(J3DSysFlag_SkinNrmCpu); + } else { + j3dSys.offFlag(J3DSysFlag_SkinNrmCpu); + } + + mModelData->syncJ3DSysFlags(); + mVertexBuffer.frameInit(); + + if (mUnkCalc2 != NULL) { + mUnkCalc2->calc(mModelData); + } + + if (mDeformData != NULL) { + mDeformData->deform(this); + } + + if (mVtxColorCalc != NULL) { + mVtxColorCalc->calc(this); + } + + if (mUnkCalc1 != NULL) { + mUnkCalc1->calc(this); + } + + calcAnmMtx(); + calcWeightEnvelopeMtx(); + + if (mSkinDeform != NULL) { + mSkinDeform->deform(this); + } + + if (mCalcCallBack != NULL) { + mCalcCallBack(this, 0); + } +} + +void J3DModel::entry() { + j3dSys.setModel(this); + + if (checkFlag(J3DMdlFlag_SkinPosCpu)) { + j3dSys.onFlag(J3DSysFlag_SkinPosCpu); + } else { + j3dSys.offFlag(J3DSysFlag_SkinPosCpu); + } + + if (checkFlag(J3DMdlFlag_SkinNrmCpu)) { + j3dSys.onFlag(J3DSysFlag_SkinNrmCpu); + } else { + j3dSys.offFlag(J3DSysFlag_SkinNrmCpu); + } + + mModelData->syncJ3DSysFlags(); + j3dSys.setTexture(mModelData->getTexture()); + + for (u16 i = 0; i < mModelData->getJointNum(); i++) { + J3DJoint* joint = mModelData->getJointNodePointer(i); + if (joint->getMesh() != NULL) { + joint->entryIn(); + } + } +} + +void J3DModel::viewCalc() { + mMtxBuffer->swapDrawMtx(); + mMtxBuffer->swapNrmMtx(); + + if (getModelData()->checkFlag(0x10)) { + if (getMtxCalcMode() == 2) { + J3DCalcViewBaseMtx(j3dSys.getViewMtx(), mBaseScale, mBaseTransformMtx, + (MtxP)&mInternalView); + } + } else if (isCpuSkinningOn()) { + if (getMtxCalcMode() == 2) { + J3DCalcViewBaseMtx(j3dSys.getViewMtx(), mBaseScale, mBaseTransformMtx, + (MtxP)&mInternalView); + } + } else if (checkFlag(J3DMdlFlag_SkinPosCpu)) { + mMtxBuffer->calcDrawMtx(getMtxCalcMode(), mBaseScale, mBaseTransformMtx); + calcNrmMtx(); + calcBumpMtx(); + DCStoreRangeNoSync(getDrawMtxPtr(), mModelData->getDrawMtxNum() * sizeof(Mtx)); + DCStoreRange(getNrmMtxPtr(), mModelData->getDrawMtxNum() * sizeof(Mtx33)); + } else if (checkFlag(J3DMdlFlag_SkinNrmCpu)) { + mMtxBuffer->calcDrawMtx(getMtxCalcMode(), mBaseScale, mBaseTransformMtx); + calcBBoardMtx(); + DCStoreRange(getDrawMtxPtr(), mModelData->getDrawMtxNum() * sizeof(Mtx)); + } else { + mMtxBuffer->calcDrawMtx(getMtxCalcMode(), mBaseScale, mBaseTransformMtx); + calcNrmMtx(); + calcBBoardMtx(); + calcBumpMtx(); + DCStoreRangeNoSync(getDrawMtxPtr(), mModelData->getDrawMtxNum() * sizeof(Mtx)); + DCStoreRange(getNrmMtxPtr(), mModelData->getDrawMtxNum() * sizeof(Mtx33)); + } + + prepareShapePackets(); +} + +void J3DModel::calcNrmMtx() { + mMtxBuffer->calcNrmMtx(); +} + +void J3DModel::calcBumpMtx() { + if (getModelData()->checkBumpFlag()) { + u32 bumpMtxIdx = 0; + u16 materialNum = getModelData()->getMaterialNum(); + + for (u16 i = 0; i < materialNum; i++) { + J3DMaterial* material = getModelData()->getMaterialNodePointer(i); + if (material->getNBTScale()->mbHasScale == TRUE) { + material->getShape()->calcNBTScale(*material->getNBTScale()->getScale(), + getNrmMtxPtr(), getBumpMtxPtr(bumpMtxIdx)); + DCStoreRange(getBumpMtxPtr(bumpMtxIdx), mModelData->getDrawMtxNum() * sizeof(Mtx33)); + bumpMtxIdx++; + } + } + } +} + +void J3DModel::calcBBoardMtx() { + if (getModelData()->checkBBoardFlag()) { + mMtxBuffer->calcBBoardMtx(); + } +} + +void J3DModel::prepareShapePackets() { + u16 shapeNum = mModelData->getShapeNum(); + + for (u16 i = 0; i < shapeNum; i++) { + J3DShape* shapeNode = mModelData->getShapeNodePointer(i); + J3DShapePacket* shapePacket = &mShapePacket[i]; + shapePacket->setMtxBuffer(mMtxBuffer); + + if (getMtxCalcMode() == 2) { + shapePacket->setBaseMtxPtr(&mInternalView); + } else { + shapePacket->setBaseMtxPtr((Mtx*)j3dSys.getViewMtx()); + } + } +} |
