From 12ab6baa68d9565dd338e77202c345f9c355865b Mon Sep 17 00:00:00 2001 From: chazmm Date: Sun, 6 Sep 2026 23:14:16 +0100 Subject: [PATCH] Bind offboard camera orbit to the native subject transform --- crates/skate-core/src/camera/compass.rs | 9 ++++--- crates/skate-game/src/camera/publication.rs | 1 - docs/OFFBOARD_CAMERA_ORBIT.md | 26 +++++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 docs/OFFBOARD_CAMERA_ORBIT.md diff --git a/crates/skate-core/src/camera/compass.rs b/crates/skate-core/src/camera/compass.rs index 85a100c2..ee17aa95 100644 --- a/crates/skate-core/src/camera/compass.rs +++ b/crates/skate-core/src/camera/compass.rs @@ -19,7 +19,8 @@ pub struct CompassSettings { pub struct CompassInputs { pub ground_normal: [f32; 4], //0: subject452 pub landing_normal: [f32; 4], //16: subject412 or448 - /// Current physical entry0+64, publisher cache80; not the lagged subject376. + /// Publisher cache80, also published as subject376: skeleton root when + /// offboard/wiping out, otherwise the previous physical transform. pub transform: [[f32; 4]; 4], //32 pub trajectory_direction: [f32; 4], //96: subject420 or normalized392 pub launch_position: [f32; 4], //112 @@ -137,7 +138,6 @@ pub(super) fn heading(v: [f32; 4]) -> f32 { /// Physical fields not already present in ManagerSubject, used by82DF7B90. #[derive(Clone, Copy, Debug, PartialEq)] pub struct CompassPoseInputs { - pub current_physical_transform: [[f32; 4]; 4], pub skeleton_direction: [f32; 4], pub look_target: [f32; 4], pub board_velocity: [f32; 4], @@ -154,7 +154,10 @@ impl CompassPoseInputs { CompassInputs { ground_normal: subject.rig.last_valid_ground_up, landing_normal: if trajectory { subject.landing_normal } else { subject.ground_normal }, - transform: self.current_physical_transform, trajectory_direction, + // 82DF80D8 chooses cache80 before 82DF69C0 publishes setter24. + // 82DF7B90 copies that same cache into compass32..80. Setter28 + // updates the separate physical history, not this orbit centre. + transform: subject.rig.transform, trajectory_direction, launch_position: if trajectory { subject.launch_position } else { [0.0; 4] }, landing_position: if trajectory { subject.landing_position } else { [0.0; 4] }, grind_direction: subject.direction_424, skeleton_direction: self.skeleton_direction, diff --git a/crates/skate-game/src/camera/publication.rs b/crates/skate-game/src/camera/publication.rs index 4f43d032..4a16b502 100644 --- a/crates/skate-game/src/camera/publication.rs +++ b/crates/skate-game/src/camera/publication.rs @@ -306,7 +306,6 @@ pub(crate) fn snapshot( grinding, }, compass: CompassPoseInputs { - current_physical_transform: physical_transform, skeleton_direction: skeleton_root[2], look_target: input.collision_look_target_64, board_velocity: velocity, diff --git a/docs/OFFBOARD_CAMERA_ORBIT.md b/docs/OFFBOARD_CAMERA_ORBIT.md new file mode 100644 index 00000000..971cd228 --- /dev/null +++ b/docs/OFFBOARD_CAMERA_ORBIT.md @@ -0,0 +1,26 @@ +# Offboard orbit centre + +The compass adapter used the current deck transform even though the camera +subject had switched to the skeleton root. This gives the orbit and its +30-degree camera-relative limit a different centre from the camera's subject. +The discrepancy can pull or constrain the orbit as the board moves away. + +Static native evidence comes from the TU3 image +`default_82000000_011B0000.bin`, base `0x82000000`, SHA-256 +`f4aa113eb541bfba03dbc108cf5ab43f58c965b20fa3b82f9c40938a0ad841c4`: + +- `82DF69C0` first calls `82DF80D8` to select publisher cache80. +- `82DF80D8` selects Skeleton output5+432 when State output7 byte59 or75 + is set. Otherwise it copies subject getter380 (previous physical transform). +- `82DF69C0` passes cache80 to setter24 (subject transform376), then passes + current physical output0+64 to the separate setter28. This does not replace + cache80. +- `82DF7B90` copies cache80's four vectors into compass input32..80. +- `82DF4100` uses compass80 as the orbit centre and measures both the retained + orbit and previous camera position relative to it. + +The adapter now binds the compass to the already selected subject transform, +sharing the native skeleton/physical-history selection instead of republishing +the current deck. The native orbit speed, deadzone and angular limit remain. +The source mismatch is confirmed by static analysis; the reported gameplay +symptom still requires the user's check. No automated or gameplay tests were run.