Change XRPositionalTracker to a reference and better expose it to GDNative

This commit is contained in:
Bastiaan Olij 2021-03-29 21:15:53 +11:00
parent 02471ba44d
commit 454c889e61
10 changed files with 103 additions and 52 deletions

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<class name="XRPositionalTracker" inherits="Object" version="4.0"> <class name="XRPositionalTracker" inherits="Reference" version="4.0">
<brief_description> <brief_description>
A tracked object. A tracked object.
</brief_description> </brief_description>

View file

@ -10,6 +10,24 @@
<link title="VR tutorial index">https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link> <link title="VR tutorial index">https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link>
</tutorials> </tutorials>
<methods> <methods>
<method name="add_interface">
<return type="void">
</return>
<argument index="0" name="interface" type="XRInterface">
</argument>
<description>
Registers an [XRInterface] object.
</description>
</method>
<method name="add_tracker">
<return type="void">
</return>
<argument index="0" name="tracker" type="XRPositionalTracker">
</argument>
<description>
Registers a new [XRPositionalTracker] that tracks a spatial location in real space.
</description>
</method>
<method name="center_on_hmd"> <method name="center_on_hmd">
<return type="void"> <return type="void">
</return> </return>
@ -26,6 +44,15 @@
You should call this method after a few seconds have passed. For instance, when the user requests a realignment of the display holding a designated button on a controller for a short period of time, or when implementing a teleport mechanism. You should call this method after a few seconds have passed. For instance, when the user requests a realignment of the display holding a designated button on a controller for a short period of time, or when implementing a teleport mechanism.
</description> </description>
</method> </method>
<method name="clear_primary_interface_if">
<return type="void">
</return>
<argument index="0" name="interface" type="XRInterface">
</argument>
<description>
Clears our current primary interface if it is set to the provided interface.
</description>
</method>
<method name="find_interface" qualifiers="const"> <method name="find_interface" qualifiers="const">
<return type="XRInterface"> <return type="XRInterface">
</return> </return>
@ -109,6 +136,24 @@
Returns the number of trackers currently registered. Returns the number of trackers currently registered.
</description> </description>
</method> </method>
<method name="remove_interface">
<return type="void">
</return>
<argument index="0" name="interface" type="XRInterface">
</argument>
<description>
Removes this interface.
</description>
</method>
<method name="remove_tracker">
<return type="void">
</return>
<argument index="0" name="tracker" type="XRPositionalTracker">
</argument>
<description>
Removes this positional tracker.
</description>
</method>
</methods> </methods>
<members> <members>
<member name="primary_interface" type="XRInterface" setter="set_primary_interface" getter="get_primary_interface"> <member name="primary_interface" type="XRInterface" setter="set_primary_interface" getter="get_primary_interface">

View file

@ -301,7 +301,8 @@ godot_int GDAPI godot_xr_add_controller(char *p_device_name, godot_int p_hand, g
Input *input = Input::get_singleton(); Input *input = Input::get_singleton();
ERR_FAIL_NULL_V(input, 0); ERR_FAIL_NULL_V(input, 0);
XRPositionalTracker *new_tracker = memnew(XRPositionalTracker); Ref<XRPositionalTracker> new_tracker;
new_tracker.instance();
new_tracker->set_tracker_name(p_device_name); new_tracker->set_tracker_name(p_device_name);
new_tracker->set_tracker_type(XRServer::TRACKER_CONTROLLER); new_tracker->set_tracker_type(XRServer::TRACKER_CONTROLLER);
if (p_hand == 1) { if (p_hand == 1) {
@ -340,8 +341,8 @@ void GDAPI godot_xr_remove_controller(godot_int p_controller_id) {
Input *input = Input::get_singleton(); Input *input = Input::get_singleton();
ERR_FAIL_NULL(input); ERR_FAIL_NULL(input);
XRPositionalTracker *remove_tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id); Ref<XRPositionalTracker> remove_tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
if (remove_tracker != nullptr) { if (remove_tracker.is_valid()) {
// unset our joystick if applicable // unset our joystick if applicable
int joyid = remove_tracker->get_joy_id(); int joyid = remove_tracker->get_joy_id();
if (joyid != -1) { if (joyid != -1) {
@ -351,7 +352,7 @@ void GDAPI godot_xr_remove_controller(godot_int p_controller_id) {
// remove our tracker from our server // remove our tracker from our server
xr_server->remove_tracker(remove_tracker); xr_server->remove_tracker(remove_tracker);
memdelete(remove_tracker); remove_tracker.unref();
} }
} }
@ -359,8 +360,8 @@ void GDAPI godot_xr_set_controller_transform(godot_int p_controller_id, godot_tr
XRServer *xr_server = XRServer::get_singleton(); XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL(xr_server); ERR_FAIL_NULL(xr_server);
XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id); Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
if (tracker != nullptr) { if (tracker.is_valid()) {
Transform *transform = (Transform *)p_transform; Transform *transform = (Transform *)p_transform;
if (p_tracks_orientation) { if (p_tracks_orientation) {
tracker->set_orientation(transform->basis); tracker->set_orientation(transform->basis);
@ -378,8 +379,8 @@ void GDAPI godot_xr_set_controller_button(godot_int p_controller_id, godot_int p
Input *input = Input::get_singleton(); Input *input = Input::get_singleton();
ERR_FAIL_NULL(input); ERR_FAIL_NULL(input);
XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id); Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
if (tracker != nullptr) { if (tracker.is_valid()) {
int joyid = tracker->get_joy_id(); int joyid = tracker->get_joy_id();
if (joyid != -1) { if (joyid != -1) {
input->joy_button(joyid, p_button, p_is_pressed); input->joy_button(joyid, p_button, p_is_pressed);
@ -394,8 +395,8 @@ void GDAPI godot_xr_set_controller_axis(godot_int p_controller_id, godot_int p_a
Input *input = Input::get_singleton(); Input *input = Input::get_singleton();
ERR_FAIL_NULL(input); ERR_FAIL_NULL(input);
XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id); Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
if (tracker != nullptr) { if (tracker.is_valid()) {
int joyid = tracker->get_joy_id(); int joyid = tracker->get_joy_id();
if (joyid != -1) { if (joyid != -1) {
Input::JoyAxisValue jx; Input::JoyAxisValue jx;
@ -410,8 +411,8 @@ godot_float GDAPI godot_xr_get_controller_rumble(godot_int p_controller_id) {
XRServer *xr_server = XRServer::get_singleton(); XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL_V(xr_server, 0.0); ERR_FAIL_NULL_V(xr_server, 0.0);
XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id); Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
if (tracker != nullptr) { if (tracker.is_valid()) {
return tracker->get_rumble(); return tracker->get_rumble();
} }

View file

@ -57,7 +57,7 @@ public:
virtual void set_requested_reference_space_types(String p_requested_reference_space_types) = 0; virtual void set_requested_reference_space_types(String p_requested_reference_space_types) = 0;
virtual String get_requested_reference_space_types() const = 0; virtual String get_requested_reference_space_types() const = 0;
virtual String get_reference_space_type() const = 0; virtual String get_reference_space_type() const = 0;
virtual XRPositionalTracker *get_controller(int p_controller_id) const = 0; virtual Ref<XRPositionalTracker> get_controller(int p_controller_id) const = 0;
virtual String get_visibility_state() const = 0; virtual String get_visibility_state() const = 0;
virtual PackedVector3Array get_bounds_geometry() const = 0; virtual PackedVector3Array get_bounds_geometry() const = 0;
}; };

View file

@ -160,7 +160,7 @@ String WebXRInterfaceJS::get_reference_space_type() const {
return reference_space_type; return reference_space_type;
} }
XRPositionalTracker *WebXRInterfaceJS::get_controller(int p_controller_id) const { Ref<XRPositionalTracker> WebXRInterfaceJS::get_controller(int p_controller_id) const {
XRServer *xr_server = XRServer::get_singleton(); XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL_V(xr_server, nullptr); ERR_FAIL_NULL_V(xr_server, nullptr);
@ -380,10 +380,10 @@ void WebXRInterfaceJS::_update_tracker(int p_controller_id) {
XRServer *xr_server = XRServer::get_singleton(); XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL(xr_server); ERR_FAIL_NULL(xr_server);
XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id + 1); Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id + 1);
if (godot_webxr_is_controller_connected(p_controller_id)) { if (godot_webxr_is_controller_connected(p_controller_id)) {
if (tracker == nullptr) { if (tracker.is_null()) {
tracker = memnew(XRPositionalTracker); tracker.instance();
tracker->set_tracker_type(XRServer::TRACKER_CONTROLLER); tracker->set_tracker_type(XRServer::TRACKER_CONTROLLER);
// Controller id's 0 and 1 are always the left and right hands. // Controller id's 0 and 1 are always the left and right hands.
if (p_controller_id < 2) { if (p_controller_id < 2) {
@ -423,7 +423,7 @@ void WebXRInterfaceJS::_update_tracker(int p_controller_id) {
} }
free(axes); free(axes);
} }
} else if (tracker) { } else if (tracker.is_valid()) {
xr_server->remove_tracker(tracker); xr_server->remove_tracker(tracker);
} }
} }

View file

@ -71,7 +71,7 @@ public:
virtual String get_requested_reference_space_types() const override; virtual String get_requested_reference_space_types() const override;
void _set_reference_space_type(String p_reference_space_type); void _set_reference_space_type(String p_reference_space_type);
virtual String get_reference_space_type() const override; virtual String get_reference_space_type() const override;
virtual XRPositionalTracker *get_controller(int p_controller_id) const override; virtual Ref<XRPositionalTracker> get_controller(int p_controller_id) const override;
virtual String get_visibility_state() const override; virtual String get_visibility_state() const override;
virtual PackedVector3Array get_bounds_geometry() const override; virtual PackedVector3Array get_bounds_geometry() const override;

View file

@ -190,8 +190,8 @@ void XRController3D::_notification(int p_what) {
ERR_FAIL_NULL(xr_server); ERR_FAIL_NULL(xr_server);
// find the tracker for our controller // find the tracker for our controller
XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
if (tracker == nullptr) { if (!tracker.is_valid()) {
// this controller is currently turned off // this controller is currently turned off
is_active = false; is_active = false;
button_states = 0; button_states = 0;
@ -277,8 +277,8 @@ String XRController3D::get_controller_name() const {
XRServer *xr_server = XRServer::get_singleton(); XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL_V(xr_server, String()); ERR_FAIL_NULL_V(xr_server, String());
XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
if (tracker == nullptr) { if (!tracker.is_valid()) {
return String("Not connected"); return String("Not connected");
}; };
@ -290,8 +290,8 @@ int XRController3D::get_joystick_id() const {
XRServer *xr_server = XRServer::get_singleton(); XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL_V(xr_server, 0); ERR_FAIL_NULL_V(xr_server, 0);
XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
if (tracker == nullptr) { if (!tracker.is_valid()) {
// No tracker? no joystick id... (0 is our first joystick) // No tracker? no joystick id... (0 is our first joystick)
return -1; return -1;
}; };
@ -322,8 +322,8 @@ real_t XRController3D::get_rumble() const {
XRServer *xr_server = XRServer::get_singleton(); XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL_V(xr_server, 0.0); ERR_FAIL_NULL_V(xr_server, 0.0);
XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
if (tracker == nullptr) { if (!tracker.is_valid()) {
return 0.0; return 0.0;
}; };
@ -335,8 +335,8 @@ void XRController3D::set_rumble(real_t p_rumble) {
XRServer *xr_server = XRServer::get_singleton(); XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL(xr_server); ERR_FAIL_NULL(xr_server);
XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
if (tracker != nullptr) { if (tracker.is_valid()) {
tracker->set_rumble(p_rumble); tracker->set_rumble(p_rumble);
}; };
}; };
@ -354,8 +354,8 @@ XRPositionalTracker::TrackerHand XRController3D::get_tracker_hand() const {
XRServer *xr_server = XRServer::get_singleton(); XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL_V(xr_server, XRPositionalTracker::TRACKER_HAND_UNKNOWN); ERR_FAIL_NULL_V(xr_server, XRPositionalTracker::TRACKER_HAND_UNKNOWN);
XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
if (tracker == nullptr) { if (!tracker.is_valid()) {
return XRPositionalTracker::TRACKER_HAND_UNKNOWN; return XRPositionalTracker::TRACKER_HAND_UNKNOWN;
}; };
@ -404,8 +404,8 @@ void XRAnchor3D::_notification(int p_what) {
ERR_FAIL_NULL(xr_server); ERR_FAIL_NULL(xr_server);
// find the tracker for our anchor // find the tracker for our anchor
XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_ANCHOR, anchor_id); Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_ANCHOR, anchor_id);
if (tracker == nullptr) { if (!tracker.is_valid()) {
// this anchor is currently not available // this anchor is currently not available
is_active = false; is_active = false;
} else { } else {
@ -475,8 +475,8 @@ String XRAnchor3D::get_anchor_name() const {
XRServer *xr_server = XRServer::get_singleton(); XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL_V(xr_server, String()); ERR_FAIL_NULL_V(xr_server, String());
XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_ANCHOR, anchor_id); Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_ANCHOR, anchor_id);
if (tracker == nullptr) { if (!tracker.is_valid()) {
return String("Not connected"); return String("Not connected");
}; };

View file

@ -43,8 +43,8 @@
This is where potentially additional AR/VR interfaces may be active as there are AR/VR SDKs that solely deal with positional tracking. This is where potentially additional AR/VR interfaces may be active as there are AR/VR SDKs that solely deal with positional tracking.
*/ */
class XRPositionalTracker : public Object { class XRPositionalTracker : public Reference {
GDCLASS(XRPositionalTracker, Object); GDCLASS(XRPositionalTracker, Reference);
_THREAD_SAFE_CLASS_ _THREAD_SAFE_CLASS_
public: public:

View file

@ -48,12 +48,17 @@ void XRServer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "world_scale"), "set_world_scale", "get_world_scale"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "world_scale"), "set_world_scale", "get_world_scale");
ClassDB::bind_method(D_METHOD("add_interface", "interface"), &XRServer::add_interface);
ClassDB::bind_method(D_METHOD("clear_primary_interface_if", "interface"), &XRServer::clear_primary_interface_if);
ClassDB::bind_method(D_METHOD("get_interface_count"), &XRServer::get_interface_count); ClassDB::bind_method(D_METHOD("get_interface_count"), &XRServer::get_interface_count);
ClassDB::bind_method(D_METHOD("remove_interface", "interface"), &XRServer::remove_interface);
ClassDB::bind_method(D_METHOD("get_interface", "idx"), &XRServer::get_interface); ClassDB::bind_method(D_METHOD("get_interface", "idx"), &XRServer::get_interface);
ClassDB::bind_method(D_METHOD("get_interfaces"), &XRServer::get_interfaces); ClassDB::bind_method(D_METHOD("get_interfaces"), &XRServer::get_interfaces);
ClassDB::bind_method(D_METHOD("find_interface", "name"), &XRServer::find_interface); ClassDB::bind_method(D_METHOD("find_interface", "name"), &XRServer::find_interface);
ClassDB::bind_method(D_METHOD("get_tracker_count"), &XRServer::get_tracker_count); ClassDB::bind_method(D_METHOD("get_tracker_count"), &XRServer::get_tracker_count);
ClassDB::bind_method(D_METHOD("get_tracker", "idx"), &XRServer::get_tracker); ClassDB::bind_method(D_METHOD("get_tracker", "idx"), &XRServer::get_tracker);
ClassDB::bind_method(D_METHOD("add_tracker", "tracker"), &XRServer::add_tracker);
ClassDB::bind_method(D_METHOD("remove_tracker", "tracker"), &XRServer::remove_tracker);
ClassDB::bind_method(D_METHOD("get_primary_interface"), &XRServer::get_primary_interface); 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); ClassDB::bind_method(D_METHOD("set_primary_interface", "interface"), &XRServer::set_primary_interface);
@ -260,15 +265,15 @@ int XRServer::get_free_tracker_id_for_type(TrackerType p_tracker_type) {
return tracker_id; return tracker_id;
}; };
void XRServer::add_tracker(XRPositionalTracker *p_tracker) { void XRServer::add_tracker(Ref<XRPositionalTracker> p_tracker) {
ERR_FAIL_NULL(p_tracker); ERR_FAIL_COND(p_tracker.is_null());
trackers.push_back(p_tracker); trackers.push_back(p_tracker);
emit_signal("tracker_added", p_tracker->get_tracker_name(), p_tracker->get_tracker_type(), p_tracker->get_tracker_id()); emit_signal("tracker_added", p_tracker->get_tracker_name(), p_tracker->get_tracker_type(), p_tracker->get_tracker_id());
}; };
void XRServer::remove_tracker(XRPositionalTracker *p_tracker) { void XRServer::remove_tracker(Ref<XRPositionalTracker> p_tracker) {
ERR_FAIL_NULL(p_tracker); ERR_FAIL_COND(p_tracker.is_null());
int idx = -1; int idx = -1;
for (int i = 0; i < trackers.size(); i++) { for (int i = 0; i < trackers.size(); i++) {
@ -288,14 +293,14 @@ int XRServer::get_tracker_count() const {
return trackers.size(); return trackers.size();
}; };
XRPositionalTracker *XRServer::get_tracker(int p_index) const { Ref<XRPositionalTracker> XRServer::get_tracker(int p_index) const {
ERR_FAIL_INDEX_V(p_index, trackers.size(), nullptr); ERR_FAIL_INDEX_V(p_index, trackers.size(), Ref<XRPositionalTracker>());
return trackers[p_index]; return trackers[p_index];
}; };
XRPositionalTracker *XRServer::find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const { Ref<XRPositionalTracker> XRServer::find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const {
ERR_FAIL_COND_V(p_tracker_id == 0, nullptr); ERR_FAIL_COND_V(p_tracker_id == 0, Ref<XRPositionalTracker>());
for (int i = 0; i < trackers.size(); i++) { for (int i = 0; i < trackers.size(); i++) {
if (trackers[i]->get_tracker_type() == p_tracker_type && trackers[i]->get_tracker_id() == p_tracker_id) { if (trackers[i]->get_tracker_type() == p_tracker_type && trackers[i]->get_tracker_id() == p_tracker_id) {
@ -303,7 +308,7 @@ XRPositionalTracker *XRServer::find_by_type_and_id(TrackerType p_tracker_type, i
}; };
}; };
return nullptr; return Ref<XRPositionalTracker>();
}; };
Ref<XRInterface> XRServer::get_primary_interface() const { Ref<XRInterface> XRServer::get_primary_interface() const {

View file

@ -77,7 +77,7 @@ public:
private: private:
Vector<Ref<XRInterface>> interfaces; Vector<Ref<XRInterface>> interfaces;
Vector<XRPositionalTracker *> trackers; Vector<Ref<XRPositionalTracker>> trackers;
Ref<XRInterface> primary_interface; /* we'll identify one interface as primary, this will be used by our viewports */ Ref<XRInterface> primary_interface; /* we'll identify one interface as primary, this will be used by our viewports */
@ -167,11 +167,11 @@ public:
*/ */
bool is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p_tracker_id) const; bool is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p_tracker_id) const;
int get_free_tracker_id_for_type(TrackerType p_tracker_type); int get_free_tracker_id_for_type(TrackerType p_tracker_type);
void add_tracker(XRPositionalTracker *p_tracker); void add_tracker(Ref<XRPositionalTracker> p_tracker);
void remove_tracker(XRPositionalTracker *p_tracker); void remove_tracker(Ref<XRPositionalTracker> p_tracker);
int get_tracker_count() const; int get_tracker_count() const;
XRPositionalTracker *get_tracker(int p_index) const; Ref<XRPositionalTracker> get_tracker(int p_index) const;
XRPositionalTracker *find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const; Ref<XRPositionalTracker> find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const;
uint64_t get_last_process_usec(); uint64_t get_last_process_usec();
uint64_t get_last_commit_usec(); uint64_t get_last_commit_usec();