Rework XR Trackers to have a common ancestor. Allow creation of XRNode3D to drive node positions and visibility.

This commit is contained in:
Malcolm Nixon
2024-04-13 17:26:46 -04:00
parent 3b1806182a
commit 823ae7b3fa
49 changed files with 769 additions and 636 deletions

View File

@@ -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]

View 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

View File

@@ -29,6 +29,7 @@
/**************************************************************************/
#include "webxr_interface.h"
#include "webxr_interface.compat.inc"
#include <stdlib.h>

View File

@@ -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;

View File

@@ -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");
}
}
}

View File

@@ -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;