summaryrefslogtreecommitdiffstats
path: root/servers/xr_server.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'servers/xr_server.cpp')
-rw-r--r--servers/xr_server.cpp263
1 files changed, 113 insertions, 150 deletions
diff --git a/servers/xr_server.cpp b/servers/xr_server.cpp
index 1e497e22c3..2cfe98ea1e 100644
--- a/servers/xr_server.cpp
+++ b/servers/xr_server.cpp
@@ -30,10 +30,12 @@
#include "xr_server.h"
#include "core/config/project_settings.h"
+#include "xr/xr_body_tracker.h"
#include "xr/xr_face_tracker.h"
#include "xr/xr_hand_tracker.h"
#include "xr/xr_interface.h"
#include "xr/xr_positional_tracker.h"
+#include "xr_server.compat.inc"
XRServer::XRMode XRServer::xr_mode = XRMODE_DEFAULT;
@@ -49,7 +51,7 @@ XRServer *XRServer::singleton = nullptr;
XRServer *XRServer::get_singleton() {
return singleton;
-};
+}
void XRServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_world_scale"), &XRServer::get_world_scale);
@@ -57,7 +59,7 @@ void XRServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_world_origin"), &XRServer::get_world_origin);
ClassDB::bind_method(D_METHOD("set_world_origin", "world_origin"), &XRServer::set_world_origin);
ClassDB::bind_method(D_METHOD("get_reference_frame"), &XRServer::get_reference_frame);
- ClassDB::bind_method(D_METHOD("clear_reference_frame"), &XRServer::get_reference_frame);
+ ClassDB::bind_method(D_METHOD("clear_reference_frame"), &XRServer::clear_reference_frame);
ClassDB::bind_method(D_METHOD("center_on_hmd", "rotation_mode", "keep_height"), &XRServer::center_on_hmd);
ClassDB::bind_method(D_METHOD("get_hmd_transform"), &XRServer::get_hmd_transform);
@@ -76,16 +78,6 @@ void XRServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_trackers", "tracker_types"), &XRServer::get_trackers);
ClassDB::bind_method(D_METHOD("get_tracker", "tracker_name"), &XRServer::get_tracker);
- ClassDB::bind_method(D_METHOD("add_hand_tracker", "tracker_name", "hand_tracker"), &XRServer::add_hand_tracker);
- ClassDB::bind_method(D_METHOD("remove_hand_tracker", "tracker_name"), &XRServer::remove_hand_tracker);
- ClassDB::bind_method(D_METHOD("get_hand_trackers"), &XRServer::get_hand_trackers);
- ClassDB::bind_method(D_METHOD("get_hand_tracker", "tracker_name"), &XRServer::get_hand_tracker);
-
- ClassDB::bind_method(D_METHOD("add_face_tracker", "tracker_name", "face_tracker"), &XRServer::add_face_tracker);
- ClassDB::bind_method(D_METHOD("remove_face_tracker", "tracker_name"), &XRServer::remove_face_tracker);
- ClassDB::bind_method(D_METHOD("get_face_trackers"), &XRServer::get_face_trackers);
- ClassDB::bind_method(D_METHOD("get_face_tracker", "tracker_name"), &XRServer::get_face_tracker);
-
ClassDB::bind_method(D_METHOD("get_primary_interface"), &XRServer::get_primary_interface);
ClassDB::bind_method(D_METHOD("set_primary_interface", "interface"), &XRServer::set_primary_interface);
@@ -95,6 +87,9 @@ void XRServer::_bind_methods() {
BIND_ENUM_CONSTANT(TRACKER_CONTROLLER);
BIND_ENUM_CONSTANT(TRACKER_BASESTATION);
BIND_ENUM_CONSTANT(TRACKER_ANCHOR);
+ BIND_ENUM_CONSTANT(TRACKER_HAND);
+ BIND_ENUM_CONSTANT(TRACKER_BODY);
+ BIND_ENUM_CONSTANT(TRACKER_FACE);
BIND_ENUM_CONSTANT(TRACKER_ANY_KNOWN);
BIND_ENUM_CONSTANT(TRACKER_UNKNOWN);
BIND_ENUM_CONSTANT(TRACKER_ANY);
@@ -109,19 +104,20 @@ void XRServer::_bind_methods() {
ADD_SIGNAL(MethodInfo("tracker_added", PropertyInfo(Variant::STRING_NAME, "tracker_name"), PropertyInfo(Variant::INT, "type")));
ADD_SIGNAL(MethodInfo("tracker_updated", PropertyInfo(Variant::STRING_NAME, "tracker_name"), PropertyInfo(Variant::INT, "type")));
ADD_SIGNAL(MethodInfo("tracker_removed", PropertyInfo(Variant::STRING_NAME, "tracker_name"), PropertyInfo(Variant::INT, "type")));
-
- ADD_SIGNAL(MethodInfo("hand_tracker_added", PropertyInfo(Variant::STRING_NAME, "tracker_name"), PropertyInfo(Variant::OBJECT, "hand_tracker", PROPERTY_HINT_RESOURCE_TYPE, "XRHandTracker")));
- ADD_SIGNAL(MethodInfo("hand_tracker_updated", PropertyInfo(Variant::STRING_NAME, "tracker_name"), PropertyInfo(Variant::OBJECT, "hand_tracker", PROPERTY_HINT_RESOURCE_TYPE, "XRHandTracker")));
- ADD_SIGNAL(MethodInfo("hand_tracker_removed", PropertyInfo(Variant::STRING_NAME, "tracker_name")));
-
- ADD_SIGNAL(MethodInfo("face_tracker_added", PropertyInfo(Variant::STRING_NAME, "tracker_name"), PropertyInfo(Variant::OBJECT, "face_tracker", PROPERTY_HINT_RESOURCE_TYPE, "XRFaceTracker")));
- ADD_SIGNAL(MethodInfo("face_tracker_updated", PropertyInfo(Variant::STRING_NAME, "tracker_name"), PropertyInfo(Variant::OBJECT, "face_tracker", PROPERTY_HINT_RESOURCE_TYPE, "XRFaceTracker")));
- ADD_SIGNAL(MethodInfo("face_tracker_removed", PropertyInfo(Variant::STRING_NAME, "tracker_name")));
-};
+}
double XRServer::get_world_scale() const {
- return world_scale;
-};
+ RenderingServer *rendering_server = RenderingServer::get_singleton();
+
+ if (rendering_server && rendering_server->is_on_render_thread()) {
+ // Return the value with which we're currently rendering,
+ // if we're on the render thread
+ return render_state.world_scale;
+ } else {
+ // Return our current value
+ return world_scale;
+ }
+}
void XRServer::set_world_scale(double p_world_scale) {
if (p_world_scale < 0.01) {
@@ -131,19 +127,58 @@ void XRServer::set_world_scale(double p_world_scale) {
}
world_scale = p_world_scale;
-};
+ set_render_world_scale(world_scale);
+}
+
+void XRServer::_set_render_world_scale(double p_world_scale) {
+ // Must be called from rendering thread!
+ ERR_NOT_ON_RENDER_THREAD;
+
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
+ xr_server->render_state.world_scale = p_world_scale;
+}
Transform3D XRServer::get_world_origin() const {
- return world_origin;
-};
+ RenderingServer *rendering_server = RenderingServer::get_singleton();
+
+ if (rendering_server && rendering_server->is_on_render_thread()) {
+ // Return the value with which we're currently rendering,
+ // if we're on the render thread
+ return render_state.world_origin;
+ } else {
+ // Return our current value
+ return world_origin;
+ }
+}
void XRServer::set_world_origin(const Transform3D &p_world_origin) {
world_origin = p_world_origin;
-};
+ set_render_world_origin(world_origin);
+}
+
+void XRServer::_set_render_world_origin(const Transform3D &p_world_origin) {
+ // Must be called from rendering thread!
+ ERR_NOT_ON_RENDER_THREAD;
+
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
+ xr_server->render_state.world_origin = p_world_origin;
+}
Transform3D XRServer::get_reference_frame() const {
- return reference_frame;
-};
+ RenderingServer *rendering_server = RenderingServer::get_singleton();
+ ERR_FAIL_NULL_V(rendering_server, reference_frame);
+
+ if (rendering_server->is_on_render_thread()) {
+ // Return the value with which we're currently rendering,
+ // if we're on the render thread
+ return render_state.reference_frame;
+ } else {
+ // Return our current value
+ return reference_frame;
+ }
+}
void XRServer::center_on_hmd(RotationMode p_rotation_mode, bool p_keep_height) {
if (primary_interface == nullptr) {
@@ -169,27 +204,38 @@ void XRServer::center_on_hmd(RotationMode p_rotation_mode, bool p_keep_height) {
} else if (p_rotation_mode == 2) {
// remove our rotation, we're only interesting in centering on position
new_reference_frame.basis = Basis();
- };
+ }
// don't negate our height
if (p_keep_height) {
new_reference_frame.origin.y = 0.0;
- };
+ }
reference_frame = new_reference_frame.inverse();
-};
+ set_render_reference_frame(reference_frame);
+}
void XRServer::clear_reference_frame() {
reference_frame = Transform3D();
+ set_render_reference_frame(reference_frame);
+}
+
+void XRServer::_set_render_reference_frame(const Transform3D &p_reference_frame) {
+ // Must be called from rendering thread!
+ ERR_NOT_ON_RENDER_THREAD;
+
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
+ xr_server->render_state.reference_frame = p_reference_frame;
}
Transform3D XRServer::get_hmd_transform() {
Transform3D hmd_transform;
if (primary_interface != nullptr) {
hmd_transform = primary_interface->get_camera_transform();
- };
+ }
return hmd_transform;
-};
+}
void XRServer::add_interface(const Ref<XRInterface> &p_interface) {
ERR_FAIL_COND(p_interface.is_null());
@@ -198,12 +244,12 @@ void XRServer::add_interface(const Ref<XRInterface> &p_interface) {
if (interfaces[i] == p_interface) {
ERR_PRINT("Interface was already added");
return;
- };
- };
+ }
+ }
interfaces.push_back(p_interface);
emit_signal(SNAME("interface_added"), p_interface->get_name());
-};
+}
void XRServer::remove_interface(const Ref<XRInterface> &p_interface) {
ERR_FAIL_COND(p_interface.is_null());
@@ -213,33 +259,33 @@ void XRServer::remove_interface(const Ref<XRInterface> &p_interface) {
if (interfaces[i] == p_interface) {
idx = i;
break;
- };
- };
+ }
+ }
ERR_FAIL_COND_MSG(idx == -1, "Interface not found.");
print_verbose("XR: Removed interface \"" + p_interface->get_name() + "\"");
emit_signal(SNAME("interface_removed"), p_interface->get_name());
interfaces.remove_at(idx);
-};
+}
int XRServer::get_interface_count() const {
return interfaces.size();
-};
+}
Ref<XRInterface> XRServer::get_interface(int p_index) const {
ERR_FAIL_INDEX_V(p_index, interfaces.size(), nullptr);
return interfaces[p_index];
-};
+}
Ref<XRInterface> XRServer::find_interface(const String &p_name) const {
for (int i = 0; i < interfaces.size(); i++) {
if (interfaces[i]->get_name() == p_name) {
return interfaces[i];
- };
- };
+ }
+ }
return Ref<XRInterface>();
-};
+}
TypedArray<Dictionary> XRServer::get_interfaces() const {
Array ret;
@@ -251,14 +297,14 @@ TypedArray<Dictionary> XRServer::get_interfaces() const {
iface_info["name"] = interfaces[i]->get_name();
ret.push_back(iface_info);
- };
+ }
return ret;
-};
+}
Ref<XRInterface> XRServer::get_primary_interface() const {
return primary_interface;
-};
+}
void XRServer::set_primary_interface(const Ref<XRInterface> &p_primary_interface) {
if (p_primary_interface.is_null()) {
@@ -269,9 +315,9 @@ void XRServer::set_primary_interface(const Ref<XRInterface> &p_primary_interface
print_verbose("XR: Primary interface set to: " + primary_interface->get_name());
}
-};
+}
-void XRServer::add_tracker(Ref<XRPositionalTracker> p_tracker) {
+void XRServer::add_tracker(const Ref<XRTracker> &p_tracker) {
ERR_FAIL_COND(p_tracker.is_null());
StringName tracker_name = p_tracker->get_tracker_name();
@@ -285,9 +331,9 @@ void XRServer::add_tracker(Ref<XRPositionalTracker> p_tracker) {
trackers[tracker_name] = p_tracker;
emit_signal(SNAME("tracker_added"), tracker_name, p_tracker->get_tracker_type());
}
-};
+}
-void XRServer::remove_tracker(Ref<XRPositionalTracker> p_tracker) {
+void XRServer::remove_tracker(const Ref<XRTracker> &p_tracker) {
ERR_FAIL_COND(p_tracker.is_null());
StringName tracker_name = p_tracker->get_tracker_name();
@@ -298,7 +344,7 @@ void XRServer::remove_tracker(Ref<XRPositionalTracker> p_tracker) {
// and remove it
trackers.erase(tracker_name);
}
-};
+}
Dictionary XRServer::get_trackers(int p_tracker_types) {
Dictionary res;
@@ -313,14 +359,14 @@ Dictionary XRServer::get_trackers(int p_tracker_types) {
return res;
}
-Ref<XRPositionalTracker> XRServer::get_tracker(const StringName &p_name) const {
+Ref<XRTracker> XRServer::get_tracker(const StringName &p_name) const {
if (trackers.has(p_name)) {
return trackers[p_name];
} else {
// tracker hasn't been registered yet, which is fine, no need to spam the error log...
- return Ref<XRPositionalTracker>();
+ return Ref<XRTracker>();
}
-};
+}
PackedStringArray XRServer::get_suggested_tracker_names() const {
PackedStringArray arr;
@@ -372,82 +418,6 @@ PackedStringArray XRServer::get_suggested_pose_names(const StringName &p_tracker
return arr;
}
-void XRServer::add_hand_tracker(const StringName &p_tracker_name, Ref<XRHandTracker> p_hand_tracker) {
- ERR_FAIL_COND(p_hand_tracker.is_null());
-
- if (!hand_trackers.has(p_tracker_name)) {
- // We don't have a tracker with this name, we're going to add it.
- hand_trackers[p_tracker_name] = p_hand_tracker;
- emit_signal(SNAME("hand_tracker_added"), p_tracker_name, p_hand_tracker);
- } else if (hand_trackers[p_tracker_name] != p_hand_tracker) {
- // We already have a tracker with this name, we're going to replace it.
- hand_trackers[p_tracker_name] = p_hand_tracker;
- emit_signal(SNAME("hand_tracker_updated"), p_tracker_name, p_hand_tracker);
- }
-}
-
-void XRServer::remove_hand_tracker(const StringName &p_tracker_name) {
- // Skip if no hand tracker is found.
- if (!hand_trackers.has(p_tracker_name)) {
- return;
- }
-
- // Send the removed signal, then remove the hand tracker.
- emit_signal(SNAME("hand_tracker_removed"), p_tracker_name);
- hand_trackers.erase(p_tracker_name);
-}
-
-Dictionary XRServer::get_hand_trackers() const {
- return hand_trackers;
-}
-
-Ref<XRHandTracker> XRServer::get_hand_tracker(const StringName &p_tracker_name) const {
- // Skip if no tracker is found.
- if (!hand_trackers.has(p_tracker_name)) {
- return Ref<XRHandTracker>();
- }
-
- return hand_trackers[p_tracker_name];
-}
-
-void XRServer::add_face_tracker(const StringName &p_tracker_name, Ref<XRFaceTracker> p_face_tracker) {
- ERR_FAIL_COND(p_face_tracker.is_null());
-
- if (!face_trackers.has(p_tracker_name)) {
- // We don't have a tracker with this name, we're going to add it.
- face_trackers[p_tracker_name] = p_face_tracker;
- emit_signal(SNAME("face_tracker_added"), p_tracker_name, p_face_tracker);
- } else if (face_trackers[p_tracker_name] != p_face_tracker) {
- // We already have a tracker with this name, we're going to replace it.
- face_trackers[p_tracker_name] = p_face_tracker;
- emit_signal(SNAME("face_tracker_updated"), p_tracker_name, p_face_tracker);
- }
-}
-
-void XRServer::remove_face_tracker(const StringName &p_tracker_name) {
- // Skip if no face tracker is found.
- if (!face_trackers.has(p_tracker_name)) {
- return;
- }
-
- // Send the removed signal, then remove the face tracker.
- emit_signal(SNAME("face_tracker_removed"), p_tracker_name);
- face_trackers.erase(p_tracker_name);
-}
-
-Dictionary XRServer::get_face_trackers() const {
- return face_trackers;
-}
-
-Ref<XRFaceTracker> XRServer::get_face_tracker(const StringName &p_tracker_name) const {
- // Skip if no tracker is found.
- if (!face_trackers.has(p_tracker_name)) {
- return Ref<XRFaceTracker>();
- }
-
- return face_trackers[p_tracker_name];
-}
-
void XRServer::_process() {
// called from our main game loop before we handle physics and game logic
// note that we can have multiple interfaces active if we have interfaces that purely handle tracking
@@ -458,9 +428,9 @@ void XRServer::_process() {
// ignore, not a valid reference
} else if (interfaces[i]->is_initialized()) {
interfaces.write[i]->process();
- };
- };
-};
+ }
+ }
+}
void XRServer::pre_render() {
// called from RendererViewport.draw_viewports right before we start drawing our viewports
@@ -472,8 +442,8 @@ void XRServer::pre_render() {
// ignore, not a valid reference
} else if (interfaces[i]->is_initialized()) {
interfaces.write[i]->pre_render();
- };
- };
+ }
+ }
}
void XRServer::end_frame() {
@@ -485,26 +455,19 @@ void XRServer::end_frame() {
// ignore, not a valid reference
} else if (interfaces[i]->is_initialized()) {
interfaces.write[i]->end_frame();
- };
- };
+ }
+ }
}
XRServer::XRServer() {
singleton = this;
- world_scale = 1.0;
-};
+}
XRServer::~XRServer() {
primary_interface.unref();
- while (interfaces.size() > 0) {
- interfaces.remove_at(0);
- }
-
- // TODO pretty sure there is a clear function or something...
- while (trackers.size() > 0) {
- trackers.erase(trackers.get_key_at_index(0));
- }
+ interfaces.clear();
+ trackers.clear();
singleton = nullptr;
-};
+}