Merge pull request #90645 from Malcolmnixon/unified-xr-trackers
Rework XR Trackers to have a common ancestor
This commit is contained in:
commit
bffaa98b13
49 changed files with 769 additions and 636 deletions
|
|
@ -23,7 +23,7 @@
|
|||
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" deprecated="Use [method XRHandTracker.get_hand_joint_angular_velocity] obtained from [method XRServer.get_hand_tracker] instead.">
|
||||
<method name="get_hand_joint_angular_velocity" qualifiers="const" deprecated="Use [method XRHandTracker.get_hand_joint_angular_velocity] obtained from [method XRServer.get_tracker] instead.">
|
||||
<return type="Vector3" />
|
||||
<param index="0" name="hand" type="int" enum="OpenXRInterface.Hand" />
|
||||
<param index="1" name="joint" type="int" enum="OpenXRInterface.HandJoints" />
|
||||
|
|
@ -31,7 +31,7 @@
|
|||
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_flags" qualifiers="const" deprecated="Use [method XRHandTracker.get_hand_joint_flags] obtained from [method XRServer.get_hand_tracker] instead.">
|
||||
<method name="get_hand_joint_flags" qualifiers="const" deprecated="Use [method XRHandTracker.get_hand_joint_flags] obtained from [method XRServer.get_tracker] instead.">
|
||||
<return type="int" enum="OpenXRInterface.HandJointFlags" is_bitfield="true" />
|
||||
<param index="0" name="hand" type="int" enum="OpenXRInterface.Hand" />
|
||||
<param index="1" name="joint" type="int" enum="OpenXRInterface.HandJoints" />
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
If handtracking is enabled, returns flags that inform us of the validity of the tracking data.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_hand_joint_linear_velocity" qualifiers="const" deprecated="Use [method XRHandTracker.get_hand_joint_linear_velocity] obtained from [method XRServer.get_hand_tracker] instead.">
|
||||
<method name="get_hand_joint_linear_velocity" qualifiers="const" deprecated="Use [method XRHandTracker.get_hand_joint_linear_velocity] obtained from [method XRServer.get_tracker] instead.">
|
||||
<return type="Vector3" />
|
||||
<param index="0" name="hand" type="int" enum="OpenXRInterface.Hand" />
|
||||
<param index="1" name="joint" type="int" enum="OpenXRInterface.HandJoints" />
|
||||
|
|
@ -47,7 +47,7 @@
|
|||
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" deprecated="Use [method XRHandTracker.get_hand_joint_transform] obtained from [method XRServer.get_hand_tracker] instead.">
|
||||
<method name="get_hand_joint_position" qualifiers="const" deprecated="Use [method XRHandTracker.get_hand_joint_transform] obtained from [method XRServer.get_tracker] instead.">
|
||||
<return type="Vector3" />
|
||||
<param index="0" name="hand" type="int" enum="OpenXRInterface.Hand" />
|
||||
<param index="1" name="joint" type="int" enum="OpenXRInterface.HandJoints" />
|
||||
|
|
@ -55,7 +55,7 @@
|
|||
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" deprecated="Use [method XRHandTracker.get_hand_joint_radius] obtained from [method XRServer.get_hand_tracker] instead.">
|
||||
<method name="get_hand_joint_radius" qualifiers="const" deprecated="Use [method XRHandTracker.get_hand_joint_radius] obtained from [method XRServer.get_tracker] instead.">
|
||||
<return type="float" />
|
||||
<param index="0" name="hand" type="int" enum="OpenXRInterface.Hand" />
|
||||
<param index="1" name="joint" type="int" enum="OpenXRInterface.HandJoints" />
|
||||
|
|
@ -63,7 +63,7 @@
|
|||
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" deprecated="Use [method XRHandTracker.get_hand_joint_transform] obtained from [method XRServer.get_hand_tracker] instead.">
|
||||
<method name="get_hand_joint_rotation" qualifiers="const" deprecated="Use [method XRHandTracker.get_hand_joint_transform] obtained from [method XRServer.get_tracker] instead.">
|
||||
<return type="Quaternion" />
|
||||
<param index="0" name="hand" type="int" enum="OpenXRInterface.Hand" />
|
||||
<param index="1" name="joint" type="int" enum="OpenXRInterface.HandJoints" />
|
||||
|
|
@ -71,7 +71,7 @@
|
|||
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_hand_tracking_source" qualifiers="const" deprecated="Use [member XRHandTracker.hand_tracking_source] obtained from [method XRServer.get_hand_tracker] instead.">
|
||||
<method name="get_hand_tracking_source" qualifiers="const" deprecated="Use [member XRHandTracker.hand_tracking_source] obtained from [method XRServer.get_tracker] instead.">
|
||||
<return type="int" enum="OpenXRInterface.HandTrackedSource" />
|
||||
<param index="0" name="hand" type="int" enum="OpenXRInterface.Hand" />
|
||||
<description>
|
||||
|
|
|
|||
|
|
@ -196,7 +196,8 @@ void OpenXRHandTrackingExtension::on_process() {
|
|||
Ref<XRHandTracker> godot_tracker;
|
||||
godot_tracker.instantiate();
|
||||
godot_tracker->set_hand(i == 0 ? XRHandTracker::HAND_LEFT : XRHandTracker::HAND_RIGHT);
|
||||
XRServer::get_singleton()->add_hand_tracker(i == 0 ? "/user/left" : "/user/right", godot_tracker);
|
||||
godot_tracker->set_tracker_name(i == 0 ? "/user/hand_tracker/left" : "/user/hand_tracker/right");
|
||||
XRServer::get_singleton()->add_tracker(godot_tracker);
|
||||
hand_trackers[i].godot_tracker = godot_tracker;
|
||||
|
||||
hand_trackers[i].is_initialized = true;
|
||||
|
|
@ -229,8 +230,7 @@ void OpenXRHandTrackingExtension::on_process() {
|
|||
|
||||
// For some reason an inactive controller isn't coming back as inactive but has coordinates either as NAN or very large
|
||||
const XrPosef &palm = hand_trackers[i].joint_locations[XR_HAND_JOINT_PALM_EXT].pose;
|
||||
if (
|
||||
!hand_trackers[i].locations.isActive || isnan(palm.position.x) || palm.position.x < -1000000.00 || palm.position.x > 1000000.00) {
|
||||
if (!hand_trackers[i].locations.isActive || isnan(palm.position.x) || palm.position.x < -1000000.00 || palm.position.x > 1000000.00) {
|
||||
hand_trackers[i].locations.isActive = false; // workaround, make sure its inactive
|
||||
}
|
||||
|
||||
|
|
@ -249,6 +249,8 @@ void OpenXRHandTrackingExtension::on_process() {
|
|||
const XrPosef &pose = location.pose;
|
||||
|
||||
Transform3D transform;
|
||||
Vector3 linear_velocity;
|
||||
Vector3 angular_velocity;
|
||||
BitField<XRHandTracker::HandJointFlags> flags;
|
||||
|
||||
if (location.locationFlags & XR_SPACE_LOCATION_ORIENTATION_VALID_BIT) {
|
||||
|
|
@ -269,27 +271,34 @@ void OpenXRHandTrackingExtension::on_process() {
|
|||
}
|
||||
if (location.locationFlags & XR_SPACE_VELOCITY_LINEAR_VALID_BIT) {
|
||||
flags.set_flag(XRHandTracker::HAND_JOINT_FLAG_LINEAR_VELOCITY_VALID);
|
||||
godot_tracker->set_hand_joint_linear_velocity((XRHandTracker::HandJoint)joint, Vector3(velocity.linearVelocity.x, velocity.linearVelocity.y, velocity.linearVelocity.z));
|
||||
linear_velocity = Vector3(velocity.linearVelocity.x, velocity.linearVelocity.y, velocity.linearVelocity.z);
|
||||
godot_tracker->set_hand_joint_linear_velocity((XRHandTracker::HandJoint)joint, linear_velocity);
|
||||
}
|
||||
if (location.locationFlags & XR_SPACE_VELOCITY_ANGULAR_VALID_BIT) {
|
||||
flags.set_flag(XRHandTracker::HAND_JOINT_FLAG_ANGULAR_VELOCITY_VALID);
|
||||
godot_tracker->set_hand_joint_angular_velocity((XRHandTracker::HandJoint)joint, Vector3(velocity.angularVelocity.x, velocity.angularVelocity.y, velocity.angularVelocity.z));
|
||||
angular_velocity = Vector3(velocity.angularVelocity.x, velocity.angularVelocity.y, velocity.angularVelocity.z);
|
||||
godot_tracker->set_hand_joint_angular_velocity((XRHandTracker::HandJoint)joint, angular_velocity);
|
||||
}
|
||||
|
||||
godot_tracker->set_hand_joint_flags((XRHandTracker::HandJoint)joint, flags);
|
||||
godot_tracker->set_hand_joint_transform((XRHandTracker::HandJoint)joint, transform);
|
||||
godot_tracker->set_hand_joint_radius((XRHandTracker::HandJoint)joint, location.radius);
|
||||
|
||||
XRHandTracker::HandTrackingSource source = XRHandTracker::HAND_TRACKING_SOURCE_UNKNOWN;
|
||||
if (data_source.dataSource == XR_HAND_TRACKING_DATA_SOURCE_UNOBSTRUCTED_EXT) {
|
||||
source = XRHandTracker::HAND_TRACKING_SOURCE_UNOBSTRUCTED;
|
||||
} else if (data_source.dataSource == XR_HAND_TRACKING_DATA_SOURCE_CONTROLLER_EXT) {
|
||||
source = XRHandTracker::HAND_TRACKING_SOURCE_CONTROLLER;
|
||||
if (joint == XR_HAND_JOINT_PALM_EXT) {
|
||||
XRHandTracker::HandTrackingSource source = XRHandTracker::HAND_TRACKING_SOURCE_UNKNOWN;
|
||||
if (data_source.dataSource == XR_HAND_TRACKING_DATA_SOURCE_UNOBSTRUCTED_EXT) {
|
||||
source = XRHandTracker::HAND_TRACKING_SOURCE_UNOBSTRUCTED;
|
||||
} else if (data_source.dataSource == XR_HAND_TRACKING_DATA_SOURCE_CONTROLLER_EXT) {
|
||||
source = XRHandTracker::HAND_TRACKING_SOURCE_CONTROLLER;
|
||||
}
|
||||
|
||||
godot_tracker->set_hand_tracking_source(source);
|
||||
godot_tracker->set_pose("default", transform, linear_velocity, angular_velocity);
|
||||
}
|
||||
godot_tracker->set_hand_tracking_source(source);
|
||||
}
|
||||
} else {
|
||||
godot_tracker->set_has_tracking_data(false);
|
||||
godot_tracker->invalidate_pose("default");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -311,7 +320,7 @@ void OpenXRHandTrackingExtension::cleanup_hand_tracking() {
|
|||
hand_trackers[i].is_initialized = false;
|
||||
hand_trackers[i].hand_tracker = XR_NULL_HANDLE;
|
||||
|
||||
XRServer::get_singleton()->remove_hand_tracker(i == 0 ? "/user/left" : "/user/right");
|
||||
XRServer::get_singleton()->remove_tracker(hand_trackers[i].godot_tracker);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "servers/rendering/rendering_server_globals.h"
|
||||
|
||||
#include "extensions/openxr_eye_gaze_interaction.h"
|
||||
#include "thirdparty/openxr/include/openxr/openxr.h"
|
||||
|
||||
void OpenXRInterface::_bind_methods() {
|
||||
// lifecycle signals
|
||||
|
|
@ -154,9 +155,14 @@ PackedStringArray OpenXRInterface::get_suggested_tracker_names() const {
|
|||
// These are hardcoded in OpenXR, note that they will only be available if added to our action map
|
||||
|
||||
PackedStringArray arr = {
|
||||
"left_hand", // /user/hand/left is mapped to our defaults
|
||||
"right_hand", // /user/hand/right is mapped to our defaults
|
||||
"/user/treadmill",
|
||||
"head", // XRPositionalTracker for the users head (Mapped from OpenXR /user/head)
|
||||
"left_hand", // XRControllerTracker for the users left hand (Mapped from OpenXR /user/hand/left)
|
||||
"right_hand", // XRControllerTracker for the users right hand (Mapped from OpenXR /user/hand/right)
|
||||
"/user/hand_tracker/left", // XRHandTracker for the users left hand
|
||||
"/user/hand_tracker/right", // XRHandTracker for the users right hand
|
||||
"/user/body_tracker", // XRBodyTracker for the users body
|
||||
"/user/face_tracker", // XRFaceTracker for the users face
|
||||
"/user/treadmill"
|
||||
};
|
||||
|
||||
for (OpenXRExtensionWrapper *wrapper : OpenXRAPI::get_singleton()->get_registered_extension_wrappers()) {
|
||||
|
|
@ -430,34 +436,31 @@ OpenXRInterface::Tracker *OpenXRInterface::find_tracker(const String &p_tracker_
|
|||
RID tracker_rid = openxr_api->tracker_create(p_tracker_name);
|
||||
ERR_FAIL_COND_V(tracker_rid.is_null(), nullptr);
|
||||
|
||||
// create our positional tracker
|
||||
Ref<XRPositionalTracker> positional_tracker;
|
||||
positional_tracker.instantiate();
|
||||
// Create our controller tracker.
|
||||
Ref<XRControllerTracker> controller_tracker;
|
||||
controller_tracker.instantiate();
|
||||
|
||||
// We have standardized some names to make things nicer to the user so lets recognize the toplevel paths related to these.
|
||||
if (p_tracker_name == "/user/hand/left") {
|
||||
positional_tracker->set_tracker_type(XRServer::TRACKER_CONTROLLER);
|
||||
positional_tracker->set_tracker_name("left_hand");
|
||||
positional_tracker->set_tracker_desc("Left hand controller");
|
||||
positional_tracker->set_tracker_hand(XRPositionalTracker::TRACKER_HAND_LEFT);
|
||||
controller_tracker->set_tracker_name("left_hand");
|
||||
controller_tracker->set_tracker_desc("Left hand controller");
|
||||
controller_tracker->set_tracker_hand(XRPositionalTracker::TRACKER_HAND_LEFT);
|
||||
} else if (p_tracker_name == "/user/hand/right") {
|
||||
positional_tracker->set_tracker_type(XRServer::TRACKER_CONTROLLER);
|
||||
positional_tracker->set_tracker_name("right_hand");
|
||||
positional_tracker->set_tracker_desc("Right hand controller");
|
||||
positional_tracker->set_tracker_hand(XRPositionalTracker::TRACKER_HAND_RIGHT);
|
||||
controller_tracker->set_tracker_name("right_hand");
|
||||
controller_tracker->set_tracker_desc("Right hand controller");
|
||||
controller_tracker->set_tracker_hand(XRPositionalTracker::TRACKER_HAND_RIGHT);
|
||||
} else {
|
||||
positional_tracker->set_tracker_type(XRServer::TRACKER_CONTROLLER);
|
||||
positional_tracker->set_tracker_name(p_tracker_name);
|
||||
positional_tracker->set_tracker_desc(p_tracker_name);
|
||||
controller_tracker->set_tracker_name(p_tracker_name);
|
||||
controller_tracker->set_tracker_desc(p_tracker_name);
|
||||
}
|
||||
positional_tracker->set_tracker_profile(INTERACTION_PROFILE_NONE);
|
||||
xr_server->add_tracker(positional_tracker);
|
||||
controller_tracker->set_tracker_profile(INTERACTION_PROFILE_NONE);
|
||||
xr_server->add_tracker(controller_tracker);
|
||||
|
||||
// create a new entry
|
||||
tracker = memnew(Tracker);
|
||||
tracker->tracker_name = p_tracker_name;
|
||||
tracker->tracker_rid = tracker_rid;
|
||||
tracker->positional_tracker = positional_tracker;
|
||||
tracker->controller_tracker = controller_tracker;
|
||||
tracker->interaction_profile = RID();
|
||||
trackers.push_back(tracker);
|
||||
|
||||
|
|
@ -477,17 +480,17 @@ void OpenXRInterface::tracker_profile_changed(RID p_tracker, RID p_interaction_p
|
|||
|
||||
if (p_interaction_profile.is_null()) {
|
||||
print_verbose("OpenXR: Interaction profile for " + tracker->tracker_name + " changed to " + INTERACTION_PROFILE_NONE);
|
||||
tracker->positional_tracker->set_tracker_profile(INTERACTION_PROFILE_NONE);
|
||||
tracker->controller_tracker->set_tracker_profile(INTERACTION_PROFILE_NONE);
|
||||
} else {
|
||||
String name = openxr_api->interaction_profile_get_name(p_interaction_profile);
|
||||
print_verbose("OpenXR: Interaction profile for " + tracker->tracker_name + " changed to " + name);
|
||||
tracker->positional_tracker->set_tracker_profile(name);
|
||||
tracker->controller_tracker->set_tracker_profile(name);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRInterface::handle_tracker(Tracker *p_tracker) {
|
||||
ERR_FAIL_NULL(openxr_api);
|
||||
ERR_FAIL_COND(p_tracker->positional_tracker.is_null());
|
||||
ERR_FAIL_COND(p_tracker->controller_tracker.is_null());
|
||||
|
||||
// Note, which actions are actually bound to inputs are handled by our interaction profiles however interaction
|
||||
// profiles are suggested bindings for controller types we know about. OpenXR runtimes can stray away from these
|
||||
|
|
@ -506,15 +509,15 @@ void OpenXRInterface::handle_tracker(Tracker *p_tracker) {
|
|||
switch (action->action_type) {
|
||||
case OpenXRAction::OPENXR_ACTION_BOOL: {
|
||||
bool pressed = openxr_api->get_action_bool(action->action_rid, p_tracker->tracker_rid);
|
||||
p_tracker->positional_tracker->set_input(action->action_name, Variant(pressed));
|
||||
p_tracker->controller_tracker->set_input(action->action_name, Variant(pressed));
|
||||
} break;
|
||||
case OpenXRAction::OPENXR_ACTION_FLOAT: {
|
||||
real_t value = openxr_api->get_action_float(action->action_rid, p_tracker->tracker_rid);
|
||||
p_tracker->positional_tracker->set_input(action->action_name, Variant(value));
|
||||
p_tracker->controller_tracker->set_input(action->action_name, Variant(value));
|
||||
} break;
|
||||
case OpenXRAction::OPENXR_ACTION_VECTOR2: {
|
||||
Vector2 value = openxr_api->get_action_vector2(action->action_rid, p_tracker->tracker_rid);
|
||||
p_tracker->positional_tracker->set_input(action->action_name, Variant(value));
|
||||
p_tracker->controller_tracker->set_input(action->action_name, Variant(value));
|
||||
} break;
|
||||
case OpenXRAction::OPENXR_ACTION_POSE: {
|
||||
Transform3D transform;
|
||||
|
|
@ -523,9 +526,9 @@ void OpenXRInterface::handle_tracker(Tracker *p_tracker) {
|
|||
XRPose::TrackingConfidence confidence = openxr_api->get_action_pose(action->action_rid, p_tracker->tracker_rid, transform, linear, angular);
|
||||
|
||||
if (confidence != XRPose::XR_TRACKING_CONFIDENCE_NONE) {
|
||||
p_tracker->positional_tracker->set_pose(action->action_name, transform, linear, angular, confidence);
|
||||
p_tracker->controller_tracker->set_pose(action->action_name, transform, linear, angular, confidence);
|
||||
} else {
|
||||
p_tracker->positional_tracker->invalidate_pose(action->action_name);
|
||||
p_tracker->controller_tracker->invalidate_pose(action->action_name);
|
||||
}
|
||||
} break;
|
||||
default: {
|
||||
|
|
@ -567,8 +570,8 @@ void OpenXRInterface::free_trackers() {
|
|||
Tracker *tracker = trackers[i];
|
||||
|
||||
openxr_api->tracker_free(tracker->tracker_rid);
|
||||
xr_server->remove_tracker(tracker->positional_tracker);
|
||||
tracker->positional_tracker.unref();
|
||||
xr_server->remove_tracker(tracker->controller_tracker);
|
||||
tracker->controller_tracker.unref();
|
||||
|
||||
memdelete(tracker);
|
||||
}
|
||||
|
|
@ -1005,7 +1008,7 @@ void OpenXRInterface::handle_hand_tracking(const String &p_path, OpenXRHandTrack
|
|||
OpenXRHandTrackingExtension *hand_tracking_ext = OpenXRHandTrackingExtension::get_singleton();
|
||||
if (hand_tracking_ext && hand_tracking_ext->get_active()) {
|
||||
OpenXRInterface::Tracker *tracker = find_tracker(p_path);
|
||||
if (tracker && tracker->positional_tracker.is_valid()) {
|
||||
if (tracker && tracker->controller_tracker.is_valid()) {
|
||||
XrSpaceLocationFlags location_flags = hand_tracking_ext->get_hand_joint_location_flags(p_hand, XR_HAND_JOINT_PALM_EXT);
|
||||
|
||||
if (location_flags & (XR_SPACE_LOCATION_ORIENTATION_VALID_BIT + XR_SPACE_LOCATION_POSITION_VALID_BIT)) {
|
||||
|
|
@ -1035,9 +1038,9 @@ void OpenXRInterface::handle_hand_tracking(const String &p_path, OpenXRHandTrack
|
|||
angular_velocity = hand_tracking_ext->get_hand_joint_angular_velocity(p_hand, XR_HAND_JOINT_PALM_EXT);
|
||||
}
|
||||
|
||||
tracker->positional_tracker->set_pose("skeleton", transform, linear_velocity, angular_velocity, confidence);
|
||||
tracker->controller_tracker->set_pose("skeleton", transform, linear_velocity, angular_velocity, confidence);
|
||||
} else {
|
||||
tracker->positional_tracker->invalidate_pose("skeleton");
|
||||
tracker->controller_tracker->invalidate_pose("skeleton");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@
|
|||
#include "extensions/openxr_hand_tracking_extension.h"
|
||||
#include "openxr_api.h"
|
||||
|
||||
#include "servers/xr/xr_controller_tracker.h"
|
||||
#include "servers/xr/xr_interface.h"
|
||||
#include "servers/xr/xr_positional_tracker.h"
|
||||
|
||||
// declare some default strings
|
||||
#define INTERACTION_PROFILE_NONE "/interaction_profiles/none"
|
||||
|
|
@ -73,7 +73,7 @@ private:
|
|||
struct Tracker { // A tracker we've registered with OpenXR
|
||||
String tracker_name; // Name of our tracker (can be altered from the action map)
|
||||
Vector<Action *> actions; // Actions related to this tracker
|
||||
Ref<XRPositionalTracker> positional_tracker; // Our positional tracker object that holds our tracker state
|
||||
Ref<XRControllerTracker> controller_tracker; // Our positional tracker object that holds our tracker state
|
||||
RID tracker_rid; // RID of the tracker registered with our OpenXR API
|
||||
RID interaction_profile; // RID of the interaction profile bound to this tracker (can be null)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -114,10 +114,10 @@
|
|||
</description>
|
||||
</method>
|
||||
<method name="get_input_source_tracker" qualifiers="const">
|
||||
<return type="XRPositionalTracker" />
|
||||
<return type="XRControllerTracker" />
|
||||
<param index="0" name="input_source_id" type="int" />
|
||||
<description>
|
||||
Gets an [XRPositionalTracker] for the given [param input_source_id].
|
||||
Gets an [XRControllerTracker] for the given [param input_source_id].
|
||||
In the context of WebXR, an input source can be an advanced VR controller like the Oculus Touch or Index controllers, or even a tap on the screen, a spoken voice command or a button press on the device itself. When a non-traditional input source is used, interpret the position and orientation of the [XRPositionalTracker] as a ray pointing at the object the user wishes to interact with.
|
||||
Use this method to get information about the input source that triggered one of these signals:
|
||||
- [signal selectstart]
|
||||
|
|
|
|||
41
modules/webxr/webxr_interface.compat.inc
Normal file
41
modules/webxr/webxr_interface.compat.inc
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/**************************************************************************/
|
||||
/* webxr_interface.compat.inc */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
|
||||
Ref<XRPositionalTracker> WebXRInterface::_get_input_source_tracker_bind_compat_90645(int p_input_source_id) const {
|
||||
return get_input_source_tracker(p_input_source_id);
|
||||
}
|
||||
|
||||
void WebXRInterface::_bind_compatibility_methods() {
|
||||
ClassDB::bind_compatibility_method(D_METHOD("get_input_source_tracker", "input_source_id"), &WebXRInterface::_get_input_source_tracker_bind_compat_90645);
|
||||
}
|
||||
|
||||
#endif // DISABLE_DEPRECATED
|
||||
|
|
@ -29,6 +29,7 @@
|
|||
/**************************************************************************/
|
||||
|
||||
#include "webxr_interface.h"
|
||||
#include "webxr_interface.compat.inc"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@
|
|||
#ifndef WEBXR_INTERFACE_H
|
||||
#define WEBXR_INTERFACE_H
|
||||
|
||||
#include "servers/xr/xr_controller_tracker.h"
|
||||
#include "servers/xr/xr_interface.h"
|
||||
#include "servers/xr/xr_positional_tracker.h"
|
||||
|
||||
/**
|
||||
The WebXR interface is a VR/AR interface that can be used on the web.
|
||||
|
|
@ -44,6 +44,11 @@ class WebXRInterface : public XRInterface {
|
|||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
static void _bind_compatibility_methods();
|
||||
Ref<XRPositionalTracker> _get_input_source_tracker_bind_compat_90645(int p_input_source_id) const;
|
||||
#endif
|
||||
|
||||
public:
|
||||
enum TargetRayMode {
|
||||
TARGET_RAY_MODE_UNKNOWN,
|
||||
|
|
@ -64,7 +69,7 @@ public:
|
|||
virtual String get_reference_space_type() const = 0;
|
||||
virtual String get_enabled_features() const = 0;
|
||||
virtual bool is_input_source_active(int p_input_source_id) const = 0;
|
||||
virtual Ref<XRPositionalTracker> get_input_source_tracker(int p_input_source_id) const = 0;
|
||||
virtual Ref<XRControllerTracker> get_input_source_tracker(int p_input_source_id) const = 0;
|
||||
virtual TargetRayMode get_input_source_target_ray_mode(int p_input_source_id) const = 0;
|
||||
virtual String get_visibility_state() const = 0;
|
||||
virtual float get_display_refresh_rate() const = 0;
|
||||
|
|
|
|||
|
|
@ -164,8 +164,8 @@ bool WebXRInterfaceJS::is_input_source_active(int p_input_source_id) const {
|
|||
return input_sources[p_input_source_id].active;
|
||||
}
|
||||
|
||||
Ref<XRPositionalTracker> WebXRInterfaceJS::get_input_source_tracker(int p_input_source_id) const {
|
||||
ERR_FAIL_INDEX_V(p_input_source_id, input_source_count, Ref<XRPositionalTracker>());
|
||||
Ref<XRControllerTracker> WebXRInterfaceJS::get_input_source_tracker(int p_input_source_id) const {
|
||||
ERR_FAIL_INDEX_V(p_input_source_id, input_source_count, Ref<XRControllerTracker>());
|
||||
return input_sources[p_input_source_id].tracker;
|
||||
}
|
||||
|
||||
|
|
@ -307,7 +307,7 @@ void WebXRInterfaceJS::uninitialize() {
|
|||
|
||||
for (int i = 0; i < HAND_MAX; i++) {
|
||||
if (hand_trackers[i].is_valid()) {
|
||||
xr_server->remove_hand_tracker(i == 0 ? "/user/left" : "/user/right");
|
||||
xr_server->remove_tracker(hand_trackers[i]);
|
||||
|
||||
hand_trackers[i].unref();
|
||||
}
|
||||
|
|
@ -616,7 +616,7 @@ void WebXRInterfaceJS::_update_input_source(int p_input_source_id) {
|
|||
input_source.target_ray_mode = (WebXRInterface::TargetRayMode)tmp_target_ray_mode;
|
||||
input_source.touch_index = touch_index;
|
||||
|
||||
Ref<XRPositionalTracker> &tracker = input_source.tracker;
|
||||
Ref<XRControllerTracker> &tracker = input_source.tracker;
|
||||
|
||||
if (tracker.is_null()) {
|
||||
tracker.instantiate();
|
||||
|
|
@ -630,7 +630,6 @@ void WebXRInterfaceJS::_update_input_source(int p_input_source_id) {
|
|||
|
||||
// Input source id's 0 and 1 are always the left and right hands.
|
||||
if (p_input_source_id < 2) {
|
||||
tracker->set_tracker_type(XRServer::TRACKER_CONTROLLER);
|
||||
tracker->set_tracker_name(tracker_name);
|
||||
tracker->set_tracker_desc(p_input_source_id == 0 ? "Left hand controller" : "Right hand controller");
|
||||
tracker->set_tracker_hand(p_input_source_id == 0 ? XRPositionalTracker::TRACKER_HAND_LEFT : XRPositionalTracker::TRACKER_HAND_RIGHT);
|
||||
|
|
@ -715,6 +714,7 @@ void WebXRInterfaceJS::_update_input_source(int p_input_source_id) {
|
|||
if (unlikely(hand_tracker.is_null())) {
|
||||
hand_tracker.instantiate();
|
||||
hand_tracker->set_hand(p_input_source_id == 0 ? XRHandTracker::HAND_LEFT : XRHandTracker::HAND_RIGHT);
|
||||
hand_tracker->set_tracker_name(p_input_source_id == 0 ? "/user/hand_tracker/left" : "/user/hand_tracker/right");
|
||||
|
||||
// These flags always apply, since WebXR doesn't give us enough insight to be more fine grained.
|
||||
BitField<XRHandTracker::HandJointFlags> joint_flags(XRHandTracker::HAND_JOINT_FLAG_POSITION_VALID | XRHandTracker::HAND_JOINT_FLAG_ORIENTATION_VALID | XRHandTracker::HAND_JOINT_FLAG_POSITION_TRACKED | XRHandTracker::HAND_JOINT_FLAG_ORIENTATION_TRACKED);
|
||||
|
|
@ -723,7 +723,7 @@ void WebXRInterfaceJS::_update_input_source(int p_input_source_id) {
|
|||
}
|
||||
|
||||
hand_trackers[p_input_source_id] = hand_tracker;
|
||||
xr_server->add_hand_tracker(p_input_source_id == 0 ? "/user/left" : "/user/right", hand_tracker);
|
||||
xr_server->add_tracker(hand_tracker);
|
||||
}
|
||||
|
||||
hand_tracker->set_has_tracking_data(true);
|
||||
|
|
@ -746,10 +746,12 @@ void WebXRInterfaceJS::_update_input_source(int p_input_source_id) {
|
|||
Transform3D palm_transform;
|
||||
palm_transform.origin = (Vector3(start_pos[0], start_pos[1], start_pos[2]) + Vector3(end_pos[0], end_pos[1], end_pos[2])) / 2.0;
|
||||
hand_tracker->set_hand_joint_transform(XRHandTracker::HAND_JOINT_PALM, palm_transform);
|
||||
hand_tracker->set_pose("default", palm_transform, Vector3(), Vector3());
|
||||
}
|
||||
|
||||
} else if (hand_tracker.is_valid()) {
|
||||
hand_tracker->set_has_tracking_data(false);
|
||||
hand_tracker->invalidate_pose("default");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@
|
|||
|
||||
#ifdef WEB_ENABLED
|
||||
|
||||
#include "servers/xr/xr_controller_tracker.h"
|
||||
#include "servers/xr/xr_hand_tracker.h"
|
||||
#include "webxr_interface.h"
|
||||
|
||||
/**
|
||||
|
|
@ -68,7 +70,7 @@ private:
|
|||
static constexpr uint8_t input_source_count = 16;
|
||||
|
||||
struct InputSource {
|
||||
Ref<XRPositionalTracker> tracker;
|
||||
Ref<XRControllerTracker> tracker;
|
||||
bool active = false;
|
||||
TargetRayMode target_ray_mode;
|
||||
int touch_index = -1;
|
||||
|
|
@ -102,7 +104,7 @@ public:
|
|||
virtual String get_reference_space_type() const override;
|
||||
virtual String get_enabled_features() const override;
|
||||
virtual bool is_input_source_active(int p_input_source_id) const override;
|
||||
virtual Ref<XRPositionalTracker> get_input_source_tracker(int p_input_source_id) const override;
|
||||
virtual Ref<XRControllerTracker> get_input_source_tracker(int p_input_source_id) const override;
|
||||
virtual TargetRayMode get_input_source_target_ray_mode(int p_input_source_id) const override;
|
||||
virtual String get_visibility_state() const override;
|
||||
virtual PackedVector3Array get_play_area() const override;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue