How to detect if I'm actually holding the controllers or not, during hand tracking

Hi,

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).

Are there any other ways that I could try?

Thanks in advance!

You would have to use XR_EXT_hand_tracking_data_source to determine it.

1 Like

Thank you @Rectus , my savior as usual :slight_smile:

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.

Thanks again! Any clarification is welcome.

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.

Yes this is true, I’ve noticed that as well.

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!