Skip to content

Commit

Permalink
Expose OpenXR raw hand tracking data
Browse files Browse the repository at this point in the history
  • Loading branch information
BastiaanOlij committed Jul 17, 2023
1 parent 851bc64 commit 72131e8
Show file tree
Hide file tree
Showing 6 changed files with 251 additions and 1 deletion.
108 changes: 108 additions & 0 deletions modules/openxr/doc_classes/OpenXRInterface.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,22 @@
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_locations">
<return type="Array" />
<param index="0" name="hand" type="int" enum="OpenXRInterface.Hand" />
<description>
If handtracking is enabled, returns an array of joint locations. All positions and orientations are relative to the origin without worldscale applied!
See [enum HandJoints] for a list of joints added to this array.
</description>
</method>
<method name="get_hand_joint_velocities">
<return type="Array" />
<param index="0" name="hand" type="int" enum="OpenXRInterface.Hand" />
<description>
If handtracking is enabled, returns an array of joint velocities. All positions and orientations are relative to the origin without worldscale applied!
See [enum HandJoints] for a list of joints added to this array.
</description>
</method>
<method name="is_action_set_active" qualifiers="const">
<return type="bool" />
<param index="0" name="name" type="String" />
Expand Down Expand Up @@ -74,4 +90,96 @@
</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_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>
39 changes: 39 additions & 0 deletions modules/openxr/extensions/openxr_hand_tracking_extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,3 +272,42 @@ 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;
}

Array OpenXRHandTrackingExtension::get_hand_joint_locations(uint32_t p_hand) {
Array arr;
ERR_FAIL_UNSIGNED_INDEX_V(p_hand, MAX_OPENXR_TRACKED_HANDS, Array());

if (hand_trackers[p_hand].is_initialized) {
for (uint32_t i = 0; i < XR_HAND_JOINT_COUNT_EXT; i++) {
Dictionary joint;
const XrHandJointLocationEXT &location = hand_trackers[p_hand].joint_locations[i];

joint["orientation"] = Quaternion(location.pose.orientation.x, location.pose.orientation.y, location.pose.orientation.z, location.pose.orientation.w);
joint["position"] = Vector3(location.pose.position.x, location.pose.position.y, location.pose.position.z);
joint["radius"] = location.radius;

arr.push_back(joint);
}
}

return arr;
}

Array OpenXRHandTrackingExtension::get_hand_joint_velocities(uint32_t p_hand) {
Array arr;
ERR_FAIL_UNSIGNED_INDEX_V(p_hand, MAX_OPENXR_TRACKED_HANDS, Array());

if (hand_trackers[p_hand].is_initialized) {
for (uint32_t i = 0; i < XR_HAND_JOINT_COUNT_EXT; i++) {
Dictionary joint;
const XrHandJointVelocityEXT &velocity = hand_trackers[p_hand].joint_velocities[i];

joint["linear_velocity"] = Vector3(velocity.linearVelocity.x, velocity.linearVelocity.y, velocity.linearVelocity.z);
joint["angular_velocity"] = Vector3(velocity.angularVelocity.x, velocity.angularVelocity.y, velocity.angularVelocity.z);

arr.push_back(joint);
}
}

return arr;
}
3 changes: 3 additions & 0 deletions modules/openxr/extensions/openxr_hand_tracking_extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ 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);

Array get_hand_joint_locations(uint32_t p_hand);
Array get_hand_joint_velocities(uint32_t p_hand);

private:
static OpenXRHandTrackingExtension *singleton;

Expand Down
57 changes: 57 additions & 0 deletions modules/openxr/openxr_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
#include "core/io/resource_saver.h"
#include "servers/rendering/rendering_server_globals.h"

#include "extensions/openxr_hand_tracking_extension.h"

void OpenXRInterface::_bind_methods() {
// lifecycle signals
ADD_SIGNAL(MethodInfo("session_begun"));
Expand All @@ -57,6 +59,42 @@ void OpenXRInterface::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_action_sets"), &OpenXRInterface::get_action_sets);

ClassDB::bind_method(D_METHOD("get_available_display_refresh_rates"), &OpenXRInterface::get_available_display_refresh_rates);

// Hand tracking
ClassDB::bind_method(D_METHOD("get_hand_joint_locations", "hand"), &OpenXRInterface::get_hand_joint_locations);
ClassDB::bind_method(D_METHOD("get_hand_joint_velocities", "hand"), &OpenXRInterface::get_hand_joint_velocities);

BIND_ENUM_CONSTANT(HAND_LEFT);
BIND_ENUM_CONSTANT(HAND_RIGHT);
BIND_ENUM_CONSTANT(HAND_MAX);

BIND_ENUM_CONSTANT(HAND_JOINT_PALM);
BIND_ENUM_CONSTANT(HAND_JOINT_WRIST);
BIND_ENUM_CONSTANT(HAND_JOINT_THUMB_METACARPAL);
BIND_ENUM_CONSTANT(HAND_JOINT_THUMB_PROXIMAL);
BIND_ENUM_CONSTANT(HAND_JOINT_THUMB_DISTAL);
BIND_ENUM_CONSTANT(HAND_JOINT_THUMB_TIP);
BIND_ENUM_CONSTANT(HAND_JOINT_INDEX_METACARPAL);
BIND_ENUM_CONSTANT(HAND_JOINT_INDEX_PROXIMAL);
BIND_ENUM_CONSTANT(HAND_JOINT_INDEX_INTERMEDIATE);
BIND_ENUM_CONSTANT(HAND_JOINT_INDEX_DISTAL);
BIND_ENUM_CONSTANT(HAND_JOINT_INDEX_TIP);
BIND_ENUM_CONSTANT(HAND_JOINT_MIDDLE_METACARPAL);
BIND_ENUM_CONSTANT(HAND_JOINT_MIDDLE_PROXIMAL);
BIND_ENUM_CONSTANT(HAND_JOINT_MIDDLE_INTERMEDIATE);
BIND_ENUM_CONSTANT(HAND_JOINT_MIDDLE_DISTAL);
BIND_ENUM_CONSTANT(HAND_JOINT_MIDDLE_TIP);
BIND_ENUM_CONSTANT(HAND_JOINT_RING_METACARPAL);
BIND_ENUM_CONSTANT(HAND_JOINT_RING_PROXIMAL);
BIND_ENUM_CONSTANT(HAND_JOINT_RING_INTERMEDIATE);
BIND_ENUM_CONSTANT(HAND_JOINT_RING_DISTAL);
BIND_ENUM_CONSTANT(HAND_JOINT_RING_TIP);
BIND_ENUM_CONSTANT(HAND_JOINT_LITTLE_METACARPAL);
BIND_ENUM_CONSTANT(HAND_JOINT_LITTLE_PROXIMAL);
BIND_ENUM_CONSTANT(HAND_JOINT_LITTLE_INTERMEDIATE);
BIND_ENUM_CONSTANT(HAND_JOINT_LITTLE_DISTAL);
BIND_ENUM_CONSTANT(HAND_JOINT_LITTLE_TIP);
BIND_ENUM_CONSTANT(HAND_JOINT_MAX);
}

StringName OpenXRInterface::get_name() const {
Expand Down Expand Up @@ -976,6 +1014,25 @@ void OpenXRInterface::on_pose_recentered() {
emit_signal(SNAME("pose_recentered"));
}

/** Hand tracking. */
Array OpenXRInterface::get_hand_joint_locations(Hand p_hand) {
OpenXRHandTrackingExtension *hand_tracking_ext = OpenXRHandTrackingExtension::get_singleton();
if (hand_tracking_ext && hand_tracking_ext->get_active()) {
return hand_tracking_ext->get_hand_joint_locations(uint32_t(p_hand));
}

return Array();
}

Array OpenXRInterface::get_hand_joint_velocities(Hand p_hand) {
OpenXRHandTrackingExtension *hand_tracking_ext = OpenXRHandTrackingExtension::get_singleton();
if (hand_tracking_ext && hand_tracking_ext->get_active()) {
return hand_tracking_ext->get_hand_joint_velocities(uint32_t(p_hand));
}

return Array();
}

OpenXRInterface::OpenXRInterface() {
openxr_api = OpenXRAPI::get_singleton();
if (openxr_api) {
Expand Down
43 changes: 43 additions & 0 deletions modules/openxr/openxr_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,51 @@ class OpenXRInterface : public XRInterface {
void on_pose_recentered();
void tracker_profile_changed(RID p_tracker, RID p_interaction_profile);

/** Hand tracking. */
enum Hand {
HAND_LEFT,
HAND_RIGHT,
HAND_MAX,
};

enum HandJoints {
HAND_JOINT_PALM = 0,
HAND_JOINT_WRIST = 1,
HAND_JOINT_THUMB_METACARPAL = 2,
HAND_JOINT_THUMB_PROXIMAL = 3,
HAND_JOINT_THUMB_DISTAL = 4,
HAND_JOINT_THUMB_TIP = 5,
HAND_JOINT_INDEX_METACARPAL = 6,
HAND_JOINT_INDEX_PROXIMAL = 7,
HAND_JOINT_INDEX_INTERMEDIATE = 8,
HAND_JOINT_INDEX_DISTAL = 9,
HAND_JOINT_INDEX_TIP = 10,
HAND_JOINT_MIDDLE_METACARPAL = 11,
HAND_JOINT_MIDDLE_PROXIMAL = 12,
HAND_JOINT_MIDDLE_INTERMEDIATE = 13,
HAND_JOINT_MIDDLE_DISTAL = 14,
HAND_JOINT_MIDDLE_TIP = 15,
HAND_JOINT_RING_METACARPAL = 16,
HAND_JOINT_RING_PROXIMAL = 17,
HAND_JOINT_RING_INTERMEDIATE = 18,
HAND_JOINT_RING_DISTAL = 19,
HAND_JOINT_RING_TIP = 20,
HAND_JOINT_LITTLE_METACARPAL = 21,
HAND_JOINT_LITTLE_PROXIMAL = 22,
HAND_JOINT_LITTLE_INTERMEDIATE = 23,
HAND_JOINT_LITTLE_DISTAL = 24,
HAND_JOINT_LITTLE_TIP = 25,
HAND_JOINT_MAX = 26,
};

Array get_hand_joint_locations(Hand p_hand);
Array get_hand_joint_velocities(Hand p_hand);

OpenXRInterface();
~OpenXRInterface();
};

VARIANT_ENUM_CAST(OpenXRInterface::Hand)
VARIANT_ENUM_CAST(OpenXRInterface::HandJoints)

#endif // OPENXR_INTERFACE_H
2 changes: 1 addition & 1 deletion modules/openxr/scene/openxr_hand.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class OpenXRHand : public Node3D {
GDCLASS(OpenXRHand, Node3D);

public:
enum Hands {
enum Hands { // deprecated, need to change this to OpenXRInterface::Hands
HAND_LEFT,
HAND_RIGHT,
HAND_MAX
Expand Down

0 comments on commit 72131e8

Please sign in to comment.