I’ve been experimenting a bit with XR_EXT_hand_tracking and XR_EXT_hand_joints_motion_range and it seems to be working nice, I can track and render my hands with and without controllers in hand (using SteamVR latest beta).
However, as per the title, I can’t find a way to determine if I am actually holding the controllers or if I’m with plain hands. Since the hands are tracked, the input/grip and input/aim poses remain active even when I’m not holding the controllers.
I tried suggesting a binding for the “/interaction_profiles/ext/hand_interaction_ext” profile, hoping that when I put the controllers down an INTERACTION_PROFILE_CHANGED event would be triggered, activating the above profile, and then verifying it with xrGetCurrentInteractionProfile(). However, this suggestion fails, probably because SteamVR doesn’t seem to be supporting the “XR_EXT_hand_interaction” extension (which I find weird and don’t understand why).
I got it working by defining both data sources (XR_HAND_TRACKING_DATA_SOURCE_UNOBSTRUCTED_EXT and XR_HAND_TRACKING_DATA_SOURCE_CONTROLLER_EXT)
and passing them in the create info of xrCreateHandTrackerEXT().
Then, when calling xrLocateHandJointsEXT() I pass an XrHandTrackingDataSourceStateEXT struct and examine its dataSource member.
However, I don’t understand how is this combined with the XrHandJointsMotionRangeInfoEXT.handJointsMotionRange member (of the XR_EXT_hand_joints_motion_range extension). They are both used in xrLocateHandJointsEXT(), although the latter is passed as input and the former as output. It seems to me that I have to provide information (XR_HAND_JOINTS_MOTION_RANGE_UNOBSTRUCTED_EXT or XR_HAND_JOINTS_MOTION_RANGE_CONFORMING_TO_CONTROLLER_EXT) that I don’t know yet (the tracking data source, hand or controller). Meaning, what’s the point of asking for XR_HAND_JOINTS_MOTION_RANGE_CONFORMING_TO_CONTROLLER_EXT if I don’t know at that moment that my data source is indeed the controller? There must be something I’m not getting here.
According to the spec, if you specify XR_HAND_JOINTS_MOTION_RANGE_CONFORMING_TO_CONTROLLER_EXT while not using a controller, it will just default to the full hand range. So you should pick a range based on the behavior you want when using a controller, and it should just work.
Hmm, I’ve seen that part, however it mentions “interaction profile”:
If the current interaction profile does not represent a controller, the implementation must return joint locations based on the unobstructed joint locations.
I was thinking it refers to profiles such as /interaction_profiles/htc/hand_interaction, /interaction_profiles/ext/hand_interaction_ext , etc that I don’t use, and not data sources?
It’s weirdly worded, but I think that the regular controller interaction profiles such as /interaction_profiles/oculus/touch_controller count as the active ones even when hand tracking is used.
All in all you’re probably correct that it’s just weirdly worded, I tested with XR_HAND_JOINTS_MOTION_RANGE_CONFORMING_TO_CONTROLLER_EXT and got correct joint tracking with both data sources (with and without controllers). Thank you!