Browse Source

Merge pull request #80419 from Faolan-Rad/fix-multi_actionsets

Properly load multiple action sets in XR
Rémi Verschelde 2 years ago
parent
commit
8a02cd0883
3 changed files with 25 additions and 14 deletions
  1. 21 12
      modules/openxr/openxr_api.cpp
  2. 1 1
      modules/openxr/openxr_api.h
  3. 3 1
      modules/openxr/openxr_interface.cpp

+ 21 - 12
modules/openxr/openxr_api.cpp

@@ -2274,33 +2274,42 @@ String OpenXRAPI::action_set_get_name(RID p_action_set) {
 	return action_set->name;
 }
 
-bool OpenXRAPI::action_set_attach(RID p_action_set) {
-	ActionSet *action_set = action_set_owner.get_or_null(p_action_set);
-	ERR_FAIL_NULL_V(action_set, false);
+bool OpenXRAPI::attach_action_sets(const Vector<RID> &p_action_sets) {
+	ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
 
-	if (action_set->is_attached) {
-		// already attached
-		return true;
-	}
+	Vector<XrActionSet> action_handles;
+	action_handles.resize(p_action_sets.size());
+	for (int i = 0; i < p_action_sets.size(); i++) {
+		ActionSet *action_set = action_set_owner.get_or_null(p_action_sets[i]);
+		ERR_FAIL_NULL_V(action_set, false);
 
-	ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false);
+		if (action_set->is_attached) {
+			return false;
+		}
+
+		action_handles.set(i, action_set->handle);
+	}
 
 	// So according to the docs, once we attach our action set to our session it becomes read only..
 	// https://www.khronos.org/registry/OpenXR/specs/1.0/man/html/xrAttachSessionActionSets.html
 	XrSessionActionSetsAttachInfo attach_info = {
 		XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO, // type
 		nullptr, // next
-		1, // countActionSets,
-		&action_set->handle // actionSets
+		(uint32_t)p_action_sets.size(), // countActionSets,
+		action_handles.ptr() // actionSets
 	};
 
 	XrResult result = xrAttachSessionActionSets(session, &attach_info);
 	if (XR_FAILED(result)) {
-		print_line("OpenXR: failed to attach action set! [", get_error_string(result), "]");
+		print_line("OpenXR: failed to attach action sets! [", get_error_string(result), "]");
 		return false;
 	}
 
-	action_set->is_attached = true;
+	for (int i = 0; i < p_action_sets.size(); i++) {
+		ActionSet *action_set = action_set_owner.get_or_null(p_action_sets[i]);
+		ERR_FAIL_NULL_V(action_set, false);
+		action_set->is_attached = true;
+	}
 
 	/* For debugging:
 	print_verbose("Attached set " + action_set->name);

+ 1 - 1
modules/openxr/openxr_api.h

@@ -380,7 +380,7 @@ public:
 
 	RID action_set_create(const String p_name, const String p_localized_name, const int p_priority);
 	String action_set_get_name(RID p_action_set);
-	bool action_set_attach(RID p_action_set);
+	bool attach_action_sets(const Vector<RID> &p_action_sets);
 	void action_set_free(RID p_action_set);
 
 	RID action_create(RID p_action_set, const String p_name, const String p_localized_name, OpenXRAction::ActionType p_action_type, const Vector<RID> &p_trackers);

+ 3 - 1
modules/openxr/openxr_interface.cpp

@@ -555,9 +555,11 @@ bool OpenXRInterface::initialize() {
 	xr_server->add_tracker(head);
 
 	// attach action sets
+	Vector<RID> loaded_action_sets;
 	for (int i = 0; i < action_sets.size(); i++) {
-		openxr_api->action_set_attach(action_sets[i]->action_set_rid);
+		loaded_action_sets.append(action_sets[i]->action_set_rid);
 	}
+	openxr_api->attach_action_sets(loaded_action_sets);
 
 	// make this our primary interface
 	xr_server->set_primary_interface(this);