Correct handplant collision bone indices to prevent arm drive collapse

This commit is contained in:
chazmm committed 2026-09-08 18:14:07 +01:00
1 parent dbefea66e1
commit c74aa44c88
4 files changed
+67 -6

No files matched your search

@@ -39,6 +39,17 @@ pub struct SkeletonCollisionMode {
}
impl SkeletonCollisionMode {
///82D91298: Body volume pointers start at3092, counters at8128.
/// The stores at3120/3104/3124/3108/3096 therefore select parts7/3/8/4/1:
/// both hands, both forearms and the head, not the next bone in each chain.
pub fn disable_handplant_contacts(&mut self, frames: u32) {
self.pending_reenable = true;
for part in [7, 3, 8, 4, 1] {
self.disable_count[part] = frames;
self.parts[part].enabled = false;
}
}
///82BE7078, used by the real teleport path82BE3508. Collision volume
///enabled flags and materials survive this reset.
pub fn reset_body_state(&mut self, feedback: &mut SkeletonCollisionFeedback) {
@@ -1,6 +1,33 @@
use super::*;
use crate::physics::{contact::RetailContactMaterial, skeleton_animation_record::IDENTITY};
#[test]
fn handplant_contact_mask_survives_updates_and_restores_on_exit() {
let mut collision = SkeletonCollisionMode::new_normal(settings().body, false);
for _ in 0..3 {
collision.disable_handplant_contacts(2);
// A driven-state refresh must not restore these volumes mid-plant.
collision.select_driven(5).unwrap();
for part in [1, 3, 4, 7, 8] {
assert!(!collision.parts[part].enabled, "plant contact part {part}");
}
for part in [2, 5, 6, 9, 10, 15, 19] {
assert!(collision.parts[part].enabled, "unaffected part {part}");
}
collision.finish_contact_frame();
assert!(collision.pending_reenable);
assert_eq!(collision.disable_count[3], 1);
assert!(!collision.parts[3].enabled);
}
// No refresh from the plant on the next tick: restore normal contact.
collision.finish_contact_frame();
assert!(!collision.pending_reenable);
for part in [1, 3, 4, 7, 8] {
assert!(collision.parts[part].enabled);
assert_eq!(collision.disable_count[part], 0);
}
}
fn settings() -> SkeletonFeedbackSettings {
SkeletonFeedbackSettings {
body: SkeletonCollisionSettings {
+2 -6
View File
@@ -269,12 +269,8 @@ pub(super) fn enter(physics: &mut GamePhysics, skater: &mut SkaterRuntime) -> Re
Ok(())
}
pub(super) fn update(physics: &mut GamePhysics, skater: &mut SkaterRuntime) -> Result<(), String> {
//82D4C3D8 ->82D91298 disables five upper-body volumes for two frames.
for part in [8, 4, 9, 5, 2] {
skater.skeleton_collision.pending_reenable = true;
skater.skeleton_collision.disable_count[part] = 2;
skater.skeleton_collision.parts[part].enabled = false;
}
//82D4C3D8 ->82D91298: keep planted hands out of collision response.
skater.skeleton_collision.disable_handplant_contacts(2);
let h = &mut skater.handplant;
h.warped += (1.0 + h.settings.time_warp.evaluate(h.warped - h.apex)) * STEP;
h.estimate_apex();
+27
View File
@@ -230,3 +230,30 @@ the selected arm, two0.65m clamps and feet-only external post pass match the
existing port. Need another normal/A/B reproduction to locate the divergence.
The same run later terminates in unsupported IsGrindBluntingBackslash at8059;
that separate grind condition remains unresolved by this diagnostic change.
## Handplant collision-mask correction (8 September, 18:06 run)
The requested normal/A/B reproduction is plants-20260908-180656-119-4993.log.
Normal plant316..395 returns to Ground; variations767..788 and1139..1166
request pose-displacement bail1. Solved traces show the free hand tracking
within0.006m at324, then falling0.57m behind at340. Its IK adjustment is
only0.002m at340. Collision weight drops to0 and the arm switches to soft
drives with local/root strengths0.5/0.0. Both variation attempts repeat this
sequence. No crash was recorded in this run.
Confirmed source error:82D91298's five volume-pointer writes use offsets
3120,3104,3124,3108,3096; matching counter writes are8156,8140,8160,8144,8132.
The generic EnableBone82BE7190 independently establishes the volume base as
4*773=3092 and counter base as4*2032=8128. Both address sets therefore resolve
to parts7,3,8,4,1 (hands, forearms, head). The port incorrectly disabled
8,4,9,5,2, leaving the hands and head collidable. TU3 dump identity remains
SHA256 f4aa113eb541bfba03dbc108cf5ab43f58c965b20fa3b82f9c40938a0ad841c4.
Evidence: logs/recomp-82d91298.asm and logs/recomp-82be7190.asm.
Handplant now calls a shared collision-owner method with the corrected
five-part mask and native two-frame countdown. A regression test checks
refresh during the plant, survival across normal driven-state setup, other
bones retaining contact, and automatic re-enabling after exit. Bail
thresholds and authored animation/IK targets are unchanged. The native mask
error is fixed; visual recovery and successful variations need gameplay
confirmation from the user. The game has not been launched by the agent.