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
This commit is contained in:
Luke Street
2026-03-01 15:35:36 -07:00
committed by GitHub
parent c9a46bd65b
commit 4df8ccc871
1740 changed files with 583 additions and 825 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,269 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/J3DGraphAnimator/J3DCluster.h"
#include "JSystem/J3DGraphAnimator/J3DAnimation.h"
#include "JSystem/J3DGraphAnimator/J3DModel.h"
#include "JSystem/JMath/JMATrigonometric.h"
#include <base/PPCArch.h>
J3DDeformData::J3DDeformData() {
mClusterNum = 0;
mClusterKeyNum = 0;
mClusterVertexNum = 0;
mClusterPointer = NULL;
mClusterKeyPointer = NULL;
mClusterVertex = NULL;
mVtxPosNum = 0;
mVtxNrmNum = 0;
mVtxPos = NULL;
mVtxNrm = NULL;
mClusterName = NULL;
mClusterKeyName = NULL;
}
void J3DDeformData::offAllFlag(u32 i_flag) {
for (u16 i = 0; i < mClusterNum; i++) {
mClusterPointer[i].getDeformer()->offFlag(i_flag);
}
}
void J3DDeformData::deform(J3DModel* model) {
J3D_ASSERT_NULLPTR(110, model);
deform(model->getVertexBuffer());
}
void J3DDeformData::deform(J3DVertexBuffer* buffer) {
J3D_ASSERT_NULLPTR(141, buffer);
buffer->swapVtxPosArrayPointer();
buffer->swapVtxNrmArrayPointer();
for (u16 i = 0; i < mClusterNum; i++) {
mClusterPointer[i].getDeformer()->deform(buffer, i);
}
DCStoreRangeNoSync(buffer->getVtxPosArrayPointer(0),
buffer->getVertexData()->getVtxNum() * sizeof(Vec));
DCStoreRangeNoSync(buffer->getVtxNrmArrayPointer(0),
buffer->getVertexData()->getNrmNum() * sizeof(Vec));
PPCSync();
buffer->setCurrentVtxPos(buffer->getVtxPosArrayPointer(0));
buffer->setCurrentVtxNrm(buffer->getVtxNrmArrayPointer(0));
}
void J3DDeformData::setAnm(J3DAnmCluster* anm) {
for (u16 i = 0; i < mClusterNum; i++) {
mClusterPointer[i].getDeformer()->setAnmCluster(anm);
}
}
J3DDeformer::J3DDeformer(J3DDeformData* data) {
mDeformData = data;
mAnmCluster = NULL;
field_0x8 = NULL;
field_0xc = NULL;
mFlags = 3;
}
void J3DDeformer::deform(J3DVertexBuffer* buffer, u16 param_1) {
J3D_ASSERT_NULLPTR(222, buffer);
u16 var_r31 = 0;
if (mAnmCluster != NULL) {
for (u16 i = 0; i < param_1; i++) {
var_r31 += mDeformData->getClusterPointer(i)->mKeyNum;
}
u16 num = mDeformData->getClusterPointer(param_1)->mKeyNum;
for (u16 i = 0; i < num; i++) {
field_0x8[i] = mAnmCluster->getWeight(var_r31++);
}
deform(buffer, param_1, field_0x8);
}
}
void J3DDeformer::deform_VtxPosF32(J3DVertexBuffer* i_buffer, J3DCluster* i_cluster,
J3DClusterKey* i_key, f32* i_weights) {
J3DClusterKey* key;
int posNum = i_cluster->mPosNum;
int keyNum = i_cluster->mKeyNum;
f32* vtxPosArray = (f32*)i_buffer->getVtxPosArrayPointer(0);
f32* deformVtxPos = mDeformData->getVtxPos();
u16* iVar9 = i_cluster->field_0x18;
for (int i = 0; i < posNum; i++) {
int index = iVar9[i] * 3;
vtxPosArray[index] = 0.0f;
vtxPosArray[index + 1] = 0.0f;
vtxPosArray[index + 2] = 0.0f;
}
f32 local_58[2] = {1.0f, -1.0f};
for (u16 i = 0; i < posNum; i++) {
int index = i_cluster->field_0x18[i] * 3;
for (u16 j = 0; j < keyNum; j++) {
int uVar8;
int uVar7;
key = &i_key[j];
uVar8 = uVar7 = ((u16*)key->field_0x4)[i];
uVar7 &= ~0xE000;
uVar7 *= 3;
f32 deform0 = deformVtxPos[uVar7];
f32 deform1 = deformVtxPos[uVar7 + 1];
f32 deform2 = deformVtxPos[uVar7 + 2];
deform0 *= local_58[((uVar8 & 0x8000) >> 0xF)];
deform1 *= local_58[((uVar8 & 0x4000) >> 0xE)];
deform2 *= local_58[((uVar8 & 0x2000) >> 0xD)];
vtxPosArray[index] += deform0 * i_weights[j];
vtxPosArray[index + 1] += deform1 * i_weights[j];
vtxPosArray[index + 2] += deform2 * i_weights[j];
}
}
}
// NONMATCHING one missing mr
void J3DDeformer::deform_VtxNrmF32(J3DVertexBuffer* i_buffer, J3DCluster* i_cluster,
J3DClusterKey* i_key, f32* i_weights) {
f32* vtxNrmArray = (f32*)i_buffer->getVtxNrmArrayPointer(0);
f32* deformVtxNrm = mDeformData->getVtxNrm();
f32* iVar13 = field_0xc;
u16 keyNum = i_cluster->mKeyNum;
int uVar2 = i_cluster->field_0x16;
for (u16 i = 0; i < i_cluster->field_0x14; i++) {
int index = i * 3;
iVar13[index] = 0.0f;
iVar13[index + 1] = 0.0f;
iVar13[index + 2] = 0.0f;
for (u16 j = 0; j < keyNum; j++) {
J3DClusterKey* key = &i_key[j];
int uVar3 = ((u16*)key->field_0x8)[i];
int uVar4 = uVar3;
uVar3 &= ~0xE000;
uVar3 *= 3;
Vec deform0;
if (uVar4 & 0x8000) {
deform0.x = -deformVtxNrm[uVar3];
} else {
deform0.x = deformVtxNrm[uVar3];
}
if (uVar4 & 0x4000) {
deform0.y = -deformVtxNrm[uVar3 + 1];
} else {
deform0.y = deformVtxNrm[uVar3 + 1];
}
if (uVar4 & 0x2000) {
deform0.z = -deformVtxNrm[uVar3 + 2];
} else {
deform0.z = deformVtxNrm[uVar3 + 2];
}
iVar13[index] += deform0.x * i_weights[j];
iVar13[index + 1] += deform0.y * i_weights[j];
iVar13[index + 2] += deform0.z * i_weights[j];
}
normalize(&iVar13[index]);
}
for (u16 i = 0; i < uVar2; i++) {
J3DClusterVertex* clusterVtx = &i_cluster->mClusterVertex[i];
Vec vec;
vec.x = 0.0f;
vec.y = 0.0f;
vec.z = 0.0f;
f32 scale = 1.0f / clusterVtx->mNum;
for (u16 j = 0; j < clusterVtx->mNum; j++) {
int index = clusterVtx->field_0x4[j] * 3;
vec.x += scale * iVar13[index];
vec.y += scale * iVar13[index + 1];
vec.z += scale * iVar13[index + 2];
}
normalize((f32*)&vec);
for (u16 j = 0; j < clusterVtx->mNum; j++) {
u16 tmp = clusterVtx->field_0x8[j];
if (tmp == 0xffff) {
continue;
}
int index = tmp * 3;
u16 iVar4 = clusterVtx->field_0x4[j];
int index2 = iVar4 * 3;
f32 dot = vec.x * iVar13[index2] + vec.y * iVar13[index2 + 1]
+ vec.z * iVar13[index2 + 2];
f32 angle;
if (dot >= 1.0f) {
angle = 0.0f;
} else if (dot > -1.0f) {
angle = JMath::acosDegree(dot);
} else {
angle = 180.0f;
}
if (angle <= i_cluster->mMinAngle) {
vtxNrmArray[index] = vec.x;
vtxNrmArray[index + 1] = vec.y;
vtxNrmArray[index + 2] = vec.z;
} else if (angle > i_cluster->mMaxAngle) {
vtxNrmArray[index] = iVar13[iVar4 * 3];
vtxNrmArray[index + 1] = iVar13[iVar4 * 3 + 1];
vtxNrmArray[index + 2] = iVar13[iVar4 * 3 + 2];
} else {
f32 weights[2];
weights[0] = (angle - i_cluster->mMinAngle)
/ (i_cluster->mMaxAngle - i_cluster->mMinAngle);
weights[1] = 1.0f - weights[0];
vtxNrmArray[index] = weights[0] * iVar13[index2] + weights[1] * vec.x;
vtxNrmArray[index + 1] = weights[0] * iVar13[index2 + 1] + weights[1] * vec.y;
vtxNrmArray[index + 2] = weights[0] * iVar13[index2 + 2] + weights[1] * vec.z;
}
}
}
}
void J3DDeformer::deform(J3DVertexBuffer* i_buffer, u16 param_1, f32* i_weights) {
J3D_ASSERT_NULLPTR(505, i_buffer != NULL);
if (checkFlag(2)) {
JUT_ASSERT_MSG(512, i_buffer->getVertexData()->getVtxPosType() == 4, "Error : Invalid Verex Format");
if (i_buffer->getVertexData()->getVtxPosType() == 4) {
J3DCluster* cluster = mDeformData->getClusterPointer(param_1);
u16 offset = 0;
J3DClusterKey* clusterKey = NULL;
for (u16 i = 0; i < param_1; i++) {
offset += mDeformData->getClusterPointer(i)->mKeyNum + 1;
}
clusterKey = mDeformData->getClusterKeyPointer(offset);
int var_r23 = cluster->mKeyNum;
normalizeWeight(var_r23, i_weights);
deform_VtxPosF32(i_buffer, cluster, clusterKey, i_weights);
if (checkFlag(1) && cluster->mFlags != 0 && i_buffer->getVertexData()->getVtxNrmType() == 4)
{
deform_VtxNrmF32(i_buffer, cluster, clusterKey, i_weights);
}
}
}
}
static void dummy(J3DDeformData* data) {
data->getClusterNum();
}
void J3DDeformer::normalizeWeight(int i_keyNum, f32* i_weights) {
f32 totalWeight = 0.0f;
for (u16 i = 0; i < i_keyNum; i++) {
totalWeight += i_weights[i];
}
f32 scale = 1.0f / totalWeight;
for (u16 i = 0; i < i_keyNum; i++) {
i_weights[i] *= scale;
}
}
@@ -0,0 +1,243 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/J3DGraphAnimator/J3DJoint.h"
#include "JSystem/J3DGraphAnimator/J3DMaterialAnm.h"
#include "JSystem/J3DGraphAnimator/J3DModel.h"
#include "JSystem/J3DGraphBase/J3DDrawBuffer.h"
#include "JSystem/J3DGraphBase/J3DMaterial.h"
#include "JSystem/JMath/JMath.h"
#include "m_Do/m_Do_mtx.h"
void J3DMtxCalcJ3DSysInitBasic::init(Vec const& scale, Mtx const& mtx) {
J3DSys::mCurrentS = scale;
Vec init = {1.0f, 1.0f, 1.0f};
J3DSys::mParentS = init;
JMAMTXApplyScale(mtx, J3DSys::mCurrentMtx, scale.x, scale.y, scale.z);
}
void J3DMtxCalcJ3DSysInitMaya::init(Vec const& scale, Mtx const& mtx) {
Vec init = {1.0f, 1.0f, 1.0f};
J3DSys::mParentS = init;
J3DSys::mCurrentS = scale;
JMAMTXApplyScale(mtx, J3DSys::mCurrentMtx, scale.x, scale.y, scale.z);
}
J3DMtxBuffer* J3DMtxCalc::mMtxBuffer;
J3DJoint* J3DMtxCalc::mJoint;
void J3DMtxCalcCalcTransformBasic::calcTransform(J3DTransformInfo const& transInfo) {
J3DJoint* joint = J3DMtxCalc::getJoint();
J3DMtxBuffer* mtxBuf = J3DMtxCalc::getMtxBuffer();
u16 jntNo = joint->getJntNo();
MtxP anmMtx = mtxBuf->getAnmMtx(jntNo);
J3DSys::mCurrentS.x *= transInfo.mScale.x;
J3DSys::mCurrentS.y *= transInfo.mScale.y;
J3DSys::mCurrentS.z *= transInfo.mScale.z;
J3DGetTranslateRotateMtx(transInfo, anmMtx);
if (!checkScaleOne(J3DSys::mCurrentS)) {
mtxBuf->setScaleFlag(jntNo, 0);
JMAMTXApplyScale(anmMtx, anmMtx, transInfo.mScale.x, transInfo.mScale.y,
transInfo.mScale.z);
} else {
mtxBuf->setScaleFlag(jntNo, 1);
}
MTXConcat(J3DSys::mCurrentMtx, anmMtx, J3DSys::mCurrentMtx);
MTXCopy(J3DSys::mCurrentMtx, anmMtx);
}
void J3DMtxCalcCalcTransformSoftimage::calcTransform(J3DTransformInfo const& transInfo) {
J3DJoint* joint = J3DMtxCalc::getJoint();
J3DMtxBuffer* mtxBuf = J3DMtxCalc::getMtxBuffer();
u16 jntNo = joint->getJntNo();
MtxP anmMtx = mtxBuf->getAnmMtx(jntNo);
J3DGetTranslateRotateMtx(transInfo.mRotation.x, transInfo.mRotation.y, transInfo.mRotation.z,
transInfo.mTranslate.x * J3DSys::mCurrentS.x,
transInfo.mTranslate.y * J3DSys::mCurrentS.y,
transInfo.mTranslate.z * J3DSys::mCurrentS.z, anmMtx);
MTXConcat(J3DSys::mCurrentMtx, anmMtx, J3DSys::mCurrentMtx);
J3DSys::mCurrentS.x *= transInfo.mScale.x;
J3DSys::mCurrentS.y *= transInfo.mScale.y;
J3DSys::mCurrentS.z *= transInfo.mScale.z;
if (!checkScaleOne(J3DSys::mCurrentS)) {
mtxBuf->setScaleFlag(jntNo, 0);
JMAMTXApplyScale(J3DSys::mCurrentMtx, anmMtx, J3DSys::mCurrentS.x, J3DSys::mCurrentS.y,
J3DSys::mCurrentS.z);
anmMtx[0][3] = J3DSys::mCurrentMtx[0][3];
anmMtx[1][3] = J3DSys::mCurrentMtx[1][3];
anmMtx[2][3] = J3DSys::mCurrentMtx[2][3];
} else {
mtxBuf->setScaleFlag(jntNo, 1);
MTXCopy(J3DSys::mCurrentMtx, anmMtx);
}
}
void J3DMtxCalcCalcTransformMaya::calcTransform(J3DTransformInfo const& transInfo) {
J3DJoint* joint = J3DMtxCalc::getJoint();
J3DMtxBuffer* mtxBuf = J3DMtxCalc::getMtxBuffer();
u16 jntNo = joint->getJntNo();
MtxP anmMtx = mtxBuf->getAnmMtx(jntNo);
J3DGetTranslateRotateMtx(transInfo, anmMtx);
if (transInfo.mScale.x == 1.0f && transInfo.mScale.y == 1.0f && transInfo.mScale.z == 1.0f) {
mtxBuf->setScaleFlag(jntNo, 1);
} else {
mtxBuf->setScaleFlag(jntNo, 0);
JMAMTXApplyScale(anmMtx, anmMtx, transInfo.mScale.x, transInfo.mScale.y,
transInfo.mScale.z);
}
u8 scaleCompensate = joint->getScaleCompensate();
if (scaleCompensate == 1) {
Vec inv;
inv.x = JMath::fastReciprocal(J3DSys::mParentS.x);
inv.y = JMath::fastReciprocal(J3DSys::mParentS.y);
inv.z = JMath::fastReciprocal(J3DSys::mParentS.z);
anmMtx[0][0] *= inv.x;
anmMtx[0][1] *= inv.x;
anmMtx[0][2] *= inv.x;
anmMtx[1][0] *= inv.y;
anmMtx[1][1] *= inv.y;
anmMtx[1][2] *= inv.y;
anmMtx[2][0] *= inv.z;
anmMtx[2][1] *= inv.z;
anmMtx[2][2] *= inv.z;
}
MTXConcat(J3DSys::mCurrentMtx, anmMtx, J3DSys::mCurrentMtx);
MTXCopy(J3DSys::mCurrentMtx, anmMtx);
J3DSys::mParentS.x = transInfo.mScale.x;
J3DSys::mParentS.y = transInfo.mScale.y;
J3DSys::mParentS.z = transInfo.mScale.z;
}
void J3DJoint::appendChild(J3DJoint* pChild) {
if (mChild == NULL) {
mChild = pChild;
return;
}
J3DJoint* curChild = mChild;
while (curChild->getYounger() != NULL) {
curChild = curChild->getYounger();
}
curChild->setYounger(pChild);
}
J3DJoint::J3DJoint() {
mCallBackUserData = NULL;
mCallBack = NULL;
field_0x8 = NULL;
mChild = NULL;
mYounger = NULL;
mJntNo = 0;
mKind = 1;
mScaleCompensate = false;
J3DTransformInfo* r30 = &mTransformInfo;
void* r29 = __memcpy(r30, &j3dDefaultTransformInfo, sizeof(J3DTransformInfo));
mBoundingSphereRadius = 0.0f;
mMtxCalc = NULL;
mMesh = NULL;
Vec init = {0.0f, 0.0f, 0.0f};
mMin = init;
Vec init2 = {0.0f, 0.0f, 0.0f};
mMax = init2;
}
void J3DJoint::entryIn() {
MtxP anmMtx = j3dSys.getModel()->getAnmMtx(mJntNo);
j3dSys.getDrawBuffer(0)->setZMtx(anmMtx);
j3dSys.getDrawBuffer(1)->setZMtx(anmMtx);
for (J3DMaterial* mesh = mMesh; mesh != NULL;) {
if (mesh->getShape()->checkFlag(J3DShpFlag_Visible)) {
mesh = mesh->getNext();
} else {
J3DMatPacket* matPacket = j3dSys.getModel()->getMatPacket(mesh->getIndex());
J3DShapePacket* shapePacket =
j3dSys.getModel()->getShapePacket(mesh->getShape()->getIndex());
if (!matPacket->isLocked()) {
if (mesh->getMaterialAnm()) {
mesh->getMaterialAnm()->calc(mesh);
}
mesh->calc(anmMtx);
}
mesh->setCurrentMtx();
matPacket->setMaterialAnmID(mesh->getMaterialAnm());
matPacket->setShapePacket(shapePacket);
bool isDrawModeOpaTexEdge = mesh->isDrawModeOpaTexEdge() == FALSE;
u8 r24 = matPacket->entry(j3dSys.getDrawBuffer(isDrawModeOpaTexEdge));
if (r24) {
j3dSys.setMatPacket(matPacket);
J3DDrawBuffer::entryNum++;
mesh->makeDisplayList();
}
mesh = mesh->getNext();
}
}
}
J3DMtxCalc* J3DJoint::mCurrentMtxCalc;
void J3DJoint::recursiveCalc() {
J3DMtxCalc* prevMtxCalc = NULL;
Mtx prevCurrentMtx;
MTXCopy(J3DSys::mCurrentMtx, prevCurrentMtx);
Vec current, parent;
current = J3DSys::mCurrentS;
parent = J3DSys::mParentS;
if (getMtxCalc() != NULL) {
prevMtxCalc = getCurrentMtxCalc();
J3DMtxCalc* piVar2 = this->getMtxCalc();
setCurrentMtxCalc(piVar2);
J3DMtxCalc::setJoint(this);
#if DEBUG
J3DMtxCalc::setMtxBuffer(J3DMtxCalc::getMtxBuffer());
#endif
piVar2->calc();
} else {
if (getCurrentMtxCalc() != NULL) {
J3DMtxCalc* uVar6 = getCurrentMtxCalc();
J3DMtxCalc::setJoint(this);
uVar6->calc();
}
}
J3DJointCallBack jointCallback = getCallBack();
if (jointCallback != NULL) {
(*jointCallback)(this, 0);
}
J3DJoint* joint = getChild();
if (joint != NULL) {
joint->recursiveCalc();
}
MTXCopy(prevCurrentMtx, J3DSys::mCurrentMtx);
J3DSys::mCurrentS = current;
J3DSys::mParentS = parent;
if (prevMtxCalc != NULL) {
setCurrentMtxCalc(prevMtxCalc);
}
if (jointCallback != NULL) {
(*jointCallback)(this, 1);
}
joint = getYounger();
if (joint != NULL) {
joint->recursiveCalc();
}
}
@@ -0,0 +1,116 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/J3DGraphAnimator/J3DJoint.h"
#include "JSystem/J3DGraphAnimator/J3DJointTree.h"
#include "JSystem/J3DGraphAnimator/J3DMaterialAttach.h"
#include "JSystem/J3DGraphAnimator/J3DShapeTable.h"
#include "JSystem/J3DGraphBase/J3DMaterial.h"
enum {
kTypeEnd = 0x00,
kTypeBeginChild = 0x01,
kTypeEndChild = 0x02,
kTypeJoint = 0x10,
kTypeMaterial = 0x11,
kTypeShape = 0x12,
};
J3DJointTree::J3DJointTree()
: mHierarchy(NULL), mFlags(0), mModelDataType(0), mRootNode(NULL), mBasicMtxCalc(NULL),
mJointNodePointer(NULL), mJointNum(0), mWEvlpMtxNum(0), mWEvlpMixMtxNum(0),
mWEvlpMixMtxIndex(0), mWEvlpMixWeight(0), mInvJointMtx(NULL), mWEvlpImportantMtxIdx(0),
field_0x40(0), mJointName(NULL) {}
void J3DJointTree::makeHierarchy(J3DJoint* pJoint, const J3DModelHierarchy** pHierarchy,
J3DMaterialTable* pMaterialTable, J3DShapeTable* pShapeTable) {
J3D_ASSERT_NULLPTR(95, pHierarchy != NULL);
J3DJoint* curJoint = pJoint;
while (true) {
J3DJoint* newJoint = NULL;
J3DMaterial* newMaterial = NULL;
J3DShape* newShape = NULL;
switch ((*pHierarchy)->mType) {
case kTypeBeginChild:
(*pHierarchy)++;
makeHierarchy(curJoint, pHierarchy, pMaterialTable, pShapeTable);
break;
case kTypeEndChild:
(*pHierarchy)++;
return;
case kTypeEnd:
return;
case kTypeJoint:
newJoint = mJointNodePointer[((*pHierarchy)++)->mValue];
break;
case kTypeMaterial:
newMaterial = pMaterialTable->getMaterialNodePointer(((*pHierarchy)++)->mValue);
break;
case kTypeShape:
newShape = pShapeTable->getShapeNodePointer(((*pHierarchy)++)->mValue);
break;
}
if (newJoint != NULL) {
curJoint = newJoint;
if (pJoint == NULL)
mRootNode = newJoint;
else
pJoint->appendChild(newJoint);
} else if (newMaterial != NULL && pJoint->getType() == 'NJNT') {
pJoint->addMesh(newMaterial);
newMaterial->setJoint(pJoint);
} else if (newShape != NULL && pJoint->getType() == 'NJNT') {
J3DMaterial* newMaterial = pJoint->getMesh();
newMaterial->addShape(newShape);
newShape->setMaterial(newMaterial);
}
}
}
void J3DJointTree::findImportantMtxIndex() {
s32 wEvlpMtxNum = getWEvlpMtxNum();
u32 tableIdx = 0;
u16 drawFullWgtMtxNum = getDrawFullWgtMtxNum();
u16* wEvlpMixIndex = getWEvlpMixMtxIndex();
f32* wEvlpMixWeight = getWEvlpMixWeight();
u16* wEvlpImportantMtxIdx = getWEvlpImportantMtxIndex();
// Rigid matrices are easy.
for (u16 i = 0; i < drawFullWgtMtxNum; i++)
wEvlpImportantMtxIdx[i] = getDrawMtxIndex(i);
// For envelope matrices, we need to find the matrix with the most contribution.
for (s32 i = 0; i < wEvlpMtxNum; i++) {
s32 mixNum = getWEvlpMixMtxNum(i);
u16 bestIdx = 0;
f32 bestWeight = -0.1f;
for (s32 j = 0; j < mixNum; j++, tableIdx++) {
if (bestWeight < wEvlpMixWeight[tableIdx]) {
bestWeight = wEvlpMixWeight[tableIdx];
bestIdx = wEvlpMixIndex[tableIdx];
}
}
wEvlpImportantMtxIdx[i + getDrawFullWgtMtxNum()] = bestIdx;
}
}
void J3DJointTree::calc(J3DMtxBuffer* pMtxBuffer, Vec const& scale, f32 const (&mtx)[3][4]) {
J3D_ASSERT_NULLPTR(217, pMtxBuffer != NULL);
getBasicMtxCalc()->init(scale, mtx);
getBasicMtxCalc()->setMtxBuffer(pMtxBuffer);
J3DJoint* root = getRootNode();
if (root == NULL)
return;
root->setCurrentMtxCalc(getBasicMtxCalc());
root->recursiveCalc();
}
void J3DMtxCalc::setMtxBuffer(J3DMtxBuffer* mtxBuffer) {
J3DMtxCalc::mMtxBuffer = mtxBuffer;
}
@@ -0,0 +1,116 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/J3DGraphAnimator/J3DMaterialAnm.h"
#include "JSystem/J3DGraphBase/J3DMaterial.h"
void J3DMaterialAnm::initialize() {
for (int i = 0; i < ARRAY_SIZE(mMatColorAnm); i++) {
mMatColorAnm[i].setAnmFlag(false);
}
for (int i = 0; i < ARRAY_SIZE(mTexNoAnm); i++) {
mTexNoAnm[i].setAnmFlag(false);
}
for (int i = 0; i < ARRAY_SIZE(mTevColorAnm); i++) {
mTevColorAnm[i].setAnmFlag(false);
}
for (int i = 0; i < ARRAY_SIZE(mTevKColorAnm); i++) {
mTevKColorAnm[i].setAnmFlag(false);
}
for (int i = 0; i < ARRAY_SIZE(mTexMtxAnm); i++) {
mTexMtxAnm[i].setAnmFlag(false);
}
}
void J3DMaterialAnm::calc(J3DMaterial* pMaterial) const {
J3D_ASSERT_NULLPTR(54, pMaterial != NULL);
for (u32 i = 0; i < ARRAY_SIZE(mMatColorAnm); i++) {
if (mMatColorAnm[i].getAnmFlag()) {
GXColor* color = pMaterial->mColorBlock->getMatColor(i);
mMatColorAnm[i].calc(color);
}
}
u16 tmp;
for (u32 i = 0; i < ARRAY_SIZE(mTexNoAnm); i++) {
if (mTexNoAnm[i].getAnmFlag()) {
mTexNoAnm[i].calc(&tmp);
pMaterial->mTevBlock->setTexNo(i, tmp);
}
}
for (u32 i = 0; i < 3; i++) {
if (mTevColorAnm[i].getAnmFlag()) {
GXColorS10* color = pMaterial->mTevBlock->getTevColor(i);
mTevColorAnm[i].calc(color);
}
}
for (u32 i = 0; i < ARRAY_SIZE(mTevKColorAnm); i++) {
if (mTevKColorAnm[i].getAnmFlag()) {
GXColor* color = pMaterial->mTevBlock->getTevKColor(i);
mTevKColorAnm[i].calc(color);
}
}
for (u32 i = 0; i < ARRAY_SIZE(mTexMtxAnm); i++) {
if (mTexMtxAnm[i].getAnmFlag()) {
J3DTextureSRTInfo* pSRT = &pMaterial->mTexGenBlock->getTexMtx(i)->getTexMtxInfo().mSRT;
mTexMtxAnm[i].calc(pSRT);
}
}
}
void J3DMaterialAnm::setMatColorAnm(int idx, J3DMatColorAnm* pMatColorAnm) {
J3D_ASSERT_RANGE(106, idx >= 0 && idx < 2);
if (pMatColorAnm == NULL) {
mMatColorAnm[idx].setAnmFlag(false);
} else {
mMatColorAnm[idx] = *pMatColorAnm;
}
}
void J3DMaterialAnm::setTexMtxAnm(int idx, J3DTexMtxAnm* pTexMtxAnm) {
J3D_ASSERT_RANGE(117, idx >= 0 && idx < 8);
if (pTexMtxAnm == NULL) {
mTexMtxAnm[idx].setAnmFlag(false);
} else {
mTexMtxAnm[idx] = *pTexMtxAnm;
}
}
void J3DMaterialAnm::setTexNoAnm(int idx, J3DTexNoAnm* pTexNoAnm) {
J3D_ASSERT_RANGE(128, idx >= 0 && idx < 8);
if (pTexNoAnm == NULL) {
mTexNoAnm[idx].setAnmFlag(false);
} else {
mTexNoAnm[idx] = *pTexNoAnm;
}
}
void J3DMaterialAnm::setTevColorAnm(int idx, J3DTevColorAnm* pTevColorAnm) {
J3D_ASSERT_RANGE(139, idx >= 0 && idx < 4);
if (pTevColorAnm == NULL) {
mTevColorAnm[idx].setAnmFlag(false);
} else {
mTevColorAnm[idx] = *pTevColorAnm;
}
}
void J3DMaterialAnm::setTevKColorAnm(int idx, J3DTevKColorAnm* pTevKColorAnm) {
J3D_ASSERT_RANGE(150, idx >= 0 && idx < 4);
if (pTevKColorAnm == NULL) {
mTevKColorAnm[idx].setAnmFlag(false);
} else {
mTevKColorAnm[idx] = *pTevKColorAnm;
}
}
@@ -0,0 +1,303 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/J3DGraphAnimator/J3DMaterialAttach.h"
#include "JSystem/J3DGraphAnimator/J3DMaterialAnm.h"
#include "JSystem/J3DGraphBase/J3DMaterial.h"
#include "JSystem/JUtility/JUTAssert.h"
void J3DMaterialTable::clear() {
mMaterialNum = 0;
mUniqueMatNum = 0;
mMaterialNodePointer = NULL;
mMaterialName = NULL;
field_0x10 = 0;
mTexture = NULL;
mTextureName = NULL;
field_0x1c = 0;
}
J3DMaterialTable::J3DMaterialTable() {
mMaterialNum = 0;
mUniqueMatNum = 0;
mMaterialNodePointer = NULL;
mMaterialName = NULL;
field_0x10 = 0;
mTexture = NULL;
mTextureName = NULL;
field_0x1c = 0;
}
J3DMaterialTable::~J3DMaterialTable() {}
int J3DMaterialTable::removeMatColorAnimator(J3DAnmColor* pAnmColor) {
J3D_ASSERT_NULLPTR(208, pAnmColor != NULL);
int ret = false;
u16 updateMatNum = pAnmColor->getUpdateMaterialNum();
for (u16 i = 0; i < updateMatNum; i++) {
if (pAnmColor->isValidUpdateMaterialID(i)) {
u16 matNo = pAnmColor->getUpdateMaterialID(i);
J3DMaterialAnm* materialAnm = getMaterialNodePointer(matNo)->getMaterialAnm();
if (materialAnm == NULL) {
ret = true;
} else {
materialAnm->setMatColorAnm(0, NULL);
}
}
}
return ret;
}
int J3DMaterialTable::removeTexNoAnimator(J3DAnmTexPattern* pAnmTexPattern) {
J3D_ASSERT_NULLPTR(242, pAnmTexPattern != NULL);
int ret = 0;
u16 materialNum = pAnmTexPattern->getUpdateMaterialNum();
J3DAnmTexPatternFullTable* anm_table = (J3DAnmTexPatternFullTable*)pAnmTexPattern->getAnmTable();
for (u16 i = 0; i < materialNum; i++) {
if (pAnmTexPattern->isValidUpdateMaterialID(i)) {
u16 matNo = pAnmTexPattern->getUpdateMaterialID(i);
J3DMaterialAnm* pMatAnm = getMaterialNodePointer(matNo)->getMaterialAnm();
u8 texNo = anm_table[i].mTexNo;
if (pMatAnm == NULL)
ret = 1;
else
pMatAnm->setTexNoAnm(texNo, NULL);
}
}
return ret;
}
int J3DMaterialTable::removeTexMtxAnimator(J3DAnmTextureSRTKey* pAnmTexSRTKey) {
J3D_ASSERT_NULLPTR(278, pAnmTexSRTKey != NULL);
s32 ret = 0;
u16 materialNum = pAnmTexSRTKey->getUpdateMaterialNum();
u16 postUpdateMaterialNum[1];
postUpdateMaterialNum[0] = pAnmTexSRTKey->getPostUpdateMaterialNum();
for (u16 i = 0; i < materialNum; i++) {
if (pAnmTexSRTKey->isValidUpdateMaterialID(i)) {
u16 matNo = pAnmTexSRTKey->getUpdateMaterialID(i);
J3DMaterial* pMaterial = getMaterialNodePointer(matNo);
J3DMaterialAnm* pMatAnm = pMaterial->getMaterialAnm();
u8 texMtxID = pAnmTexSRTKey->getUpdateTexMtxID(i);
if (pMatAnm == NULL) {
ret = 1;
} else if (texMtxID != 0xFF) {
pMatAnm->setTexMtxAnm(texMtxID, NULL);
}
}
}
return ret;
}
int J3DMaterialTable::removeTevRegAnimator(J3DAnmTevRegKey* pAnmTevRegKey) {
J3D_ASSERT_NULLPTR(320, pAnmTevRegKey != NULL);
s32 ret = 0;
u16 cRegMaterialNum = pAnmTevRegKey->getCRegUpdateMaterialNum();
u16 kRegMaterialNum = pAnmTevRegKey->getKRegUpdateMaterialNum();
for (u16 i = 0; i < cRegMaterialNum; i++) {
if (pAnmTevRegKey->isValidCRegUpdateMaterialID(i)) {
const u16 spC = pAnmTevRegKey->getCRegUpdateMaterialID(i);
J3DMaterialAnm* pMatAnm = getMaterialNodePointer(spC)->getMaterialAnm();
const J3DAnmCRegKeyTable* table = pAnmTevRegKey->getAnmCRegKeyTable();
const u8 colorId = table[i].mColorId;
if (pMatAnm == NULL)
ret = 1;
else
pMatAnm->setTevColorAnm(colorId, NULL);
}
}
for (u16 i = 0; i < kRegMaterialNum; i++) {
if (pAnmTevRegKey->isValidKRegUpdateMaterialID(i)) {
const u16 spA = pAnmTevRegKey->getKRegUpdateMaterialID(i);
J3DMaterialAnm* pMatAnm = getMaterialNodePointer(spA)->getMaterialAnm();
const J3DAnmKRegKeyTable* table = pAnmTevRegKey->getAnmKRegKeyTable();
const u8 colorId = table[i].mColorId;
if (pMatAnm == NULL) {
ret = 1;
} else {
pMatAnm->setTevKColorAnm(colorId, NULL);
}
}
}
return ret;
}
int J3DMaterialTable::createTexMtxForAnimator(J3DAnmTextureSRTKey* pTexSRTKey) {
J3D_ASSERT_NULLPTR(382, pTexSRTKey != NULL);
int rv = 0;
u16 materialNum = pTexSRTKey->getUpdateMaterialNum();
if (isLocked()) {
return 2;
}
for (u16 i = 0; i < materialNum; i++) {
if (pTexSRTKey->isValidUpdateMaterialID(i)) {
const u16 matNo = pTexSRTKey->getUpdateMaterialID(i);
J3DMaterial* material = getMaterialNodePointer(matNo);
u8 texMtx = pTexSRTKey->getUpdateTexMtxID(i);
J3DMaterialAnm* pMaterialAnm = material->getMaterialAnm();
if (pMaterialAnm == NULL) {
rv = 1;
} else {
if (texMtx != 0xff && material->getTexMtx(texMtx) == NULL) {
J3DTexMtx* mtx = new J3DTexMtx();
rv = 4;
material->setTexMtx(texMtx, mtx);
JUT_WARN(420, "matNo<%d> : texMtx%d nothing !\n", matNo, texMtx);
}
}
}
}
return rv;
}
int J3DMaterialTable::entryMatColorAnimator(J3DAnmColor* pAnmColor) {
J3D_ASSERT_NULLPTR(450, pAnmColor != NULL);
int rv = 0;
u16 materialNum = pAnmColor->getUpdateMaterialNum();
if (isLocked()) {
return 2;
}
for (u16 i = 0; i < materialNum; i++) {
if (pAnmColor->isValidUpdateMaterialID(i)) {
const u16 matNo = pAnmColor->getUpdateMaterialID(i);
J3DMaterialAnm* materialAnm = getMaterialNodePointer(matNo)->getMaterialAnm();
if (materialAnm == NULL) {
rv = 1;
} else {
J3DMatColorAnm matColorAnm(i, pAnmColor);
materialAnm->setMatColorAnm(0, &matColorAnm);
}
}
}
return rv;
}
int J3DMaterialTable::entryTexNoAnimator(J3DAnmTexPattern* pAnmTexPattern) {
J3D_ASSERT_NULLPTR(489, pAnmTexPattern != NULL);
int rv = 0;
u16 materialNum = pAnmTexPattern->getUpdateMaterialNum();
if (isLocked()) {
return 2;
}
for (u16 i = 0; i < materialNum; i++) {
if (pAnmTexPattern->isValidUpdateMaterialID(i)) {
const u16 matNo = pAnmTexPattern->getUpdateMaterialID(i);
J3DMaterialAnm* materialAnm = getMaterialNodePointer(matNo)->getMaterialAnm();
const J3DAnmTexPatternFullTable* table = pAnmTexPattern->getAnmTable();
const u8 texNo = table[i].mTexNo;
if (materialAnm == NULL) {
rv = 1;
} else {
J3DTexNoAnm texNoAnm(i, pAnmTexPattern);
materialAnm->setTexNoAnm(texNo, &texNoAnm);
}
}
}
return rv;
}
int J3DMaterialTable::entryTexMtxAnimator(J3DAnmTextureSRTKey* pAnmTexSRTKey) {
J3D_ASSERT_NULLPTR(532, pAnmTexSRTKey != NULL);
int rv = 0;
u16 materialNum = pAnmTexSRTKey->getUpdateMaterialNum();
rv = createTexMtxForAnimator(pAnmTexSRTKey);
if (rv != 0) {
return rv;
}
if (isLocked()) {
return 2;
}
for (u16 no = 0; no < materialNum; no++) {
if (pAnmTexSRTKey->isValidUpdateMaterialID(no)) {
const u16 matNo = pAnmTexSRTKey->getUpdateMaterialID(no);
J3DMaterial* material = getMaterialNodePointer(matNo);
J3DMaterialAnm* materialAnm = material->getMaterialAnm();
u8 texMtxID = pAnmTexSRTKey->getUpdateTexMtxID(no);
if (materialAnm == NULL) {
rv = 1;
} else {
if (texMtxID != 0xff) {
if (material->getTexCoord(texMtxID) != NULL) {
material->getTexCoord(texMtxID)->setTexGenMtx((u8)texMtxID * 3 + 30);
}
J3DTexMtxInfo& tmtxinfo = material->getTexMtx(texMtxID)->getTexMtxInfo();
tmtxinfo.mInfo = (tmtxinfo.mInfo & 0x3f) | (pAnmTexSRTKey->getTexMtxCalcType() << 7);
tmtxinfo.mCenter.x = pAnmTexSRTKey->getSRTCenter(no)->x;
tmtxinfo.mCenter.y = pAnmTexSRTKey->getSRTCenter(no)->y;
tmtxinfo.mCenter.z = pAnmTexSRTKey->getSRTCenter(no)->z;
J3DTexMtxAnm texMtxAnm(no, pAnmTexSRTKey);
materialAnm->setTexMtxAnm(texMtxID, &texMtxAnm);
}
}
}
}
return rv;
}
int J3DMaterialTable::entryTevRegAnimator(J3DAnmTevRegKey* pAnmTevRegKey) {
J3D_ASSERT_NULLPTR(599, pAnmTevRegKey != NULL);
int rv = 0;
u16 cRegNum = pAnmTevRegKey->getCRegUpdateMaterialNum();
u16 kRegNum = pAnmTevRegKey->getKRegUpdateMaterialNum();
if (isLocked()) {
return 2;
}
for (u16 i = 0; i < cRegNum; i++) {
if (pAnmTevRegKey->isValidCRegUpdateMaterialID(i)) {
const u16 matNo = pAnmTevRegKey->getCRegUpdateMaterialID(i);
J3DMaterialAnm* materialAnm = getMaterialNodePointer(matNo)->getMaterialAnm();
const J3DAnmCRegKeyTable* table = pAnmTevRegKey->getAnmCRegKeyTable();
u8 colorId = table[i].mColorId;
if (materialAnm == NULL) {
rv = 1;
} else {
J3DTevColorAnm tevColorAnm(i, pAnmTevRegKey);
materialAnm->setTevColorAnm(colorId, &tevColorAnm);
}
}
}
for (u16 i = 0; i < kRegNum; i++) {
if (pAnmTevRegKey->isValidKRegUpdateMaterialID(i)) {
const u16 matNo = pAnmTevRegKey->getKRegUpdateMaterialID(i);
J3DMaterialAnm* materialAnm = getMaterialNodePointer(matNo)->getMaterialAnm();
const J3DAnmKRegKeyTable* table = pAnmTevRegKey->getAnmKRegKeyTable();
const u8 colorId = table[i].mColorId;
if (materialAnm == NULL) {
rv = 1;
} else {
J3DTevKColorAnm tevKColorAnm(i, pAnmTevRegKey);
materialAnm->setTevKColorAnm(colorId, &tevKColorAnm);
}
}
}
return rv;
}
@@ -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());
}
}
}
@@ -0,0 +1,100 @@
//
// J3DModelData
//
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/J3DGraphAnimator/J3DModelData.h"
#include "JSystem/J3DGraphAnimator/J3DJoint.h"
#include "JSystem/J3DGraphAnimator/J3DMaterialAnm.h"
#include "JSystem/J3DGraphAnimator/J3DModel.h"
#include "JSystem/J3DGraphBase/J3DMaterial.h"
void J3DModelData::clear() {
mpRawData = 0;
mFlags = 0;
mbHasBumpArray = 0;
mbHasBillboard = 0;
}
J3DModelData::J3DModelData() {
clear();
}
s32 J3DModelData::newSharedDisplayList(u32 mdlFlags) {
u16 matNum = getMaterialNum();
for (u16 i = 0; i < matNum; i++) {
s32 ret;
if (mdlFlags & J3DMdlFlag_UseSingleDL) {
ret = getMaterialNodePointer(i)->newSingleSharedDisplayList(getMaterialNodePointer(i)->countDLSize());
if (ret != kJ3DError_Success)
return ret;
} else {
ret = getMaterialNodePointer(i)->newSharedDisplayList(getMaterialNodePointer(i)->countDLSize());
if (ret != kJ3DError_Success)
return ret;
}
}
return kJ3DError_Success;
}
void J3DModelData::indexToPtr() {
j3dSys.setTexture(getTexture());
static BOOL sInterruptFlag = OSDisableInterrupts();
OSDisableScheduler();
GDLObj gdl_obj;
u16 matNum = getMaterialNum();
for (u16 i = 0; i < matNum; i++) {
J3DMaterial* matNode = getMaterialNodePointer(i);
J3DDisplayListObj* dl_obj = matNode->getSharedDisplayListObj();
GDInitGDLObj(&gdl_obj, dl_obj->getDisplayList(0), dl_obj->getDisplayListSize());
GDSetCurrent(&gdl_obj);
matNode->getTevBlock()->indexToPtr();
}
GDSetCurrent(NULL);
OSEnableScheduler();
OSRestoreInterrupts(sInterruptFlag);
}
void J3DModelData::makeSharedDL() {
j3dSys.setTexture(getTexture());
u16 matNum = getMaterialNum();
for (u16 i = 0; i < matNum; i++) {
getMaterialNodePointer(i)->makeSharedDisplayList();
}
}
void J3DModelData::simpleCalcMaterial(u16 idx, Mtx param_1) {
syncJ3DSysFlags();
J3DMaterial* mat;
J3DJoint* jointNode = getJointNodePointer(idx);
for (mat = jointNode->getMesh(); mat != NULL; mat = mat->getNext()) {
if (mat->getMaterialAnm() != NULL) {
mat->getMaterialAnm()->calc(mat);
}
mat->calc(param_1);
}
}
void J3DModelData::syncJ3DSysPointers() const {
j3dSys.setTexture(getTexture());
j3dSys.setVtxPos(getVtxPosArray());
j3dSys.setVtxNrm(getVtxNrmArray());
j3dSys.setVtxCol(getVtxColorArray(0));
}
void J3DModelData::syncJ3DSysFlags() const {
if (checkFlag(0x20)) {
j3dSys.onFlag(J3DSysFlag_PostTexMtx);
} else {
j3dSys.offFlag(J3DSysFlag_PostTexMtx);
}
}
@@ -0,0 +1,523 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/J3DGraphAnimator/J3DJoint.h"
#include "JSystem/J3DGraphAnimator/J3DMtxBuffer.h"
#include "JSystem/J3DGraphBase/J3DMaterial.h"
#include "JSystem/J3DGraphLoader/J3DModelLoader.h"
#include "JSystem/JKernel/JKRHeap.h"
Mtx J3DMtxBuffer::sNoUseDrawMtx;
Mtx33 J3DMtxBuffer::sNoUseNrmMtx;
Mtx* J3DMtxBuffer::sNoUseDrawMtxPtr = &J3DMtxBuffer::sNoUseDrawMtx;
Mtx33* J3DMtxBuffer::sNoUseNrmMtxPtr = &J3DMtxBuffer::sNoUseNrmMtx;
// force .sdata2 order
f32 dummy1() {
return 1.0f;
}
f32 dummy0() {
return 0.0f;
}
void J3DMtxBuffer::initialize() {
mJointTree = NULL;
mpScaleFlagArr = NULL;
mpEvlpScaleFlagArr = NULL;
mpAnmMtx = NULL;
mpWeightEvlpMtx = NULL;
mpDrawMtxArr[0] = NULL;
mpDrawMtxArr[1] = NULL;
mpNrmMtxArr[0] = NULL;
mpNrmMtxArr[1] = NULL;
mpBumpMtxArr[0] = NULL;
mpBumpMtxArr[1] = NULL;
mMtxNum = 1;
mCurrentViewNo = 0;
mpUserAnmMtx = NULL;
}
enum {
J3DMdlDataFlag_ConcatView = 0x10,
J3DMdlDataFlag_NoAnimation = 0x100,
};
s32 J3DMtxBuffer::create(J3DModelData* pModelData, u32 mtxNum) {
J3D_ASSERT_NULLPTR(76, pModelData != NULL);
J3D_ASSERT_NONZEROARG(77, mtxNum != 0);
s32 ret = kJ3DError_Success;
mMtxNum = mtxNum;
mJointTree = &pModelData->getJointTree();
ret = createAnmMtx(pModelData);
if (ret != kJ3DError_Success)
return ret;
ret = createWeightEnvelopeMtx(pModelData);
if (ret != kJ3DError_Success)
return ret;
if (pModelData->checkFlag(J3DMdlDataFlag_NoAnimation)) {
setNoUseDrawMtx();
} else {
u32 loadType = getMdlDataFlag_MtxLoadType(pModelData->getFlag());
switch (loadType) {
case J3DMdlDataFlag_ConcatView:
ret = setNoUseDrawMtx();
break;
case 0:
default:
ret = createDoubleDrawMtx(pModelData, mtxNum);
break;
}
}
if (ret != kJ3DError_Success)
return ret;
if (pModelData->getFlag() & J3DMdlDataFlag_ConcatView) {
pModelData->setBumpFlag(0);
} else {
ret = createBumpMtxArray(pModelData, mtxNum);
if (ret != kJ3DError_Success)
return ret;
}
return ret;
}
J3DError J3DMtxBuffer::createAnmMtx(J3DModelData* pModelData) {
if (pModelData->getJointNum() != 0) {
mpScaleFlagArr = new u8[pModelData->getJointNum()];
mpAnmMtx = new Mtx[pModelData->getJointNum()];
mpUserAnmMtx = mpAnmMtx;
}
if (mpScaleFlagArr == NULL)
return kJ3DError_Alloc;
if (mpAnmMtx == NULL) {
return kJ3DError_Alloc;
}
return kJ3DError_Success;
}
s32 J3DMtxBuffer::createWeightEnvelopeMtx(J3DModelData* pModelData) {
if (pModelData->getWEvlpMtxNum() != 0) {
mpEvlpScaleFlagArr = new u8[pModelData->getWEvlpMtxNum()];
mpWeightEvlpMtx = new Mtx[pModelData->getWEvlpMtxNum()];
}
if (pModelData->getWEvlpMtxNum() != 0 && mpEvlpScaleFlagArr == NULL)
return kJ3DError_Alloc;
if (pModelData->getWEvlpMtxNum() != 0 && mpWeightEvlpMtx == NULL)
return kJ3DError_Alloc;
return kJ3DError_Success;
}
s32 J3DMtxBuffer::setNoUseDrawMtx() {
mpDrawMtxArr[0] = mpDrawMtxArr[1] = &sNoUseDrawMtxPtr;
mpNrmMtxArr[0] = mpNrmMtxArr[1] = &sNoUseNrmMtxPtr;
mpBumpMtxArr[0] = mpBumpMtxArr[1] = NULL;
return kJ3DError_Success;
}
s32 J3DMtxBuffer::createDoubleDrawMtx(J3DModelData* pModelData, u32 mtxNum) {
if (mtxNum != 0) {
for (s32 i = 0; i < 2; i++) {
mpDrawMtxArr[i] = new Mtx*[mtxNum];
mpNrmMtxArr[i] = new Mtx33*[mtxNum];
mpBumpMtxArr[i] = NULL;
}
}
if (mtxNum != 0) {
for (s32 i = 0; i < 2; i++) {
if (mpDrawMtxArr[i] == NULL)
return kJ3DError_Alloc;
if (mpNrmMtxArr[i] == NULL)
return kJ3DError_Alloc;
}
}
for (s32 i = 0; i < 2; i++) {
for (u32 j = 0; j < mtxNum; j++) {
if (pModelData->getDrawMtxNum() != 0) {
mpDrawMtxArr[i][j] = new (0x20) Mtx[pModelData->getDrawMtxNum()];
mpNrmMtxArr[i][j] = new (0x20) Mtx33[pModelData->getDrawMtxNum()];
}
}
}
for (s32 i = 0; i < 2; i++) {
for (u32 j = 0; j < mtxNum; j++) {
if (pModelData->getDrawMtxNum() != 0) {
if (mpDrawMtxArr[i][j] == NULL)
return kJ3DError_Alloc;
if (mpNrmMtxArr[i][j] == NULL)
return kJ3DError_Alloc;
}
}
}
return kJ3DError_Success;
}
s32 J3DMtxBuffer::createBumpMtxArray(J3DModelData* i_modelData, u32 mtxNum) {
J3D_ASSERT_NULLPTR(295, i_modelData != NULL);
if (i_modelData->getModelDataType() == 0) {
u16 bumpMtxNum = 0;
u16 materialCount = 0;
u16 materialNum = i_modelData->getMaterialNum();
for (u16 j = 0; j < materialNum; j++) {
J3DMaterial* material = i_modelData->getMaterialNodePointer(j);
if (material->getNBTScale()->mbHasScale == true) {
bumpMtxNum += material->getShape()->countBumpMtxNum();
materialCount++;
}
}
if (bumpMtxNum != 0 && mtxNum != 0) {
for (int i = 0; i < 2; i++) {
mpBumpMtxArr[i] = new Mtx33**[(u16)materialCount];
if (mpBumpMtxArr[i] == NULL) {
return kJ3DError_Alloc;
}
}
}
for (int i = 0; i < 2; i++) {
u32 offset = 0;
u16 materialNum = i_modelData->getMaterialNum();
for (u16 j = 0; j < materialNum; j++) {
J3DMaterial* material = i_modelData->getMaterialNodePointer(j);
if (material->getNBTScale()->mbHasScale == true) {
mpBumpMtxArr[i][offset] = new Mtx33*[mtxNum];
if (mpBumpMtxArr[i][offset] == NULL) {
return kJ3DError_Alloc;
}
material->getShape()->setBumpMtxOffset(offset);
offset++;
}
}
}
for (int i = 0; i < 2; i++) {
u32 offset = 0;
u16 materialNum = i_modelData->getMaterialNum();
for (u16 j = 0; j < materialNum; j++) {
J3DMaterial* material = i_modelData->getMaterialNodePointer((u16)j);
if (material->getNBTScale()->mbHasScale == true) {
for (int k = 0; k < mtxNum; k++) {
mpBumpMtxArr[i][offset][k] = new (0x20) Mtx33[i_modelData->getDrawMtxNum()];
if (mpBumpMtxArr[i][offset][k] == NULL) {
return kJ3DError_Alloc;
}
}
offset++;
}
}
}
if (materialCount != 0) {
i_modelData->setBumpFlag(1);
}
}
return kJ3DError_Success;
}
static f32 J3DUnit01[] = { 0.0f, 1.0f };
void J3DMtxBuffer::calcWeightEnvelopeMtx() {
__REGISTER MtxP weightAnmMtx;
__REGISTER Mtx* worldMtx;
__REGISTER Mtx* invMtx;
__REGISTER f32 weight;
int idx;
int j;
int mixNum;
int i;
int max;
u16* indices;
f32* weights;
u8* pScale;
#if DEBUG || !__MWERKS__
__REGISTER Mtx mtx;
#else
__REGISTER f32 var_f1;
__REGISTER f32 var_f2;
__REGISTER f32 var_f3;
__REGISTER f32 var_f4;
__REGISTER f32 var_f5;
__REGISTER f32 var_f6;
__REGISTER f32 var_f7;
__REGISTER f32 var_f8;
__REGISTER f32 var_f9;
__REGISTER f32 var_f10;
__REGISTER f32 var_f11;
__REGISTER f32 var_f12;
__REGISTER f32 var_f13;
__REGISTER f32 var_f31;
__REGISTER f32 var_f30;
__REGISTER f32 var_f29;
__REGISTER f32 var_f28;
__REGISTER f32 var_f27;
__REGISTER f32* var_r7 = J3DUnit01;
#endif
i = -1;
max = mJointTree->getWEvlpMtxNum();
indices = mJointTree->getWEvlpMixMtxIndex() - 1;
weights = mJointTree->getWEvlpMixWeight() - 1;
#if !DEBUG && __MWERKS__
asm {
psq_l var_f27, 0x0(var_r7), 0, 0 /* qr0 */
ps_merge00 var_f10, var_f27, var_f27
ps_merge00 var_f12, var_f27, var_f27
ps_merge00 var_f31, var_f27, var_f27
}
#endif
while (++i < max) {
pScale = &mpEvlpScaleFlagArr[i];
*pScale = 1;
weightAnmMtx = mpWeightEvlpMtx[i];
#if DEBUG || !__MWERKS__
weightAnmMtx[0][0] = weightAnmMtx[0][1] = weightAnmMtx[0][2] = weightAnmMtx[0][3] =
weightAnmMtx[1][0] = weightAnmMtx[1][1] = weightAnmMtx[1][2] = weightAnmMtx[1][3] =
weightAnmMtx[2][0] = weightAnmMtx[2][1] = weightAnmMtx[2][2] = weightAnmMtx[2][3] = 0.0f;
#else
asm {
ps_merge00 var_f9, var_f27, var_f27
ps_merge00 var_f11, var_f27, var_f27
ps_merge00 var_f13, var_f27, var_f27
}
#endif
j = 0;
mixNum = mJointTree->getWEvlpMixMtxNum(i);
do {
idx = *++indices;
worldMtx = &mpAnmMtx[idx];
invMtx = &mJointTree->getInvJointMtx((u16)idx);
#if DEBUG || !__MWERKS__
MTXConcat(*worldMtx, *invMtx, mtx);
#else
// Fakematch? Doesn't match if worldMtx and invMtx are used directly.
__REGISTER void* var_r5 = worldMtx;
__REGISTER void* var_r6 = invMtx;
asm {
psq_l var_f2, 0x0(var_r6), 0, 0 /* qr0 */
psq_l var_f1, 0x0(var_r5), 0, 0 /* qr0 */
psq_l var_f3, 0x10(var_r5), 0, 0 /* qr0 */
psq_l var_f5, 0x20(var_r5), 0, 0 /* qr0 */
ps_muls0 var_f8, var_f2, var_f1
psq_l var_f6, 0x10(var_r6), 0, 0 /* qr0 */
ps_muls0 var_f30, var_f2, var_f3
ps_muls0 var_f29, var_f2, var_f5
psq_l var_f7, 0x20(var_r6), 0, 0 /* qr0 */
ps_madds1 var_f8, var_f6, var_f1, var_f8
psq_l var_f2, 0x8(var_r5), 0, 0 /* qr0 */
ps_madds1 var_f30, var_f6, var_f3, var_f30
psq_l var_f4, 0x18(var_r5), 0, 0 /* qr0 */
ps_madds1 var_f29, var_f6, var_f5, var_f29
psq_l var_f6, 0x28(var_r5), 0, 0 /* qr0 */
ps_madds0 var_f8, var_f7, var_f2, var_f8
}
#endif
weight = *++weights;
#if DEBUG || !__MWERKS__
weightAnmMtx[0][0] += mtx[0][0] * weight;
weightAnmMtx[0][1] += mtx[0][1] * weight;
weightAnmMtx[0][2] += mtx[0][2] * weight;
weightAnmMtx[0][3] += mtx[0][3] * weight;
weightAnmMtx[1][0] += mtx[1][0] * weight;
weightAnmMtx[1][1] += mtx[1][1] * weight;
weightAnmMtx[1][2] += mtx[1][2] * weight;
weightAnmMtx[1][3] += mtx[1][3] * weight;
weightAnmMtx[2][0] += mtx[2][0] * weight;
weightAnmMtx[2][1] += mtx[2][1] * weight;
weightAnmMtx[2][2] += mtx[2][2] * weight;
weightAnmMtx[2][3] += mtx[2][3] * weight;
#else
asm {
ps_madds0 var_f30, var_f7, var_f4, var_f30
ps_madds0 var_f29, var_f7, var_f6, var_f29
psq_l var_f7, 0x8(var_r6), 0, 0 /* qr0 */
ps_madds0 var_f9, var_f8, weight, var_f9
ps_madds0 var_f11, var_f30, weight, var_f11
ps_madds0 var_f13, var_f29, weight, var_f13
psq_l var_f8, 0x18(var_r6), 0, 0 /* qr0 */
ps_muls0 var_f30, var_f7, var_f1
ps_muls0 var_f29, var_f7, var_f3
ps_muls0 var_f28, var_f7, var_f5
psq_l var_f7, 0x28(var_r6), 0, 0 /* qr0 */
psq_st var_f9, 0x0(weightAnmMtx), 0, 0 /* qr0 */
ps_madds1 var_f30, var_f8, var_f1, var_f30
ps_madds1 var_f29, var_f8, var_f3, var_f29
ps_madds1 var_f28, var_f8, var_f5, var_f28
ps_madds0 var_f30, var_f7, var_f2, var_f30
ps_madds0 var_f29, var_f7, var_f4, var_f29
ps_madds0 var_f28, var_f7, var_f6, var_f28
psq_st var_f11, 0x10(weightAnmMtx), 0, 0 /* qr0 */
psq_st var_f13, 0x20(weightAnmMtx), 0, 0 /* qr0 */
ps_madd var_f30, var_f27, var_f2, var_f30
ps_madd var_f29, var_f27, var_f4, var_f29
ps_madd var_f28, var_f27, var_f6, var_f28
ps_madds0 var_f10, var_f30, weight, var_f10
ps_madds0 var_f12, var_f29, weight, var_f12
ps_madds0 var_f31, var_f28, weight, var_f31
}
#endif
*pScale &= mpScaleFlagArr[idx];
} while (++j < mixNum);
#if !DEBUG && __MWERKS__
asm {
psq_st var_f10, 0x8(weightAnmMtx), 0, 0 /* qr0 */
ps_merge00 var_f10, var_f27, var_f27
psq_st var_f12, 0x18(weightAnmMtx), 0, 0 /* qr0 */
ps_merge00 var_f12, var_f27, var_f27
psq_st var_f31, 0x28(weightAnmMtx), 0, 0 /* qr0 */
ps_merge00 var_f31, var_f27, var_f27
}
#endif
}
}
void J3DMtxBuffer::calcDrawMtx(u32 mdlFlag, Vec const& param_1, Mtx const& param_2) {
Mtx* sp24, *sp20;
int sp1C = 0;
sp20 = mpAnmMtx;
sp24 = mpWeightEvlpMtx;
MtxP viewMtx;
Mtx viewBaseMtx;
u16 fullWgtNum; // r25
u16 local_68;
u16 local_6a;
u16 local_6c;
switch (mdlFlag) {
case 0:
viewMtx = j3dSys.getViewMtx();
fullWgtNum = mJointTree->getDrawFullWgtMtxNum();
for (u16 i = 0; i < fullWgtNum; i++) {
MTXConcat(viewMtx, getAnmMtx(mJointTree->getDrawMtxIndex(i)), *getDrawMtx(i));
}
if (mJointTree->getDrawMtxNum() > fullWgtNum) {
J3DPSMtxArrayConcat(viewMtx, *mpWeightEvlpMtx, *getDrawMtx(fullWgtNum),
mJointTree->getWEvlpMtxNum());
}
return;
case 1:
local_68 = mJointTree->getDrawFullWgtMtxNum();
for (u16 i = 0; i < local_68; i++) {
MTXCopy(getAnmMtx(mJointTree->getDrawMtxIndex(i)), *getDrawMtx(i));
}
local_6a = mJointTree->getDrawFullWgtMtxNum();
for (u16 i = 0; i < local_6a; i++) {
MTXCopy(getWeightAnmMtx(i), *getDrawMtx(mJointTree->getDrawFullWgtMtxNum() + i));
}
break;
case 2:
J3DCalcViewBaseMtx(j3dSys.getViewMtx(), param_1, param_2, viewBaseMtx);
local_6c = mJointTree->getDrawFullWgtMtxNum();
for (u16 i = 0; i < local_6c; i++) {
MTXConcat(viewBaseMtx, getAnmMtx(mJointTree->getDrawMtxIndex(i)), *getDrawMtx(i));
}
if (mJointTree->getDrawMtxNum() > mJointTree->getDrawFullWgtMtxNum()) {
J3DPSMtxArrayConcat(viewBaseMtx, *mpWeightEvlpMtx,
*getDrawMtx(mJointTree->getDrawFullWgtMtxNum()),
mJointTree->getWEvlpMtxNum());
}
return;
default:
JUT_ASSERT_MSG(778, 0, "Error : model flag is invalid.")
}
}
void J3DMtxBuffer::calcNrmMtx() {
u16 drawMtxNum = mJointTree->getDrawMtxNum();
for (u16 i = 0; i < drawMtxNum; i++) {
if (mJointTree->getDrawMtxFlag(i) == 0) {
if (getScaleFlag(mJointTree->getDrawMtxIndex(i)) == 1) {
setNrmMtx(i, *getDrawMtx(i));
} else {
J3DPSCalcInverseTranspose(*getDrawMtx(i), *getNrmMtx(i));
}
} else {
if (getEnvScaleFlag(mJointTree->getDrawMtxIndex(i)) == 1) {
setNrmMtx(i, *getDrawMtx(i));
} else {
J3DPSCalcInverseTranspose(*getDrawMtx(i), *getNrmMtx(i));
}
}
}
}
void J3DMtxBuffer::calcBBoardMtx() {
u16 drawMtxNum = mJointTree->getDrawMtxNum();
for (u16 i = 0; i < drawMtxNum; i++) {
if (mJointTree->getDrawMtxFlag(i) == 0) {
u16 index = mJointTree->getDrawMtxIndex(i);
if (mJointTree->getJointNodePointer(index)->getMtxType() == 1) {
MtxP drawMtx = *getDrawMtx(i);
J3DCalcBBoardMtx(drawMtx);
Mtx33* nrmMtx = getNrmMtx(i);
(*nrmMtx)[0][0] = 1.0f / drawMtx[0][0];
(*nrmMtx)[0][1] = 0.0f;
(*nrmMtx)[0][2] = 0.0f;
(*nrmMtx)[1][0] = 0.0f;
(*nrmMtx)[1][1] = 1.0f / drawMtx[1][1];
(*nrmMtx)[1][2] = 0.0f;
(*nrmMtx)[2][0] = 0.0f;
(*nrmMtx)[2][1] = 0.0f;
(*nrmMtx)[2][2] = 1.0f / drawMtx[2][2];
} else if (mJointTree->getJointNodePointer(index)->getMtxType() == 2) {
MtxP drawMtx = *getDrawMtx(i);
J3DCalcYBBoardMtx(drawMtx);
Mtx33* nrmMtx = getNrmMtx(i);
J3DPSCalcInverseTranspose(drawMtx, *nrmMtx);
}
}
}
}
void J3DCalcViewBaseMtx(Mtx view, Vec const& scale, const Mtx& base, Mtx dst) {
Mtx m;
m[0][0] = base[0][0] * scale.x;
m[0][1] = base[0][1] * scale.y;
m[0][2] = base[0][2] * scale.z;
m[0][3] = base[0][3];
m[1][0] = base[1][0] * scale.x;
m[1][1] = base[1][1] * scale.y;
m[1][2] = base[1][2] * scale.z;
m[1][3] = base[1][3];
m[2][0] = base[2][0] * scale.x;
m[2][1] = base[2][1] * scale.y;
m[2][2] = base[2][2] * scale.z;
m[2][3] = base[2][3];
MTXConcat(view, m, dst);
}
@@ -0,0 +1,40 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/J3DGraphAnimator/J3DShapeTable.h"
#include "JSystem/J3DGraphBase/J3DShape.h"
void J3DShapeTable::hide() {
u16 shapeNum = mShapeNum;
for (u16 i = 0; i < shapeNum; i++) {
mShapeNodePointer[i]->onFlag(1);
}
}
void J3DShapeTable::show() {
u16 shapeNum = mShapeNum;
for (u16 i = 0; i < shapeNum; i++) {
mShapeNodePointer[i]->offFlag(1);
}
}
void J3DShapeTable::initShapeNodes(J3DDrawMtxData* pMtxData, J3DVertexData* pVtxData) {
u16 shapeNum = mShapeNum;
for (u16 i = 0; i < shapeNum; i++) {
J3DShape* shapeNode = mShapeNodePointer[i];
shapeNode->setDrawMtxDataPointer(pMtxData);
shapeNode->setVertexDataPointer(pVtxData);
shapeNode->makeVcdVatCmd();
}
}
void J3DShapeTable::sortVcdVatCmd() {
u16 shapeNum = mShapeNum;
for (u16 next = 0; next < shapeNum; next++) {
for (u16 prev = 0; prev < next; prev++) {
if (mShapeNodePointer[next]->isSameVcdVatCmd(mShapeNodePointer[prev])) {
mShapeNodePointer[next]->setVcdVatCmd(mShapeNodePointer[prev]->getVcdVatCmd());
}
}
}
}
@@ -0,0 +1,698 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include "JSystem/J3DGraphAnimator/J3DSkinDeform.h"
#include "JSystem/J3DGraphAnimator/J3DAnimation.h"
#include "JSystem/J3DGraphAnimator/J3DModel.h"
#include "JSystem/JKernel/JKRHeap.h"
#include <cstring>
J3DSkinNList::J3DSkinNList() {
field_0x0 = NULL;
field_0x4 = NULL;
field_0x8 = NULL;
field_0xc = NULL;
field_0x10 = 0;
field_0x12 = 0;
}
static void J3DPSWeightMTXMultVec(f32 (*param_0)[4], f32 param_1, Vec* param_2, Vec* param_3) {
f32 f4 = param_0[0][3] + param_0[0][0] * param_2->x;
f32 f5 = param_0[1][3] + param_0[1][0] * param_2->x;
f32 f3 = param_0[2][3] + param_0[2][0] * param_2->x;
f4 += param_0[0][1] * param_2->y;
f5 += param_0[1][1] * param_2->y;
f3 += param_0[2][1] * param_2->y;
f4 += param_0[0][2] * param_2->z;
f5 += param_0[1][2] * param_2->z;
f3 += param_0[2][2] * param_2->z;
param_3->x += f4 * param_1;
param_3->y += f5 * param_1;
param_3->z += f3 * param_1;
}
static void J3DPSWeightMTXMultVecSR(f32 (*param_0)[4], f32 param_1, Vec* param_2,
Vec* param_3) {
f32 f4 = param_0[0][0] * param_2->x;
f32 f5 = param_0[1][0] * param_2->x;
f32 f3 = param_0[2][0] * param_2->x;
f4 += param_0[0][1] * param_2->y;
f5 += param_0[1][1] * param_2->y;
f3 += param_0[2][1] * param_2->y;
f4 += param_0[0][2] * param_2->z;
f5 += param_0[1][2] * param_2->z;
f3 += param_0[2][2] * param_2->z;
param_3->x += f4 * param_1;
param_3->y += f5 * param_1;
param_3->z += f3 * param_1;
}
void J3DSkinNList::calcSkin_VtxPosF32(f32 (*param_0)[4], void* param_1, void* param_2) {
int r29 = field_0x10;
for (int i = 0; i < r29; i++) {
Vec* pVec1 = (Vec*)param_1 + field_0x0[i];
Vec* pVec2 = (Vec*)param_2 + field_0x0[i];
f32 weight = field_0x8[i];
J3DPSWeightMTXMultVec(param_0, weight, pVec1, pVec2);
}
}
void J3DSkinNList::calcSkin_VtxNrmF32(f32 (*param_0)[4], void* param_1, void* param_2) {
int r29 = field_0x12;
for (int i = 0; i < r29; i++) {
Vec* pVec1 = (Vec*)param_1 + field_0x4[i];
Vec* pVec2 = (Vec*)param_2 + field_0x4[i];
f32 weight = field_0xc[i];
J3DPSWeightMTXMultVecSR(param_0, weight, pVec1, pVec2);
}
}
J3DSkinDeform::J3DSkinDeform() {
mPosData = NULL;
mNrmData = NULL;
mPosMtx = NULL;
mNrmMtx = NULL;
mFlags = 3;
field_0x18 = 1;
field_0x19 = 0;
field_0x1c = 0;
field_0x20 = 0;
mSkinNList = NULL;
}
u16* J3DSkinDeform::sWorkArea_WEvlpMixMtx[1024];
f32* J3DSkinDeform::sWorkArea_WEvlpMixWeight[1024];
void J3DSkinDeform::initSkinInfo(J3DModelData* pModelData) {
J3D_ASSERT_NULLPTR(322, pModelData != NULL);
int vtxNum = pModelData->getVtxNum();
int wevlpMtxNum = pModelData->getWEvlpMtxNum();
u16* wevlpMtxIndex = pModelData->getWEvlpMixMtxIndex();
f32* wevlpMixWeights = pModelData->getWEvlpMixWeight();
int currentOffset = 0;
for (int i = 0; i < wevlpMtxNum; i++) {
sWorkArea_WEvlpMixMtx[i] = wevlpMtxIndex + currentOffset;
sWorkArea_WEvlpMixWeight[i] = wevlpMixWeights + currentOffset;
currentOffset += pModelData->getWEvlpMixMtxNum(i);
}
if (pModelData->getJointNum() != 0) {
mSkinNList = new J3DSkinNList[pModelData->getJointNum()];
}
for (int i = 0; i < pModelData->getVtxNum(); i++) {
u16 uVar8 = mPosData[i];
if (uVar8 != 0xffff) {
if (!pModelData->getDrawMtxFlag(uVar8)) {
u16 drawMtxIndex = pModelData->getDrawMtxIndex(uVar8);
mSkinNList[drawMtxIndex].field_0x10++;
} else {
u16 drawMtxIndex = pModelData->getDrawMtxIndex(uVar8);
int wevlpMtxNum = pModelData->getWEvlpMixMtxNum(drawMtxIndex);
u16* indices = sWorkArea_WEvlpMixMtx[drawMtxIndex];
for (int j = 0; j < wevlpMtxNum; j++) {
mSkinNList[indices[j]].field_0x10++;
}
}
}
}
for (int i = 0; i < pModelData->getNrmNum(); i++) {
u16 uVar8 = mNrmData[i];
if (uVar8 != 0xffff) {
if (!pModelData->getDrawMtxFlag(uVar8)) {
u16 drawMtxIndex = pModelData->getDrawMtxIndex(uVar8);
mSkinNList[drawMtxIndex].field_0x12++;
} else {
u16 drawMtxIndex = pModelData->getDrawMtxIndex(uVar8);
int wevlpMtxNum = pModelData->getWEvlpMixMtxNum(drawMtxIndex);
u16* indices = sWorkArea_WEvlpMixMtx[drawMtxIndex];
for (int j = 0; j < wevlpMtxNum; j++) {
mSkinNList[indices[j]].field_0x12++;
}
}
}
}
for (u16 i = 0; i < pModelData->getJointNum(); i++) {
if (mSkinNList[i].field_0x10) {
mSkinNList[i].field_0x0 = new u16[mSkinNList[i].field_0x10];
mSkinNList[i].field_0x8 = new f32[mSkinNList[i].field_0x10];
mSkinNList[i].field_0x10 = 0;
}
if (mSkinNList[i].field_0x12) {
mSkinNList[i].field_0x4 = new u16[mSkinNList[i].field_0x12];
mSkinNList[i].field_0xc = new f32[mSkinNList[i].field_0x12];
mSkinNList[i].field_0x12 = 0;
}
}
for (int i = 0; i < pModelData->getVtxNum(); i++) {
u16 uVar8 = mPosData[i];
if (uVar8 != 0xffff) {
if (!pModelData->getDrawMtxFlag(uVar8)) {
u16 drawMtxIndex = pModelData->getDrawMtxIndex(uVar8);
int uVar9 = mSkinNList[drawMtxIndex].field_0x10++;
mSkinNList[drawMtxIndex].field_0x0[uVar9] = i;
mSkinNList[drawMtxIndex].field_0x8[uVar9] = 1.0f;
} else {
u16 drawMtxIndex = pModelData->getDrawMtxIndex(uVar8);
int wevlpMtxNum = pModelData->getWEvlpMixMtxNum(drawMtxIndex);
u16* indices = sWorkArea_WEvlpMixMtx[drawMtxIndex];
f32* weights = sWorkArea_WEvlpMixWeight[drawMtxIndex];
for (int j = 0; j < wevlpMtxNum; j++) {
int uVar9 = mSkinNList[indices[j]].field_0x10++;
mSkinNList[indices[j]].field_0x0[uVar9] = i;
mSkinNList[indices[j]].field_0x8[uVar9] = weights[j];
}
}
}
}
for (int i = 0; i < pModelData->getNrmNum(); i++) {
u16 uVar8 = mNrmData[i];
if (uVar8 != 0xffff) {
if (!pModelData->getDrawMtxFlag(uVar8)) {
u16 drawMtxIndex = pModelData->getDrawMtxIndex(uVar8);
int uVar9 = mSkinNList[drawMtxIndex].field_0x12++;
mSkinNList[drawMtxIndex].field_0x4[uVar9] = i;
mSkinNList[drawMtxIndex].field_0xc[uVar9] = 1.0f;
} else {
u16 drawMtxIndex = pModelData->getDrawMtxIndex(uVar8);
int wevlpMtxNum = pModelData->getWEvlpMixMtxNum(drawMtxIndex);
u16* indices = sWorkArea_WEvlpMixMtx[drawMtxIndex];
f32* weights = sWorkArea_WEvlpMixWeight[drawMtxIndex];
for (int j = 0; j < wevlpMtxNum; j++) {
int uVar9 = mSkinNList[indices[j]].field_0x12++;
mSkinNList[indices[j]].field_0x4[uVar9] = i;
mSkinNList[indices[j]].field_0xc[uVar9] = weights[j];
}
}
}
}
}
u16 J3DSkinDeform::sWorkArea_MtxReg[1024];
int J3DSkinDeform::initMtxIndexArray(J3DModelData* pModelData) {
J3D_ASSERT_NULLPTR(507, pModelData != NULL);
if (mPosData != NULL && mNrmData != NULL) {
return kJ3DError_Success;
}
mPosData = new u16[pModelData->getVtxNum()];
if (mPosData == NULL) {
return kJ3DError_Alloc;
}
for (int i = 0; i < pModelData->getVtxNum(); i++) {
mPosData[i] = 0xffff;
}
if (pModelData->getNrmNum()) {
mNrmData = new u16[pModelData->getNrmNum()];
if (mNrmData == NULL) {
return kJ3DError_Alloc;
}
for (int i = 0; i < pModelData->getNrmNum(); i++) {
mNrmData[i] = 0;
}
} else {
mNrmData = NULL;
}
mPosMtx = new Mtx[pModelData->getJointNum()];
mNrmMtx = new (32) Mtx33[pModelData->getDrawMtxNum()];
if (mPosMtx == NULL) {
return kJ3DError_Alloc;
}
if (mNrmMtx == NULL) {
return kJ3DError_Alloc;
}
for (u16 i = 0; i < pModelData->getShapeNum(); i++) {
u32 kSize[4] = {0, 1, 1, 2};
int pnmtx_num = -1;
int vtx_num = -1;
int nrm_num = -1;
int tex_num = -1;
int r23 = 0;
for (GXVtxDescList* vtxDesc = pModelData->getShapeNodePointer(i)->getVtxDesc(); vtxDesc->attr != 0xff; vtxDesc++) {
switch (vtxDesc->attr) {
case GX_VA_PNMTXIDX:
pnmtx_num = r23;
break;
case GX_VA_POS:
vtx_num = r23;
if (vtxDesc->type != GX_INDEX16) {
OSReport(" Invlid Data : CPU Pipeline process GX_INDEX16 Data Only\n");
return 6;
}
break;
case GX_VA_NRM:
nrm_num = r23;
if (vtxDesc->type != GX_INDEX16) {
OSReport(" Invlid Data : CPU Pipeline process GX_INDEX16 Data Only\n");
return 6;
}
break;
case GX_VA_TEX0:
tex_num = r23;
if (vtxDesc->type != GX_INDEX16) {
OSReport(" Invlid Data : CPU Pipeline process GX_INDEX16 Data Only\n");
return 6;
}
break;
}
r23 += kSize[(int)vtxDesc->type];
}
for (u16 j = 0; j < (u16)pModelData->getShapeNodePointer(i)->getMtxGroupNum(); j++) {
J3DShapeMtx* pShapeMtx = pModelData->getShapeNodePointer(i)->getShapeMtx(j);
u8* pDList = pModelData->getShapeNodePointer(i)->getShapeDraw(j)->getDisplayList();
u8* pDListPos = pDList;
int uVar13;
for (;
(intptr_t)pDListPos - (intptr_t)pDList < pModelData->getShapeNodePointer(i)->getShapeDraw(j)->getDisplayListSize();
pDListPos += r23 * uVar13
//TODO: This loop's logic has drastically different codegen between GCN and Shield
// in a way that so far can't be pinned down as just compiler differences. This
// may have been refactored in the J3D version used for Shield, but note that
// it's very possible that this is a fakematch and there's some other way of
// expressing it that matches for both versions.
#if PLATFORM_GCN
, pDListPos += 3
#endif
)
{
u8 command = *pDListPos;
#if !PLATFORM_GCN
pDListPos++;
#endif
if (command != GX_TRIANGLEFAN && command != GX_TRIANGLESTRIP) {
break;
}
#if PLATFORM_GCN
uVar13 = *(u16*)(pDListPos + 1);
#else
uVar13 = *(u16*)pDListPos;
pDListPos += 2;
#endif
for (int local_60 = 0; local_60 < uVar13; local_60++) {
#if PLATFORM_GCN
u8* iVar5 = ((u8*)(pDListPos + 3) + r23 * local_60);
#else
u8* iVar5 = ((u8*)pDListPos + r23 * local_60);
#endif
u8 bVar3 = *(u8*)(iVar5 + pnmtx_num) / 3U;
u16 vtx_idx = *(u16*)(iVar5 + vtx_num);
u16 nrm_idx = *(u16*)(iVar5 + nrm_num);
u16 uVar3 = *(u16*)(iVar5 + tex_num);
u16 local_76 = pShapeMtx->getUseMtxIndex(bVar3);
if (local_76 == 0xffff) {
local_76 = sWorkArea_MtxReg[bVar3];
} else if (pnmtx_num != -1) {
sWorkArea_MtxReg[bVar3] = local_76;
}
J3D_ASSERT_RANGE(673, local_76 < pModelData->getDrawMtxNum());
J3D_ASSERT_RANGE(674, vtx_idx < pModelData->getVtxNum());
mPosData[vtx_idx] = local_76;
if (nrm_num != -1) {
J3D_ASSERT_RANGE(680, nrm_idx < pModelData->getNrmNum());
mNrmData[nrm_idx] = local_76;
}
}
}
if (nrm_num == -1) {
pModelData->getShapeNodePointer(i)->onFlag(J3DShpFlag_EnableLod);
pModelData->getShapeNodePointer(i)->offFlag(J3DShpFlag_SkinNrmCpu);
}
}
}
for (int i = 0; i < pModelData->getVtxNum(); i++) {
if (mPosData[i] == 0xffff) {
field_0x18 = 0x0;
mPosData[i] = 0;
OS_REPORT("Error : Invalid Positon Data Exists!.");
OS_REPORT("Error : Invalid Positon Index = %d\n", i);
}
}
return kJ3DError_Success;
}
void J3DSkinDeform::changeFastSkinDL(J3DModelData* pModelData) {
J3D_ASSERT_NULLPTR(740, pModelData != NULL);
for (u16 i = 0; i < pModelData->getShapeNum(); i++) {
u32 kSize[4] = {0,1,1,2};
int pnmtxIdxOffs = -1;
int vtxSize = 0;
J3DShape* pShapeNode = pModelData->getShapeNodePointer(i);
for (GXVtxDescList* vtxDesc = pShapeNode->getVtxDesc(); vtxDesc->attr != GX_VA_NULL; vtxDesc++) {
if (vtxDesc->attr == GX_VA_PNMTXIDX) {
pnmtxIdxOffs = vtxSize;
}
vtxSize += kSize[vtxDesc->type];
}
if (pnmtxIdxOffs != -1) {
for (u16 j = 0; j < (u16)pShapeNode->getMtxGroupNum(); j++) {
u8* displayListStart = pShapeNode->getShapeDraw(j)->getDisplayList();
u8* dl = displayListStart;
u8* dst = displayListStart;
while ((dl - displayListStart) < pShapeNode->getShapeDraw(j)->getDisplayListSize()) {
u8 cmd = *dl;
dl++;
*dst++ = cmd;
if (cmd != GX_TRIANGLEFAN && cmd != GX_TRIANGLESTRIP)
break;
int vtxCount = *(u16*)dl;
dl += 2;
*(u16*)dst = vtxCount;
dst += 2;
for (int k = 0; k < vtxCount; k++) {
u8* src = &dl[vtxSize * k];
memcpy(dst, src + 1, (int)(vtxSize - 1)); // The -1 is to remove GX_VA_PNMTXIDX
dst += (int)(vtxSize - 1);
}
dl = (u8*)dl + vtxSize * vtxCount;
}
int dlistSize = ((intptr_t)dst - (intptr_t)displayListStart + 0x1f) & ~0x1f;
while ((intptr_t)dst - (intptr_t)displayListStart < pShapeNode->getShapeDraw(j)->getDisplayListSize()) {
*dst++ = 0;
}
pShapeNode->getShapeDraw(j)->setDisplayListSize(dlistSize);
DCStoreRange(displayListStart, pShapeNode->getShapeDraw(j)->getDisplayListSize());
}
}
}
for (u16 i = 0; i < pModelData->getShapeNum(); i++) {
J3DShape* shape = pModelData->getShapeNodePointer(i);
GXVtxDescList* desc = shape->getVtxDesc();
GXVtxDescList* descDst = desc;
for (; desc->attr != GX_VA_NULL; desc++) {
if (desc->attr != GX_VA_PNMTXIDX) {
descDst->attr = desc->attr;
descDst->type = desc->type;
descDst++;
}
}
descDst->attr = GX_VA_NULL;
descDst->type = GX_NONE;
shape->makeVcdVatCmd();
}
}
void J3DSkinDeform::calcNrmMtx(J3DMtxBuffer* pMtxBuffer) {
J3DJointTree* jointTree = pMtxBuffer->getJointTree();
u16 drawMtxNum = jointTree->getDrawMtxNum();
for (u16 i = 0; i < drawMtxNum; i++) {
if (jointTree->getDrawMtxFlag(i) == 0) {
if (pMtxBuffer->getScaleFlag(jointTree->getDrawMtxIndex(i)) == 1) {
setNrmMtx(i, pMtxBuffer->getAnmMtx(jointTree->getDrawMtxIndex(i)));
} else {
J3DPSCalcInverseTranspose(pMtxBuffer->getAnmMtx(jointTree->getDrawMtxIndex(i)), getNrmMtx(i));
}
} else {
if (pMtxBuffer->getEnvScaleFlag(jointTree->getDrawMtxIndex(i)) == 1) {
setNrmMtx(i, pMtxBuffer->getWeightAnmMtx(jointTree->getDrawMtxIndex(i)));
} else {
J3DPSCalcInverseTranspose(pMtxBuffer->getWeightAnmMtx(jointTree->getDrawMtxIndex(i)), getNrmMtx(i));
}
}
}
}
void J3DSkinDeform::transformVtxPosNrm(J3DModelData* pModelData) {
if (pModelData->getWEvlpMtxNum() != 0 && field_0x19 == 0) {
int vtmNum = pModelData->getVtxNum();
int nrmNum = pModelData->getNrmNum();
for (int i = 0; i < vtmNum; i++) {
u16 posIndex = mPosData[i];
if (pModelData->getDrawMtxFlag(posIndex) == 0) {
u16 drawMtxIndex = pModelData->getDrawMtxIndex(posIndex);
Vec* pos = ((Vec*)pModelData->getVtxPosArray()) + i;
Mtx invMtx;
MTXInverse(pModelData->getInvJointMtx(drawMtxIndex), invMtx);
MTXMultVec(invMtx, pos, pos);
}
}
for (int i = 0; i < nrmNum; i++) {
u16 nrmIndex = mNrmData[i];
if (pModelData->getDrawMtxFlag(nrmIndex) == 0) {
u16 drawMtxIndex = pModelData->getDrawMtxIndex(nrmIndex);
Vec* nrm = ((Vec*)pModelData->getVtxNrmArray()) + i;
Mtx invMtx;
MTXInverse(pModelData->getInvJointMtx(drawMtxIndex), invMtx);
MTXMultVecSR(invMtx, nrm, nrm);
}
}
field_0x19 = 1;
}
}
void J3DSkinDeform::calcAnmInvJointMtx(J3DMtxBuffer* pMtxBuffer) {
J3D_ASSERT_NULLPTR(978, pMtxBuffer != NULL);
if (pMtxBuffer->getJointTree()->getWEvlpMtxNum() != 0) {
int jointNum = pMtxBuffer->getJointTree()->getJointNum();
Mtx* anmMtx = (Mtx*)pMtxBuffer->getAnmMtx(0);
Mtx* invJointMtx = &pMtxBuffer->getJointTree()->getInvJointMtx(0);
Mtx* posMtx = mPosMtx;
for (int i = 0; i < jointNum; i++) {
MTXConcat(anmMtx[i], invJointMtx[i], posMtx[i]);
}
}
}
void J3DSkinDeform::deformFastVtxPos_F32(J3DVertexBuffer* pVtxBuffer, J3DMtxBuffer* pMtxBuffer) const {
pVtxBuffer->swapTransformedVtxPos();
J3DJointTree* jointTree = pMtxBuffer->getJointTree();
u32 vtxNum = pVtxBuffer->getVertexData()->getVtxNum();
int sp14 = jointTree->getDrawMtxNum();
void* currentVtxPos = pVtxBuffer->getCurrentVtxPos();
void* transformedVtxPos = pVtxBuffer->getTransformedVtxPos(0);
J3DFillZero32B(transformedVtxPos, OSRoundUp32B(vtxNum * sizeof(Vec)));
if (jointTree->getWEvlpMtxNum() != 0) {
u16 jointNum = jointTree->getJointNum();
for (u16 i = 0; i < jointNum; i++) {
J3DSkinNList* skinList = mSkinNList + i;
skinList->calcSkin_VtxPosF32(mPosMtx[i], currentVtxPos, transformedVtxPos);
}
} else {
u16 jointNum = jointTree->getJointNum();
for (u16 i = 0; i < jointNum; i++) {
J3DSkinNList* skinList = mSkinNList + i;
skinList->calcSkin_VtxPosF32(pMtxBuffer->getAnmMtx(i), currentVtxPos, transformedVtxPos);
}
}
DCStoreRange(pVtxBuffer->getTransformedVtxPos(0), pVtxBuffer->getVertexData()->getVtxNum() * sizeof(Vec));
pVtxBuffer->setCurrentVtxPos(transformedVtxPos);
}
void J3DSkinDeform::deformFastVtxNrm_F32(J3DVertexBuffer* pVtxBuffer, J3DMtxBuffer* pMtxBuffer) const {
pVtxBuffer->swapTransformedVtxNrm();
J3DJointTree* jointTree = pMtxBuffer->getJointTree();
int nrmNum = pVtxBuffer->getVertexData()->getNrmNum();
int sp18 = jointTree->getDrawMtxNum();
void* currentVtxNrm = pVtxBuffer->getCurrentVtxNrm();
void* transformedVtxNrm = pVtxBuffer->getTransformedVtxNrm(0);
for (int i = 0; i < nrmNum; i++) {
((f32*)transformedVtxNrm)[(i * 3) + 0] = 0.0f;
((f32*)transformedVtxNrm)[(i * 3) + 1] = 0.0f;
((f32*)transformedVtxNrm)[(i * 3) + 2] = 0.0f;
}
if (jointTree->getWEvlpMtxNum() != 0) {
u16 jointNum = jointTree->getJointNum();
for (u16 i = 0; i < jointNum; i++) {
J3DSkinNList* skinList = mSkinNList + i;
skinList->calcSkin_VtxNrmF32(mPosMtx[i], currentVtxNrm, transformedVtxNrm);
}
} else {
u16 jointNum = jointTree->getJointNum();
for (u16 i = 0; i < jointNum; i++) {
J3DSkinNList* skinList = mSkinNList + i;
skinList->calcSkin_VtxNrmF32(pMtxBuffer->getAnmMtx(i), currentVtxNrm, transformedVtxNrm);
}
}
DCStoreRange(pVtxBuffer->getTransformedVtxNrm(0), pVtxBuffer->getVertexData()->getNrmNum() * sizeof(Vec));
pVtxBuffer->setCurrentVtxNrm(transformedVtxNrm);
}
void J3DSkinDeform::deformVtxPos_F32(J3DVertexBuffer* pVtxBuffer, J3DMtxBuffer* pMtxBuffer) const {
Mtx* anmMtx = NULL;
Mtx* anmMtxs[2];
anmMtxs[0] = (Mtx*)pMtxBuffer->getAnmMtx(0);
anmMtxs[1] = (Mtx*)pMtxBuffer->getWeightAnmMtx(0);
pVtxBuffer->swapTransformedVtxPos();
J3DJointTree* jointTree = pMtxBuffer->getJointTree();
int vtxNum = pVtxBuffer->getVertexData()->getVtxNum();
int sp8 = jointTree->getDrawMtxNum();
void* currentVtxPos = (void*)pVtxBuffer->getCurrentVtxPos();
void* transformedVtxPos = (void*)pVtxBuffer->getTransformedVtxPos(0);
for (int i = 0; i < vtxNum; i++) {
anmMtx = anmMtxs[jointTree->getDrawMtxFlag(mPosData[i])];
J3DPSMulMtxVec(anmMtx[jointTree->getDrawMtxIndex(mPosData[i])], (Vec*)(((f32*)currentVtxPos) + (i * 3)), (Vec*)(((f32*)transformedVtxPos) + (i * 3)));
}
DCStoreRange(pVtxBuffer->getTransformedVtxPos(0), pVtxBuffer->getVertexData()->getVtxNum() * sizeof(Vec));
pVtxBuffer->setCurrentVtxPos(transformedVtxPos);
}
void J3DSkinDeform::deformVtxPos_S16(J3DVertexBuffer* pVtxBuffer, J3DMtxBuffer* pMtxBuffer) const {
Mtx* anmMtx = NULL;
Mtx* anmMtxs[2];
anmMtxs[0] = (Mtx*)pMtxBuffer->getAnmMtx(0);
anmMtxs[1] = (Mtx*)pMtxBuffer->getWeightAnmMtx(0);
int vtxPosFrac = pVtxBuffer->getVertexData()->getVtxPosFrac();
J3DGQRSetup7(vtxPosFrac, 7, vtxPosFrac, 7);
pVtxBuffer->swapTransformedVtxPos();
J3DJointTree* jointTree = pMtxBuffer->getJointTree();
int vtxNum = pVtxBuffer->getVertexData()->getVtxNum();
int sp8 = jointTree->getDrawMtxNum();
void* currentVtxPos = (void*)pVtxBuffer->getCurrentVtxPos();
void* transformedVtxPos = (void*)pVtxBuffer->getTransformedVtxPos(0);
for (int i = 0; i < vtxNum; i++) {
anmMtx = anmMtxs[jointTree->getDrawMtxFlag(mPosData[i])];
J3DPSMulMtxVec(anmMtx[jointTree->getDrawMtxIndex(mPosData[i])], (S16Vec*)(((s16*)currentVtxPos) + (i * 3)), (S16Vec*)(((s16*)transformedVtxPos) + (i * 3)));
}
DCStoreRange(pVtxBuffer->getTransformedVtxPos(0), pVtxBuffer->getVertexData()->getVtxNum() * sizeof(S16Vec));
pVtxBuffer->setCurrentVtxPos(transformedVtxPos);
}
void J3DSkinDeform::deformVtxNrm_F32(J3DVertexBuffer* pVtxBuffer) const {
pVtxBuffer->swapTransformedVtxNrm();
int nrmNum = pVtxBuffer->getVertexData()->getNrmNum();
void* currentVtxNrm = (void*)pVtxBuffer->getCurrentVtxNrm();
void* transformedVtxNrm = (void*)pVtxBuffer->getTransformedVtxNrm(0);
for (int i = 0; i < nrmNum; i++) {
J3DPSMulMtxVec(mNrmMtx[mNrmData[i]], (Vec*)((u8*)currentVtxNrm + i * 3 * 4), (Vec*)((u8*)transformedVtxNrm + i * 3 * 4));
}
DCStoreRange(pVtxBuffer->getTransformedVtxNrm(0), pVtxBuffer->getVertexData()->getNrmNum() * sizeof(Vec));
pVtxBuffer->setCurrentVtxNrm(transformedVtxNrm);
}
void J3DSkinDeform::deformVtxNrm_S16(J3DVertexBuffer* pVtxBuffer) const {
int vtxNrmFrac = pVtxBuffer->getVertexData()->getVtxNrmFrac();
J3DGQRSetup7(vtxNrmFrac, 7, vtxNrmFrac, 7);
pVtxBuffer->swapTransformedVtxNrm();
int nrmNum = pVtxBuffer->getVertexData()->getNrmNum();
void* currentVtxNrm = (void*)pVtxBuffer->getCurrentVtxNrm();
void* transformedVtxNrm = (void*)pVtxBuffer->getTransformedVtxNrm(0);
for (int i = 0; i < nrmNum; i++) {
J3DPSMulMtxVec(mNrmMtx[mNrmData[i]], (S16Vec*)(((s16*)currentVtxNrm) + (i * 3)), (S16Vec*)(((s16*)transformedVtxNrm) + (i * 3)));
}
DCStoreRange(pVtxBuffer->getTransformedVtxNrm(0), pVtxBuffer->getVertexData()->getNrmNum() * sizeof(S16Vec));
pVtxBuffer->setCurrentVtxNrm(transformedVtxNrm);
}
void J3DSkinDeform::deform(J3DModel* pModel) {
J3D_ASSERT_NULLPTR(1270, pModel != NULL);
if (pModel->checkFlag(J3DMdlFlag_SkinPosCpu)) {
onFlag(2);
} else {
offFlag(2);
}
if (pModel->checkFlag(J3DMdlFlag_SkinNrmCpu)) {
onFlag(1);
} else {
offFlag(1);
}
deform(pModel->getVertexBuffer(), pModel->getMtxBuffer());
}
void J3DSkinDeform::deform(J3DVertexBuffer* pVtxBuffer, J3DMtxBuffer* pMtxBuffer) {
J3D_ASSERT_NULLPTR(1299, pVtxBuffer != NULL);
J3D_ASSERT_NULLPTR(1300, pMtxBuffer != NULL);
if (pMtxBuffer->getJointTree()->checkFlag(0x100)) {
calcAnmInvJointMtx(pMtxBuffer);
}
if (checkFlag(2) != 0) {
if (pMtxBuffer->getJointTree()->checkFlag(0x100)) {
deformFastVtxPos_F32(pVtxBuffer, pMtxBuffer);
} else {
if (pVtxBuffer->getVertexData()->getVtxPosType() == 4) {
deformVtxPos_F32(pVtxBuffer, pMtxBuffer);
} else {
deformVtxPos_S16(pVtxBuffer, pMtxBuffer);
}
}
}
if (checkFlag(1)) {
if (pMtxBuffer->getJointTree()->checkFlag(0x100)) {
deformFastVtxNrm_F32(pVtxBuffer, pMtxBuffer);
} else {
calcNrmMtx(pMtxBuffer);
if (pVtxBuffer->getVertexData()->getVtxNrmType() == 4) {
deformVtxNrm_F32(pVtxBuffer);
} else {
deformVtxNrm_S16(pVtxBuffer);
}
}
}
}
void J3DVtxColorCalc::calc(J3DModel* pModel) {
J3D_ASSERT_NULLPTR(1351, pModel != NULL);
calc(pModel->getVertexBuffer());
}
void J3DVtxColorCalc::calc(J3DVertexBuffer* buffer) {
J3D_ASSERT_NULLPTR(1366, buffer != NULL);
if (checkFlag(1) && mpVtxColor) {
buffer->swapVtxColArrayPointer();
u16 anmTableNum = mpVtxColor->getAnmTableNum(0);
GXColor* colorArray = buffer->getVtxColArrayPointer(0);
for (u32 i = 0; i < anmTableNum; i++) {
GXColor color;
mpVtxColor->getColor(0, i, &color);
J3DAnmVtxColorIndexData* r28 = mpVtxColor->getAnmVtxColorIndexData(0, i);
for (u32 j = 0; j < r28->mNum; j++) {
colorArray[((u16*)r28->mpData)[j]] = color;
}
}
DCStoreRange(colorArray, buffer->getVertexData()->getColNum() * 4);
buffer->setCurrentVtxCol(colorArray);
}
}
J3DSkinDeform::~J3DSkinDeform() {}