marioparty4/src/game/EnvelopeExec.c
2025-04-19 03:15:44 +02:00

467 lines
16 KiB
C

#include "game/EnvelopeExec.h"
#include "game/hsfex.h"
#include "string.h"
static void SetEnvelopMtx(HsfObject *arg0, HsfObject *arg1, Mtx arg2);
static void SetEnvelopMain(HsfData *arg0);
static void SetEnvelop(HsfCenv *arg0);
static void SetMtx(HsfObject *arg0, Mtx arg1);
static void SetRevMtx(void);
static HsfSkeleton *SearchSklenton(char *arg0);
Vec *Vertextop;
Mtx *MtxTop;
static u32 nObj;
static u32 nMesh;
static HsfObject *objtop;
static HsfData *CurHsf;
static Vec *vtxenv;
static Vec *normenv;
static Vec *normtop;
static s32 Meshcnt;
static s32 Meshno;
void InitEnvelope(HsfData *arg0) {
HsfBuffer *spC;
HsfBuffer *sp8;
HsfMatrix *temp_r28;
HsfObject *var_r31;
HsfSkeleton *var_r30;
Mtx sp10;
s32 i;
s32 j;
if (arg0->cenvCnt != 0) {
var_r31 = arg0->object;
for (Meshcnt = i = 0; i < arg0->objectCnt; i++, var_r31++) {
if (var_r31->type == 2) {
if (var_r31->data.vtxtop) {
spC = var_r31->data.vertex;
sp8 = var_r31->data.normal;
Meshcnt++;
} else {
continue;
}
}
var_r30 = arg0->skeleton;
for (j = 0; j < arg0->skeletonCnt; j++, var_r30++) {
if (strcmp(var_r31->name, var_r30->name) == 0) {
var_r31->data.base.pos.x = var_r30->transform.pos.x;
var_r31->data.base.pos.y = var_r30->transform.pos.y;
var_r31->data.base.pos.z = var_r30->transform.pos.z;
var_r31->data.base.rot.x = var_r30->transform.rot.x;
var_r31->data.base.rot.y = var_r30->transform.rot.y;
var_r31->data.base.rot.z = var_r30->transform.rot.z;
var_r31->data.base.scale.x = var_r30->transform.scale.x;
var_r31->data.base.scale.y = var_r30->transform.scale.y;
var_r31->data.base.scale.z = var_r30->transform.scale.z;
}
}
var_r31->data.curr.pos.x = var_r31->data.base.pos.x;
var_r31->data.curr.pos.y = var_r31->data.base.pos.y;
var_r31->data.curr.pos.z = var_r31->data.base.pos.z;
var_r31->data.curr.rot.x = var_r31->data.base.rot.x;
var_r31->data.curr.rot.y = var_r31->data.base.rot.y;
var_r31->data.curr.rot.z = var_r31->data.base.rot.z;
var_r31->data.curr.scale.x = var_r31->data.base.scale.x;
var_r31->data.curr.scale.y = var_r31->data.base.scale.y;
var_r31->data.curr.scale.z = var_r31->data.base.scale.z;
}
CurHsf = arg0;
objtop = arg0->object;
temp_r28 = CurHsf->matrix;
if (temp_r28) {
MtxTop = temp_r28->data;
nObj = temp_r28->count;
nMesh = temp_r28->base_idx;
}
MTXIdentity(sp10);
SetMtx(arg0->root, sp10);
SetRevMtx();
}
}
static void SetEnvelopMtx(HsfObject *arg0, HsfObject *arg1, Mtx arg2) {
Mtx sp6C;
Mtx sp3C;
Mtx spC;
s32 var_r29;
s32 i;
MTXTrans(spC, arg1->data.curr.pos.x, arg1->data.curr.pos.y, arg1->data.curr.pos.z);
MTXConcat(arg2, spC, sp3C);
if (arg1->data.curr.rot.z) {
MTXRotRad(sp6C, 'z', MTXDegToRad(arg1->data.curr.rot.z));
MTXConcat(sp3C, sp6C, sp3C);
}
if (arg1->data.curr.rot.y) {
MTXRotRad(sp6C, 'y', MTXDegToRad(arg1->data.curr.rot.y));
MTXConcat(sp3C, sp6C, sp3C);
}
if (arg1->data.curr.rot.x) {
MTXRotRad(sp6C, 'x', MTXDegToRad(arg1->data.curr.rot.x));
MTXConcat(sp3C, sp6C, sp3C);
}
if (arg1->data.curr.scale.x != 1.0f) {
sp3C[0][0] *= arg1->data.curr.scale.x;
sp3C[1][0] *= arg1->data.curr.scale.x;
sp3C[2][0] *= arg1->data.curr.scale.x;
}
if (arg1->data.curr.scale.y != 1.0f) {
sp3C[0][1] *= arg1->data.curr.scale.y;
sp3C[1][1] *= arg1->data.curr.scale.y;
sp3C[2][1] *= arg1->data.curr.scale.y;
}
if (arg1->data.curr.scale.z != 1.0f) {
sp3C[0][2] *= arg1->data.curr.scale.z;
sp3C[1][2] *= arg1->data.curr.scale.z;
sp3C[2][2] *= arg1->data.curr.scale.z;
}
var_r29 = arg1 - arg0;
MTXCopy(sp3C, MtxTop[nMesh + var_r29]);
for (i = 0; i < arg1->data.childrenCount; i++) {
SetEnvelopMtx(arg0, arg1->data.children[i], sp3C);
}
}
void EnvelopeProc(HsfData *arg0) {
#ifdef TARGET_PC
// TODO PC still buggy
return;
#endif
HsfMatrix *temp_r31;
HsfObject *temp_r29;
Mtx sp8;
CurHsf = arg0;
temp_r31 = CurHsf->matrix;
MtxTop = temp_r31->data;
nObj = temp_r31->count;
nMesh = temp_r31->base_idx;
temp_r29 = arg0->root;
MTXIdentity(sp8);
SetEnvelopMtx(arg0->object, temp_r29, sp8);
SetEnvelopMain(arg0);
}
void InitVtxParm(HsfData *arg0) {
HsfObject *var_r31;
s32 i;
var_r31 = arg0->object;
for (i = 0; i < arg0->objectCnt; i++, var_r31++) {
if (var_r31->type == 2) {
var_r31->data.unk120[0] = 0;
}
}
}
static void SetEnvelopMain(HsfData *arg0) {
void *sp10;
void *spC;
void *sp8;
HsfBuffer *temp_r28;
HsfBuffer *temp_r30;
HsfObject *var_r31;
s32 i;
s32 j;
HsfCenv *var_r25;
var_r31 = arg0->object;
for (Meshno = i = 0; i < arg0->objectCnt; i++, var_r31++) {
if (var_r31->type == 2) {
MTXInverse(MtxTop[&var_r31[nMesh] - arg0->object], MtxTop[Meshno]);
temp_r30 = var_r31->data.vertex;
temp_r28 = var_r31->data.normal;
if (var_r31->data.unk120[0] != 0) {
Vertextop = temp_r30->data;
} else {
Vertextop = (Vec*)var_r31->data.vtxtop;
}
vtxenv = temp_r30->data;
normtop = (Vec*)var_r31->data.normtop;
normenv = temp_r28->data;
var_r25 = var_r31->data.cenv;
for (j = 0; j < var_r31->data.cenvCnt; j++, var_r25++) {
SetEnvelop(var_r25);
}
sp10 = temp_r30->data;
spC = var_r31->data.vtxtop;
sp8 = temp_r30->data;
DCStoreRangeNoSync(normenv, temp_r28->count * sizeof(Vec));
DCStoreRangeNoSync(vtxenv, temp_r30->count * sizeof(Vec));
Meshno++;
}
}
}
static void SetEnvelop(HsfCenv *arg0) {
Vec sp44;
Vec sp38;
Vec sp2C;
Vec sp20;
Vec sp14;
s32 sp10;
u32 spC;
u32 sp8;
HsfCenvDual *var_r20;
HsfCenvDualWeight *var_r30;
HsfCenvMulti *var_r19;
HsfCenvMultiWeight *var_r25;
HsfCenvSingle *var_r27;
Vec *temp_r22;
Vec *temp_r26;
Vec *temp_r28;
Vec *temp_r31;
float temp_f31;
MtxPtr var_r29;
s32 temp_r18;
s32 temp_r21;
s32 i;
s32 j;
Mtx sp1A0;
Mtx sp170;
Mtx sp140;
Mtx sp110;
Mtx spE0;
Mtx spB0;
Mtx sp80;
Mtx sp50;
var_r27 = arg0->singleData;
for (i = 0; i < arg0->singleCount; i++, var_r27++) {
temp_r18 = var_r27->normal;
temp_r21 = var_r27->pos;
temp_r28 = &vtxenv[temp_r21];
temp_r31 = &Vertextop[temp_r21];
temp_r22 = &normenv[temp_r18];
temp_r26 = &normtop[temp_r18];
MTXConcat(MtxTop[nMesh + var_r27->target], MtxTop[nMesh + nObj + nObj * Meshno + var_r27->target], sp140);
MTXConcat(MtxTop[Meshno], sp140, sp1A0);
Hu3DMtxScaleGet(&sp1A0[0], &sp14);
if (sp14.x != 1.0f || sp14.y != 1.0f || sp14.z != 1.0f) {
MTXScale(spE0, 1.0 / sp14.x, 1.0 / sp14.y, 1.0 / sp14.z);
MTXConcat(spE0, sp1A0, sp170);
MTXInvXpose(sp170, sp170);
} else {
MTXInvXpose(sp1A0, sp170);
}
if (var_r27->posCnt == 1) {
MTXMultVec(sp1A0, temp_r31, temp_r28);
MTXMultVec(sp170, temp_r26, temp_r22);
} else if (var_r27->posCnt <= 6) {
MTXMultVecArray(sp1A0, temp_r31, temp_r28, var_r27->posCnt);
MTXMultVecArray(sp170, temp_r26, temp_r22, var_r27->normalCnt);
} else {
MTXReorder(sp1A0, (ROMtxPtr) sp140);
MTXReorder(sp170, (ROMtxPtr) sp110);
MTXROMultVecArray((ROMtxPtr) sp140, temp_r31, temp_r28, var_r27->posCnt);
MTXROMultVecArray((ROMtxPtr) sp110, temp_r26, temp_r22, var_r27->normalCnt);
}
}
var_r20 = arg0->dualData;
for (i = 0; i < arg0->dualCount; i++, var_r20++) {
spC = var_r20->target1;
sp8 = var_r20->target2;
MTXConcat(MtxTop[nMesh + spC], MtxTop[nMesh + nObj + nObj * Meshno + spC], sp140);
MTXConcat(MtxTop[Meshno], sp140, sp1A0);
MTXConcat(MtxTop[nMesh + sp8], MtxTop[nMesh + nObj + nObj * Meshno + sp8], sp140);
MTXConcat(MtxTop[Meshno], sp140, (float (*)[4]) &spB0[0]);
var_r30 = var_r20->weight;
for (j = 0; j < var_r20->weightCnt; j++, var_r30++) {
temp_r18 = var_r30->normal;
temp_r21 = var_r30->pos;
temp_r28 = &vtxenv[temp_r21];
temp_r31 = &Vertextop[temp_r21];
temp_r22 = &normenv[temp_r18];
temp_r26 = &normtop[temp_r18];
temp_f31 = var_r30->weight;
sp140[0][0] = sp1A0[0][0] * temp_f31;
sp140[1][0] = sp1A0[1][0] * temp_f31;
sp140[2][0] = sp1A0[2][0] * temp_f31;
sp140[0][1] = sp1A0[0][1] * temp_f31;
sp140[1][1] = sp1A0[1][1] * temp_f31;
sp140[2][1] = sp1A0[2][1] * temp_f31;
sp140[0][2] = sp1A0[0][2] * temp_f31;
sp140[1][2] = sp1A0[1][2] * temp_f31;
sp140[2][2] = sp1A0[2][2] * temp_f31;
sp140[0][3] = sp1A0[0][3] * temp_f31;
sp140[1][3] = sp1A0[1][3] * temp_f31;
sp140[2][3] = sp1A0[2][3] * temp_f31;
temp_f31 = 1.0f - var_r30->weight;
sp110[0][0] = spB0[0][0] * temp_f31;
sp110[1][0] = spB0[1][0] * temp_f31;
sp110[2][0] = spB0[2][0] * temp_f31;
sp110[0][1] = spB0[0][1] * temp_f31;
sp110[1][1] = spB0[1][1] * temp_f31;
sp110[2][1] = spB0[2][1] * temp_f31;
sp110[0][2] = spB0[0][2] * temp_f31;
sp110[1][2] = spB0[1][2] * temp_f31;
sp110[2][2] = spB0[2][2] * temp_f31;
sp110[0][3] = spB0[0][3] * temp_f31;
sp110[1][3] = spB0[1][3] * temp_f31;
sp110[2][3] = spB0[2][3] * temp_f31;
if (sp80 == sp110 || sp80 == sp140) {
var_r29 = sp50;
} else {
var_r29 = sp80;
}
var_r29[0][0] = sp110[0][0] + sp140[0][0];
var_r29[0][1] = sp110[0][1] + sp140[0][1];
var_r29[0][2] = sp110[0][2] + sp140[0][2];
var_r29[0][3] = sp110[0][3] + sp140[0][3];
var_r29[1][0] = sp110[1][0] + sp140[1][0];
var_r29[1][1] = sp110[1][1] + sp140[1][1];
var_r29[1][2] = sp110[1][2] + sp140[1][2];
var_r29[1][3] = sp110[1][3] + sp140[1][3];
var_r29[2][0] = sp110[2][0] + sp140[2][0];
var_r29[2][1] = sp110[2][1] + sp140[2][1];
var_r29[2][2] = sp110[2][2] + sp140[2][2];
var_r29[2][3] = sp110[2][3] + sp140[2][3];
if (var_r29 == sp50) {
MTXCopy(sp50, sp80);
}
Hu3DMtxScaleGet(&sp80[0], &sp14);
if (sp14.x != 1.0f || sp14.y != 1.0f || sp14.z != 1.0f) {
MTXScale(spE0, 1.0 / sp14.x, 1.0 / sp14.y, 1.0 / sp14.z);
MTXConcat(spE0, sp80, sp110);
MTXInvXpose(sp110, sp110);
} else {
MTXInvXpose(sp80, sp110);
}
if (var_r30->posCnt == 1) {
MTXMultVec(sp80, temp_r31, temp_r28);
} else if (var_r30->posCnt <= 6) {
MTXMultVecArray(sp80, temp_r31, temp_r28, var_r30->posCnt);
} else {
MTXReorder(sp80, (ROMtxPtr) sp140);
MTXROMultVecArray((ROMtxPtr) sp140, temp_r31, temp_r28, var_r30->posCnt);
}
if (var_r30->normalCnt != 0) {
if (var_r30->normalCnt == 1) {
MTXMultVec(sp110, temp_r26, temp_r22);
} else if (var_r30->normalCnt <= 6) {
MTXMultVecArray(sp110, temp_r26, temp_r22, var_r30->normalCnt);
} else {
MTXReorder(sp110, (ROMtxPtr) sp140);
MTXROMultVecArray((ROMtxPtr) sp140, temp_r26, temp_r22, var_r30->normalCnt);
}
}
}
}
var_r19 = arg0->multiData;
for (i = 0; i < arg0->multiCount; i++, var_r19++) {
var_r25 = var_r19->weight;
temp_r18 = var_r19->normal;
temp_r21 = var_r19->pos;
temp_r28 = &vtxenv[temp_r21];
temp_r31 = &Vertextop[temp_r21];
temp_r22 = &normenv[temp_r18];
temp_r26 = &normtop[temp_r18];
sp38.x = sp38.y = sp38.z = 0.0f;
sp20.x = sp20.y = sp20.z = 0.0f;
sp10 = 0;
for (j = 0; j < var_r19->weightCnt; j++, var_r25++) {
MTXConcat(MtxTop[nMesh + var_r25->target], MtxTop[nMesh + nObj + nObj * Meshno + var_r25->target], sp1A0);
MTXConcat(MtxTop[Meshno], sp1A0, sp1A0);
MTXInvXpose(sp1A0, sp170);
MTXMultVec(sp1A0, temp_r31, &sp44);
MTXMultVec(sp170, temp_r26, &sp2C);
sp44.x = var_r25->value * (sp44.x - temp_r31->x);
sp44.y = var_r25->value * (sp44.y - temp_r31->y);
sp44.z = var_r25->value * (sp44.z - temp_r31->z);
VECAdd(&sp38, &sp44, &sp38);
sp2C.x = var_r25->value * (sp2C.x - temp_r26->x);
sp2C.y = var_r25->value * (sp2C.y - temp_r26->y);
sp2C.z = var_r25->value * (sp2C.z - temp_r26->z);
VECAdd(&sp20, &sp2C, &sp20);
}
temp_r28->x = temp_r31->x + sp38.x;
temp_r28->y = temp_r31->y + sp38.y;
temp_r28->z = temp_r31->z + sp38.z;
temp_r22->x = temp_r26->x + sp20.x;
temp_r22->y = temp_r26->y + sp20.y;
temp_r22->z = temp_r26->z + sp20.z;
}
temp_r21 = arg0->vtxCount;
temp_r28 = &vtxenv[temp_r21];
temp_r31 = &Vertextop[temp_r21];
for (i = 0; i < arg0->copyCount; i++, temp_r28++, temp_r31++) {
temp_r28->x = temp_r31->x;
temp_r28->y = temp_r31->y;
temp_r28->z = temp_r31->z;
}
}
static void SetMtx(HsfObject *arg0, Mtx arg1) {
HsfSkeleton *temp_r3;
Mtx spFC;
Mtx spCC;
Mtx sp9C;
s32 temp_r25;
s32 i;
temp_r3 = SearchSklenton(arg0->name);
if (temp_r3) {
arg0->data.base.pos.x = temp_r3->transform.pos.x;
arg0->data.base.pos.y = temp_r3->transform.pos.y;
arg0->data.base.pos.z = temp_r3->transform.pos.z;
arg0->data.base.rot.x = temp_r3->transform.rot.x;
arg0->data.base.rot.y = temp_r3->transform.rot.y;
arg0->data.base.rot.z = temp_r3->transform.rot.z;
arg0->data.base.scale.x = temp_r3->transform.scale.x;
arg0->data.base.scale.y = temp_r3->transform.scale.y;
arg0->data.base.scale.z = temp_r3->transform.scale.z;
}
MTXTrans(spFC, arg0->data.base.pos.x, arg0->data.base.pos.y, arg0->data.base.pos.z);
MTXScale(spCC, arg0->data.base.scale.x, arg0->data.base.scale.y, arg0->data.base.scale.z);
MTXConcat(arg1, spFC, spFC);
MTXRotRad(sp9C, 'z', MTXDegToRad(arg0->data.base.rot.z));
MTXConcat(spFC, sp9C, spFC);
MTXRotRad(sp9C, 'y', MTXDegToRad(arg0->data.base.rot.y));
MTXConcat(spFC, sp9C, spFC);
MTXRotRad(sp9C, 'x', MTXDegToRad(arg0->data.base.rot.x));
MTXConcat(spFC, sp9C, spFC);
MTXConcat(spFC, spCC, spFC);
temp_r25 = arg0 - objtop;
MTXCopy(spFC, MtxTop[nMesh + temp_r25]);
for (i = 0; i < arg0->data.childrenCount; i++) {
SetMtx(arg0->data.children[i], spFC);
}
}
static void SetRevMtx(void) {
HsfObject *var_r29;
s32 var_r28;
s32 i;
s32 var_r30;
Mtx sp38;
Mtx sp8;
var_r29 = CurHsf->object;
for (var_r28 = i = 0; i < CurHsf->objectCnt; i++, var_r29++) {
if (var_r29->type == 2) {
MTXCopy(MtxTop[nMesh + i], sp8);
for (var_r30 = 0; var_r30 < CurHsf->objectCnt; var_r30++) {
MTXInverse(MtxTop[nMesh + var_r30], sp38);
MTXConcat(sp38, sp8, MtxTop[nMesh + nObj + nObj * var_r28 + var_r30]);
}
MTXInverse(MtxTop[nMesh + i], sp8);
var_r28++;
}
}
}
static HsfSkeleton *SearchSklenton(char *arg0) {
HsfSkeleton *var_r31;
s32 i;
var_r31 = CurHsf->skeleton;
for (i = 0; i < CurHsf->skeletonCnt; i++, var_r31++) {
if (strcmp(arg0, var_r31->name) == 0) {
return var_r31;
}
}
return NULL;
}