Skip to content

Commit 3b9dbb0

Browse files
committed
fix(vr): an untracked held hand still reads as lost
Review: keeping the last pose hid tracking loss from support, visuals and the refit. The hand now keeps the reported (untracked) pose and only skips placing the item. Physics guard reuses GripPose::is_tracked; stale comments fixed.
1 parent d4c7115 commit 3b9dbb0

5 files changed

Lines changed: 35 additions & 47 deletions

File tree

‎shock2vr/src/hand_glove.rs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,8 @@ impl GloveRenderer {
185185
})
186186
}
187187

188-
/// `posed_joints` in authored units (world scale 1), as grips are fitted.
188+
/// The glove's 26 skin joints posed with `pose`, in calibrated hand space
189+
/// at authored size (world scale 1), as grips are fitted.
189190
fn authored_joints(
190191
&mut self,
191192
pose: &Pose,

‎shock2vr/src/interaction.rs‎

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3694,17 +3694,19 @@ mod tests {
36943694
for _ in 0..3 {
36953695
let effects = interaction.update(&context(&world, &physics, &input));
36963696
assert_eq!(interaction.right_hand.get_held_entity(), Some(entity));
3697-
for effect in effects {
3698-
if let VirtualHandEffect::SetPositionRotation {
3699-
position, rotation, ..
3700-
} = effect
3701-
{
3702-
assert!(
3703-
GripPose { position, rotation }.is_tracked(),
3704-
"{position:?} {rotation:?}"
3705-
);
3706-
}
3707-
}
3697+
assert!(
3698+
!effects.iter().any(|e| matches!(
3699+
e,
3700+
VirtualHandEffect::SetPositionRotation { entity_id, .. } if *entity_id == entity
3701+
)),
3702+
"the item is not placed"
3703+
);
3704+
// `fit_held_items` reads this pose: still lost, so it places nothing.
3705+
let pose = GripPose {
3706+
position: interaction.right_hand.get_position(),
3707+
rotation: interaction.right_hand.get_rotation(),
3708+
};
3709+
assert!(!pose.is_tracked());
37083710
}
37093711
}
37103712

‎shock2vr/src/interaction/pose_tool.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ impl GripPoseTool {
460460
.map_or(self.hand_pose.position, |(item, _)| item.position)
461461
}
462462

463-
/// Draws the bench (item, posed gloves, their spheres) as turned. The
463+
/// Draws the bench (item and posed gloves) as turned. The
464464
/// tool works in the unturned bench, so captures stay relative to the
465465
/// item.
466466
pub fn turn_matrix(&self) -> Matrix4<f32> {

‎shock2vr/src/physics/mod.rs‎

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4114,21 +4114,12 @@ impl PhysicsWorld {
41144114
// A zero quaternion (an untracked Quest controller) or a non-finite
41154115
// pose would normalize to NaN and panic parry's broad-phase rebuild;
41164116
// the body keeps its last pose instead.
4117-
let finite = [
4118-
position.x,
4119-
position.y,
4120-
position.z,
4121-
rotation.s,
4122-
rotation.v.x,
4123-
rotation.v.y,
4124-
rotation.v.z,
4125-
]
4126-
.into_iter()
4127-
.all(f32::is_finite);
4128-
let Some(rotation) = crate::util::tracked_rotation(rotation).filter(|_| finite) else {
4117+
let pose = crate::vr_support::GripPose { position, rotation };
4118+
if !pose.is_tracked() {
41294119
tracing::warn!("[physics] ignored non-finite pose {position:?} {rotation:?}");
41304120
return;
4131-
};
4121+
}
4122+
let rotation = rotation.normalize();
41324123
let nquat = nalgebra::geometry::Quaternion::new(
41334124
rotation.s,
41344125
rotation.v.x,

‎shock2vr/src/virtual_hand.rs‎

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -436,16 +436,17 @@ impl VirtualHand {
436436
HandState::Grabbing { entity_id } => {
437437
// See what we're hitting
438438
let mut msgs = Vec::new();
439+
let tracked = crate::vr_support::GripPose {
440+
position: input_hand.position,
441+
rotation: input_hand.rotation,
442+
}
443+
.is_tracked();
439444

440445
// A held download also collects on trigger, through the same
441446
// drop a release takes. Never from an untracked fallback pose.
442447
let trigger_collects = prev.trigger_value < 0.5
443448
&& input_hand.trigger_value > 0.5
444-
&& crate::vr_support::GripPose {
445-
position: input_hand.position,
446-
rotation: input_hand.rotation,
447-
}
448-
.is_tracked()
449+
&& tracked
449450
&& crate::scripts::script_util::is_download_pickup(world, entity_id);
450451

451452
// If we're holding onto something, but not grabbing, we can drop it
@@ -521,17 +522,8 @@ impl VirtualHand {
521522
}
522523

523524
// A set-down controller (Quest: the zero quaternion)
524-
// leaves the item, and the hand, where they last were.
525-
let tracked = crate::vr_support::GripPose {
526-
position: input_hand.position,
527-
rotation: input_hand.rotation,
528-
}
529-
.is_tracked();
530-
let (hand_position, hand_rotation) = if tracked {
531-
(hand_position, hand_rotation)
532-
} else {
533-
(prev.position, prev.rotation)
534-
};
525+
// leaves the item where it is. The hand keeps that pose,
526+
// so tracking checks downstream still see it lost.
535527
if tracked {
536528
msgs.push(VirtualHandEffect::SetPositionRotation {
537529
entity_id,
@@ -1978,12 +1970,14 @@ mod tests {
19781970
.any(|e| matches!(e, VirtualHandEffect::SetPositionRotation { .. })),
19791971
"the item is not moved"
19801972
);
1981-
assert_eq!(
1982-
hand.get_rotation(),
1983-
held.get_rotation(),
1984-
"the hand keeps its last pose"
1973+
assert!(
1974+
!crate::vr_support::GripPose {
1975+
position: hand.get_position(),
1976+
rotation: hand.get_rotation(),
1977+
}
1978+
.is_tracked(),
1979+
"the hand still reads as lost, so the refit places nothing either"
19851980
);
1986-
assert_eq!(hand.get_position(), held.get_position());
19871981
}
19881982

19891983
#[test]

0 commit comments

Comments
 (0)