mirror of
https://github.com/SK8-ENGINE/skate-3-rust-engine.git
synced 2026-10-26 19:47:44 +00:00
Fix wipeout bail teleport NaN physics abort.
Reset biped controller on checkpoint teleport and fall back to identity when skeleton root orthonormalization sees a degenerate axis, preventing poisoned COM frames and deck torque before the shared solve. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
1 parent
e2b85b6489
commit
c87373dd6a
2 files changed
+25
-2
No files matched your search
@@ -123,8 +123,16 @@ pub(crate) fn orthonormalize(source: AnimationPartTransform) -> AnimationPartTra
|
||||
*value -= result[prior][lane] * projection;
|
||||
}
|
||||
}
|
||||
let reciprocal = inverse_length_squared(dot3(vector, vector), 2);
|
||||
result[axis] = vector.map(|v| v * reciprocal);
|
||||
let squared = dot3(vector, vector);
|
||||
if squared <= f32::from_bits(0x3586_37bd) {
|
||||
// Degenerate axes appear after wipeout bail teleports when heading
|
||||
// initialization and ragdoll frames disagree. NaN here poisons COM
|
||||
// frames and deck torque before the shared solve.
|
||||
result[axis] = IDENTITY[axis];
|
||||
} else {
|
||||
let reciprocal = inverse_length_squared(squared, 2);
|
||||
result[axis] = vector.map(|v| v * reciprocal);
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
@@ -171,4 +179,16 @@ mod tests {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn degenerate_axis_falls_back_to_identity() {
|
||||
let mut source = IDENTITY;
|
||||
source[0] = [0.; 4];
|
||||
source[1] = [0.; 4];
|
||||
source[2] = [0.; 4];
|
||||
let result = orthonormalize(source);
|
||||
for axis in 0..3 {
|
||||
assert_eq!(result[axis], IDENTITY[axis]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,6 +86,9 @@ pub(super) fn advance(
|
||||
super::offboard_root_trace::trace(tick, "teleport", skater);
|
||||
//82DB93B0..CC: complete pending queries and clear contact history.
|
||||
skater.offboard_contact.reset_history();
|
||||
// Biped cadence survives ordinary Ground reset, but a checkpoint teleport
|
||||
// must not retain an off-board placement from a prior wipeout recovery.
|
||||
skater.biped_ground.controller.reset();
|
||||
skater.player_state.reset_for_teleport();
|
||||
skater.centre_of_mass_filter.reset();
|
||||
skater.animation_feedback.reset();
|
||||
|
||||
Reference in new issue
Block a user