diff options
| author | Garrett <garrettjcox@gmail.com> | 2026-07-04 10:10:47 -0500 |
|---|---|---|
| committer | Garrett <garrettjcox@gmail.com> | 2026-07-04 10:10:47 -0500 |
| commit | 97e69ef531cd33259e088979daf33bab8cc30880 (patch) | |
| tree | f131b447f24eac453dfa0f61938c42f9c90e43be | |
| parent | 8b945205609748f8c6a1ee77d5c4c2f6773c2c68 (diff) | |
Fix some shadow flickering
| -rw-r--r-- | mm/2s2h/Enhancements/FrameInterpolation/FrameInterpolation.cpp | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/mm/2s2h/Enhancements/FrameInterpolation/FrameInterpolation.cpp b/mm/2s2h/Enhancements/FrameInterpolation/FrameInterpolation.cpp index e7f442712..49a78a289 100644 --- a/mm/2s2h/Enhancements/FrameInterpolation/FrameInterpolation.cpp +++ b/mm/2s2h/Enhancements/FrameInterpolation/FrameInterpolation.cpp @@ -121,6 +121,10 @@ union Data { struct { Mtx* dest; MtxF src; + // The matrix as it actually was for this frame, before any actor-relative adjustment. Kept around + // (regardless of has_adjusted) so a has_adjusted mismatch between frames has a correct, non-relative + // matrix to fall back to instead of blending across incompatible spaces. + MtxF raw; bool has_adjusted; } matrix_to_mtx; @@ -385,7 +389,15 @@ struct InterpolateCtx { case Op::MatrixToMtx: { //*new_replacement(new_op.matrix_to_mtx.dest) = *Matrix_GetCurrent(); - if (old_op.matrix_to_mtx.has_adjusted && new_op.matrix_to_mtx.has_adjusted) { + if (old_op.matrix_to_mtx.has_adjusted != new_op.matrix_to_mtx.has_adjusted) { + // has_adjusted toggled between frames (e.g. ActorShadow_Draw's isotropic-shadow + // check flipping as scale.x drifts in and out of equality with scale.z). old.src + // and new.src aren't comparable here: whichever side has has_adjusted=true holds + // an actor-relative matrix that still needs actor_mtx re-applied, not a final + // matrix. Use raw (the true un-relativized matrix for that frame) and snap to the + // new frame instead of interpolating. + *new_replacement(new_op.matrix_to_mtx.dest) = new_op.matrix_to_mtx.raw; + } else if (old_op.matrix_to_mtx.has_adjusted && new_op.matrix_to_mtx.has_adjusted) { interpolate_mtxf(&tmp_mtxf, &old_op.matrix_to_mtx.src, &new_op.matrix_to_mtx.src); SkinMatrix_MtxFMtxFMult(&actor_mtx, &tmp_mtxf, new_replacement(new_op.matrix_to_mtx.dest)); @@ -592,11 +604,12 @@ void FrameInterpolation_RecordMatrixToMtx(Mtx* dest, char* file, s32 line) { if (!is_recording) return; auto& d = append(Op::MatrixToMtx).matrix_to_mtx = { dest }; + d.raw = *Matrix_GetCurrent(); if (has_inv_actor_mtx && !ignore_inv_actor_mtx) { d.has_adjusted = true; SkinMatrix_MtxFMtxFMult(&inv_actor_mtx, Matrix_GetCurrent(), &d.src); } else { - d.src = *Matrix_GetCurrent(); + d.src = d.raw; } } |
