Skip to content

Commit 45b341b

Browse files
committed
fix(grip): xreview - locked index keeps a curl grip's trigger pose, lock change clears its refusal, shared snapshot_fingers and with_fingers
1 parent d521b99 commit 45b341b

4 files changed

Lines changed: 76 additions & 17 deletions

File tree

‎shock2vr/src/interaction.rs‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1822,8 +1822,7 @@ impl VrInteraction {
18221822
return false;
18231823
}
18241824
let personal = crate::world_scale::WorldScale::active().personal();
1825-
let captured = tool.with_locked(&current.fingers, fitted.fit.bones);
1826-
let fingers = pose_tool::slot_fingers(tool.slot, &current.fingers, captured);
1825+
let fingers = tool.snapshot_fingers(&current.fingers, fitted.fit.bones);
18271826
let places = tool.places();
18281827
let (grip, hand_pose) = if !places {
18291828
// Fingers only: the wrist and item stay where the grip has them.
@@ -2103,8 +2102,9 @@ impl VrInteraction {
21032102
};
21042103
let profile = self.support_profiles.get(&held.model);
21052104
let posed = glove.ok_or("degenerate_joints").and_then(|(glove, bones)| {
2105+
let profile = profile.ok_or("invalid_support_pose")?;
21062106
// Locked fingers keep the support pose's.
2107-
let bones = profile.map_or(bones, |profile| tool.with_locked(&profile.fingers, bones));
2107+
let bones = tool.with_locked(&profile.fingers, bones);
21082108
let pose = SupportProfile::captured_pose(
21092109
[Handedness::Left, Handedness::Right][tool.hand],
21102110
model,
@@ -2118,9 +2118,9 @@ impl VrInteraction {
21182118
},
21192119
)
21202120
.ok_or("degenerate_joints")?;
2121-
self.support_profiles
2122-
.get(&held.model)
2123-
.is_some_and(|profile| profile.with_pose(&pose).is_valid())
2121+
profile
2122+
.with_pose(&pose)
2123+
.is_valid()
21242124
.then_some(pose)
21252125
.ok_or("invalid_support_pose")
21262126
});

‎shock2vr/src/interaction/pose_tool.rs‎

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,8 @@ impl GripPoseTool {
563563
if self.slot != Slot::Trigger {
564564
Err("trigger slot only".to_owned())
565565
} else if self.locks[1] {
566-
Err("index locked".to_owned())
566+
// The Trigger slot's only finger.
567+
Err(self.all_locked().replace('_', " "))
567568
} else {
568569
Ok(())
569570
}
@@ -572,6 +573,14 @@ impl GripPoseTool {
572573
/// Lock or unlock finger `finger` (0 thumb .. 4 little).
573574
pub fn toggle_lock(&mut self, finger: usize) {
574575
self.locks[finger] = !self.locks[finger];
576+
// A snapshot refused for locks is stale once they change.
577+
if self
578+
.capture_failure
579+
.as_deref()
580+
.is_some_and(|reason| reason.ends_with("_locked"))
581+
{
582+
self.capture_failure = None;
583+
}
575584
}
576585

577586
/// Whether a snapshot can set anything, or why not (a capture failure
@@ -592,6 +601,26 @@ impl GripPoseTool {
592601
crate::vr_grip::with_fingers(&tracked, &stored, self.locks)
593602
}
594603

604+
/// The fingers a primary snapshot of `tracked` stores over `stored`:
605+
/// the slot's (`slot_fingers`), locked ones as stored.
606+
pub fn snapshot_fingers(&self, stored: &FingerPose, tracked: FingerBones) -> FingerPose {
607+
match slot_fingers(self.slot, stored, self.with_locked(stored, tracked)) {
608+
// A locked index keeps its rest, so a curl grip's trigger pose
609+
// still pairs with it: kept, as a bone grip's is.
610+
FingerPose::Bones {
611+
bones,
612+
trigger_bones: None,
613+
} if self.locks[1] && stored.has_trigger_pose() => FingerPose::Bones {
614+
trigger_bones: Some(crate::vr_grip::with_index(
615+
&bones,
616+
&stored.at(1.0).rest_bones(),
617+
)),
618+
bones,
619+
},
620+
fingers => fingers,
621+
}
622+
}
623+
595624
/// A primary snapshot places the glove where the tracked hand is: a rest
596625
/// one with the placement not kept (a trigger one always keeps it).
597626
pub fn places(&self) -> bool {
@@ -619,8 +648,7 @@ impl GripPoseTool {
619648
let stored =
620649
stored.filter(|_| index == self.posing() && (kept || self.locks.contains(&true)))?;
621650
let at = if kept { self.hand_pose } else { glove.palm() };
622-
let fingers = self.with_locked(stored, glove.fit.bones);
623-
Some((at, slot_fingers(self.slot, stored, fingers)))
651+
Some((at, self.snapshot_fingers(stored, glove.fit.bones)))
624652
}
625653

626654
/// The trigger value the posed glove is drawn at: test hold's controller
@@ -1948,6 +1976,41 @@ mod tests {
19481976
);
19491977
}
19501978

1979+
/// A curl grip's trigger pose survives a rest snapshot while the index is
1980+
/// locked (the rest index it pairs with is kept); unlocked, it goes.
1981+
#[test]
1982+
fn a_locked_index_keeps_a_curl_grips_trigger_pose_through_a_rest_snapshot() {
1983+
use crate::vr_grip::with_index;
1984+
let mut tool = posing_tool();
1985+
let stored = FingerPose::curls([0.2; 5]).with_trigger_index(0.6);
1986+
let tracked = FingerPose::curls([0.9; 5]).rest_bones();
1987+
assert!(!tool.snapshot_fingers(&stored, tracked).has_trigger_pose());
1988+
tool.toggle_lock(1);
1989+
let FingerPose::Bones {
1990+
bones,
1991+
trigger_bones,
1992+
} = tool.snapshot_fingers(&stored, tracked)
1993+
else {
1994+
panic!("a snapshot is bones");
1995+
};
1996+
assert_eq!(
1997+
trigger_bones,
1998+
Some(with_index(&bones, &stored.at(1.0).rest_bones()))
1999+
);
2000+
}
2001+
2002+
/// A snapshot refused for locks stops saying so once they change.
2003+
#[test]
2004+
fn changing_a_lock_clears_a_lock_refusal() {
2005+
let mut tool = posing_tool();
2006+
tool.capture_failure = Some("index_locked".to_owned());
2007+
tool.toggle_lock(1);
2008+
assert_eq!(tool.capture_failure, None);
2009+
tool.capture_failure = Some("window_short".to_owned());
2010+
tool.toggle_lock(1);
2011+
assert_eq!(tool.capture_failure.as_deref(), Some("window_short"));
2012+
}
2013+
19512014
#[test]
19522015
fn a_rest_snapshot_captures_the_placement_until_toggled_on_a_primary_grip() {
19532016
let mut tool = posing_tool();

‎shock2vr/src/vr_grip.rs‎

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,15 +1280,11 @@ impl GripSurface {
12801280
let rest = moved_fingers(bones, &amounts, &open, &fist);
12811281
FingerPose::Bones {
12821282
bones: rest,
1283-
trigger_bones: trigger_bones.map(|mut pulled| {
1283+
trigger_bones: trigger_bones.map(|pulled| {
12841284
let behind =
12851285
fingers[1] && bones_to_curls(&pulled)[1] < bones_to_curls(&rest)[1];
1286-
for f in (0..5).filter(|&f| follows(f) || (f == 1 && behind)) {
1287-
for i in FINGER_BONES[f].clone() {
1288-
pulled[i] = rest[i];
1289-
}
1290-
}
1291-
pulled
1286+
let take = std::array::from_fn(|f| follows(f) || (f == 1 && behind));
1287+
with_fingers(&pulled, &rest, take)
12921288
}),
12931289
}
12941290
}

‎tools/dark_explorer/src/grip_editor.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ impl CurlPoseEditor {
5959
ui.label("Lock:");
6060
for (name, lock) in FINGER_NAMES.into_iter().zip(self.locks.iter_mut()) {
6161
ui.checkbox(lock, name)
62-
.on_hover_text("Keep this finger as it is while editing the others");
62+
.on_hover_text("Keep this finger: its sliders, presets and Tighten skip it");
6363
}
6464
});
6565
if let FingerPose::Bones { .. } = fingers {

0 commit comments

Comments
 (0)