diff options
| author | Anghelo Carvajal <angheloalf95@gmail.com> | 2022-03-23 18:30:34 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-03-23 17:30:34 -0400 |
| commit | 92c4d42f446cc12c79de9b441b9afa341cf294e8 (patch) | |
| tree | 68e412217a3961905efa586d85b5cb1c92c5725d /src/code | |
| parent | f1560614d6671ecee1ea067349a06ea088536edf (diff) | |
`z_skin` and `z_skin_awb` OK and documented a bit (#415)
* oot copypaste
* func_8013859C non matching and func_80138700
* protos
* the other functions
* func_80138300
* progress
* func_80137F58
* func_80137EBC
* func_80137B34 NON_MATCHING
* func_80137970
* func_8013835C
* z64skin
* some docs
* some bits
* Match func_80137B34
* Match Skin_DrawImpl
* Match Skin_Init tahnks to Anon
* Some docs?
* AnimatedLimb
* SkinVtx
* more names
* fix merge issue
* format
* another clean
* trailing comma
* cleanup
* format
* add some descriptions
* Import bss
* last cleanup
* Update ZAPD symbol map
* Reanme gIdentityMtx and gIdentityMtxF
* fix merge issues
* bss
* review
* Update include/z64skin.h
Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>
* bss
* Port @fig02 skin docs
* format and a few changes
* format
* Port over OoT review
* fixes
* Engineer's review
* format
* address pr
* Fix bss
* fix bss
* Update src/code/z_skin_awb.c
Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>
* bss
* bss
* undo
* pr
* Skin_Setup
Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>
Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>
Diffstat (limited to 'src/code')
| -rw-r--r-- | src/code/z_bgcheck.c | 1 | ||||
| -rw-r--r-- | src/code/z_demo.c | 1 | ||||
| -rw-r--r-- | src/code/z_lifemeter.c | 17 | ||||
| -rw-r--r-- | src/code/z_skelanime.c | 2 | ||||
| -rw-r--r-- | src/code/z_skin.c | 272 | ||||
| -rw-r--r-- | src/code/z_skin_awb.c | 203 |
6 files changed, 470 insertions, 26 deletions
diff --git a/src/code/z_bgcheck.c b/src/code/z_bgcheck.c index 3f5583f79..910458b77 100644 --- a/src/code/z_bgcheck.c +++ b/src/code/z_bgcheck.c @@ -1,3 +1,4 @@ +#include "prevent_bss_reordering.h" #include "global.h" #include "vt.h" diff --git a/src/code/z_demo.c b/src/code/z_demo.c index fb6f8687c..785f86856 100644 --- a/src/code/z_demo.c +++ b/src/code/z_demo.c @@ -1,3 +1,4 @@ +#include "prevent_bss_reordering.h" #include "global.h" #include "overlays/gamestates/ovl_daytelop/z_daytelop.h" diff --git a/src/code/z_lifemeter.c b/src/code/z_lifemeter.c index 17e73dc34..703b966de 100644 --- a/src/code/z_lifemeter.c +++ b/src/code/z_lifemeter.c @@ -1,15 +1,16 @@ +#include "prevent_bss_reordering.h" #include "global.h" #include "interface/parameter_static/parameter_static.h" #include "prevent_bss_reordering.h" -static s16 sHeartsPrimColors[3][3] = { { 255, 70, 50 }, { 255, 190, 0 }, { 100, 100, 255 } }; -static s16 sHeartsEnvColors[3][3] = { { 50, 40, 60 }, { 255, 0, 0 }, { 0, 0, 255 } }; -static s16 sHeartsPrimFactors[3][3] = { { 0, 0, 0 }, { 0, 120, -50 }, { -155, 30, 205 } }; -static s16 sHeartsEnvFactors[3][3] = { { 0, 0, 0 }, { 205, -40, -60 }, { -50, -40, 195 } }; -static s16 sHeartsDDPrimColors[3][3] = { { 255, 255, 255 }, { 255, 190, 0 }, { 100, 100, 255 } }; -static s16 sHeartsDDEnvColors[3][3] = { { 200, 0, 0 }, { 255, 0, 0 }, { 0, 0, 255 } }; -static s16 sHeartsDDPrimFactors[3][3] = { { 0, 0, 0 }, { 0, -65, -255 }, { -155, -155, 0 } }; -static s16 sHeartsDDEnvFactors[3][3] = { { 0, 0, 0 }, { 55, 0, 0 }, { -200, 0, 255 } }; +s16 sHeartsPrimColors[3][3] = { { 255, 70, 50 }, { 255, 190, 0 }, { 100, 100, 255 } }; +s16 sHeartsEnvColors[3][3] = { { 50, 40, 60 }, { 255, 0, 0 }, { 0, 0, 255 } }; +s16 sHeartsPrimFactors[3][3] = { { 0, 0, 0 }, { 0, 120, -50 }, { -155, 30, 205 } }; +s16 sHeartsEnvFactors[3][3] = { { 0, 0, 0 }, { 205, -40, -60 }, { -50, -40, 195 } }; +s16 sHeartsDDPrimColors[3][3] = { { 255, 255, 255 }, { 255, 190, 0 }, { 100, 100, 255 } }; +s16 sHeartsDDEnvColors[3][3] = { { 200, 0, 0 }, { 255, 0, 0 }, { 0, 0, 255 } }; +s16 sHeartsDDPrimFactors[3][3] = { { 0, 0, 0 }, { 0, -65, -255 }, { -155, -155, 0 } }; +s16 sHeartsDDEnvFactors[3][3] = { { 0, 0, 0 }, { 55, 0, 0 }, { -200, 0, 255 } }; s16 sBeatingHeartsDDPrim[3]; s16 sBeatingHeartsDDEnv[3]; diff --git a/src/code/z_skelanime.c b/src/code/z_skelanime.c index 9fc5467e0..f0ed1f516 100644 --- a/src/code/z_skelanime.c +++ b/src/code/z_skelanime.c @@ -1577,7 +1577,7 @@ void SkelAnime_InitFlex(GlobalContext* globalCtx, SkelAnime* skelAnime, FlexSkel /** * Initializes a skeleton with SkinLimbs to a looping animation, dynamically allocating the frame tables. */ -void SkelAnime_InitSkin(GlobalContext* globalCtx, SkelAnime* skelAnime, SkeletonHeader* skeletonHeaderSeg, +void SkelAnime_InitSkin(GameState* gameState, SkelAnime* skelAnime, SkeletonHeader* skeletonHeaderSeg, AnimationHeader* animation) { SkeletonHeader* skeletonHeader; diff --git a/src/code/z_skin.c b/src/code/z_skin.c index f031b007f..808a00da0 100644 --- a/src/code/z_skin.c +++ b/src/code/z_skin.c @@ -1,23 +1,273 @@ #include "global.h" +#include "z64skin.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin/func_80137970.s") +// 60 is an arbitrary number which specifies the max amount of limbs per skeleton this system supports +MtxF gSkinLimbMatrices[60]; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin/func_80137B34.s") +static s32 sUnused; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin/func_80137EBC.s") +void Skin_UpdateVertices(MtxF* mtx, SkinVertex* skinVertices, SkinLimbModif* modifEntry, Vtx* vtxBuf, Vec3f* pos) { + SkinVertex* vertexEntry; + Vtx* vtx; + Vec3f wTemp; + Vec3f normal; + Vec3f sp44; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin/func_80137F58.s") + wTemp.x = mtx->wx; + wTemp.y = mtx->wy; + wTemp.z = mtx->wz; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin/func_80138050.s") + mtx->wx = 0.0f; + mtx->wy = 0.0f; + mtx->wz = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin/func_80138228.s") + for (vertexEntry = skinVertices; vertexEntry < &skinVertices[modifEntry->vtxCount]; vertexEntry++) { + vtx = &vtxBuf[vertexEntry->index]; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin/func_80138258.s") + vtx->n.ob[0] = pos->x; + vtx->n.ob[1] = pos->y; + vtx->n.ob[2] = pos->z; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin/func_8013828C.s") + sp44.x = vertexEntry->normX; + sp44.y = vertexEntry->normY; + sp44.z = vertexEntry->normZ; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin/func_801382C4.s") + SkinMatrix_Vec3fMtxFMultXYZ(mtx, &sp44, &normal); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin/func_80138300.s") + vtx->n.n[0] = normal.x; + vtx->n.n[1] = normal.y; + vtx->n.n[2] = normal.z; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin/func_8013835C.s") + mtx->wx = wTemp.x; + mtx->wy = wTemp.y; + mtx->wz = wTemp.z; +} + +void Skin_ApplyLimbModifications(GraphicsContext* gfxCtx, Skin* skin, s32 limbIndex, s32 arg3) { + s32 modifCount; + SkinLimb** skeleton; + s32 pad; + SkinAnimatedLimbData* data; + s32 pad2[5]; + SkinLimbModif* modif; + SkinLimbVtx* vtxEntry; + s32 pad3; + s32 transformCount; + f32 scale; + SkinVertex* skinVertices; + Vec3f sp88; + Vtx* vtxBuf; + SkinTransformation* limbTransformations; + Vec3f spDC; + Vec3f spD0; + SkinTransformation* transformationEntry; + SkinLimb* limb; + SkinLimbModif* modifications; + + OPEN_DISPS(gfxCtx); + + skeleton = (SkinLimb**)Lib_SegmentedToVirtual(skin->skeletonHeader->segment); + limb = (SkinLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]); + data = Lib_SegmentedToVirtual(limb->segment); + modifications = (SkinLimbModif*)Lib_SegmentedToVirtual(data->limbModifications); + + vtxEntry = &skin->vtxTable[limbIndex]; + + vtxBuf = vtxEntry->buf[vtxEntry->index]; + modifCount = data->limbModifCount; + + for (modif = modifications; modif < &modifications[modifCount]; modif++) { + Vec3f spAC; + Vec3f spA0; + + skinVertices = (SkinVertex*)Lib_SegmentedToVirtual(modif->skinVertices); + limbTransformations = (SkinTransformation*)Lib_SegmentedToVirtual(modif->limbTransformations); + transformCount = modif->transformCount; + + if (transformCount == 1) { + spAC.x = limbTransformations[0].x; + spAC.y = limbTransformations[0].y; + spAC.z = limbTransformations[0].z; + + SkinMatrix_Vec3fMtxFMultXYZ(&gSkinLimbMatrices[limbTransformations[0].limbIndex], &spAC, &spDC); + } else if (arg3) { + transformationEntry = &limbTransformations[modif->unk_04]; + + spA0.x = transformationEntry->x; + spA0.y = transformationEntry->y; + spA0.z = transformationEntry->z; + SkinMatrix_Vec3fMtxFMultXYZ(&gSkinLimbMatrices[transformationEntry->limbIndex], &spA0, &spDC); + } else { + spDC.x = 0.0f; + spDC.y = 0.0f; + spDC.z = 0.0f; + + for (transformationEntry = limbTransformations; transformationEntry < &limbTransformations[transformCount]; + transformationEntry++) { + scale = transformationEntry->scale * 0.01f; + + sp88.x = transformationEntry->x; + sp88.y = transformationEntry->y; + sp88.z = transformationEntry->z; + + SkinMatrix_Vec3fMtxFMultXYZ(&gSkinLimbMatrices[transformationEntry->limbIndex], &sp88, &spD0); + + spDC.x += spD0.x * scale; + spDC.y += spD0.y * scale; + spDC.z += spD0.z * scale; + } + } + + Skin_UpdateVertices(&gSkinLimbMatrices[limbTransformations[modif->unk_04].limbIndex], skinVertices, modif, + vtxBuf, &spDC); + } + + gSPSegment(POLY_OPA_DISP++, 0x08, vtxEntry->buf[vtxEntry->index]); + + vtxEntry->index = (vtxEntry->index == 0); + + CLOSE_DISPS(gfxCtx); +} + +/** + * Draw a limb of type SKIN_LIMB_TYPE_ANIMATED, of the skeleton `skin` at index `limbIndex` + * The vertices of this limb are modified dynamically + */ +void Skin_DrawAnimatedLimb(GraphicsContext* gfxCtx, Skin* skin, s32 limbIndex, s32 arg3, s32 drawFlags) { + SkinLimb** skeleton; + s32 pad[3]; + SkinAnimatedLimbData* data; + + OPEN_DISPS(gfxCtx); + + skeleton = Lib_SegmentedToVirtual(skin->skeletonHeader->segment); + data = Lib_SegmentedToVirtual(((SkinLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]))->segment); + + if (!(drawFlags & SKIN_DRAW_FLAG_CUSTOM_TRANSFORMS)) { + Skin_ApplyLimbModifications(gfxCtx, skin, limbIndex, arg3); + } + + gSPDisplayList(POLY_OPA_DISP++, data->dlist); + + CLOSE_DISPS(gfxCtx); +} + +/** + * Draw a limb of type SKIN_LIMB_TYPE_NORMAL, of the skeleton `skin` at index `limbIndex` + */ +void Skin_DrawLimb(GraphicsContext* gfxCtx, Skin* skin, s32 limbIndex, Gfx* dListOverride, s32 drawFlags) { + Gfx* gfx = dListOverride; + SkinLimb** skeleton; + + OPEN_DISPS(gfxCtx); + + skeleton = Lib_SegmentedToVirtual(skin->skeletonHeader->segment); + + if (dListOverride == NULL) { + gfx = ((SkinLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]))->segment; + } + + if (gfx != NULL) { + Mtx* mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &gSkinLimbMatrices[limbIndex]); + + if (mtx != NULL) { + gSPMatrix(POLY_OPA_DISP++, mtx, G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gfx); + gSPPopMatrix(POLY_OPA_DISP++, G_MTX_MODELVIEW); + gDPPipeSync(POLY_OPA_DISP++); + } + } + + CLOSE_DISPS(gfxCtx); +} + +void Skin_DrawImpl(Actor* actor, GlobalContext* globalCtx, Skin* skin, SkinPostDraw postDraw, + SkinOverrideLimbDraw overrideLimbDraw, s32 setTranslation, s32 arg6, s32 drawFlags) { + s32 i; + SkinLimb** skeleton; + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + + OPEN_DISPS(gfxCtx); + + if (!(drawFlags & SKIN_DRAW_FLAG_CUSTOM_TRANSFORMS)) { + Skin_ApplyAnimTransformations(skin, gSkinLimbMatrices, actor, setTranslation); + } + + skeleton = Lib_SegmentedToVirtual(skin->skeletonHeader->segment); + + if (!(drawFlags & SKIN_DRAW_FLAG_CUSTOM_MATRIX)) { + Mtx* mtx; + + gSPMatrix(POLY_OPA_DISP++, &gIdentityMtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &skin->mtx); + if (mtx == NULL) { + goto close_disps; + } + gSPMatrix(POLY_OPA_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + } + + for (i = 0; i < skin->skeletonHeader->limbCount; i++) { + s32 shouldDraw = true; + s32 segmentType; + + if (overrideLimbDraw != NULL) { + shouldDraw = overrideLimbDraw(actor, globalCtx, i, skin); + } + + segmentType = ((SkinLimb*)Lib_SegmentedToVirtual(skeleton[i]))->segmentType; + + if (segmentType == SKIN_LIMB_TYPE_ANIMATED && shouldDraw) { + Skin_DrawAnimatedLimb(gfxCtx, skin, i, arg6, drawFlags); + } else if (segmentType == SKIN_LIMB_TYPE_NORMAL && shouldDraw) { + Skin_DrawLimb(gfxCtx, skin, i, NULL, drawFlags); + } + } + + if (postDraw != NULL) { + postDraw(actor, globalCtx, skin); + } + +close_disps:; + CLOSE_DISPS(gfxCtx); +} + +// allows specifying postDraw and setTranslation +void func_80138228(Actor* actor, GlobalContext* globalCtx, Skin* skin, SkinPostDraw postDraw, s32 setTranslation) { + Skin_DrawImpl(actor, globalCtx, skin, postDraw, NULL, setTranslation, false, 0); +} + +// allows specifying OverrideLimbDraw, postDraw and setTranslation +void func_80138258(Actor* actor, GlobalContext* globalCtx, Skin* skin, SkinPostDraw postDraw, + SkinOverrideLimbDraw overrideLimbDraw, s32 setTranslation) { + Skin_DrawImpl(actor, globalCtx, skin, postDraw, overrideLimbDraw, setTranslation, false, 0); +} + +// allows specifying OverrideLimbDraw, postDraw, setTranslation, and arg6 +void func_8013828C(Actor* actor, GlobalContext* globalCtx, Skin* skin, SkinPostDraw postDraw, + SkinOverrideLimbDraw overrideLimbDraw, s32 setTranslation, s32 arg6) { + Skin_DrawImpl(actor, globalCtx, skin, postDraw, overrideLimbDraw, setTranslation, arg6, 0); +} + +// allows specifying all variables +void func_801382C4(Actor* actor, GlobalContext* globalCtx, Skin* skin, SkinPostDraw postDraw, + SkinOverrideLimbDraw overrideLimbDraw, s32 setTranslation, s32 arg6, s32 drawFlags) { + Skin_DrawImpl(actor, globalCtx, skin, postDraw, overrideLimbDraw, setTranslation, arg6, drawFlags); +} + +void Skin_GetLimbPos(Skin* skin, s32 limbIndex, Vec3f* offset, Vec3f* dst) { + MtxF mtxf; + + SkinMatrix_MtxFMtxFMult(&skin->mtx, &gSkinLimbMatrices[limbIndex], &mtxf); + SkinMatrix_Vec3fMtxFMultXYZ(&mtxf, offset, dst); +} + +void Skin_GetVertexPos(Skin* skin, s32 limbIndex, s32 vtxIndex, Vec3f* dst) { + Vec3f pos; + Vtx* vtx = &skin->vtxTable[limbIndex].buf[skin->vtxTable[0].index][vtxIndex]; + + pos.x = vtx->n.ob[0]; + pos.y = vtx->n.ob[1]; + pos.z = vtx->n.ob[2]; + SkinMatrix_Vec3fMtxFMultXYZ(&skin->mtx, &pos, dst); +} diff --git a/src/code/z_skin_awb.c b/src/code/z_skin_awb.c index 22a1c637f..d45b9bc25 100644 --- a/src/code/z_skin_awb.c +++ b/src/code/z_skin_awb.c @@ -1,13 +1,204 @@ #include "global.h" +#include "z64skin.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin_awb/func_80138410.s") +void Skin_Setup(Skin* skin) { + skin->skeletonHeader = NULL; + skin->limbCount = 0; + skin->vtxTable = NULL; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin_awb/func_80138424.s") +/** + * Initialises the Vtx buffers used for limb at index `limbIndex` + */ +void Skin_InitAnimatedLimb(GameState* gameState, Skin* skin, s32 limbIndex) { + s32 i; + SkinLimb** skeleton = Lib_SegmentedToVirtual(skin->skeletonHeader->segment); + SkinAnimatedLimbData* animatedLimbData = + Lib_SegmentedToVirtual(((SkinLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]))->segment); + SkinLimbModif* limbModifications = Lib_SegmentedToVirtual(animatedLimbData->limbModifications); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin_awb/func_8013859C.s") + for (i = 0; i < ARRAY_COUNT(skin->vtxTable->buf); i++) { + Vtx* vertices = skin->vtxTable[limbIndex].buf[i]; + SkinLimbModif* modifEntry; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin_awb/func_80138700.s") + for (modifEntry = limbModifications; modifEntry < &limbModifications[animatedLimbData->limbModifCount]; + modifEntry++) { + SkinVertex* skinVertices = Lib_SegmentedToVirtual(modifEntry->skinVertices); + SkinVertex* skinVtxEntry; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin_awb/func_801387D4.s") + for (skinVtxEntry = skinVertices; skinVtxEntry < &skinVertices[modifEntry->vtxCount];) { + Vtx* vtx = &vertices[skinVtxEntry->index]; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin_awb/func_801388E4.s") + skinVtxEntry++; + + vtx->n.flag = 0; + vtx->n.tc[0] = skinVtxEntry[-1].s; + vtx->n.tc[1] = skinVtxEntry[-1].t; + vtx->n.a = skinVtxEntry[-1].alpha; + } + } + } +} + +/** + * Initializes a skin skeleton to looping animation, dynamically allocating the frame tables, + * and dynamically allocating and initialising the Vtx and SkinLimbVtx buffers for its animated limbs + */ +void Skin_Init(GameState* gameState, Skin* skin, SkeletonHeader* skeletonHeader, AnimationHeader* animationHeader) { + s32 limbCount; + s32 i; + SkinLimb** skeleton; + SkeletonHeader* virtSkelHeader = Lib_SegmentedToVirtual(skeletonHeader); + + skin->limbCount = virtSkelHeader->limbCount; + skin->skeletonHeader = virtSkelHeader; + limbCount = skin->skeletonHeader->limbCount; + + skeleton = Lib_SegmentedToVirtual(skin->skeletonHeader->segment); + skin->vtxTable = ZeldaArena_Malloc(limbCount * sizeof(SkinLimbVtx)); + + for (i = 0; i < limbCount; i++) { + SkinLimbVtx* vtxEntry = &skin->vtxTable[i]; + + if ((((SkinLimb*)Lib_SegmentedToVirtual(skeleton[i]))->segmentType != SKIN_LIMB_TYPE_ANIMATED) || + (((SkinLimb*)Lib_SegmentedToVirtual(skeleton[i]))->segment == NULL)) { + vtxEntry->index = 0; + + vtxEntry->buf[0] = NULL; + vtxEntry->buf[1] = NULL; + } else { + SkinAnimatedLimbData* animatedLimbData = + Lib_SegmentedToVirtual((((SkinLimb*)Lib_SegmentedToVirtual(skeleton[i]))->segment)); + + { s32 tmp; } + + vtxEntry->index = 0; + vtxEntry->buf[0] = ZeldaArena_Malloc(animatedLimbData->totalVtxCount * sizeof(Vtx)); + vtxEntry->buf[1] = ZeldaArena_Malloc(animatedLimbData->totalVtxCount * sizeof(Vtx)); + + Skin_InitAnimatedLimb(gameState, skin, i); + } + } + + SkelAnime_InitSkin(gameState, &skin->skelAnime, skeletonHeader, animationHeader); +} + +/** + * Frees the dynamically allocated Vtx and SkinLimbVtx buffers and tables + */ +void Skin_Free(GameState* gameState, Skin* skin) { + if (skin->vtxTable != NULL) { + s32 i; + + for (i = 0; i < skin->limbCount; i++) { + if (skin->vtxTable[i].buf[0] != NULL) { + ZeldaArena_Free(skin->vtxTable[i].buf[0]); + skin->vtxTable[i].buf[0] = NULL; + } + if (skin->vtxTable[i].buf[1] != NULL) { + ZeldaArena_Free(skin->vtxTable[i].buf[1]); + skin->vtxTable[i].buf[1] = NULL; + } + } + + if (skin->vtxTable != NULL) { + ZeldaArena_Free(skin->vtxTable); + } + + SkelAnime_Free(&skin->skelAnime, (GlobalContext*)gameState); + } +} + +s32 func_801387D4(Skin* skin, SkinLimb** skeleton, MtxF* limbMatrices, u8 parentIndex, u8 limbIndex) { + s32 pad; + SkinLimb* limb = Lib_SegmentedToVirtual(skeleton[limbIndex]); + MtxF* mtx; + s32 ret; + MtxF sp28; + + if (parentIndex == LIMB_DONE) { + SkinMatrix_GetClear(&mtx); + } else { + mtx = &limbMatrices[(s32)parentIndex]; + } + + SkinMatrix_MtxFMtxFMult(mtx, &limbMatrices[limbIndex], &sp28); + SkinMatrix_MtxFCopy(&sp28, &limbMatrices[limbIndex]); + + if (limb->child != LIMB_DONE) { + ret = func_801387D4(skin, skeleton, limbMatrices, limbIndex, limb->child); + if (ret) { + return ret; + } + } + + if (limb->sibling != LIMB_DONE) { + ret = func_801387D4(skin, skeleton, limbMatrices, parentIndex, limb->sibling); + if (ret) { + return ret; + } + } + + return false; +} + +/** + * Recursively applies matrix tranformations to each limb + */ +s32 Skin_ApplyAnimTransformations(Skin* skin, MtxF* limbMatrices, Actor* actor, s32 setTranslation) { + s32 i; + s32 pad; + f32 yRot; + f32 xRot; + f32 zRot; + s32 ret; + f32 yTransl; + f32 xTransl; + f32 zTransl; + SkinLimb** skeleton = Lib_SegmentedToVirtual(skin->skeletonHeader->segment); + Vec3s* jointRot = skin->skelAnime.jointTable; + + jointRot++; + xRot = jointRot->x; + yRot = jointRot->y; + zRot = jointRot->z; + + if (setTranslation) { + jointRot--; + xTransl = jointRot->x; + yTransl = jointRot->y; + zTransl = jointRot->z; + jointRot++; + + SkinMatrix_SetRotateRPYTranslate(limbMatrices, xRot, yRot, zRot, xTransl, yTransl, zTransl); + } else { + SkinMatrix_SetRotateRPYTranslate(limbMatrices, xRot, yRot, zRot, 0.0f, 0.0f, 0.0f); + } + + jointRot++; + + for (i = 1; i < skin->skeletonHeader->limbCount; i++) { + SkinLimb* limb = Lib_SegmentedToVirtual(skeleton[i]); + + xTransl = limb->jointPos.x; + yTransl = limb->jointPos.y; + zTransl = limb->jointPos.z; + xRot = jointRot->x; + yRot = jointRot->y; + zRot = jointRot->z; + jointRot++; + SkinMatrix_SetRotateRPYTranslate(&limbMatrices[i], xRot, yRot, zRot, xTransl, yTransl, zTransl); + } + + SkinMatrix_SetScaleRotateYRPTranslate( + &skin->mtx, actor->scale.x, actor->scale.y, actor->scale.z, actor->shape.rot.x, actor->shape.rot.y, + actor->shape.rot.z, actor->world.pos.x, actor->world.pos.y + (actor->shape.yOffset * actor->scale.y), + actor->world.pos.z); + + ret = func_801387D4(skin, Lib_SegmentedToVirtual(skin->skeletonHeader->segment), limbMatrices, LIMB_DONE, 0); + if (!ret) { + return ret; + } + + return false; +} |
