Skip to content

Commit

Permalink
Various fixes for interpolation (#880)
Browse files Browse the repository at this point in the history
* Various fixes for interpolation

* fix interpolation for kankyo particles and effects

* update twinmold effect tracking
  • Loading branch information
Archez authored Dec 1, 2024
1 parent 268d123 commit 78a0a0c
Show file tree
Hide file tree
Showing 22 changed files with 166 additions and 73 deletions.
20 changes: 12 additions & 8 deletions mm/src/code/z_actor.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ void ActorShadow_Draw(Actor* actor, Lights* lights, PlayState* play, Gfx* dlist,

if ((dlist != gCircleShadowDL) || (actor->scale.x != actor->scale.z)) {
Matrix_RotateYS(actor->shape.rot.y, MTXMODE_APPLY);
} else {
// Mark non-rotating shadows to ignore the actor mtx prevents interpolation glitches when actor moves
FrameInterpolation_IgnoreActorMtx();
}

shadowScale *= actor->shape.shadowScale;
Expand Down Expand Up @@ -179,6 +182,9 @@ void ActorShadow_DrawFoot(PlayState* play, Light* light, MtxF* arg2, s32 lightNu

OPEN_DISPS(play->state.gfxCtx);

// Ignore the players rotation prevents feet shadow from glitching when turning abruptly
FrameInterpolation_IgnoreActorMtx();

gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 0, (u8)(CLAMP_MAX(lightNum * 1.3e-05f, 1.0f) * shadowAlpha));

dir0 = light->l.dir[0];
Expand Down Expand Up @@ -5089,7 +5095,6 @@ void Actor_DrawDamageEffects(PlayState* play, Actor* actor, Vec3f bodyPartsPos[]
Vec3f* bodyPartsPosStart = bodyPartsPos;
u32 gameplayFrames = play->gameplayFrames;
f32 effectAlphaScaled;
static int effectEpoch = 0;

currentMatrix = Matrix_GetCurrent();

Expand Down Expand Up @@ -5129,8 +5134,7 @@ void Actor_DrawDamageEffects(PlayState* play, Actor* actor, Vec3f bodyPartsPos[]

// Apply and draw ice over each body part of frozen actor
for (bodyPartIndex = 0; bodyPartIndex < bodyPartsCount; bodyPartIndex++, bodyPartsPos++) {
// BENTODO is using bodyPartsPos OK here? should actor be used instead?
FrameInterpolation_RecordOpenChild(bodyPartsPos, effectEpoch++);
FrameInterpolation_RecordOpenChild(bodyPartsPos, type);
alpha = bodyPartIndex & 3;
alpha = effectAlphaScaled - (30.0f * alpha);
if (effectAlphaScaled < (30.0f * (bodyPartIndex & 3))) {
Expand Down Expand Up @@ -5177,7 +5181,7 @@ void Actor_DrawDamageEffects(PlayState* play, Actor* actor, Vec3f bodyPartsPos[]

// Apply and draw steam over each body part of frozen actor
for (bodyPartIndex = 0; bodyPartIndex < bodyPartsCount; bodyPartIndex++, bodyPartsPos++) {
FrameInterpolation_RecordOpenChild(bodyPartsPos, effectEpoch++);
FrameInterpolation_RecordOpenChild(bodyPartsPos, type);
twoTexScrollParam = ((bodyPartIndex * 3) + gameplayFrames);
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TwoTexScroll(play->state.gfxCtx, 0, twoTexScrollParam * 3, twoTexScrollParam * -12,
Expand Down Expand Up @@ -5213,7 +5217,7 @@ void Actor_DrawDamageEffects(PlayState* play, Actor* actor, Vec3f bodyPartsPos[]

// Apply and draw fire on every body part
for (bodyPartIndex = 0; bodyPartIndex < bodyPartsCount; bodyPartIndex++, bodyPartsPos++) {
FrameInterpolation_RecordOpenChild(bodyPartsPos, effectEpoch++);
FrameInterpolation_RecordOpenChild(bodyPartsPos, type);
alpha = bodyPartIndex & 3;
alpha = effectAlphaScaled - 30.0f * alpha;
if (effectAlphaScaled < 30.0f * (bodyPartIndex & 3)) {
Expand Down Expand Up @@ -5275,7 +5279,7 @@ void Actor_DrawDamageEffects(PlayState* play, Actor* actor, Vec3f bodyPartsPos[]

// Apply and draw a light orb over each body part of frozen actor
for (bodyPartIndex = 0; bodyPartIndex < bodyPartsCount; bodyPartIndex++, bodyPartsPos++) {
FrameInterpolation_RecordOpenChild(bodyPartsPos, effectEpoch++);
FrameInterpolation_RecordOpenChild(bodyPartsPos, type);
Matrix_RotateZF(Rand_CenteredFloat(2 * M_PI), MTXMODE_APPLY);
currentMatrix->mf[3][0] = bodyPartsPos->x;
currentMatrix->mf[3][1] = bodyPartsPos->y;
Expand Down Expand Up @@ -5315,7 +5319,7 @@ void Actor_DrawDamageEffects(PlayState* play, Actor* actor, Vec3f bodyPartsPos[]

// Every body part draws two electric sparks at random orientations
for (bodyPartIndex = 0; bodyPartIndex < bodyPartsCount; bodyPartIndex++, bodyPartsPos++) {
FrameInterpolation_RecordOpenChild(bodyPartsPos, effectEpoch++);
FrameInterpolation_RecordOpenChild(bodyPartsPos, type);
// first electric spark
Matrix_RotateXFApply(Rand_ZeroFloat(2 * M_PI));
Matrix_RotateZF(Rand_ZeroFloat(2 * M_PI), MTXMODE_APPLY);
Expand Down Expand Up @@ -5344,7 +5348,7 @@ void Actor_DrawDamageEffects(PlayState* play, Actor* actor, Vec3f bodyPartsPos[]

break;
}
effectEpoch = 0;

CLOSE_DISPS(play->state.gfxCtx);
}
}
Expand Down
1 change: 1 addition & 0 deletions mm/src/code/z_eff_blure.c
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,7 @@ void EffectBlure_DrawSmooth(EffectBlure* this2, GraphicsContext* gfxCtx) {
interpolationEpoch++;

OPEN_DISPS(gfxCtx);
// Force blure effects to never interpolate
FrameInterpolation_RecordOpenChild(this, interpolationEpoch);

if (this->numElements < 2) {
Expand Down
18 changes: 14 additions & 4 deletions mm/src/overlays/actors/ovl_Boss_02/z_boss_02.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "overlays/actors/ovl_En_Tanron5/z_en_tanron5.h"
#include "overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h"
#include "objects/gameplay_keep/gameplay_keep.h"

#include "2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h"
#include "2s2h/GameInteractor/GameInteractor.h"

Expand Down Expand Up @@ -533,6 +534,7 @@ void Boss02_SpawnEffectSand(TwinmoldEffect* effects, Vec3f* pos, f32 scale) {
effects->timer = 0;
effects->targetScale = 2.0f * scale;
effects->accel.x = effects->accel.z = 0.0f;
effects->epoch++;
break;
}
}
Expand All @@ -555,6 +557,7 @@ void Boss02_SpawnEffectFragment(TwinmoldEffect* effects, Vec3f* pos) {
effects->scale = Rand_ZeroFloat(0.04f) + 0.02f;
effects->rotY = Rand_ZeroFloat(32767.0f);
effects->rotX = Rand_ZeroFloat(32767.0f);
effects->epoch++;
break;
}
}
Expand All @@ -571,6 +574,7 @@ void Boss02_SpawnEffectFlash(TwinmoldEffect* effects, Vec3f* pos) {
Math_Vec3f_Copy(&effects->accel, &gZeroVec3f);
effects->alpha = 255;
effects->scale = 0.0f;
effects->epoch++;
break;
}
}
Expand Down Expand Up @@ -1569,7 +1573,9 @@ void Boss02_DrawEffects(PlayState* play) {

for (i = 0; i < TWINMOLD_EFFECT_COUNT; i++, effect++) {
if (effect->type == TWINMOLD_EFFECT_SAND) {
FrameInterpolation_RecordOpenChild(effect, i);
// Here and below, key by effect type merged with epoch
FrameInterpolation_RecordOpenChild(effect, (effect->epoch << 4) | effect->type);
FrameInterpolation_IgnoreActorMtx();
if (!flag) {
gSPDisplayList(POLY_XLU_DISP++, gTwinmoldDustMaterialDL);
gDPSetEnvColor(POLY_XLU_DISP++, 185, 140, 70, 128);
Expand Down Expand Up @@ -1600,7 +1606,8 @@ void Boss02_DrawEffects(PlayState* play) {
effect = (TwinmoldEffect*)play->specialEffects;
for (i = 0, flag = false; i < TWINMOLD_EFFECT_COUNT; i++, effect++) {
if (effect->type == TWINMOLD_EFFECT_FRAGMENT) {
FrameInterpolation_RecordOpenChild(effect, i);
FrameInterpolation_RecordOpenChild(effect, (effect->epoch << 4) | effect->type);
FrameInterpolation_IgnoreActorMtx();
if (!flag) {
gDPSetCombineLERP(POLY_OPA_DISP++, SHADE, 0, PRIMITIVE, 0, SHADE, 0, PRIMITIVE, 0, SHADE, 0, PRIMITIVE,
0, SHADE, 0, PRIMITIVE, 0);
Expand All @@ -1623,7 +1630,8 @@ void Boss02_DrawEffects(PlayState* play) {
effect = (TwinmoldEffect*)play->specialEffects;
for (i = 0, flag = false; i < TWINMOLD_EFFECT_COUNT; i++, effect++) {
if (effect->type == TWINMOLD_EFFECT_FLASH) {
FrameInterpolation_RecordOpenChild(effect, i);
FrameInterpolation_RecordOpenChild(effect, (effect->epoch << 4) | effect->type);
FrameInterpolation_IgnoreActorMtx();
if (!flag) { //! @bug - dev forgot to set flag to 1, should only apply to first entry?
gSPDisplayList(POLY_XLU_DISP++, gLightOrbMaterial1DL);
gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 128);
Expand All @@ -1645,7 +1653,8 @@ void Boss02_DrawEffects(PlayState* play) {
effect = (TwinmoldEffect*)play->specialEffects;
for (i = 0, flag = false; i < TWINMOLD_EFFECT_COUNT; i++, effect++) {
if (effect->type == TWINMOLD_EFFECT_BLACK_DUST) {
FrameInterpolation_RecordOpenChild(effect, i);
FrameInterpolation_RecordOpenChild(effect, (effect->epoch << 4) | effect->type);
FrameInterpolation_IgnoreActorMtx();
if (!flag) {
gSPDisplayList(POLY_XLU_DISP++, gTwinmoldDustMaterialDL);
gDPSetEnvColor(POLY_XLU_DISP++, 30, 30, 30, 128);
Expand Down Expand Up @@ -2352,5 +2361,6 @@ void Boss02_Reset(void) {

for (int i = 0; i < TWINMOLD_EFFECT_COUNT; i++) {
sTwinmoldEffects[i].type = TWINMOLD_EFFECT_NONE;
sTwinmoldEffects[i].epoch = 0;
}
}
2 changes: 2 additions & 0 deletions mm/src/overlays/actors/ovl_Boss_02/z_boss_02.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ typedef struct {
/* 0x30 */ s16 rotY;
/* 0x34 */ f32 scale;
/* 0x38 */ f32 targetScale;
// 2S2H [Port]
/* */ s16 epoch; // Tracks when an effect is spawned for use with interpolation skipping
} TwinmoldEffect; // size = 0x3C

typedef enum {
Expand Down
9 changes: 6 additions & 3 deletions mm/src/overlays/actors/ovl_Boss_03/z_boss_03.c
Original file line number Diff line number Diff line change
Expand Up @@ -2418,7 +2418,8 @@ void Boss03_DrawEffects(PlayState* play) {

for (i = 0; i < GYORG_EFFECT_COUNT; i++, eff++) {
if (eff->type == GYORG_EFFECT_BUBBLE) {
FrameInterpolation_RecordOpenChild(eff, i);
FrameInterpolation_RecordOpenChild(eff, eff->type);
FrameInterpolation_IgnoreActorMtx();
if (!flag) {
gSPDisplayList(POLY_OPA_DISP++, gGyorgBubbleMaterialDL);
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255);
Expand All @@ -2445,7 +2446,8 @@ void Boss03_DrawEffects(PlayState* play) {

for (i = 0; i < GYORG_EFFECT_COUNT; i++, eff++) {
if ((eff->type == GYORG_EFFECT_DROPLET) || (eff->type == GYORG_EFFECT_SPLASH)) {
FrameInterpolation_RecordOpenChild(eff, i);
FrameInterpolation_RecordOpenChild(eff, eff->type);
FrameInterpolation_IgnoreActorMtx();
if (!flag) {
POLY_XLU_DISP = Gfx_SetupDL(POLY_XLU_DISP, SETUPDL_0);

Expand Down Expand Up @@ -2481,7 +2483,8 @@ void Boss03_DrawEffects(PlayState* play) {

for (i = 0; i < GYORG_EFFECT_COUNT; i++, eff++) {
if (eff->type == GYORG_EFFECT_WET_SPOT) {
FrameInterpolation_RecordOpenChild(eff, i);
FrameInterpolation_RecordOpenChild(eff, eff->type);
FrameInterpolation_IgnoreActorMtx();
if (!flag) {
Gfx_SetupDL44_Xlu(gfxCtx);

Expand Down
5 changes: 3 additions & 2 deletions mm/src/overlays/actors/ovl_Boss_07/z_boss_07.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_boss07/object_boss07.h"
#include "overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h"
#include "BenPort.h"

#include "2s2h/BenPort.h"
#include "2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h"

#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UNFRIENDLY | ACTOR_FLAG_10 | ACTOR_FLAG_20)
Expand Down Expand Up @@ -6080,7 +6081,7 @@ void Boss07_Static_DrawEffects(PlayState* play) {
Gfx_SetupDL25_Xlu(play->state.gfxCtx);
for (i = 0; i < ARRAY_COUNT(sEffects); i++, effect++) {
if (effect->type > MAJORAS_EFFECT_NONE) {
FrameInterpolation_RecordOpenChild(effect, i);
FrameInterpolation_RecordOpenChild(effect, effect->type);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 200, 20, 0, effect->alpha);
gDPPipeSync(POLY_XLU_DISP++);
gDPSetEnvColor(POLY_XLU_DISP++, 255, 215, 255, 128);
Expand Down
20 changes: 10 additions & 10 deletions mm/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.c
Original file line number Diff line number Diff line change
Expand Up @@ -2653,27 +2653,27 @@ void func_80B0C398(BossHakugin* this, PlayState* play) {
gSPDisplayList(POLY_OPA_DISP++, gGohtRockMaterialDL);
for (i = 0; i < ARRAY_COUNT(this->unk_09F8); i++) {
effect = &this->unk_09F8[i];
FrameInterpolation_RecordOpenChild(effect, i);
if ((effect->unk_18 >= 0) && (effect->unk_1A == 0)) {
FrameInterpolation_RecordOpenChild(effect, effect->unk_1A);
Matrix_SetTranslateRotateYXZ(effect->unk_0.x, effect->unk_0.y, effect->unk_0.z, &effect->unk_1C);
Matrix_Scale(effect->unk_24, effect->unk_24, effect->unk_24, MTXMODE_APPLY);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, gGohtRockModelDL);
FrameInterpolation_RecordCloseChild();
}
FrameInterpolation_RecordCloseChild();
}

gSPDisplayList(POLY_OPA_DISP++, gGohtStalactiteMaterialDL);
for (i = 0; i < ARRAY_COUNT(this->unk_09F8); i++) {
effect = &this->unk_09F8[i];
FrameInterpolation_RecordOpenChild(effect, i);
if ((effect->unk_18 >= 0) && (effect->unk_1A == 1)) {
FrameInterpolation_RecordOpenChild(effect, effect->unk_1A);
Matrix_SetTranslateRotateYXZ(effect->unk_0.x, effect->unk_0.y, effect->unk_0.z, &effect->unk_1C);
Matrix_Scale(effect->unk_24, effect->unk_24, effect->unk_24, MTXMODE_APPLY);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, gGohtStalactiteModelDL);
FrameInterpolation_RecordCloseChild();
}
FrameInterpolation_RecordCloseChild();
}

CLOSE_DISPS(play->state.gfxCtx);
Expand All @@ -2696,8 +2696,8 @@ void func_80B0C570(BossHakugin* this, PlayState* play) {
for (i = 0; i < ARRAY_COUNT(this->unk_3158); i++) {
for (j = 0; j < ARRAY_COUNT(this->unk_3158[0]); j++) {
iter = &this->unk_3158[i][j];
FrameInterpolation_RecordOpenChild(iter, j);
if (iter->unk_10 > 0) {
FrameInterpolation_RecordOpenChild(iter, j);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 0, 0, 0, iter->unk_10);
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TwoTexScroll(play->state.gfxCtx, 0, iter->unk_12 * 3, iter->unk_12 * 15, 32, 64, 1, 0, 0,
Expand All @@ -2708,8 +2708,8 @@ void func_80B0C570(BossHakugin* this, PlayState* play) {
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gFrozenSteamModelDL);
FrameInterpolation_RecordCloseChild();
}
FrameInterpolation_RecordCloseChild();
}
}

Expand Down Expand Up @@ -2776,8 +2776,8 @@ void func_80B0CAF0(BossHakugin* this, PlayState* play) {
for (i = 0; i < ARRAY_COUNT(this->unk_2618); i++) {
iter = &this->unk_2618[i];

FrameInterpolation_RecordOpenChild(iter, i);
if ((iter->unk_0C > 0) && (iter->unk_0C <= 255)) {
FrameInterpolation_RecordOpenChild(iter, i);
Matrix_SetTranslateRotateYXZ(iter->unk_00.x, iter->unk_00.y, iter->unk_00.z, &iter->unk_0E);
Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY);

Expand All @@ -2790,8 +2790,8 @@ void func_80B0CAF0(BossHakugin* this, PlayState* play) {

gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gGohtLightningModelDL);
FrameInterpolation_RecordCloseChild();
}
FrameInterpolation_RecordCloseChild();
}

CLOSE_DISPS(play->state.gfxCtx);
Expand Down Expand Up @@ -2832,19 +2832,19 @@ void func_80B0CCD8(BossHakugin* this, PlayState* play2) {
for (; i >= end; i--) {
pos = &this->unk_3734[i];

FrameInterpolation_RecordOpenChild(this, i);
FrameInterpolation_RecordOpenChild(pos, 0);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, alpha);
Matrix_Translate(pos->x, pos->y, pos->z, MTXMODE_NEW);
Matrix_ReplaceRotation(&play->billboardMtxF);
Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
Matrix_RotateZS(rotZ, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gGohtLightOrbModelDL);
FrameInterpolation_RecordCloseChild();

scale += 1.5f;
alpha += 15;
rotZ += 0x1000;
FrameInterpolation_RecordCloseChild();
}

CLOSE_DISPS(play->state.gfxCtx);
Expand Down
Loading

0 comments on commit 78a0a0c

Please sign in to comment.