From 6cbe5c545761bb31cc60d99bda2f68d0b94f7277 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 19 Apr 2024 21:42:52 -0700 Subject: [PATCH] J3DCluster work --- include/JSystem/J3DGraphAnimator/J3DCluster.h | 5 +- src/JSystem/J3DGraphAnimator/J3DCluster.cpp | 175 +++++++++++++++++- src/JSystem/JParticle/JPADrawVisitor.cpp | 28 +++ 3 files changed, 198 insertions(+), 10 deletions(-) diff --git a/include/JSystem/J3DGraphAnimator/J3DCluster.h b/include/JSystem/J3DGraphAnimator/J3DCluster.h index 40afc1657..f199d4859 100644 --- a/include/JSystem/J3DGraphAnimator/J3DCluster.h +++ b/include/JSystem/J3DGraphAnimator/J3DCluster.h @@ -50,10 +50,7 @@ public: field_0x8 = other.field_0x8; } -private: - friend class J3DClusterLoader; - friend class J3DClusterLoader_v15; - +public: /* 0x00 */ u16 mPosNum; /* 0x02 */ u16 mNrmNum; /* 0x04 */ void* field_0x4; diff --git a/src/JSystem/J3DGraphAnimator/J3DCluster.cpp b/src/JSystem/J3DGraphAnimator/J3DCluster.cpp index 18bfca040..d0e7ad398 100644 --- a/src/JSystem/J3DGraphAnimator/J3DCluster.cpp +++ b/src/JSystem/J3DGraphAnimator/J3DCluster.cpp @@ -7,7 +7,8 @@ #include "JSystem/J3DGraphAnimator/J3DModel.h" #include "JSystem/J3DGraphAnimator/J3DSkinDeform.h" #include "JSystem/J3DGraphAnimator/J3DAnimation.h" -#include "dolphin/os/OSCache.h" +#include "JSystem/JKernel/JKRHeap.h" +#include "dolphin/os/OS.h" /* 802F37C4-802F37E4 .text clear__13J3DDeformDataFv */ void J3DDeformData::clear() { @@ -54,7 +55,6 @@ void J3DDeformer::clear() { /* 802F3920-802F3A08 .text deform__11J3DDeformerFP15J3DVertexBufferUs */ void J3DDeformer::deform(J3DVertexBuffer* vtx, u16 idx) { - /* Nonmatching */ u16 keyIdx = 0; if (mAnmCluster) { for (u16 i = 0; i < idx; i++) @@ -70,6 +70,31 @@ void J3DDeformer::deform(J3DVertexBuffer* vtx, u16 idx) { /* 802F3A08-802F3FA8 .text deform__11J3DDeformerFP15J3DVertexBufferUsPf */ void J3DDeformer::deform(J3DVertexBuffer* vtx, u16 idx, f32* weightList) { /* Nonmatching */ + if (!(mFlags & 2) || vtx->getVertexData()->getVtxPosType() != GX_F32) + return; + + J3DCluster* cluster = mDeformData->getClusterPointer(idx); + u16 posNum = cluster->mPosNum; + u16 keyNum = cluster->mKeyNum; + + u16 keyStart = 0; + for (u16 i = 0; i < idx; i++) + keyStart += mDeformData->getClusterPointer(idx)->mKeyNum + 1; + + J3DClusterKey* key = mDeformData->getClusterKeyPointer(keyStart); + normalizeWeight(keyNum, weightList); + + Vec* vtxPosArr = (Vec*)vtx->getVtxPosArrayPointer(0); + f32* vtxPosDeform = mDeformData->getVtxPos(); + u16* cluster_0x18 = cluster->field_0x18; + + for (u16 i = 0; i < posNum; i++) { + vtxPosArr[i].x = 0.0f; + vtxPosArr[i].y = 0.0f; + vtxPosArr[i].z = 0.0f; + } + + // TODO: the rest of the owl } /* 802F3FA8-802F4064 .text normalize__11J3DDeformerFPf */ @@ -100,8 +125,117 @@ J3DSkinDeform::J3DSkinDeform() { } /* 802F40F0-802F44E8 .text initMtxIndexArray__13J3DSkinDeformFP12J3DModelData */ -int J3DSkinDeform::initMtxIndexArray(J3DModelData*) { +int J3DSkinDeform::initMtxIndexArray(J3DModelData* modelData) { /* Nonmatching */ + + if (mPosData != NULL && mNrmData != NULL) + return J3DErrType_Success; + + mPosData = new u16[modelData->getVtxNum()]; + if (mPosData == NULL) + return J3DErrType_OutOfMemory; + + for (u32 i = 0; i < modelData->getVtxNum(); i++) + mPosData[i] = 0xFFFF; + + if (modelData->getNrmNum() != 0) { + mNrmData = new u16[modelData->getNrmNum()]; + if (mNrmData == NULL) + return J3DErrType_OutOfMemory; + + for (u32 i = 0; i < modelData->getNrmNum(); i++) + mNrmData[i] = 0; + } else { + mNrmData = NULL; + } + + mNrmMtx = new(0x20) Mtx33[modelData->getDrawMtxNum()]; + if (mNrmMtx == NULL) + return J3DErrType_OutOfMemory; + + for (u16 i = 0; i < modelData->getShapeNum(); i++) { + int size[4] = { 0, 1, 1, 2 }; + + int posOffs = -1; + int nrmOffs = -1; + int pnmtxIdxOffs = -1; + int curOffs = 0; + for (GXVtxDescList* desc = modelData->getShapeNodePointer(i)->getVtxDesc(); desc->attr != GX_VA_NULL; desc++) { + switch (desc->attr) { + case GX_VA_PNMTXIDX: + pnmtxIdxOffs = curOffs; + break; + case GX_VA_POS: + posOffs = curOffs; + if (desc->type != GX_INDEX16) { + OSReport(" Invlid Data : CPU Pipeline process GX_INDEX16 Data Only\n"); + } + break; + case GX_VA_NRM: + nrmOffs = curOffs; + if (desc->type != GX_INDEX16) { + OSReport(" Invlid Data : CPU Pipeline process GX_INDEX16 Data Only\n"); + } + break; + case GX_VA_TEX0: + if (desc->type != GX_INDEX16) { + OSReport(" Invlid Data : CPU Pipeline process GX_INDEX16 Data Only\n"); + } + break; + } + + curOffs += size[desc->type]; + } + + for (u32 j = 0; j < modelData->getShapeNodePointer(i)->getMtxGroupNum(); j++) { + J3DShapeMtx* shapeMtx = modelData->getShapeNodePointer(i)->getShapeMtx(j); + J3DShapeDraw* shapeDraw = modelData->getShapeNodePointer(i)->getShapeDraw(j); + + u8* displayListStart = shapeDraw->getDisplayList(); + for (u8* dl = displayListStart; (dl - displayListStart) < shapeDraw->getDisplayListSize(); ) { + u8 cmd = dl[0]; + if (cmd != GX_TRIANGLEFAN && cmd != GX_TRIANGLESTRIP) + break; + + u16 vtxCount = *(u16*)(&dl[1]); + + u32 useMtxIdxBuf[10]; + for (int k = 0; k < vtxCount; vtxCount++) { + int vtxOffs = k * curOffs + 3; + int pnmtxIdx = dl[vtxOffs + pnmtxIdx] / 3; + int posIdx = dl[vtxOffs + posIdx]; + int nrmIdx = dl[vtxOffs + nrmIdx]; + + u32 useMtxIdx = shapeMtx->getUseMtxIndex(pnmtxIdx); + if (useMtxIdx == 0xFFFF) { + useMtxIdx = useMtxIdxBuf[pnmtxIdx]; + } else if (pnmtxIdx != -1) { + useMtxIdxBuf[pnmtxIdx] = useMtxIdx; + } + + mPosData[posIdx] = useMtxIdx; + if (nrmOffs != -1) + mNrmData[nrmIdx] = useMtxIdx; + } + + dl += vtxCount * curOffs + 3; + } + + if (nrmOffs == -1) { + modelData->getShapeNodePointer(i)->onFlag(J3DShpFlag_EnableLod); + modelData->getShapeNodePointer(i)->offFlag(J3DShpFlag_SkinNrmCpu); + } + } + } + + for (u32 i = 0; i < modelData->getVtxNum(); i++) { + if (mPosData[i] == 0xFFFF) { + field_0x14 = 0; + mPosData[i] = 0; + } + } + + return J3DErrType_Success; } /* 802F44E8-802F4734 .text changeFastSkinDL__13J3DSkinDeformFP12J3DModelData */ @@ -110,8 +244,24 @@ void J3DSkinDeform::changeFastSkinDL(J3DModelData*) { } /* 802F4734-802F4850 .text calcNrmMtx__13J3DSkinDeformFP8J3DModel */ -void J3DSkinDeform::calcNrmMtx(J3DModel*) { +void J3DSkinDeform::calcNrmMtx(J3DModel* model) { /* Nonmatching */ + J3DModelData* modelData = model->getModelData(); + for (u16 i = 0; i < modelData->getDrawMtxNum(); i++) { + if (modelData->getDrawMtxFlag(i) == 0) { + if (model->getScaleFlag(modelData->getDrawMtxIndex(i)) == 1) { + J3DPSMtx33CopyFrom34(model->getAnmMtx(i), mNrmMtx[i]); + } else { + J3DPSCalcInverseTranspose(model->getAnmMtx(i), mNrmMtx[i]); + } + } else { + if (model->getEnvScaleFlag(modelData->getDrawMtxIndex(i)) == 1) { + J3DPSMtx33CopyFrom34(model->getWeightAnmMtx(i), mNrmMtx[i]); + } else { + J3DPSCalcInverseTranspose(model->getWeightAnmMtx(i), mNrmMtx[i]); + } + } + } } /* 802F4850-802F4974 .text deformVtxPos_F32__13J3DSkinDeformCFP8J3DModel */ @@ -135,6 +285,19 @@ void J3DSkinDeform::deformVtxNrm_S16(J3DModel*) const { } /* 802F4CD8-802F4D78 .text deform__13J3DSkinDeformFP8J3DModel */ -void J3DSkinDeform::deform(J3DModel*) { - /* Nonmatching */ +void J3DSkinDeform::deform(J3DModel* model) { + if (model->checkFlag(J3DMdlFlag_SkinPosCpu)) { + if (model->getModelData()->getVertexData().getVtxPosType() == GX_F32) + deformVtxPos_F32(model); + else + deformVtxPos_S16(model); + } + + if (model->checkFlag(J3DMdlFlag_SkinNrmCpu)) { + calcNrmMtx(model); + if (model->getModelData()->getVertexData().getVtxNrmType() == GX_F32) + deformVtxNrm_F32(model); + else + deformVtxNrm_S16(model); + } } diff --git a/src/JSystem/JParticle/JPADrawVisitor.cpp b/src/JSystem/JParticle/JPADrawVisitor.cpp index b5a8b9548..cbde824f6 100644 --- a/src/JSystem/JParticle/JPADrawVisitor.cpp +++ b/src/JSystem/JParticle/JPADrawVisitor.cpp @@ -308,6 +308,34 @@ void JPADrawExecBillBoard::exec(const JPADrawContext* pDC, JPABaseParticle* ptcl /* 80260D24-80260F2C .text exec__23JPADrawExecRotBillBoardFPC14JPADrawContextP15JPABaseParticle */ void JPADrawExecRotBillBoard::exec(const JPADrawContext* pDC, JPABaseParticle* ptcl) { /* Nonmatching */ + if (ptcl->isInvisibleParticle()) + return; + + f32 sin = JMASSin(ptcl->mRotateAngle); + f32 cos = JMASCos(ptcl->mRotateAngle); + + f32 scaleX = ptcl->mScaleX; + f32 scaleY = ptcl->mScaleY; + + f32 x0 = -ptcl->mScaleX * (JPADrawContext::pcb->mGlobalScaleX + JPADrawContext::pcb->mPivotX); + f32 y0 = +ptcl->mScaleY * (JPADrawContext::pcb->mGlobalScaleY + JPADrawContext::pcb->mPivotY); + f32 x1 = +ptcl->mScaleX * (JPADrawContext::pcb->mGlobalScaleX - JPADrawContext::pcb->mPivotX); + f32 y1 = -ptcl->mScaleY * (JPADrawContext::pcb->mGlobalScaleY - JPADrawContext::pcb->mPivotY); + + JGeometry::TVec3 pt; + pt.set(ptcl->mPosition); + MTXMultVec(JPADrawContext::pcb->mDrawMtxPtr, pt, &pt); + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition3f32((x0 * cos - y0 * sin) + pt.x, x0 + y0 + pt.y, pt.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[0].x, JPADrawContext::pcb->mTexCoordPt[0].y); + GXPosition3f32((x1 * cos - y0 * sin) + pt.x, y0 + x1 + pt.y, pt.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[1].x, JPADrawContext::pcb->mTexCoordPt[1].y); + GXPosition3f32((x1 * cos - y1 * sin) + pt.x, y1 + x1 + pt.y, pt.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[2].x, JPADrawContext::pcb->mTexCoordPt[2].y); + GXPosition3f32((x0 * cos - y1 * sin) + pt.x, y1 + x0 + pt.y, pt.z); + GXTexCoord2f32(JPADrawContext::pcb->mTexCoordPt[3].x, JPADrawContext::pcb->mTexCoordPt[3].y); + GXEnd(); } /* 80260F2C-8026110C .text exec__21JPADrawExecYBillBoardFPC14JPADrawContextP15JPABaseParticle */