mirror of
https://github.com/zeldaret/mm.git
synced 2026-09-04 10:11:51 -04:00
SubS Skelanime functions (#572)
* Bring code over * Change ActorDraw typedefs from actor to thisx * Rename functions * Format * Rename and clean up limb draws * Some more limb draw cleanup * Some more cleanup * Function comments * Last bit of cleanup * update tutorial * More tutorial and format * Remove extra newlines form actorfixer * Missed one * Remove some unnecessary casts * Fix SkelAnime transform functions in functions.h * Remove bug comments, and add note * Remove some more unneeded casts and rename one variable * format * Fix merge * Format
This commit is contained in:
+112
-2
@@ -36,9 +36,119 @@ EnDoor* SubS_FindDoor(GlobalContext* globalCtx, s32 unk_1A5) {
|
||||
return door;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013A860.s")
|
||||
Gfx* SubS_DrawTransformFlexLimb(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable,
|
||||
OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw,
|
||||
TransformLimbDraw transformLimbDraw, Actor* actor, Mtx** mtx, Gfx* gfx) {
|
||||
StandardLimb* limb;
|
||||
Gfx* newDList;
|
||||
Gfx* limbDList;
|
||||
Vec3f pos;
|
||||
Vec3s rot;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013AB00.s")
|
||||
Matrix_StatePush();
|
||||
limb = Lib_SegmentedToVirtual(skeleton[limbIndex]);
|
||||
limbIndex++;
|
||||
rot = jointTable[limbIndex];
|
||||
pos.x = limb->jointPos.x;
|
||||
pos.y = limb->jointPos.y;
|
||||
pos.z = limb->jointPos.z;
|
||||
newDList = limbDList = limb->dList;
|
||||
|
||||
if ((overrideLimbDraw == NULL) || !overrideLimbDraw(globalCtx, limbIndex, &newDList, &pos, &rot, actor, &gfx)) {
|
||||
Matrix_JointPosition(&pos, &rot);
|
||||
Matrix_StatePush();
|
||||
|
||||
transformLimbDraw(globalCtx, limbIndex, actor, &gfx);
|
||||
|
||||
if (newDList != NULL) {
|
||||
Matrix_ToMtx(*mtx);
|
||||
gSPMatrix(gfx++, *mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(gfx++, newDList);
|
||||
(*mtx)++;
|
||||
} else if (limbDList != NULL) {
|
||||
Matrix_ToMtx(*mtx);
|
||||
(*mtx)++;
|
||||
}
|
||||
Matrix_StatePop();
|
||||
}
|
||||
if (postLimbDraw != NULL) {
|
||||
postLimbDraw(globalCtx, limbIndex, &limbDList, &rot, actor, &gfx);
|
||||
}
|
||||
if (limb->child != LIMB_DONE) {
|
||||
gfx = SubS_DrawTransformFlexLimb(globalCtx, limb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw,
|
||||
transformLimbDraw, actor, mtx, gfx);
|
||||
}
|
||||
Matrix_StatePop();
|
||||
if (limb->sibling != LIMB_DONE) {
|
||||
gfx = SubS_DrawTransformFlexLimb(globalCtx, limb->sibling, skeleton, jointTable, overrideLimbDraw, postLimbDraw,
|
||||
transformLimbDraw, actor, mtx, gfx);
|
||||
}
|
||||
return gfx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw all limbs of type `StandardLimb` in a given flexible skeleton
|
||||
* Limbs in a flexible skeleton have meshes that can stretch to line up with other limbs.
|
||||
* An array of matrices is dynamically allocated so each limb can access any transform to ensure its meshes line up.
|
||||
*
|
||||
* Also makes use of a `TransformLimbDraw`, which transforms limbs based on world coordinates, as opposed to local limb
|
||||
* coordinates.
|
||||
* Note that the `TransformLimbDraw` does not have a NULL check, so must be provided even if empty.
|
||||
*/
|
||||
Gfx* SubS_DrawTransformFlex(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount,
|
||||
OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw,
|
||||
TransformLimbDraw transformLimbDraw, Actor* actor, Gfx* gfx) {
|
||||
StandardLimb* rootLimb;
|
||||
s32 pad;
|
||||
Gfx* newDlist;
|
||||
Gfx* limbDList;
|
||||
Vec3f pos;
|
||||
Vec3s rot;
|
||||
Mtx* mtx = GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(dListCount * sizeof(Mtx)));
|
||||
|
||||
if (skeleton == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gSPSegment(gfx++, 0x0D, mtx);
|
||||
Matrix_StatePush();
|
||||
rootLimb = Lib_SegmentedToVirtual(skeleton[0]);
|
||||
pos.x = jointTable->x;
|
||||
pos.y = jointTable->y;
|
||||
pos.z = jointTable->z;
|
||||
rot = jointTable[1];
|
||||
newDlist = rootLimb->dList;
|
||||
limbDList = rootLimb->dList;
|
||||
|
||||
if (overrideLimbDraw == NULL || !overrideLimbDraw(globalCtx, 1, &newDlist, &pos, &rot, actor, &gfx)) {
|
||||
Matrix_JointPosition(&pos, &rot);
|
||||
Matrix_StatePush();
|
||||
|
||||
transformLimbDraw(globalCtx, 1, actor, &gfx);
|
||||
|
||||
if (newDlist != NULL) {
|
||||
Matrix_ToMtx(mtx);
|
||||
gSPMatrix(gfx++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(gfx++, newDlist);
|
||||
mtx++;
|
||||
} else if (limbDList != NULL) {
|
||||
Matrix_ToMtx(mtx);
|
||||
mtx++;
|
||||
}
|
||||
Matrix_StatePop();
|
||||
}
|
||||
|
||||
if (postLimbDraw != NULL) {
|
||||
postLimbDraw(globalCtx, 1, &limbDList, &rot, actor, &gfx);
|
||||
}
|
||||
|
||||
if (rootLimb->child != LIMB_DONE) {
|
||||
gfx = SubS_DrawTransformFlexLimb(globalCtx, rootLimb->child, skeleton, jointTable, overrideLimbDraw,
|
||||
postLimbDraw, transformLimbDraw, actor, &mtx, gfx);
|
||||
}
|
||||
Matrix_StatePop();
|
||||
return gfx;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013AD6C.s")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user