Browse Source

Merge pull request #14897 from BastiaanOlij/arvr_tweaks

Few small tweaks for ARVR
Rémi Verschelde 7 years ago
parent
commit
7d9b7f9c47

+ 4 - 1
doc/classes/ARVRController.xml

@@ -62,7 +62,10 @@
 	</methods>
 	</methods>
 	<members>
 	<members>
 		<member name="controller_id" type="int" setter="set_controller_id" getter="get_controller_id">
 		<member name="controller_id" type="int" setter="set_controller_id" getter="get_controller_id">
-			The controller's id. The first controller that the [ARVRServer] detects will have id 1, the second id 2, the third id 3, etc. When a controller is turned off, it's slot is freed. This ensures controllers will keep the same id even when controllers with lower ids are turned off.
+			The controller's id.
+			A controller id of 0 is unbound and will always result in an inactive node. Controller id 1 is reserved for the first controller that identifies itself as the left hand controller and id 2 is reserved for the first controller that identifies itself as the right hand controller.
+			For any other controller that the [ARVRServer] detects we continue with controller id 3.
+			When a controller is turned off, its slot is freed. This ensures controllers will keep the same id even when controllers with lower ids are turned off.
 		</member>
 		</member>
 		<member name="rumble" type="float" setter="set_rumble" getter="get_rumble">
 		<member name="rumble" type="float" setter="set_rumble" getter="get_rumble">
 			The degree to which the tracker rumbles. Ranges from [code]0.0[/code] to [code]1.0[/code] with precision [code].01[/code]. If changed, updates [member ARVRPositionalTracker.rumble] accordingly.
 			The degree to which the tracker rumbles. Ranges from [code]0.0[/code] to [code]1.0[/code] with precision [code].01[/code]. If changed, updates [member ARVRPositionalTracker.rumble] accordingly.

+ 10 - 1
doc/classes/ARVRServer.xml

@@ -14,7 +14,7 @@
 		<method name="center_on_hmd">
 		<method name="center_on_hmd">
 			<return type="void">
 			<return type="void">
 			</return>
 			</return>
-			<argument index="0" name="ignore_tilt" type="bool">
+			<argument index="0" name="rotation_mode" type="bool">
 			</argument>
 			</argument>
 			<argument index="1" name="keep_height" type="bool">
 			<argument index="1" name="keep_height" type="bool">
 			</argument>
 			</argument>
@@ -154,5 +154,14 @@
 		<constant name="TRACKER_ANY" value="255" enum="TrackerType">
 		<constant name="TRACKER_ANY" value="255" enum="TrackerType">
 			Used internally to select all trackers.
 			Used internally to select all trackers.
 		</constant>
 		</constant>
+		<constant name="RESET_FULL_ROTATION" value="0" enum="RotationMode">
+			Fully reset the orientation of the HMD. Regardless of what direction the user is looking to in the real world. The user will look dead ahead in the virtual world.
+		</constant>
+		<constant name="RESET_BUT_KEEP_TILT" value="1" enum="RotationMode">
+			Resets the orientation but keeps the tilt of the device. So if we're looking down, we keep looking down but heading will be reset.
+		</constant>
+		<constant name="DONT_RESET_ROTATION" value="2" enum="RotationMode">
+			Does not reset the orientation of the HMD, only the position of the player gets centered.
+		</constant>
 	</constants>
 	</constants>
 </class>
 </class>

+ 6 - 4
scene/3d/arvr_nodes.cpp

@@ -231,7 +231,7 @@ void ARVRController::_notification(int p_what) {
 void ARVRController::_bind_methods() {
 void ARVRController::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_controller_id", "controller_id"), &ARVRController::set_controller_id);
 	ClassDB::bind_method(D_METHOD("set_controller_id", "controller_id"), &ARVRController::set_controller_id);
 	ClassDB::bind_method(D_METHOD("get_controller_id"), &ARVRController::get_controller_id);
 	ClassDB::bind_method(D_METHOD("get_controller_id"), &ARVRController::get_controller_id);
-	ADD_PROPERTY(PropertyInfo(Variant::INT, "controller_id", PROPERTY_HINT_RANGE, "1,32,1"), "set_controller_id", "get_controller_id");
+	ADD_PROPERTY(PropertyInfo(Variant::INT, "controller_id", PROPERTY_HINT_RANGE, "0,32,1"), "set_controller_id", "get_controller_id");
 	ClassDB::bind_method(D_METHOD("get_controller_name"), &ARVRController::get_controller_name);
 	ClassDB::bind_method(D_METHOD("get_controller_name"), &ARVRController::get_controller_name);
 
 
 	// passthroughs to information about our related joystick
 	// passthroughs to information about our related joystick
@@ -251,7 +251,8 @@ void ARVRController::_bind_methods() {
 };
 };
 
 
 void ARVRController::set_controller_id(int p_controller_id) {
 void ARVRController::set_controller_id(int p_controller_id) {
-	// we don't check any bounds here, this controller may not yet be active and just be a place holder until it is.
+	// We don't check any bounds here, this controller may not yet be active and just be a place holder until it is.
+	// Note that setting this to 0 means this node is not bound to a controller yet.
 	controller_id = p_controller_id;
 	controller_id = p_controller_id;
 };
 };
 
 
@@ -420,7 +421,7 @@ void ARVRAnchor::_bind_methods() {
 
 
 	ClassDB::bind_method(D_METHOD("set_anchor_id", "anchor_id"), &ARVRAnchor::set_anchor_id);
 	ClassDB::bind_method(D_METHOD("set_anchor_id", "anchor_id"), &ARVRAnchor::set_anchor_id);
 	ClassDB::bind_method(D_METHOD("get_anchor_id"), &ARVRAnchor::get_anchor_id);
 	ClassDB::bind_method(D_METHOD("get_anchor_id"), &ARVRAnchor::get_anchor_id);
-	ADD_PROPERTY(PropertyInfo(Variant::INT, "anchor_id"), "set_anchor_id", "get_anchor_id");
+	ADD_PROPERTY(PropertyInfo(Variant::INT, "anchor_id", PROPERTY_HINT_RANGE, "0,32,1"), "set_anchor_id", "get_anchor_id");
 	ClassDB::bind_method(D_METHOD("get_anchor_name"), &ARVRAnchor::get_anchor_name);
 	ClassDB::bind_method(D_METHOD("get_anchor_name"), &ARVRAnchor::get_anchor_name);
 
 
 	ClassDB::bind_method(D_METHOD("get_is_active"), &ARVRAnchor::get_is_active);
 	ClassDB::bind_method(D_METHOD("get_is_active"), &ARVRAnchor::get_is_active);
@@ -430,7 +431,8 @@ void ARVRAnchor::_bind_methods() {
 };
 };
 
 
 void ARVRAnchor::set_anchor_id(int p_anchor_id) {
 void ARVRAnchor::set_anchor_id(int p_anchor_id) {
-	// we don't check any bounds here, this anchor may not yet be active and just be a place holder until it is.
+	// We don't check any bounds here, this anchor may not yet be active and just be a place holder until it is.
+	// Note that setting this to 0 means this node is not bound to an anchor yet.
 	anchor_id = p_anchor_id;
 	anchor_id = p_anchor_id;
 };
 };
 
 

+ 21 - 2
servers/arvr/arvr_positional_tracker.cpp

@@ -62,13 +62,15 @@ void ARVRPositionalTracker::_bind_methods() {
 void ARVRPositionalTracker::set_type(ARVRServer::TrackerType p_type) {
 void ARVRPositionalTracker::set_type(ARVRServer::TrackerType p_type) {
 	if (type != p_type) {
 	if (type != p_type) {
 		type = p_type;
 		type = p_type;
+		hand = ARVRPositionalTracker::TRACKER_HAND_UNKNOWN;
 
 
 		ARVRServer *arvr_server = ARVRServer::get_singleton();
 		ARVRServer *arvr_server = ARVRServer::get_singleton();
 		ERR_FAIL_NULL(arvr_server);
 		ERR_FAIL_NULL(arvr_server);
 
 
 		// get a tracker id for our type
 		// get a tracker id for our type
+		// note if this is a controller this will be 3 or higher but we may change it later.
 		tracker_id = arvr_server->get_free_tracker_id_for_type(p_type);
 		tracker_id = arvr_server->get_free_tracker_id_for_type(p_type);
-	}
+	};
 };
 };
 
 
 ARVRServer::TrackerType ARVRPositionalTracker::get_type() const {
 ARVRServer::TrackerType ARVRPositionalTracker::get_type() const {
@@ -156,7 +158,24 @@ ARVRPositionalTracker::TrackerHand ARVRPositionalTracker::get_hand() const {
 };
 };
 
 
 void ARVRPositionalTracker::set_hand(const ARVRPositionalTracker::TrackerHand p_hand) {
 void ARVRPositionalTracker::set_hand(const ARVRPositionalTracker::TrackerHand p_hand) {
-	hand = p_hand;
+	ARVRServer *arvr_server = ARVRServer::get_singleton();
+	ERR_FAIL_NULL(arvr_server);
+
+	if (hand != p_hand) {
+		// we can only set this if we've previously set this to be a controller!!
+		ERR_FAIL_COND((type != ARVRServer::TRACKER_CONTROLLER) && (p_hand != ARVRPositionalTracker::TRACKER_HAND_UNKNOWN));
+
+		hand = p_hand;
+		if (hand == ARVRPositionalTracker::TRACKER_LEFT_HAND) {
+			if (!arvr_server->is_tracker_id_in_use_for_type(type, 1)) {
+				tracker_id = 1;
+			};
+		} else if (hand == ARVRPositionalTracker::TRACKER_RIGHT_HAND) {
+			if (!arvr_server->is_tracker_id_in_use_for_type(type, 2)) {
+				tracker_id = 2;
+			};
+		};
+	};
 };
 };
 
 
 Transform ARVRPositionalTracker::get_transform(bool p_adjust_by_reference_frame) const {
 Transform ARVRPositionalTracker::get_transform(bool p_adjust_by_reference_frame) const {

+ 16 - 5
servers/arvr_server.cpp

@@ -43,7 +43,7 @@ void ARVRServer::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_world_scale"), &ARVRServer::get_world_scale);
 	ClassDB::bind_method(D_METHOD("get_world_scale"), &ARVRServer::get_world_scale);
 	ClassDB::bind_method(D_METHOD("set_world_scale"), &ARVRServer::set_world_scale);
 	ClassDB::bind_method(D_METHOD("set_world_scale"), &ARVRServer::set_world_scale);
 	ClassDB::bind_method(D_METHOD("get_reference_frame"), &ARVRServer::get_reference_frame);
 	ClassDB::bind_method(D_METHOD("get_reference_frame"), &ARVRServer::get_reference_frame);
-	ClassDB::bind_method(D_METHOD("center_on_hmd", "ignore_tilt", "keep_height"), &ARVRServer::center_on_hmd);
+	ClassDB::bind_method(D_METHOD("center_on_hmd", "rotation_mode", "keep_height"), &ARVRServer::center_on_hmd);
 
 
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "world_scale"), "set_world_scale", "get_world_scale");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "world_scale"), "set_world_scale", "get_world_scale");
 
 
@@ -63,6 +63,10 @@ void ARVRServer::_bind_methods() {
 	BIND_ENUM_CONSTANT(TRACKER_UNKNOWN);
 	BIND_ENUM_CONSTANT(TRACKER_UNKNOWN);
 	BIND_ENUM_CONSTANT(TRACKER_ANY);
 	BIND_ENUM_CONSTANT(TRACKER_ANY);
 
 
+	BIND_ENUM_CONSTANT(RESET_FULL_ROTATION);
+	BIND_ENUM_CONSTANT(RESET_BUT_KEEP_TILT);
+	BIND_ENUM_CONSTANT(DONT_RESET_ROTATION);
+
 	ADD_SIGNAL(MethodInfo("interface_added", PropertyInfo(Variant::STRING, "name")));
 	ADD_SIGNAL(MethodInfo("interface_added", PropertyInfo(Variant::STRING, "name")));
 	ADD_SIGNAL(MethodInfo("interface_removed", PropertyInfo(Variant::STRING, "name")));
 	ADD_SIGNAL(MethodInfo("interface_removed", PropertyInfo(Variant::STRING, "name")));
 
 
@@ -96,7 +100,7 @@ Transform ARVRServer::get_reference_frame() const {
 	return reference_frame;
 	return reference_frame;
 };
 };
 
 
-void ARVRServer::center_on_hmd(bool p_ignore_tilt, bool p_keep_height) {
+void ARVRServer::center_on_hmd(RotationMode p_rotation_mode, bool p_keep_height) {
 	if (primary_interface != NULL) {
 	if (primary_interface != NULL) {
 		// clear our current reference frame or we'll end up double adjusting it
 		// clear our current reference frame or we'll end up double adjusting it
 		reference_frame = Transform();
 		reference_frame = Transform();
@@ -105,7 +109,7 @@ void ARVRServer::center_on_hmd(bool p_ignore_tilt, bool p_keep_height) {
 		Transform new_reference_frame = primary_interface->get_transform_for_eye(ARVRInterface::EYE_MONO, Transform());
 		Transform new_reference_frame = primary_interface->get_transform_for_eye(ARVRInterface::EYE_MONO, Transform());
 
 
 		// remove our tilt
 		// remove our tilt
-		if (p_ignore_tilt) {
+		if (p_rotation_mode == 1) {
 			// take the Y out of our Z
 			// take the Y out of our Z
 			new_reference_frame.basis.set_axis(2, Vector3(new_reference_frame.basis.elements[0][2], 0.0, new_reference_frame.basis.elements[2][2]).normalized());
 			new_reference_frame.basis.set_axis(2, Vector3(new_reference_frame.basis.elements[0][2], 0.0, new_reference_frame.basis.elements[2][2]).normalized());
 
 
@@ -114,6 +118,9 @@ void ARVRServer::center_on_hmd(bool p_ignore_tilt, bool p_keep_height) {
 
 
 			// and X is our cross reference
 			// and X is our cross reference
 			new_reference_frame.basis.set_axis(0, new_reference_frame.basis.get_axis(1).cross(new_reference_frame.basis.get_axis(2)).normalized());
 			new_reference_frame.basis.set_axis(0, new_reference_frame.basis.get_axis(1).cross(new_reference_frame.basis.get_axis(2)).normalized());
+		} 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
 		// don't negate our height
@@ -229,8 +236,12 @@ bool ARVRServer::is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p
 };
 };
 
 
 int ARVRServer::get_free_tracker_id_for_type(TrackerType p_tracker_type) {
 int ARVRServer::get_free_tracker_id_for_type(TrackerType p_tracker_type) {
-	// we start checking at 1, 0 means that it's not a controller..
-	int tracker_id = 1;
+	// We start checking at 1, 0 means that it's not a controller..
+	// Note that for controller we reserve:
+	// - 1 for the left hand controller and
+	// - 2 for the right hand controller
+	// so we start at 3 :)
+	int tracker_id = p_tracker_type == ARVRServer::TRACKER_CONTROLLER ? 3 : 1;
 
 
 	while (is_tracker_id_in_use_for_type(p_tracker_type, tracker_id)) {
 	while (is_tracker_id_in_use_for_type(p_tracker_type, tracker_id)) {
 		// try the next one
 		// try the next one

+ 9 - 5
servers/arvr_server.h

@@ -68,6 +68,12 @@ public:
 		TRACKER_ANY = 0xff /* used by get_connected_trackers to return all types */
 		TRACKER_ANY = 0xff /* used by get_connected_trackers to return all types */
 	};
 	};
 
 
+	enum RotationMode {
+		RESET_FULL_ROTATION = 0, /* we reset the full rotation, regardless of how the HMD is oriented, we're looking dead ahead */
+		RESET_BUT_KEEP_TILT = 1, /* reset rotation but keep tilt. */
+		DONT_RESET_ROTATION = 2, /* don't reset the rotation, we will only center on position */
+	};
+
 private:
 private:
 	Vector<Ref<ARVRInterface> > interfaces;
 	Vector<Ref<ARVRInterface> > interfaces;
 	Vector<ARVRPositionalTracker *> trackers;
 	Vector<ARVRPositionalTracker *> trackers;
@@ -78,8 +84,6 @@ private:
 	Transform world_origin; /* our world origin point, maps a location in our virtual world to the origin point in our real world tracking volume */
 	Transform world_origin; /* our world origin point, maps a location in our virtual world to the origin point in our real world tracking volume */
 	Transform reference_frame; /* our reference frame */
 	Transform reference_frame; /* our reference frame */
 
 
-	bool is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p_tracker_id) const;
-
 protected:
 protected:
 	static ARVRServer *singleton;
 	static ARVRServer *singleton;
 
 
@@ -127,7 +131,7 @@ public:
 		and in the virtual world out of sync
 		and in the virtual world out of sync
 	*/
 	*/
 	Transform get_reference_frame() const;
 	Transform get_reference_frame() const;
-	void center_on_hmd(bool p_ignore_tilt, bool p_keep_height);
+	void center_on_hmd(RotationMode p_rotation_mode, bool p_keep_height);
 
 
 	/*
 	/*
 		Interfaces are objects that 'glue' Godot to an AR or VR SDK such as the Oculus SDK, OpenVR, OpenHMD, etc.
 		Interfaces are objects that 'glue' Godot to an AR or VR SDK such as the Oculus SDK, OpenVR, OpenHMD, etc.
@@ -150,9 +154,8 @@ public:
 	/*
 	/*
 		Our trackers are objects that expose the orientation and position of physical devices such as controller, anchor points, etc.
 		Our trackers are objects that expose the orientation and position of physical devices such as controller, anchor points, etc.
 		They are created and managed by our active AR/VR interfaces.
 		They are created and managed by our active AR/VR interfaces.
-
-		Note that for trackers that
 	*/
 	*/
+	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(ARVRPositionalTracker *p_tracker);
 	void add_tracker(ARVRPositionalTracker *p_tracker);
 	void remove_tracker(ARVRPositionalTracker *p_tracker);
 	void remove_tracker(ARVRPositionalTracker *p_tracker);
@@ -167,5 +170,6 @@ public:
 #define ARVR ARVRServer
 #define ARVR ARVRServer
 
 
 VARIANT_ENUM_CAST(ARVRServer::TrackerType);
 VARIANT_ENUM_CAST(ARVRServer::TrackerType);
+VARIANT_ENUM_CAST(ARVRServer::RotationMode);
 
 
 #endif
 #endif