Переглянути джерело

Reserved controller ids 1 and 2 for left and right hand controllers and added new center on hmd option

Bastiaan Olij 7 роки тому
батько
коміт
6fd51b6a1b

+ 4 - 1
doc/classes/ARVRController.xml

@@ -62,7 +62,10 @@
 	</methods>
 	<members>
 		<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 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.

+ 10 - 1
doc/classes/ARVRServer.xml

@@ -14,7 +14,7 @@
 		<method name="center_on_hmd">
 			<return type="void">
 			</return>
-			<argument index="0" name="ignore_tilt" type="bool">
+			<argument index="0" name="rotation_mode" type="bool">
 			</argument>
 			<argument index="1" name="keep_height" type="bool">
 			</argument>
@@ -154,5 +154,14 @@
 		<constant name="TRACKER_ANY" value="255" enum="TrackerType">
 			Used internally to select all trackers.
 		</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>
 </class>

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

@@ -231,7 +231,7 @@ void ARVRController::_notification(int p_what) {
 void ARVRController::_bind_methods() {
 	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);
-	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);
 
 	// passthroughs to information about our related joystick
@@ -251,7 +251,8 @@ void ARVRController::_bind_methods() {
 };
 
 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;
 };
 
@@ -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("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_is_active"), &ARVRAnchor::get_is_active);
@@ -430,7 +431,8 @@ void ARVRAnchor::_bind_methods() {
 };
 
 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;
 };
 

+ 21 - 2
servers/arvr/arvr_positional_tracker.cpp

@@ -62,13 +62,15 @@ void ARVRPositionalTracker::_bind_methods() {
 void ARVRPositionalTracker::set_type(ARVRServer::TrackerType p_type) {
 	if (type != p_type) {
 		type = p_type;
+		hand = ARVRPositionalTracker::TRACKER_HAND_UNKNOWN;
 
 		ARVRServer *arvr_server = ARVRServer::get_singleton();
 		ERR_FAIL_NULL(arvr_server);
 
 		// 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);
-	}
+	};
 };
 
 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) {
-	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 {

+ 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("set_world_scale"), &ARVRServer::set_world_scale);
 	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");
 
@@ -63,6 +63,10 @@ void ARVRServer::_bind_methods() {
 	BIND_ENUM_CONSTANT(TRACKER_UNKNOWN);
 	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_removed", PropertyInfo(Variant::STRING, "name")));
 
@@ -96,7 +100,7 @@ Transform ARVRServer::get_reference_frame() const {
 	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) {
 		// clear our current reference frame or we'll end up double adjusting it
 		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());
 
 		// remove our tilt
-		if (p_ignore_tilt) {
+		if (p_rotation_mode == 1) {
 			// 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());
 
@@ -114,6 +118,9 @@ void ARVRServer::center_on_hmd(bool p_ignore_tilt, bool p_keep_height) {
 
 			// 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());
+		} 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
@@ -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) {
-	// 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)) {
 		// 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 */
 	};
 
+	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:
 	Vector<Ref<ARVRInterface> > interfaces;
 	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 reference_frame; /* our reference frame */
 
-	bool is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p_tracker_id) const;
-
 protected:
 	static ARVRServer *singleton;
 
@@ -127,7 +131,7 @@ public:
 		and in the virtual world out of sync
 	*/
 	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.
@@ -150,9 +154,8 @@ public:
 	/*
 		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.
-
-		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);
 	void add_tracker(ARVRPositionalTracker *p_tracker);
 	void remove_tracker(ARVRPositionalTracker *p_tracker);
@@ -167,5 +170,6 @@ public:
 #define ARVR ARVRServer
 
 VARIANT_ENUM_CAST(ARVRServer::TrackerType);
+VARIANT_ENUM_CAST(ARVRServer::RotationMode);
 
 #endif