Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose OpenXR raw hand tracking data #78032

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 153 additions & 0 deletions modules/openxr/doc_classes/OpenXRInterface.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,53 @@
Returns display refresh rates supported by the current HMD. Only returned if this feature is supported by the OpenXR runtime and after the interface has been initialized.
</description>
</method>
<method name="get_hand_joint_angular_velocity" qualifiers="const">
<return type="Vector3" />
<param index="0" name="hand" type="int" enum="OpenXRInterface.Hand" />
<param index="1" name="joint" type="int" enum="OpenXRInterface.HandJoints" />
<description>
If handtracking is enabled, returns the angular velocity of a joint ([param joint]) of a hand ([param hand]) as provided by OpenXR. This is relative to [XROrigin3D]!
</description>
</method>
<method name="get_hand_joint_linear_velocity" qualifiers="const">
<return type="Vector3" />
<param index="0" name="hand" type="int" enum="OpenXRInterface.Hand" />
<param index="1" name="joint" type="int" enum="OpenXRInterface.HandJoints" />
<description>
If handtracking is enabled, returns the linear velocity of a joint ([param joint]) of a hand ([param hand]) as provided by OpenXR. This is relative to [XROrigin3D] without worldscale applied!
</description>
</method>
<method name="get_hand_joint_position" qualifiers="const">
<return type="Vector3" />
<param index="0" name="hand" type="int" enum="OpenXRInterface.Hand" />
<param index="1" name="joint" type="int" enum="OpenXRInterface.HandJoints" />
<description>
If handtracking is enabled, returns the position of a joint ([param joint]) of a hand ([param hand]) as provided by OpenXR. This is relative to [XROrigin3D] without worldscale applied!
</description>
</method>
<method name="get_hand_joint_radius" qualifiers="const">
<return type="float" />
<param index="0" name="hand" type="int" enum="OpenXRInterface.Hand" />
<param index="1" name="joint" type="int" enum="OpenXRInterface.HandJoints" />
<description>
If handtracking is enabled, returns the radius of a joint ([param joint]) of a hand ([param hand]) as provided by OpenXR. This is without worldscale applied!
</description>
</method>
<method name="get_hand_joint_rotation" qualifiers="const">
<return type="Quaternion" />
<param index="0" name="hand" type="int" enum="OpenXRInterface.Hand" />
<param index="1" name="joint" type="int" enum="OpenXRInterface.HandJoints" />
<description>
If handtracking is enabled, returns the rotation of a joint ([param joint]) of a hand ([param hand]) as provided by OpenXR.
</description>
</method>
<method name="get_motion_range" qualifiers="const">
<return type="int" enum="OpenXRInterface.HandMotionRange" />
<param index="0" name="hand" type="int" enum="OpenXRInterface.Hand" />
<description>
If handtracking is enabled and motion range is supported, gets the currently configured motion range for [param hand].
</description>
</method>
<method name="is_action_set_active" qualifiers="const">
<return type="bool" />
<param index="0" name="name" type="String" />
Expand All @@ -38,6 +85,14 @@
Sets the given action set as active or inactive.
</description>
</method>
<method name="set_motion_range">
<return type="void" />
<param index="0" name="hand" type="int" enum="OpenXRInterface.Hand" />
<param index="1" name="motion_range" type="int" enum="OpenXRInterface.HandMotionRange" />
<description>
If handtracking is enabled and motion range is supported, sets the currently configured motion range for [param hand] to [param motion_range].
</description>
</method>
</methods>
<members>
<member name="display_refresh_rate" type="float" setter="set_display_refresh_rate" getter="get_display_refresh_rate" default="0.0">
Expand Down Expand Up @@ -74,4 +129,102 @@
</description>
</signal>
</signals>
<constants>
<constant name="HAND_LEFT" value="0" enum="Hand">
Left hand.
</constant>
<constant name="HAND_RIGHT" value="1" enum="Hand">
Right hand.
</constant>
<constant name="HAND_MAX" value="2" enum="Hand">
Maximum value for the hand enum.
</constant>
<constant name="HAND_MOTION_RANGE_UNOBSTRUCTED" value="0" enum="HandMotionRange">
</constant>
<constant name="HAND_MOTION_RANGE_CONFORM_TO_CONTROLLER" value="1" enum="HandMotionRange">
</constant>
<constant name="HAND_MOTION_RANGE_MAX" value="2" enum="HandMotionRange">
</constant>
<constant name="HAND_JOINT_PALM" value="0" enum="HandJoints">
Palm joint.
</constant>
<constant name="HAND_JOINT_WRIST" value="1" enum="HandJoints">
Wrist joint.
</constant>
<constant name="HAND_JOINT_THUMB_METACARPAL" value="2" enum="HandJoints">
Thumb metacarpal joint.
</constant>
<constant name="HAND_JOINT_THUMB_PROXIMAL" value="3" enum="HandJoints">
Thumb proximal joint.
</constant>
<constant name="HAND_JOINT_THUMB_DISTAL" value="4" enum="HandJoints">
Thumb distal joint.
</constant>
<constant name="HAND_JOINT_THUMB_TIP" value="5" enum="HandJoints">
Thumb tip joint.
</constant>
<constant name="HAND_JOINT_INDEX_METACARPAL" value="6" enum="HandJoints">
Index metacarpal joint.
</constant>
<constant name="HAND_JOINT_INDEX_PROXIMAL" value="7" enum="HandJoints">
Index proximal joint.
</constant>
<constant name="HAND_JOINT_INDEX_INTERMEDIATE" value="8" enum="HandJoints">
Index intermediate joint.
</constant>
<constant name="HAND_JOINT_INDEX_DISTAL" value="9" enum="HandJoints">
Index distal joint.
</constant>
<constant name="HAND_JOINT_INDEX_TIP" value="10" enum="HandJoints">
Index tip joint.
</constant>
<constant name="HAND_JOINT_MIDDLE_METACARPAL" value="11" enum="HandJoints">
Middle metacarpal joint.
</constant>
<constant name="HAND_JOINT_MIDDLE_PROXIMAL" value="12" enum="HandJoints">
Middle proximal joint.
</constant>
<constant name="HAND_JOINT_MIDDLE_INTERMEDIATE" value="13" enum="HandJoints">
Middle intermediate joint.
</constant>
<constant name="HAND_JOINT_MIDDLE_DISTAL" value="14" enum="HandJoints">
Middle distal joint.
</constant>
<constant name="HAND_JOINT_MIDDLE_TIP" value="15" enum="HandJoints">
Middle tip joint.
</constant>
<constant name="HAND_JOINT_RING_METACARPAL" value="16" enum="HandJoints">
Ring metacarpal joint.
</constant>
<constant name="HAND_JOINT_RING_PROXIMAL" value="17" enum="HandJoints">
Ring proximal joint.
</constant>
<constant name="HAND_JOINT_RING_INTERMEDIATE" value="18" enum="HandJoints">
Ring intermediate joint.
</constant>
<constant name="HAND_JOINT_RING_DISTAL" value="19" enum="HandJoints">
Ring distal joint.
</constant>
<constant name="HAND_JOINT_RING_TIP" value="20" enum="HandJoints">
Ring tip joint.
</constant>
<constant name="HAND_JOINT_LITTLE_METACARPAL" value="21" enum="HandJoints">
Little metacarpal joint.
</constant>
<constant name="HAND_JOINT_LITTLE_PROXIMAL" value="22" enum="HandJoints">
Little proximal joint.
</constant>
<constant name="HAND_JOINT_LITTLE_INTERMEDIATE" value="23" enum="HandJoints">
Little intermediate joint.
</constant>
<constant name="HAND_JOINT_LITTLE_DISTAL" value="24" enum="HandJoints">
Little distal joint.
</constant>
<constant name="HAND_JOINT_LITTLE_TIP" value="25" enum="HandJoints">
Little tip joint.
</constant>
<constant name="HAND_JOINT_MAX" value="26" enum="HandJoints">
Maximum value for the hand joint enum.
</constant>
</constants>
</class>
59 changes: 59 additions & 0 deletions modules/openxr/extensions/openxr_hand_tracking_extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,3 +276,62 @@ void OpenXRHandTrackingExtension::set_motion_range(uint32_t p_hand, XrHandJoints
ERR_FAIL_UNSIGNED_INDEX(p_hand, MAX_OPENXR_TRACKED_HANDS);
hand_trackers[p_hand].motion_range = p_motion_range;
}

Quaternion OpenXRHandTrackingExtension::get_hand_joint_rotation(uint32_t p_hand, XrHandJointEXT p_joint) const {
ERR_FAIL_UNSIGNED_INDEX_V(p_hand, MAX_OPENXR_TRACKED_HANDS, Quaternion());
ERR_FAIL_UNSIGNED_INDEX_V(p_joint, XR_HAND_JOINT_COUNT_EXT, Quaternion());

if (!hand_trackers[p_hand].is_initialized) {
return Quaternion();
}

const XrHandJointLocationEXT &location = hand_trackers[p_hand].joint_locations[p_joint];
return Quaternion(location.pose.orientation.x, location.pose.orientation.y, location.pose.orientation.z, location.pose.orientation.w);
}

Vector3 OpenXRHandTrackingExtension::get_hand_joint_position(uint32_t p_hand, XrHandJointEXT p_joint) const {
ERR_FAIL_UNSIGNED_INDEX_V(p_hand, MAX_OPENXR_TRACKED_HANDS, Vector3());
ERR_FAIL_UNSIGNED_INDEX_V(p_joint, XR_HAND_JOINT_COUNT_EXT, Vector3());

if (!hand_trackers[p_hand].is_initialized) {
return Vector3();
}

const XrHandJointLocationEXT &location = hand_trackers[p_hand].joint_locations[p_joint];
return Vector3(location.pose.position.x, location.pose.position.y, location.pose.position.z);
}

float OpenXRHandTrackingExtension::get_hand_joint_radius(uint32_t p_hand, XrHandJointEXT p_joint) const {
ERR_FAIL_UNSIGNED_INDEX_V(p_hand, MAX_OPENXR_TRACKED_HANDS, 0.0);
ERR_FAIL_UNSIGNED_INDEX_V(p_joint, XR_HAND_JOINT_COUNT_EXT, 0.0);

if (!hand_trackers[p_hand].is_initialized) {
return 0.0;
}

return hand_trackers[p_hand].joint_locations[p_joint].radius;
}

Vector3 OpenXRHandTrackingExtension::get_hand_joint_linear_velocity(uint32_t p_hand, XrHandJointEXT p_joint) const {
ERR_FAIL_UNSIGNED_INDEX_V(p_hand, MAX_OPENXR_TRACKED_HANDS, Vector3());
ERR_FAIL_UNSIGNED_INDEX_V(p_joint, XR_HAND_JOINT_COUNT_EXT, Vector3());

if (!hand_trackers[p_hand].is_initialized) {
return Vector3();
}

const XrHandJointVelocityEXT &velocity = hand_trackers[p_hand].joint_velocities[p_joint];
return Vector3(velocity.linearVelocity.x, velocity.linearVelocity.y, velocity.linearVelocity.z);
}

Vector3 OpenXRHandTrackingExtension::get_hand_joint_angular_velocity(uint32_t p_hand, XrHandJointEXT p_joint) const {
ERR_FAIL_UNSIGNED_INDEX_V(p_hand, MAX_OPENXR_TRACKED_HANDS, Vector3());
ERR_FAIL_UNSIGNED_INDEX_V(p_joint, XR_HAND_JOINT_COUNT_EXT, Vector3());

if (!hand_trackers[p_hand].is_initialized) {
return Vector3();
}

const XrHandJointVelocityEXT &velocity = hand_trackers[p_hand].joint_velocities[p_joint];
return Vector3(velocity.angularVelocity.x, velocity.angularVelocity.y, velocity.angularVelocity.z);
}
8 changes: 8 additions & 0 deletions modules/openxr/extensions/openxr_hand_tracking_extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#define OPENXR_HAND_TRACKING_EXTENSION_H

#include "../util.h"
#include "core/math/quaternion.h"
#include "openxr_extension_wrapper.h"

#define MAX_OPENXR_TRACKED_HANDS 2
Expand Down Expand Up @@ -73,6 +74,13 @@ class OpenXRHandTrackingExtension : public OpenXRExtensionWrapper {
XrHandJointsMotionRangeEXT get_motion_range(uint32_t p_hand) const;
void set_motion_range(uint32_t p_hand, XrHandJointsMotionRangeEXT p_motion_range);

Quaternion get_hand_joint_rotation(uint32_t p_hand, XrHandJointEXT p_joint) const;
Vector3 get_hand_joint_position(uint32_t p_hand, XrHandJointEXT p_joint) const;
float get_hand_joint_radius(uint32_t p_hand, XrHandJointEXT p_joint) const;

Vector3 get_hand_joint_linear_velocity(uint32_t p_hand, XrHandJointEXT p_joint) const;
Vector3 get_hand_joint_angular_velocity(uint32_t p_hand, XrHandJointEXT p_joint) const;

private:
static OpenXRHandTrackingExtension *singleton;

Expand Down
Loading