mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 21:51:22 +00:00 
			
		
		
		
	OpenXR: Add access to session state and change interaction profile update.
This commit is contained in:
		
							parent
							
								
									46c495ca21
								
							
						
					
					
						commit
						df06aa8392
					
				
					 5 changed files with 104 additions and 13 deletions
				
			
		|  | @ -85,6 +85,12 @@ | ||||||
| 				If handtracking is enabled and motion range is supported, gets the currently configured motion range for [param hand]. | 				If handtracking is enabled and motion range is supported, gets the currently configured motion range for [param hand]. | ||||||
| 			</description> | 			</description> | ||||||
| 		</method> | 		</method> | ||||||
|  | 		<method name="get_session_state"> | ||||||
|  | 			<return type="int" enum="OpenXRInterface.OpenXrSessionState" /> | ||||||
|  | 			<description> | ||||||
|  | 				Returns the current state of our OpenXR session. | ||||||
|  | 			</description> | ||||||
|  | 		</method> | ||||||
| 		<method name="is_action_set_active" qualifiers="const"> | 		<method name="is_action_set_active" qualifiers="const"> | ||||||
| 			<return type="bool" /> | 			<return type="bool" /> | ||||||
| 			<param index="0" name="name" type="String" /> | 			<param index="0" name="name" type="String" /> | ||||||
|  | @ -216,7 +222,7 @@ | ||||||
| 		</signal> | 		</signal> | ||||||
| 		<signal name="session_focussed"> | 		<signal name="session_focussed"> | ||||||
| 			<description> | 			<description> | ||||||
| 				Informs our OpenXR session now has focus. | 				Informs our OpenXR session now has focus, e.g. output is sent to our HMD and we're receiving XR input. | ||||||
| 			</description> | 			</description> | ||||||
| 		</signal> | 		</signal> | ||||||
| 		<signal name="session_loss_pending"> | 		<signal name="session_loss_pending"> | ||||||
|  | @ -229,13 +235,47 @@ | ||||||
| 				Informs our OpenXR session is stopping. | 				Informs our OpenXR session is stopping. | ||||||
| 			</description> | 			</description> | ||||||
| 		</signal> | 		</signal> | ||||||
|  | 		<signal name="session_synchronized"> | ||||||
|  | 			<description> | ||||||
|  | 				Informs our OpenXR session has been synchronized. | ||||||
|  | 			</description> | ||||||
|  | 		</signal> | ||||||
| 		<signal name="session_visible"> | 		<signal name="session_visible"> | ||||||
| 			<description> | 			<description> | ||||||
| 				Informs our OpenXR session is now visible (output is being sent to the HMD). | 				Informs our OpenXR session is now visible, e.g. output is being sent to the HMD but we don't receive XR input. | ||||||
| 			</description> | 			</description> | ||||||
| 		</signal> | 		</signal> | ||||||
| 	</signals> | 	</signals> | ||||||
| 	<constants> | 	<constants> | ||||||
|  | 		<constant name="OPENXR_SESSION_STATE_UNKNOWN" value="0" enum="OpenXrSessionState"> | ||||||
|  | 			The state of the session is unknown, we haven't tried setting up OpenXR yet. | ||||||
|  | 		</constant> | ||||||
|  | 		<constant name="OPENXR_SESSION_STATE_IDLE" value="1" enum="OpenXrSessionState"> | ||||||
|  | 			The initial state after the OpenXR session is created or after the session is destroyed. | ||||||
|  | 		</constant> | ||||||
|  | 		<constant name="OPENXR_SESSION_STATE_READY" value="2" enum="OpenXrSessionState"> | ||||||
|  | 			OpenXR is ready to begin our session. [signal session_begun] is emitted when we change to this state. | ||||||
|  | 		</constant> | ||||||
|  | 		<constant name="OPENXR_SESSION_STATE_SYNCHRONIZED" value="3" enum="OpenXrSessionState"> | ||||||
|  | 			The application has synched its frame loop with the runtime but we're not rendering anything. [signal session_synchronized] is emitted when we change to this state. | ||||||
|  | 		</constant> | ||||||
|  | 		<constant name="OPENXR_SESSION_STATE_VISIBLE" value="4" enum="OpenXrSessionState"> | ||||||
|  | 			The application has synched its frame loop with the runtime and we're rendering output to the user, however we receive no user input. [signal session_visible] is emitted when we change to this state. | ||||||
|  | 			[b]Note:[/b] This is the current state just before we get the focused state, whenever the user opens a system menu, switches to another application or takes off their headset. | ||||||
|  | 		</constant> | ||||||
|  | 		<constant name="OPENXR_SESSION_STATE_FOCUSED" value="5" enum="OpenXrSessionState"> | ||||||
|  | 			The application has synched its frame loop with the runtime, we're rendering output to the user and we're receiving XR input. [signal session_focussed] is emitted when we change to this state. | ||||||
|  | 			[b]Note:[/b] This is the state OpenXR will be in when the user can fully interact with your game. | ||||||
|  | 		</constant> | ||||||
|  | 		<constant name="OPENXR_SESSION_STATE_STOPPING" value="6" enum="OpenXrSessionState"> | ||||||
|  | 			Our session is being stopped. [signal session_stopping] is emitted when we change to this state. | ||||||
|  | 		</constant> | ||||||
|  | 		<constant name="OPENXR_SESSION_STATE_LOSS_PENDING" value="7" enum="OpenXrSessionState"> | ||||||
|  | 			The session is about to be lost. [signal session_loss_pending] is emitted when we change to this state. | ||||||
|  | 		</constant> | ||||||
|  | 		<constant name="OPENXR_SESSION_STATE_EXITING" value="8" enum="OpenXrSessionState"> | ||||||
|  | 			The OpenXR instance is about to be destroyed and we're existing. [signal instance_exiting] is emitted when we change to this state. | ||||||
|  | 		</constant> | ||||||
| 		<constant name="HAND_LEFT" value="0" enum="Hand"> | 		<constant name="HAND_LEFT" value="0" enum="Hand"> | ||||||
| 			Left hand. | 			Left hand. | ||||||
| 		</constant> | 		</constant> | ||||||
|  |  | ||||||
|  | @ -1418,15 +1418,14 @@ bool OpenXRAPI::on_state_ready() { | ||||||
| bool OpenXRAPI::on_state_synchronized() { | bool OpenXRAPI::on_state_synchronized() { | ||||||
| 	print_verbose("On state synchronized"); | 	print_verbose("On state synchronized"); | ||||||
| 
 | 
 | ||||||
| 	// Just in case, see if we already have active trackers...
 |  | ||||||
| 	for (const RID &tracker : tracker_owner.get_owned_list()) { |  | ||||||
| 		tracker_check_profile(tracker); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) { | 	for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) { | ||||||
| 		wrapper->on_state_synchronized(); | 		wrapper->on_state_synchronized(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if (xr_interface) { | ||||||
|  | 		xr_interface->on_state_synchronized(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -2075,11 +2074,10 @@ bool OpenXRAPI::poll_events() { | ||||||
| 				print_verbose("OpenXR EVENT: interaction profile changed!"); | 				print_verbose("OpenXR EVENT: interaction profile changed!"); | ||||||
| 
 | 
 | ||||||
| 				XrEventDataInteractionProfileChanged *event = (XrEventDataInteractionProfileChanged *)&runtimeEvent; | 				XrEventDataInteractionProfileChanged *event = (XrEventDataInteractionProfileChanged *)&runtimeEvent; | ||||||
| 
 | 				if (event->session == session) { | ||||||
| 				for (const RID &tracker : tracker_owner.get_owned_list()) { | 					// Make sure we get our interaction profile change
 | ||||||
| 					tracker_check_profile(tracker, event->session); | 					interaction_profile_changed = true; | ||||||
| 				} | 				} | ||||||
| 
 |  | ||||||
| 			} break; | 			} break; | ||||||
| 			default: | 			default: | ||||||
| 				if (!handled) { | 				if (!handled) { | ||||||
|  | @ -3454,8 +3452,16 @@ bool OpenXRAPI::sync_action_sets(const Vector<RID> p_active_sets) { | ||||||
| 
 | 
 | ||||||
| 	XrResult result = xrSyncActions(session, &sync_info); | 	XrResult result = xrSyncActions(session, &sync_info); | ||||||
| 	if (XR_FAILED(result)) { | 	if (XR_FAILED(result)) { | ||||||
| 		print_line("OpenXR: failed to sync active action sets! [", get_error_string(result), "]"); | 		ERR_FAIL_V_MSG(false, "OpenXR: failed to sync active action sets! [" + get_error_string(result) + "]"); | ||||||
| 		return false; | 	} | ||||||
|  | 
 | ||||||
|  | 	if (interaction_profile_changed) { | ||||||
|  | 		// Just in case, see if we already have active trackers...
 | ||||||
|  | 		for (const RID &tracker : tracker_owner.get_owned_list()) { | ||||||
|  | 			tracker_check_profile(tracker); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		interaction_profile_changed = false; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return true; | 	return true; | ||||||
|  |  | ||||||
|  | @ -272,6 +272,7 @@ private: | ||||||
| 	}; | 	}; | ||||||
| 	RID_Owner<Tracker, true> tracker_owner; | 	RID_Owner<Tracker, true> tracker_owner; | ||||||
| 	RID get_tracker_rid(XrPath p_path); | 	RID get_tracker_rid(XrPath p_path); | ||||||
|  | 	bool interaction_profile_changed = true; // If true we need to check for updates to our active_profile_rid.
 | ||||||
| 
 | 
 | ||||||
| 	struct ActionSet { // Action sets define a set of actions that can be enabled together
 | 	struct ActionSet { // Action sets define a set of actions that can be enabled together
 | ||||||
| 		String name; // Name for this action set (i.e. "godot_action_set")
 | 		String name; // Name for this action set (i.e. "godot_action_set")
 | ||||||
|  | @ -420,6 +421,7 @@ public: | ||||||
| 	XrInstance get_instance() const { return instance; } | 	XrInstance get_instance() const { return instance; } | ||||||
| 	XrSystemId get_system_id() const { return system_id; } | 	XrSystemId get_system_id() const { return system_id; } | ||||||
| 	XrSession get_session() const { return session; } | 	XrSession get_session() const { return session; } | ||||||
|  | 	XrSessionState get_session_state() const { return session_state; } | ||||||
| 	OpenXRGraphicsExtensionWrapper *get_graphics_extension() const { return graphics_extension; } | 	OpenXRGraphicsExtensionWrapper *get_graphics_extension() const { return graphics_extension; } | ||||||
| 	String get_runtime_name() const { return runtime_name; } | 	String get_runtime_name() const { return runtime_name; } | ||||||
| 	String get_runtime_version() const { return runtime_version; } | 	String get_runtime_version() const { return runtime_version; } | ||||||
|  |  | ||||||
|  | @ -44,6 +44,7 @@ void OpenXRInterface::_bind_methods() { | ||||||
| 	// lifecycle signals
 | 	// lifecycle signals
 | ||||||
| 	ADD_SIGNAL(MethodInfo("session_begun")); | 	ADD_SIGNAL(MethodInfo("session_begun")); | ||||||
| 	ADD_SIGNAL(MethodInfo("session_stopping")); | 	ADD_SIGNAL(MethodInfo("session_stopping")); | ||||||
|  | 	ADD_SIGNAL(MethodInfo("session_synchronized")); | ||||||
| 	ADD_SIGNAL(MethodInfo("session_focussed")); | 	ADD_SIGNAL(MethodInfo("session_focussed")); | ||||||
| 	ADD_SIGNAL(MethodInfo("session_visible")); | 	ADD_SIGNAL(MethodInfo("session_visible")); | ||||||
| 	ADD_SIGNAL(MethodInfo("session_loss_pending")); | 	ADD_SIGNAL(MethodInfo("session_loss_pending")); | ||||||
|  | @ -54,6 +55,9 @@ void OpenXRInterface::_bind_methods() { | ||||||
| 	ADD_SIGNAL(MethodInfo("cpu_level_changed", PropertyInfo(Variant::INT, "sub_domain"), PropertyInfo(Variant::INT, "from_level"), PropertyInfo(Variant::INT, "to_level"))); | 	ADD_SIGNAL(MethodInfo("cpu_level_changed", PropertyInfo(Variant::INT, "sub_domain"), PropertyInfo(Variant::INT, "from_level"), PropertyInfo(Variant::INT, "to_level"))); | ||||||
| 	ADD_SIGNAL(MethodInfo("gpu_level_changed", PropertyInfo(Variant::INT, "sub_domain"), PropertyInfo(Variant::INT, "from_level"), PropertyInfo(Variant::INT, "to_level"))); | 	ADD_SIGNAL(MethodInfo("gpu_level_changed", PropertyInfo(Variant::INT, "sub_domain"), PropertyInfo(Variant::INT, "from_level"), PropertyInfo(Variant::INT, "to_level"))); | ||||||
| 
 | 
 | ||||||
|  | 	// State
 | ||||||
|  | 	ClassDB::bind_method(D_METHOD("get_session_state"), &OpenXRInterface::get_session_state); | ||||||
|  | 
 | ||||||
| 	// Display refresh rate
 | 	// Display refresh rate
 | ||||||
| 	ClassDB::bind_method(D_METHOD("get_display_refresh_rate"), &OpenXRInterface::get_display_refresh_rate); | 	ClassDB::bind_method(D_METHOD("get_display_refresh_rate"), &OpenXRInterface::get_display_refresh_rate); | ||||||
| 	ClassDB::bind_method(D_METHOD("set_display_refresh_rate", "refresh_rate"), &OpenXRInterface::set_display_refresh_rate); | 	ClassDB::bind_method(D_METHOD("set_display_refresh_rate", "refresh_rate"), &OpenXRInterface::set_display_refresh_rate); | ||||||
|  | @ -116,6 +120,16 @@ void OpenXRInterface::_bind_methods() { | ||||||
| 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "vrs_min_radius", PROPERTY_HINT_RANGE, "1.0,100.0,1.0"), "set_vrs_min_radius", "get_vrs_min_radius"); | 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "vrs_min_radius", PROPERTY_HINT_RANGE, "1.0,100.0,1.0"), "set_vrs_min_radius", "get_vrs_min_radius"); | ||||||
| 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "vrs_strength", PROPERTY_HINT_RANGE, "0.1,10.0,0.1"), "set_vrs_strength", "get_vrs_strength"); | 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "vrs_strength", PROPERTY_HINT_RANGE, "0.1,10.0,0.1"), "set_vrs_strength", "get_vrs_strength"); | ||||||
| 
 | 
 | ||||||
|  | 	BIND_ENUM_CONSTANT(OPENXR_SESSION_STATE_UNKNOWN); | ||||||
|  | 	BIND_ENUM_CONSTANT(OPENXR_SESSION_STATE_IDLE); | ||||||
|  | 	BIND_ENUM_CONSTANT(OPENXR_SESSION_STATE_READY); | ||||||
|  | 	BIND_ENUM_CONSTANT(OPENXR_SESSION_STATE_SYNCHRONIZED); | ||||||
|  | 	BIND_ENUM_CONSTANT(OPENXR_SESSION_STATE_VISIBLE); | ||||||
|  | 	BIND_ENUM_CONSTANT(OPENXR_SESSION_STATE_FOCUSED); | ||||||
|  | 	BIND_ENUM_CONSTANT(OPENXR_SESSION_STATE_STOPPING); | ||||||
|  | 	BIND_ENUM_CONSTANT(OPENXR_SESSION_STATE_LOSS_PENDING); | ||||||
|  | 	BIND_ENUM_CONSTANT(OPENXR_SESSION_STATE_EXITING); | ||||||
|  | 
 | ||||||
| 	BIND_ENUM_CONSTANT(HAND_LEFT); | 	BIND_ENUM_CONSTANT(HAND_LEFT); | ||||||
| 	BIND_ENUM_CONSTANT(HAND_RIGHT); | 	BIND_ENUM_CONSTANT(HAND_RIGHT); | ||||||
| 	BIND_ENUM_CONSTANT(HAND_MAX); | 	BIND_ENUM_CONSTANT(HAND_MAX); | ||||||
|  | @ -1375,6 +1389,10 @@ void OpenXRInterface::on_state_visible() { | ||||||
| 	emit_signal(SNAME("session_visible")); | 	emit_signal(SNAME("session_visible")); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void OpenXRInterface::on_state_synchronized() { | ||||||
|  | 	emit_signal(SNAME("session_synchronized")); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void OpenXRInterface::on_state_focused() { | void OpenXRInterface::on_state_focused() { | ||||||
| 	emit_signal(SNAME("session_focussed")); | 	emit_signal(SNAME("session_focussed")); | ||||||
| } | } | ||||||
|  | @ -1399,6 +1417,14 @@ void OpenXRInterface::on_refresh_rate_changes(float p_new_rate) { | ||||||
| 	emit_signal(SNAME("refresh_rate_changed"), p_new_rate); | 	emit_signal(SNAME("refresh_rate_changed"), p_new_rate); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | OpenXRInterface::OpenXrSessionState OpenXRInterface::get_session_state() { | ||||||
|  | 	if (openxr_api) { | ||||||
|  | 		return (OpenXrSessionState)openxr_api->get_session_state(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return OPENXR_SESSION_STATE_UNKNOWN; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /** Hand tracking. */ | /** Hand tracking. */ | ||||||
| void OpenXRInterface::set_motion_range(const Hand p_hand, const HandMotionRange p_motion_range) { | void OpenXRInterface::set_motion_range(const Hand p_hand, const HandMotionRange p_motion_range) { | ||||||
| 	ERR_FAIL_INDEX(p_hand, HAND_MAX); | 	ERR_FAIL_INDEX(p_hand, HAND_MAX); | ||||||
|  |  | ||||||
|  | @ -209,6 +209,7 @@ public: | ||||||
| 	void on_state_ready(); | 	void on_state_ready(); | ||||||
| 	void on_state_visible(); | 	void on_state_visible(); | ||||||
| 	void on_state_focused(); | 	void on_state_focused(); | ||||||
|  | 	void on_state_synchronized(); | ||||||
| 	void on_state_stopping(); | 	void on_state_stopping(); | ||||||
| 	void on_state_loss_pending(); | 	void on_state_loss_pending(); | ||||||
| 	void on_state_exiting(); | 	void on_state_exiting(); | ||||||
|  | @ -216,6 +217,21 @@ public: | ||||||
| 	void on_refresh_rate_changes(float p_new_rate); | 	void on_refresh_rate_changes(float p_new_rate); | ||||||
| 	void tracker_profile_changed(RID p_tracker, RID p_interaction_profile); | 	void tracker_profile_changed(RID p_tracker, RID p_interaction_profile); | ||||||
| 
 | 
 | ||||||
|  | 	/** Session */ | ||||||
|  | 	enum OpenXrSessionState { // Should mirror XrSessionState
 | ||||||
|  | 		OPENXR_SESSION_STATE_UNKNOWN = 0, | ||||||
|  | 		OPENXR_SESSION_STATE_IDLE = 1, | ||||||
|  | 		OPENXR_SESSION_STATE_READY = 2, | ||||||
|  | 		OPENXR_SESSION_STATE_SYNCHRONIZED = 3, | ||||||
|  | 		OPENXR_SESSION_STATE_VISIBLE = 4, | ||||||
|  | 		OPENXR_SESSION_STATE_FOCUSED = 5, | ||||||
|  | 		OPENXR_SESSION_STATE_STOPPING = 6, | ||||||
|  | 		OPENXR_SESSION_STATE_LOSS_PENDING = 7, | ||||||
|  | 		OPENXR_SESSION_STATE_EXITING = 8, | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	OpenXrSessionState get_session_state(); | ||||||
|  | 
 | ||||||
| 	/** Hand tracking. */ | 	/** Hand tracking. */ | ||||||
| 	enum Hand { | 	enum Hand { | ||||||
| 		HAND_LEFT, | 		HAND_LEFT, | ||||||
|  | @ -321,6 +337,7 @@ public: | ||||||
| 	~OpenXRInterface(); | 	~OpenXRInterface(); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | VARIANT_ENUM_CAST(OpenXRInterface::OpenXrSessionState) | ||||||
| VARIANT_ENUM_CAST(OpenXRInterface::Hand) | VARIANT_ENUM_CAST(OpenXRInterface::Hand) | ||||||
| VARIANT_ENUM_CAST(OpenXRInterface::HandMotionRange) | VARIANT_ENUM_CAST(OpenXRInterface::HandMotionRange) | ||||||
| VARIANT_ENUM_CAST(OpenXRInterface::HandTrackedSource) | VARIANT_ENUM_CAST(OpenXRInterface::HandTrackedSource) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Bastiaan Olij
						Bastiaan Olij