diff options
Diffstat (limited to 'servers/xr_server.cpp')
| -rw-r--r-- | servers/xr_server.cpp | 263 |
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; -}; +} |
