diff --git a/misc/extension_api_validation/4.2-stable.expected b/misc/extension_api_validation/4.2-stable.expected index e8195d0aa08..9384ca62993 100644 --- a/misc/extension_api_validation/4.2-stable.expected +++ b/misc/extension_api_validation/4.2-stable.expected @@ -263,9 +263,6 @@ Removed VisualShaderNodeComment, which is replaced by VisualShaderNodeFrame. GH-87888 -------- -Validate extension JSON: API was removed: classes/OpenXRHand/methods/get_hand_skeleton -Validate extension JSON: API was removed: classes/OpenXRHand/methods/set_hand_skeleton -Validate extension JSON: API was removed: classes/OpenXRHand/properties/hand_skeleton Validate extension JSON: API was removed: classes/Skeleton3D/properties/animate_physical_bones Validate extension JSON: API was removed: classes/SkeletonIK3D/methods/get_interpolation Validate extension JSON: API was removed: classes/SkeletonIK3D/methods/set_interpolation diff --git a/modules/openxr/doc_classes/OpenXRHand.xml b/modules/openxr/doc_classes/OpenXRHand.xml index 9cc548dd6f2..23d932ddd75 100644 --- a/modules/openxr/doc_classes/OpenXRHand.xml +++ b/modules/openxr/doc_classes/OpenXRHand.xml @@ -1,5 +1,5 @@ - + Node supporting hand and finger tracking in OpenXR. @@ -18,11 +18,14 @@ Specifies whether this node tracks the left or right hand of the player. + + Set a [Skeleton3D] node for which the pose positions will be updated. + Set the motion range (if supported) limiting the hand motion. - Set the type of skeleton rig the parent [Skeleton3D] is compliant with. + Set the type of skeleton rig the [member hand_skeleton] is compliant with. diff --git a/modules/openxr/scene/openxr_hand.cpp b/modules/openxr/scene/openxr_hand.cpp index f20d1f8e19b..2a4104f6eef 100644 --- a/modules/openxr/scene/openxr_hand.cpp +++ b/modules/openxr/scene/openxr_hand.cpp @@ -40,6 +40,9 @@ void OpenXRHand::_bind_methods() { ClassDB::bind_method(D_METHOD("set_hand", "hand"), &OpenXRHand::set_hand); ClassDB::bind_method(D_METHOD("get_hand"), &OpenXRHand::get_hand); + ClassDB::bind_method(D_METHOD("set_hand_skeleton", "hand_skeleton"), &OpenXRHand::set_hand_skeleton); + ClassDB::bind_method(D_METHOD("get_hand_skeleton"), &OpenXRHand::get_hand_skeleton); + ClassDB::bind_method(D_METHOD("set_motion_range", "motion_range"), &OpenXRHand::set_motion_range); ClassDB::bind_method(D_METHOD("get_motion_range"), &OpenXRHand::get_motion_range); @@ -51,6 +54,7 @@ void OpenXRHand::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "hand", PROPERTY_HINT_ENUM, "Left,Right"), "set_hand", "get_hand"); ADD_PROPERTY(PropertyInfo(Variant::INT, "motion_range", PROPERTY_HINT_ENUM, "Unobstructed,Conform to controller"), "set_motion_range", "get_motion_range"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "hand_skeleton", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton3D"), "set_hand_skeleton", "get_hand_skeleton"); ADD_PROPERTY(PropertyInfo(Variant::INT, "skeleton_rig", PROPERTY_HINT_ENUM, "OpenXR,Humanoid"), "set_skeleton_rig", "get_skeleton_rig"); ADD_PROPERTY(PropertyInfo(Variant::INT, "bone_update", PROPERTY_HINT_ENUM, "Full,Rotation Only"), "set_bone_update", "get_bone_update"); @@ -86,6 +90,12 @@ OpenXRHand::Hands OpenXRHand::get_hand() const { return hand; } +void OpenXRHand::set_hand_skeleton(const NodePath &p_hand_skeleton) { + hand_skeleton = p_hand_skeleton; + + // TODO if inside tree call _get_bones() +} + void OpenXRHand::set_motion_range(MotionRange p_motion_range) { ERR_FAIL_INDEX(p_motion_range, MOTION_RANGE_MAX); motion_range = p_motion_range; @@ -97,6 +107,10 @@ OpenXRHand::MotionRange OpenXRHand::get_motion_range() const { return motion_range; } +NodePath OpenXRHand::get_hand_skeleton() const { + return hand_skeleton; +} + void OpenXRHand::_set_motion_range() { if (!hand_tracking_ext) { return; @@ -138,6 +152,20 @@ OpenXRHand::BoneUpdate OpenXRHand::get_bone_update() const { return bone_update; } +Skeleton3D *OpenXRHand::get_skeleton() { + if (!has_node(hand_skeleton)) { + return nullptr; + } + + Node *node = get_node(hand_skeleton); + if (!node) { + return nullptr; + } + + Skeleton3D *skeleton = Object::cast_to(node); + return skeleton; +} + void OpenXRHand::_get_joint_data() { // Table of bone names for different rig types. static const String bone_names[SKELETON_RIG_MAX][XR_HAND_JOINT_COUNT_EXT] = { @@ -262,7 +290,7 @@ void OpenXRHand::_get_joint_data() { } } -void OpenXRHand::_process_modification() { +void OpenXRHand::_update_skeleton() { if (openxr_api == nullptr || !openxr_api->is_initialized()) { return; } else if (hand_tracking_ext == nullptr || !hand_tracking_ext->get_active()) { @@ -367,14 +395,21 @@ void OpenXRHand::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { _get_joint_data(); + + set_process_internal(true); } break; case NOTIFICATION_EXIT_TREE: { + set_process_internal(false); + // reset for (int i = 0; i < XR_HAND_JOINT_COUNT_EXT; i++) { joints[i].bone = -1; joints[i].parent_joint = -1; } } break; + case NOTIFICATION_INTERNAL_PROCESS: { + _update_skeleton(); + } break; default: { } break; } diff --git a/modules/openxr/scene/openxr_hand.h b/modules/openxr/scene/openxr_hand.h index fc0a994f488..4c77e7277c8 100644 --- a/modules/openxr/scene/openxr_hand.h +++ b/modules/openxr/scene/openxr_hand.h @@ -31,15 +31,16 @@ #ifndef OPENXR_HAND_H #define OPENXR_HAND_H -#include "scene/3d/skeleton_modifier_3d.h" +#include "scene/3d/node_3d.h" +#include "scene/3d/skeleton_3d.h" #include class OpenXRAPI; class OpenXRHandTrackingExtension; -class OpenXRHand : public SkeletonModifier3D { - GDCLASS(OpenXRHand, SkeletonModifier3D); +class OpenXRHand : public Node3D { + GDCLASS(OpenXRHand, Node3D); public: enum Hands { // Deprecated, need to change this to OpenXRInterface::Hands. @@ -85,13 +86,13 @@ private: void _set_motion_range(); + Skeleton3D *get_skeleton(); void _get_joint_data(); + void _update_skeleton(); protected: static void _bind_methods(); - virtual void _process_modification() override; - public: OpenXRHand(); @@ -101,6 +102,9 @@ public: void set_motion_range(MotionRange p_motion_range); MotionRange get_motion_range() const; + void set_hand_skeleton(const NodePath &p_hand_skeleton); + NodePath get_hand_skeleton() const; + void set_skeleton_rig(SkeletonRig p_skeleton_rig); SkeletonRig get_skeleton_rig() const;