@@ -15,6 +15,7 @@ use alvr_common::{
15
15
glam:: { Quat , Vec3 } ,
16
16
* ,
17
17
} ;
18
+ use alvr_graphics:: HandData ;
18
19
use alvr_packets:: { ButtonEntry , ButtonValue , StreamConfig , ViewParams } ;
19
20
use alvr_session:: { BodyTrackingBDConfig , BodyTrackingSourcesConfig , FaceTrackingSourcesConfig } ;
20
21
use openxr as xr;
@@ -107,13 +108,14 @@ pub struct HandInteraction {
107
108
pub grip_action : xr:: Action < xr:: Posef > ,
108
109
pub grip_space : xr:: Space ,
109
110
110
- pub detached_controller_space : Option < xr:: Space > ,
111
-
112
111
#[ expect( dead_code) ]
113
112
pub aim_action : xr:: Action < xr:: Posef > ,
114
113
#[ expect( dead_code) ]
115
114
pub aim_space : xr:: Space ,
116
115
116
+ pub detached_grip_action : Option < xr:: Action < xr:: Posef > > ,
117
+ pub detached_grip_space : Option < xr:: Space > ,
118
+
117
119
pub vibration_action : xr:: Action < xr:: Haptic > ,
118
120
pub skeleton_tracker : Option < xr:: HandTracker > ,
119
121
}
@@ -304,49 +306,53 @@ impl InteractionContext {
304
306
MultimodalMeta :: new ( xr_session. clone ( ) , & extra_extensions, xr_system)
305
307
} ) ;
306
308
307
- let left_detached_controller_pose_action ;
308
- let right_detached_controller_pose_action ;
309
- let mut left_detached_controller_space = None ;
310
- let mut right_detached_controller_space = None ;
309
+ let mut left_detached_grip_action = None ;
310
+ let mut right_detached_grip_action = None ;
311
+ let mut left_detached_grip_space = None ;
312
+ let mut right_detached_grip_space = None ;
311
313
if multimodal_handle. is_some ( ) {
312
314
// Note: when multimodal input is enabled, both controllers and hands will always be active.
313
315
// To be able to detect when controllers are actually held, we have to register detached
314
316
// controllers pose; the controller pose will be diverted to the detached controllers when
315
317
// they are not held. Currently the detached controllers pose is ignored
316
- left_detached_controller_pose_action = action_set
318
+ left_detached_grip_action = action_set
317
319
. create_action :: < xr:: Posef > (
318
- "left_detached_controller_pose " ,
319
- "Left detached controller pose" ,
320
+ "left_detached_grip_pose " ,
321
+ "Left detached grip pose" ,
320
322
& [ ] ,
321
323
)
322
- . unwrap ( ) ;
323
- right_detached_controller_pose_action = action_set
324
+ . ok ( ) ;
325
+ right_detached_grip_action = action_set
324
326
. create_action :: < xr:: Posef > (
325
- "right_detached_controller_pose " ,
326
- "Right detached controller pose" ,
327
+ "right_detached_grip_pose " ,
328
+ "Right detached grip pose" ,
327
329
& [ ] ,
328
330
)
329
- . unwrap ( ) ;
331
+ . ok ( ) ;
330
332
331
- bindings. push ( binding (
332
- & left_detached_controller_pose_action,
333
- "/user/detached_controller_meta/left/input/grip/pose" ,
334
- ) ) ;
335
- bindings. push ( binding (
336
- & right_detached_controller_pose_action,
337
- "/user/detached_controller_meta/right/input/grip/pose" ,
338
- ) ) ;
339
-
340
- left_detached_controller_space = Some (
341
- left_detached_controller_pose_action
333
+ if let Some ( action) = & left_detached_grip_action {
334
+ bindings. push ( binding (
335
+ action,
336
+ "/user/detached_controller_meta/left/input/grip/pose" ,
337
+ ) ) ;
338
+ }
339
+ if let Some ( action) = & right_detached_grip_action {
340
+ bindings. push ( binding (
341
+ action,
342
+ "/user/detached_controller_meta/right/input/grip/pose" ,
343
+ ) ) ;
344
+ }
345
+
346
+ left_detached_grip_space = left_detached_grip_action. as_ref ( ) . map ( |action| {
347
+ action
342
348
. create_space ( xr_session. clone ( ) , xr:: Path :: NULL , xr:: Posef :: IDENTITY )
343
- . unwrap ( ) ,
344
- ) ;
345
- right_detached_controller_space = Some (
346
- right_detached_controller_pose_action
349
+ . unwrap ( )
350
+ } ) ;
351
+ right_detached_grip_space = right_detached_grip_action . as_ref ( ) . map ( |action| {
352
+ action
347
353
. create_space ( xr_session. clone ( ) , xr:: Path :: NULL , xr:: Posef :: IDENTITY )
348
- . unwrap ( ) ,
349
- ) ;
354
+ . unwrap ( )
355
+ } ) ;
350
356
}
351
357
352
358
// Apply bindings:
@@ -452,7 +458,8 @@ impl InteractionContext {
452
458
pose_offset : get_controller_offset ( platform, false ) ,
453
459
grip_action : left_grip_action,
454
460
grip_space : left_grip_space,
455
- detached_controller_space : left_detached_controller_space,
461
+ detached_grip_action : left_detached_grip_action,
462
+ detached_grip_space : left_detached_grip_space,
456
463
aim_action : left_aim_action,
457
464
aim_space : left_aim_space,
458
465
vibration_action : left_vibration_action,
@@ -463,7 +470,8 @@ impl InteractionContext {
463
470
pose_offset : get_controller_offset ( platform, true ) ,
464
471
grip_action : right_grip_action,
465
472
grip_space : right_grip_space,
466
- detached_controller_space : right_detached_controller_space,
473
+ detached_grip_action : right_detached_grip_action,
474
+ detached_grip_space : right_detached_grip_space,
467
475
aim_action : right_aim_action,
468
476
aim_space : right_aim_space,
469
477
vibration_action : right_vibration_action,
@@ -748,49 +756,6 @@ pub fn get_head_data(
748
756
Some ( ( motion, view_params) )
749
757
}
750
758
751
- pub fn get_detached_controller_motion_data (
752
- xr_session : & xr:: Session < xr:: OpenGlEs > ,
753
- reference_space : & xr:: Space ,
754
- time : Duration ,
755
- hand_source : & HandInteraction ,
756
- last_controller_pose : & mut Pose ,
757
- ) -> Option < DeviceMotion > {
758
- let xr_time = crate :: to_xr_time ( time) ;
759
-
760
- if hand_source
761
- . grip_action
762
- . is_active ( xr_session, xr:: Path :: NULL )
763
- . unwrap_or ( false )
764
- {
765
- return None ;
766
- }
767
-
768
- if let Some ( space) = & hand_source. detached_controller_space {
769
- if let Ok ( ( location, velocity) ) = space. relate ( reference_space, xr_time) {
770
- if location
771
- . location_flags
772
- . contains ( xr:: SpaceLocationFlags :: ORIENTATION_VALID )
773
- {
774
- last_controller_pose. orientation = crate :: from_xr_quat ( location. pose . orientation ) ;
775
- }
776
- if location
777
- . location_flags
778
- . contains ( xr:: SpaceLocationFlags :: POSITION_VALID )
779
- {
780
- last_controller_pose. position = crate :: from_xr_vec3 ( location. pose . position ) ;
781
- }
782
-
783
- return Some ( DeviceMotion {
784
- pose : * last_controller_pose * hand_source. pose_offset ,
785
- linear_velocity : crate :: from_xr_vec3 ( velocity. linear_velocity ) ,
786
- angular_velocity : crate :: from_xr_vec3 ( velocity. angular_velocity ) ,
787
- } ) ;
788
- }
789
- }
790
-
791
- None
792
- }
793
-
794
759
#[ expect( clippy:: too_many_arguments) ]
795
760
pub fn get_hand_data (
796
761
xr_session : & xr:: Session < xr:: OpenGlEs > ,
@@ -801,10 +766,10 @@ pub fn get_hand_data(
801
766
hand_source : & HandInteraction ,
802
767
last_controller_pose : & mut Pose ,
803
768
last_palm_pose : & mut Pose ,
804
- ) -> ( Option < DeviceMotion > , Option < [ Pose ; 26 ] > ) {
769
+ ) -> HandData {
805
770
let xr_time = crate :: to_xr_time ( time) ;
806
771
807
- let controller_motion = if hand_source
772
+ let grip_motion = if hand_source
808
773
. grip_action
809
774
. is_active ( xr_session, xr:: Path :: NULL )
810
775
. unwrap_or ( false )
@@ -873,7 +838,49 @@ pub fn get_hand_data(
873
838
None
874
839
} ;
875
840
876
- let hand_joints = if let Some ( tracker) = & hand_source. skeleton_tracker {
841
+ let detached_grip_motion = if let Some ( detached_grip_action) = & hand_source. detached_grip_action
842
+ {
843
+ if detached_grip_action
844
+ . is_active ( xr_session, xr:: Path :: NULL )
845
+ . unwrap_or ( false )
846
+ {
847
+ if let Ok ( ( location, velocity) ) = hand_source
848
+ . detached_grip_space
849
+ . as_ref ( )
850
+ . unwrap ( )
851
+ . relate ( reference_space, xr_time)
852
+ {
853
+ if location
854
+ . location_flags
855
+ . contains ( xr:: SpaceLocationFlags :: ORIENTATION_VALID )
856
+ {
857
+ last_controller_pose. orientation =
858
+ crate :: from_xr_quat ( location. pose . orientation ) ;
859
+ }
860
+
861
+ if location
862
+ . location_flags
863
+ . contains ( xr:: SpaceLocationFlags :: POSITION_VALID )
864
+ {
865
+ last_controller_pose. position = crate :: from_xr_vec3 ( location. pose . position ) ;
866
+ }
867
+
868
+ Some ( DeviceMotion {
869
+ pose : * last_controller_pose,
870
+ linear_velocity : crate :: from_xr_vec3 ( velocity. linear_velocity ) ,
871
+ angular_velocity : crate :: from_xr_vec3 ( velocity. angular_velocity ) ,
872
+ } )
873
+ } else {
874
+ None
875
+ }
876
+ } else {
877
+ None
878
+ }
879
+ } else {
880
+ None
881
+ } ;
882
+
883
+ let skeleton_joints = if let Some ( tracker) = & hand_source. skeleton_tracker {
877
884
let xr_now = crate :: xr_runtime_now ( xr_session. instance ( ) ) . unwrap_or ( xr_time) ;
878
885
879
886
if let Some ( joint_locations) = reference_space
@@ -913,7 +920,11 @@ pub fn get_hand_data(
913
920
None
914
921
} ;
915
922
916
- ( controller_motion, hand_joints)
923
+ HandData {
924
+ grip_motion,
925
+ detached_grip_motion,
926
+ skeleton_joints,
927
+ }
917
928
}
918
929
919
930
pub fn update_buttons (
0 commit comments