Browse Source

Merge pull request #47452 from BastiaanOlij/xr_positional_tracker_ref

Change XRPositionalTracker to a reference (master)
Rémi Verschelde 4 years ago
parent
commit
ed2f51b15f

+ 1 - 1
doc/classes/XRPositionalTracker.xml

@@ -1,5 +1,5 @@
 <?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>
 		A tracked object.
 	</brief_description>

+ 45 - 0
doc/classes/XRServer.xml

@@ -10,6 +10,24 @@
 		<link title="VR tutorial index">https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link>
 	</tutorials>
 	<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">
 			<return type="void">
 			</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.
 			</description>
 		</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">
 			<return type="XRInterface">
 			</return>
@@ -109,6 +136,24 @@
 				Returns the number of trackers currently registered.
 			</description>
 		</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>
 	<members>
 		<member name="primary_interface" type="XRInterface" setter="set_primary_interface" getter="get_primary_interface">

+ 13 - 12
modules/gdnative/xr/xr_interface_gdnative.cpp

@@ -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();
 	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_type(XRServer::TRACKER_CONTROLLER);
 	if (p_hand == 1) {
@@ -340,8 +341,8 @@ void GDAPI godot_xr_remove_controller(godot_int p_controller_id) {
 	Input *input = Input::get_singleton();
 	ERR_FAIL_NULL(input);
 
-	XRPositionalTracker *remove_tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
-	if (remove_tracker != nullptr) {
+	Ref<XRPositionalTracker> remove_tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
+	if (remove_tracker.is_valid()) {
 		// unset our joystick if applicable
 		int joyid = remove_tracker->get_joy_id();
 		if (joyid != -1) {
@@ -351,7 +352,7 @@ void GDAPI godot_xr_remove_controller(godot_int p_controller_id) {
 
 		// remove our tracker from our server
 		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();
 	ERR_FAIL_NULL(xr_server);
 
-	XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
-	if (tracker != nullptr) {
+	Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
+	if (tracker.is_valid()) {
 		Transform *transform = (Transform *)p_transform;
 		if (p_tracks_orientation) {
 			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();
 	ERR_FAIL_NULL(input);
 
-	XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
-	if (tracker != nullptr) {
+	Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
+	if (tracker.is_valid()) {
 		int joyid = tracker->get_joy_id();
 		if (joyid != -1) {
 			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();
 	ERR_FAIL_NULL(input);
 
-	XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
-	if (tracker != nullptr) {
+	Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
+	if (tracker.is_valid()) {
 		int joyid = tracker->get_joy_id();
 		if (joyid != -1) {
 			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();
 	ERR_FAIL_NULL_V(xr_server, 0.0);
 
-	XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
-	if (tracker != nullptr) {
+	Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
+	if (tracker.is_valid()) {
 		return tracker->get_rumble();
 	}
 

+ 1 - 1
modules/webxr/webxr_interface.h

@@ -57,7 +57,7 @@ public:
 	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_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 PackedVector3Array get_bounds_geometry() const = 0;
 };

+ 5 - 5
modules/webxr/webxr_interface_js.cpp

@@ -160,7 +160,7 @@ String WebXRInterfaceJS::get_reference_space_type() const {
 	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();
 	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();
 	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 (tracker == nullptr) {
-			tracker = memnew(XRPositionalTracker);
+		if (tracker.is_null()) {
+			tracker.instance();
 			tracker->set_tracker_type(XRServer::TRACKER_CONTROLLER);
 			// Controller id's 0 and 1 are always the left and right hands.
 			if (p_controller_id < 2) {
@@ -423,7 +423,7 @@ void WebXRInterfaceJS::_update_tracker(int p_controller_id) {
 			}
 			free(axes);
 		}
-	} else if (tracker) {
+	} else if (tracker.is_valid()) {
 		xr_server->remove_tracker(tracker);
 	}
 }

+ 1 - 1
modules/webxr/webxr_interface_js.h

@@ -71,7 +71,7 @@ public:
 	virtual String get_requested_reference_space_types() const override;
 	void _set_reference_space_type(String p_reference_space_type);
 	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 PackedVector3Array get_bounds_geometry() const override;
 

+ 16 - 16
scene/3d/xr_nodes.cpp

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

+ 2 - 2
servers/xr/xr_positional_tracker.h

@@ -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.
 */
 
-class XRPositionalTracker : public Object {
-	GDCLASS(XRPositionalTracker, Object);
+class XRPositionalTracker : public Reference {
+	GDCLASS(XRPositionalTracker, Reference);
 	_THREAD_SAFE_CLASS_
 
 public:

+ 14 - 9
servers/xr_server.cpp

@@ -48,12 +48,17 @@ void XRServer::_bind_methods() {
 
 	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("remove_interface", "interface"), &XRServer::remove_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("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", "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("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;
 };
 
-void XRServer::add_tracker(XRPositionalTracker *p_tracker) {
-	ERR_FAIL_NULL(p_tracker);
+void XRServer::add_tracker(Ref<XRPositionalTracker> p_tracker) {
+	ERR_FAIL_COND(p_tracker.is_null());
 
 	trackers.push_back(p_tracker);
 	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) {
-	ERR_FAIL_NULL(p_tracker);
+void XRServer::remove_tracker(Ref<XRPositionalTracker> p_tracker) {
+	ERR_FAIL_COND(p_tracker.is_null());
 
 	int idx = -1;
 	for (int i = 0; i < trackers.size(); i++) {
@@ -288,14 +293,14 @@ int XRServer::get_tracker_count() const {
 	return trackers.size();
 };
 
-XRPositionalTracker *XRServer::get_tracker(int p_index) const {
-	ERR_FAIL_INDEX_V(p_index, trackers.size(), nullptr);
+Ref<XRPositionalTracker> XRServer::get_tracker(int p_index) const {
+	ERR_FAIL_INDEX_V(p_index, trackers.size(), Ref<XRPositionalTracker>());
 
 	return trackers[p_index];
 };
 
-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);
+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, Ref<XRPositionalTracker>());
 
 	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) {
@@ -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 {

+ 5 - 5
servers/xr_server.h

@@ -77,7 +77,7 @@ public:
 
 private:
 	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 */
 
@@ -167,11 +167,11 @@ public:
 	*/
 	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);
-	void add_tracker(XRPositionalTracker *p_tracker);
-	void remove_tracker(XRPositionalTracker *p_tracker);
+	void add_tracker(Ref<XRPositionalTracker> p_tracker);
+	void remove_tracker(Ref<XRPositionalTracker> p_tracker);
 	int get_tracker_count() const;
-	XRPositionalTracker *get_tracker(int p_index) const;
-	XRPositionalTracker *find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const;
+	Ref<XRPositionalTracker> get_tracker(int p_index) 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_commit_usec();