Fix various runtime shenanigans
CI / build-and-test (pull_request) Successful in 1m32s
CI / production-build (pull_request) Successful in 10m22s

This commit is contained in:
2026-09-25 16:29:11 +02:00
parent 65727ed04f
commit 84e731fbc8
6 changed files with 29 additions and 12 deletions
+12
View File
@@ -71,6 +71,7 @@ pub struct FighterBoneMatrices {
local_matrices: Vec<FixedMat4>,
previous_local_matrices: Vec<FixedMat4>,
model_matrices: Vec<Option<FixedMat4>>,
presentation_kind: Option<AnimKind>,
}
#[derive(Component, Clone, Debug, Default)]
@@ -138,6 +139,7 @@ impl FighterBoneMatrices {
}
pub(super) fn set_pose(
&mut self,
kind: AnimKind,
bone_names: &[String],
parents: &[Option<usize>],
local: &[FixedMat4],
@@ -166,6 +168,7 @@ impl FighterBoneMatrices {
self.previous_local_matrices.reserve(local.len());
self.model_matrices.reserve(local.len());
std::mem::swap(&mut self.matrices, &mut self.previous_frame_matrices);
let animation_changed = self.presentation_kind != Some(kind);
std::mem::swap(&mut self.local_matrices, &mut self.previous_local_matrices);
self.local_matrices.clear();
self.local_matrices.extend_from_slice(local);
@@ -189,6 +192,14 @@ impl FighterBoneMatrices {
model_scale.mul(matrix.expect("baked bone hierarchy should be valid"))
}),
);
// A state transition is a discontinuity, not an animation frame to
// interpolate from the previous clip. Keep the presentation pose at
// the new clip's first/current frame immediately.
if animation_changed {
self.previous_local_matrices
.clone_from(&self.local_matrices);
}
self.presentation_kind = Some(kind);
}
}
@@ -218,6 +229,7 @@ pub fn update_fighter_bone_matrices(
.get(&fighter.manifest)
.expect("fighter manifest should be loaded before the match starts");
matrices.set_pose(
frame.kind,
&baked.bone_names,
&baked.parents,
pose,