@@ -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 ( ) ;
0 commit comments