1
0
mirror of https://github.com/zeldaret/oot.git synced 2024-09-22 21:35:27 +00:00
oot/src/code/z_skin_awb.c

212 lines
6.9 KiB
C
Raw Normal View History

#include "global.h"
#include "overlays/actors/ovl_En_fHG/z_en_fhg.h"
2020-03-17 04:31:30 +00:00
/**
* Initialises the Vtx buffers used for limb at index `limbIndex`
*/
void Skin_InitAnimatedLimb(GlobalContext* globalCtx, Skin* skin, s32 limbIndex) {
s32 i;
SkinLimb** skeleton = SEGMENTED_TO_VIRTUAL(skin->skeletonHeader->segment);
SkinAnimatedLimbData* animatedLimbData =
SEGMENTED_TO_VIRTUAL(((SkinLimb*)SEGMENTED_TO_VIRTUAL(skeleton[limbIndex]))->segment);
SkinLimbModif* limbModifications = SEGMENTED_TO_VIRTUAL(animatedLimbData->limbModifications);
SkinLimbModif* modifEntry;
SkinVertex* skinVtxEntry;
for (i = 0; i < ARRAY_COUNT(skin->vtxTable->buf); i++) {
Vtx* vtxBuf = skin->vtxTable[limbIndex].buf[i];
for (modifEntry = limbModifications; modifEntry < limbModifications + animatedLimbData->limbModifCount;
modifEntry++) {
SkinVertex* skinVertices = SEGMENTED_TO_VIRTUAL(modifEntry->skinVertices);
for (skinVtxEntry = skinVertices; skinVtxEntry < &skinVertices[modifEntry->vtxCount]; skinVtxEntry++) {
Vtx* vtx = &vtxBuf[skinVtxEntry->index];
vtx->n.flag = 0;
vtx->n.tc[0] = skinVtxEntry->s;
vtx->n.tc[1] = skinVtxEntry->t;
vtx->n.a = skinVtxEntry->alpha;
}
}
}
}
/**
* Initializes a skin skeleton to looping animation, dynamically allocating the frame tables,
* and dynamically allocating and initializing the Vtx and SkinLimbVtx buffers for its animated limbs
*/
void Skin_Init(GlobalContext* globalCtx, Skin* skin, SkeletonHeader* skeletonHeader, AnimationHeader* animationHeader) {
s32 limbCount;
s32 i;
SkinLimb** skeleton;
SkeletonHeader* virtSkelHeader = SEGMENTED_TO_VIRTUAL(skeletonHeader);
skin->limbCount = virtSkelHeader->limbCount;
skin->skeletonHeader = virtSkelHeader;
skeleton = SEGMENTED_TO_VIRTUAL(skin->skeletonHeader->segment);
limbCount = skin->skeletonHeader->limbCount;
skin->vtxTable = ZeldaArena_MallocDebug(limbCount * sizeof(SkinLimbVtx), "../z_skin_awb.c", 212);
ASSERT(skin->vtxTable != NULL, "pskin_awb->avb_tbl != NULL", "../z_skin_awb.c", 214);
for (i = 0; i < limbCount; i++) {
SkinLimbVtx* vtxEntry = &skin->vtxTable[i];
SkinLimb* limb = SEGMENTED_TO_VIRTUAL(skeleton[i]);
if ((limb->segmentType != SKIN_LIMB_TYPE_ANIMATED) || (limb->segment == NULL)) {
vtxEntry->index = 0;
vtxEntry->buf[0] = NULL;
vtxEntry->buf[1] = NULL;
} else {
SkinAnimatedLimbData* animatedLimbData = SEGMENTED_TO_VIRTUAL(((void)0, limb->segment));
vtxEntry->index = 0;
vtxEntry->buf[0] =
ZeldaArena_MallocDebug(animatedLimbData->totalVtxCount * sizeof(Vtx), "../z_skin_awb.c", 235);
ASSERT(vtxEntry->buf[0] != NULL, "psavb->buf[0] != NULL", "../z_skin_awb.c", 237);
vtxEntry->buf[1] =
ZeldaArena_MallocDebug(animatedLimbData->totalVtxCount * sizeof(Vtx), "../z_skin_awb.c", 240);
ASSERT(vtxEntry->buf[1] != NULL, "psavb->buf[1] != NULL", "../z_skin_awb.c", 242);
Skin_InitAnimatedLimb(globalCtx, skin, i);
}
}
SkelAnime_InitSkin(globalCtx, &skin->skelAnime, skeletonHeader, animationHeader);
}
/**
* Frees the dynamically allocated Vtx and SkinLimbVtx buffers and tables
*/
void Skin_Free(GlobalContext* globalCtx, Skin* skin) {
if (skin->vtxTable != NULL) {
Volvagia (ovl_Boss_Fd) and related actors (#352) * Darkmeiro decompilation Bg_Gnd_Darkmeiro decompiled, matched, and documented. * Lots of functions matched. Some big ones are close. * Five left unmatched, one close. * Merged data and decompiled the giant function into something readable. Its branch structure has yet to be matched. * Three unmatched, one essentially matched, the rest matched. * More fixes. * Documented more of the structure and cleaned up a bit. * BossFd2, BgVbSima, and EnVbBall matched and documented * Also removed unneeded .s files * And need to name EnVbBall's functions * give this a shot * fix conflict * one more try * removing darkmeiro changes * and again * now OK from make clean * minor cleanup * One more matching function for BossFd * which means it doesn't need its .s * splitting * splitting * splitting * forgot some .s * fancy new names * fancy new names * trying again * sneaky .s files * sound effects and some hex to decimal conversions * Sound effects and static variable cleanup * format.sh and clean up static variables * sfx and formatting * ZAP and cleanup * small cleanup * cleanup and ZAP * ZAP * looking at the giant function again * looking at the giant function again * Only the big function left. * Those .s files aren't mine, officer * float literals might be fixed. regalloc still a nightmare * almost done with the big function * should make now * not much of a change * all functions match. rodata somehow doesn't. * forgot some things * lots of cleanup * and a little more * small error * large cleanup. Also BossFd has function names and inlined variable declarations * still more cleanup * the quest for 0.1f continues * forgot to put NON_MATCHING back in * Data structures fully documented. Still more cleanup. * DECR now works with BossFd2 * should match now * cleanup * small cleanup * cleanup and names * tiny thing * particles and headers and stuff * now with more enums * merge * test * end test * update * cleanup * object 2 * object 1 * doc object_fd2 * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "6f874af4a" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "6f874af4a" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * formatting * .s * merge actor * vertex arrays * a little more * formatting * merge opd * fixed damage check * cleanup * fixes * effect struct * review Co-authored-by: petrie911 <pmontag@DESKTOP-LG8A167.localdomain> Co-authored-by: fig02 <fig02srl@gmail.com>
2021-04-17 17:12:46 +00:00
s32 i;
for (i = 0; i < skin->limbCount; i++) {
if (skin->vtxTable[i].buf[0] != NULL) {
ZeldaArena_FreeDebug(skin->vtxTable[i].buf[0], "../z_skin_awb.c", 276);
skin->vtxTable[i].buf[0] = NULL;
}
if (skin->vtxTable[i].buf[1] != NULL) {
ZeldaArena_FreeDebug(skin->vtxTable[i].buf[1], "../z_skin_awb.c", 280);
skin->vtxTable[i].buf[1] = NULL;
}
}
if (skin->vtxTable != NULL) {
ZeldaArena_FreeDebug(skin->vtxTable, "../z_skin_awb.c", 286);
}
SkelAnime_Free(&skin->skelAnime, globalCtx);
}
}
s32 func_800A698C(Skin* skin, SkinLimb** skeleton, MtxF* limbMatrices, u8 parentIndex, u8 limbIndex) {
s32 pad;
SkinLimb* limb = SEGMENTED_TO_VIRTUAL(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_800A698C(skin, skeleton, limbMatrices, limbIndex, limb->child);
if (ret) {
return ret;
}
}
if (limb->sibling != LIMB_DONE) {
ret = func_800A698C(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 = SEGMENTED_TO_VIRTUAL(skin->skeletonHeader->segment);
Vec3s* jointRot = &skin->skelAnime.jointTable[0];
jointRot++;
xRot = jointRot->x;
yRot = jointRot->y;
zRot = jointRot->z;
if (setTranslation) {
jointRot--; // access joint table entry 0 for translation data
xTransl = jointRot->x;
yTransl = jointRot->y;
zTransl = jointRot->z;
jointRot++;
if (setTranslation == SKIN_TRANSFORM_IS_FHG) {
EnfHG* horse = (EnfHG*)actor;
yRot += horse->turnRot;
}
SkinMatrix_SetTranslateRotateZYX(&limbMatrices[0], xRot, yRot, zRot, xTransl, yTransl, zTransl);
} else {
SkinMatrix_SetTranslateRotateZYX(&limbMatrices[0], xRot, yRot, zRot, 0.0f, 0.0f, 0.0f);
}
jointRot++;
for (i = 1; i < skin->skeletonHeader->limbCount; i++) {
SkinLimb* limb = SEGMENTED_TO_VIRTUAL(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_SetTranslateRotateZYX(&limbMatrices[i], xRot, yRot, zRot, xTransl, yTransl, zTransl);
}
SkinMatrix_SetTranslateRotateYXZScale(
&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_800A698C(skin, SEGMENTED_TO_VIRTUAL(skin->skeletonHeader->segment), limbMatrices, LIMB_DONE, 0);
if (!ret) {
return ret;
}
return false;
}