1
0
mirror of https://github.com/godotengine/godot.git synced 2025-12-01 16:38:31 +00:00

Add OpenXR 1.1 support

This commit is contained in:
Bastiaan Olij
2025-07-28 10:13:23 +10:00
parent 9dd6c4dbac
commit c0bc43d1de
88 changed files with 638 additions and 251 deletions

View File

@@ -128,3 +128,11 @@ Validate extension JSON: Error: Field 'builtin_classes/PackedVector3Array/method
Validate extension JSON: Error: Field 'builtin_classes/PackedVector4Array/methods/bsearch': is_const changed value in new API, from false to true. Validate extension JSON: Error: Field 'builtin_classes/PackedVector4Array/methods/bsearch': is_const changed value in new API, from false to true.
bsearch method made const. Compatibility methods registered. bsearch method made const. Compatibility methods registered.
GH-109302
---------
Validate extension JSON: Error: Field 'classes/OpenXRExtensionWrapper/methods/_set_instance_create_info_and_get_next_pointer/arguments': size changed value in new API, from 1 to 2.
Validate extension JSON: Error: Field 'classes/OpenXRExtensionWrapper/methods/_set_instance_create_info_and_get_next_pointer/arguments/0': type changed value in new API, from "void*" to "int".
Validate extension JSON: JSON file: Field was added in a way that breaks compatibility 'classes/OpenXRExtensionWrapper/methods/_get_requested_extensions': arguments

View File

@@ -261,7 +261,7 @@ void OpenXRActionMap::create_default_action_sets() {
profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose"); profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose"); profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/menu/click"); profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/menu/click");
profile->add_new_binding(select_button, "/user/hand/left/input/select/click,/user/hand/right/input/select/click"); profile->add_new_binding(select_button, "/user/hand/left/input/select/click,/user/hand/right/input/select/click");
// generic has no support for triggers, grip, A/B buttons, nor joystick/trackpad inputs. // generic has no support for triggers, grip, A/B buttons, nor joystick/trackpad inputs.
@@ -273,7 +273,7 @@ void OpenXRActionMap::create_default_action_sets() {
profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose"); profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose"); profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/menu/click"); profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/menu/click");
profile->add_new_binding(select_button, "/user/hand/left/input/system/click,/user/hand/right/input/system/click"); profile->add_new_binding(select_button, "/user/hand/left/input/system/click,/user/hand/right/input/system/click");
// wmr controller has no a/b/x/y buttons. // wmr controller has no a/b/x/y buttons.
@@ -294,7 +294,7 @@ void OpenXRActionMap::create_default_action_sets() {
profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose"); profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose"); profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
// wmr controllers have no select button we can use. // wmr controllers have no select button we can use.
profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/menu/click"); profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/menu/click");
// wmr controller has no a/b/x/y buttons. // wmr controller has no a/b/x/y buttons.
@@ -317,7 +317,7 @@ void OpenXRActionMap::create_default_action_sets() {
profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose"); profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose"); profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
// touch controllers have no select button we can use. // touch controllers have no select button we can use.
profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/system/click"); // right hand system click may not be available. profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/system/click"); // right hand system click may not be available.
profile->add_new_binding(ax_button, "/user/hand/left/input/x/click,/user/hand/right/input/a/click"); // x on left hand, a on right hand. profile->add_new_binding(ax_button, "/user/hand/left/input/x/click,/user/hand/right/input/a/click"); // x on left hand, a on right hand.
@@ -342,7 +342,7 @@ void OpenXRActionMap::create_default_action_sets() {
profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose"); profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose"); profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
profile->add_new_binding(select_button, "/user/hand/left/input/system/click,/user/hand/right/input/system/click"); // system click may not be available. profile->add_new_binding(select_button, "/user/hand/left/input/system/click,/user/hand/right/input/system/click"); // system click may not be available.
profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click"); profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click");
profile->add_new_binding(ax_button, "/user/hand/left/input/x/click,/user/hand/right/input/a/click"); // x on left hand, a on right hand. profile->add_new_binding(ax_button, "/user/hand/left/input/x/click,/user/hand/right/input/a/click"); // x on left hand, a on right hand.
@@ -367,7 +367,7 @@ void OpenXRActionMap::create_default_action_sets() {
profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose"); profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose"); profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
// index controllers have no select button we can use. // index controllers have no select button we can use.
profile->add_new_binding(menu_button, "/user/hand/left/input/system/click,/user/hand/right/input/system/click"); profile->add_new_binding(menu_button, "/user/hand/left/input/system/click,/user/hand/right/input/system/click");
profile->add_new_binding(ax_button, "/user/hand/left/input/a/click,/user/hand/right/input/a/click"); // a on both controllers. profile->add_new_binding(ax_button, "/user/hand/left/input/a/click,/user/hand/right/input/a/click"); // a on both controllers.
@@ -396,7 +396,7 @@ void OpenXRActionMap::create_default_action_sets() {
profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose"); profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose"); profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
// hpmr controllers have no select button we can use. // hpmr controllers have no select button we can use.
profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/menu/click"); profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/menu/click");
// hpmr controllers only register click, not touch, on our a/b/x/y buttons. // hpmr controllers only register click, not touch, on our a/b/x/y buttons.
@@ -419,7 +419,7 @@ void OpenXRActionMap::create_default_action_sets() {
profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose"); profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose"); profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
// Odyssey controllers have no select button we can use. // Odyssey controllers have no select button we can use.
profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/menu/click"); profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/menu/click");
// Odyssey controller has no a/b/x/y buttons. // Odyssey controller has no a/b/x/y buttons.
@@ -442,7 +442,7 @@ void OpenXRActionMap::create_default_action_sets() {
profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose"); profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose"); profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click"); profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click");
profile->add_new_binding(select_button, "/user/hand/right/input/system/click"); // we'll map system to select. profile->add_new_binding(select_button, "/user/hand/right/input/system/click"); // we'll map system to select.
profile->add_new_binding(ax_button, "/user/hand/left/input/x/click,/user/hand/right/input/a/click"); // x on left hand, a on right hand. profile->add_new_binding(ax_button, "/user/hand/left/input/x/click,/user/hand/right/input/a/click"); // x on left hand, a on right hand.
@@ -466,7 +466,7 @@ void OpenXRActionMap::create_default_action_sets() {
profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose"); profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose"); profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click"); profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click");
profile->add_new_binding(select_button, "/user/hand/right/input/system/click"); // we'll map system to select. profile->add_new_binding(select_button, "/user/hand/right/input/system/click"); // we'll map system to select.
profile->add_new_binding(ax_button, "/user/hand/left/input/x/click,/user/hand/right/input/a/click"); // x on left hand, a on right hand. profile->add_new_binding(ax_button, "/user/hand/left/input/x/click,/user/hand/right/input/a/click"); // x on left hand, a on right hand.
@@ -490,7 +490,7 @@ void OpenXRActionMap::create_default_action_sets() {
profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose"); profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose"); profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
profile->add_new_binding(menu_button, "/user/hand/left/input/home/click,/user/hand/right/input/home/click"); profile->add_new_binding(menu_button, "/user/hand/left/input/home/click,/user/hand/right/input/home/click");
profile->add_new_binding(trigger, "/user/hand/left/input/trigger/value,/user/hand/right/input/trigger/value"); profile->add_new_binding(trigger, "/user/hand/left/input/trigger/value,/user/hand/right/input/trigger/value");
profile->add_new_binding(trigger_click, "/user/hand/left/input/trigger/click,/user/hand/right/input/trigger/click"); profile->add_new_binding(trigger_click, "/user/hand/left/input/trigger/click,/user/hand/right/input/trigger/click");
@@ -551,7 +551,7 @@ void OpenXRActionMap::create_default_action_sets() {
profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(default_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose"); profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose"); profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose"); profile->add_new_binding(palm_pose, "/user/hand/left/input/grip_surface/pose,/user/hand/right/input/grip_surface/pose");
// Use pinch as primary. // Use pinch as primary.
profile->add_new_binding(primary, "/user/hand/left/input/pinch_ext/value,/user/hand/right/input/pinch_ext/value"); profile->add_new_binding(primary, "/user/hand/left/input/pinch_ext/value,/user/hand/right/input/pinch_ext/value");

View File

@@ -79,7 +79,14 @@ Ref<OpenXRAction> OpenXRIPBinding::get_action() const {
} }
void OpenXRIPBinding::set_binding_path(const String &p_path) { void OpenXRIPBinding::set_binding_path(const String &p_path) {
binding_path = p_path; OpenXRInteractionProfileMetadata *pmd = OpenXRInteractionProfileMetadata::get_singleton();
if (pmd) {
binding_path = pmd->check_path_name(p_path);
} else {
// OpenXR not enabled, ignore checks.
binding_path = p_path;
}
emit_changed(); emit_changed();
} }
@@ -244,7 +251,7 @@ void OpenXRInteractionProfile::set_interaction_profile_path(const String &p_inpu
if (pmd) { if (pmd) {
interaction_profile_path = pmd->check_profile_name(p_input_profile_path); interaction_profile_path = pmd->check_profile_name(p_input_profile_path);
} else { } else {
// OpenXR module not enabled, ignore checks. // OpenXR not enabled, ignore checks.
interaction_profile_path = p_input_profile_path; interaction_profile_path = p_input_profile_path;
} }
emit_changed(); emit_changed();

View File

@@ -47,9 +47,10 @@ OpenXRInteractionProfileMetadata::~OpenXRInteractionProfileMetadata() {
void OpenXRInteractionProfileMetadata::_bind_methods() { void OpenXRInteractionProfileMetadata::_bind_methods() {
ClassDB::bind_method(D_METHOD("register_profile_rename", "old_name", "new_name"), &OpenXRInteractionProfileMetadata::register_profile_rename); ClassDB::bind_method(D_METHOD("register_profile_rename", "old_name", "new_name"), &OpenXRInteractionProfileMetadata::register_profile_rename);
ClassDB::bind_method(D_METHOD("register_top_level_path", "display_name", "openxr_path", "openxr_extension_name"), &OpenXRInteractionProfileMetadata::register_top_level_path); ClassDB::bind_method(D_METHOD("register_path_rename", "old_name", "new_name"), &OpenXRInteractionProfileMetadata::register_path_rename);
ClassDB::bind_method(D_METHOD("register_interaction_profile", "display_name", "openxr_path", "openxr_extension_name"), &OpenXRInteractionProfileMetadata::register_interaction_profile); ClassDB::bind_method(D_METHOD("register_top_level_path", "display_name", "openxr_path", "openxr_extension_names"), &OpenXRInteractionProfileMetadata::register_top_level_path);
ClassDB::bind_method(D_METHOD("register_io_path", "interaction_profile", "display_name", "toplevel_path", "openxr_path", "openxr_extension_name", "action_type"), &OpenXRInteractionProfileMetadata::register_io_path); ClassDB::bind_method(D_METHOD("register_interaction_profile", "display_name", "openxr_path", "openxr_extension_names"), &OpenXRInteractionProfileMetadata::register_interaction_profile);
ClassDB::bind_method(D_METHOD("register_io_path", "interaction_profile", "display_name", "toplevel_path", "openxr_path", "openxr_extension_names", "action_type"), &OpenXRInteractionProfileMetadata::register_io_path);
} }
void OpenXRInteractionProfileMetadata::register_profile_rename(const String &p_old_name, const String &p_new_name) { void OpenXRInteractionProfileMetadata::register_profile_rename(const String &p_old_name, const String &p_new_name) {
@@ -66,30 +67,44 @@ String OpenXRInteractionProfileMetadata::check_profile_name(const String &p_name
return p_name; return p_name;
} }
void OpenXRInteractionProfileMetadata::register_top_level_path(const String &p_display_name, const String &p_openxr_path, const String &p_openxr_extension_name) { void OpenXRInteractionProfileMetadata::register_path_rename(const String &p_old_name, const String &p_new_name) {
ERR_FAIL_COND(path_renames.has(p_old_name));
path_renames[p_old_name] = p_new_name;
}
String OpenXRInteractionProfileMetadata::check_path_name(const String &p_name) const {
if (path_renames.has(p_name)) {
return path_renames[p_name];
}
return p_name;
}
void OpenXRInteractionProfileMetadata::register_top_level_path(const String &p_display_name, const String &p_openxr_path, const String &p_openxr_extension_names) {
ERR_FAIL_COND_MSG(has_top_level_path(p_openxr_path), p_openxr_path + " had already been registered"); ERR_FAIL_COND_MSG(has_top_level_path(p_openxr_path), p_openxr_path + " had already been registered");
TopLevelPath new_toplevel_path = { TopLevelPath new_toplevel_path = {
p_display_name, p_display_name,
p_openxr_path, p_openxr_path,
p_openxr_extension_name p_openxr_extension_names
}; };
top_level_paths.push_back(new_toplevel_path); top_level_paths.push_back(new_toplevel_path);
} }
void OpenXRInteractionProfileMetadata::register_interaction_profile(const String &p_display_name, const String &p_openxr_path, const String &p_openxr_extension_name) { void OpenXRInteractionProfileMetadata::register_interaction_profile(const String &p_display_name, const String &p_openxr_path, const String &p_openxr_extension_names) {
ERR_FAIL_COND_MSG(has_interaction_profile(p_openxr_path), p_openxr_path + " has already been registered"); ERR_FAIL_COND_MSG(has_interaction_profile(p_openxr_path), p_openxr_path + " has already been registered");
InteractionProfile new_profile; InteractionProfile new_profile;
new_profile.display_name = p_display_name; new_profile.display_name = p_display_name;
new_profile.openxr_path = p_openxr_path; new_profile.openxr_path = p_openxr_path;
new_profile.openxr_extension_name = p_openxr_extension_name; new_profile.openxr_extension_names = p_openxr_extension_names;
interaction_profiles.push_back(new_profile); interaction_profiles.push_back(new_profile);
} }
void OpenXRInteractionProfileMetadata::register_io_path(const String &p_interaction_profile, const String &p_display_name, const String &p_toplevel_path, const String &p_openxr_path, const String &p_openxr_extension_name, OpenXRAction::ActionType p_action_type) { void OpenXRInteractionProfileMetadata::register_io_path(const String &p_interaction_profile, const String &p_display_name, const String &p_toplevel_path, const String &p_openxr_path, const String &p_openxr_extension_names, OpenXRAction::ActionType p_action_type) {
ERR_FAIL_COND_MSG(!has_interaction_profile(p_interaction_profile), "Unknown interaction profile " + p_interaction_profile); ERR_FAIL_COND_MSG(!has_interaction_profile(p_interaction_profile), "Unknown interaction profile " + p_interaction_profile);
ERR_FAIL_COND_MSG(!has_top_level_path(p_toplevel_path), "Unknown top level path " + p_toplevel_path); ERR_FAIL_COND_MSG(!has_top_level_path(p_toplevel_path), "Unknown top level path " + p_toplevel_path);
@@ -101,7 +116,7 @@ void OpenXRInteractionProfileMetadata::register_io_path(const String &p_interact
p_display_name, p_display_name,
p_toplevel_path, p_toplevel_path,
p_openxr_path, p_openxr_path,
p_openxr_extension_name, p_openxr_extension_names,
p_action_type p_action_type
}; };
@@ -130,10 +145,10 @@ String OpenXRInteractionProfileMetadata::get_top_level_name(const String &p_open
return String(); return String();
} }
String OpenXRInteractionProfileMetadata::get_top_level_extension(const String &p_openxr_path) const { String OpenXRInteractionProfileMetadata::get_top_level_extensions(const String &p_openxr_path) const {
for (int i = 0; i < top_level_paths.size(); i++) { for (int i = 0; i < top_level_paths.size(); i++) {
if (top_level_paths[i].openxr_path == p_openxr_path) { if (top_level_paths[i].openxr_path == p_openxr_path) {
return top_level_paths[i].openxr_extension_name; return top_level_paths[i].openxr_extension_names;
} }
} }
@@ -150,10 +165,10 @@ bool OpenXRInteractionProfileMetadata::has_interaction_profile(const String &p_o
return false; return false;
} }
String OpenXRInteractionProfileMetadata::get_interaction_profile_extension(const String &p_openxr_path) const { String OpenXRInteractionProfileMetadata::get_interaction_profile_extensions(const String &p_openxr_path) const {
for (const InteractionProfile &interaction_profile : interaction_profiles) { for (const InteractionProfile &interaction_profile : interaction_profiles) {
if (interaction_profile.openxr_path == p_openxr_path) { if (interaction_profile.openxr_path == p_openxr_path) {
return interaction_profile.openxr_extension_name; return interaction_profile.openxr_extension_names;
} }
} }
@@ -218,6 +233,11 @@ void OpenXRInteractionProfileMetadata::_register_core_metadata() {
// Note that we'll make an exception for XR_EXT_palm_pose, which is used everywhere // Note that we'll make an exception for XR_EXT_palm_pose, which is used everywhere
// OpenXR 1.1 uses various new names.
// We use the new names in our action map and translate back IF OpenXR 1.1 is not supported.
register_path_rename("/user/hand/left/input/palm_ext/pose", "/user/hand/left/input/grip_surface/pose");
register_path_rename("/user/hand/right/input/palm_ext/pose", "/user/hand/right/input/grip_surface/pose");
// Our core toplevel paths // Our core toplevel paths
register_top_level_path("Left hand controller", "/user/hand/left", ""); register_top_level_path("Left hand controller", "/user/hand/left", "");
register_top_level_path("Right hand controller", "/user/hand/right", ""); register_top_level_path("Right hand controller", "/user/hand/right", "");
@@ -231,7 +251,7 @@ void OpenXRInteractionProfileMetadata::_register_core_metadata() {
for (const String user_path : { "/user/hand/left", "/user/hand/right" }) { for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE); register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE); register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL); register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
register_io_path(profile_path, "Select click", user_path, user_path + "/input/select/click", "", OpenXRAction::OPENXR_ACTION_BOOL); register_io_path(profile_path, "Select click", user_path, user_path + "/input/select/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
@@ -246,7 +266,7 @@ void OpenXRInteractionProfileMetadata::_register_core_metadata() {
for (const String user_path : { "/user/hand/left", "/user/hand/right" }) { for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE); register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE); register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL); register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
register_io_path(profile_path, "System click", user_path, user_path + "/input/system/click", "", OpenXRAction::OPENXR_ACTION_BOOL); register_io_path(profile_path, "System click", user_path, user_path + "/input/system/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
@@ -275,7 +295,7 @@ void OpenXRInteractionProfileMetadata::_register_core_metadata() {
for (const String user_path : { "/user/hand/left", "/user/hand/right" }) { for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE); register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE); register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL); register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
@@ -310,7 +330,7 @@ void OpenXRInteractionProfileMetadata::_register_core_metadata() {
for (const String user_path : { "/user/hand/left", "/user/hand/right" }) { for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE); register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE); register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
register_io_path(profile_path, "Trigger", user_path, user_path + "/input/trigger/value", "", OpenXRAction::OPENXR_ACTION_FLOAT); register_io_path(profile_path, "Trigger", user_path, user_path + "/input/trigger/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
register_io_path(profile_path, "Trigger touch", user_path, user_path + "/input/trigger/touch", "", OpenXRAction::OPENXR_ACTION_BOOL); register_io_path(profile_path, "Trigger touch", user_path, user_path + "/input/trigger/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
@@ -349,7 +369,7 @@ void OpenXRInteractionProfileMetadata::_register_core_metadata() {
for (const String user_path : { "/user/hand/left", "/user/hand/right" }) { for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE); register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE); register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
register_io_path(profile_path, "System click", user_path, user_path + "/input/system/click", "", OpenXRAction::OPENXR_ACTION_BOOL); register_io_path(profile_path, "System click", user_path, user_path + "/input/system/click", "", OpenXRAction::OPENXR_ACTION_BOOL);

View File

@@ -64,21 +64,21 @@ public:
struct TopLevelPath { struct TopLevelPath {
String display_name; // User friendly display name (i.e. Left controller) String display_name; // User friendly display name (i.e. Left controller)
String openxr_path; // Path in OpenXR (i.e. /user/hand/left) String openxr_path; // Path in OpenXR (i.e. /user/hand/left)
String openxr_extension_name; // If set, only available if extension is enabled (i.e. XR_HTCX_vive_tracker_interaction) String openxr_extension_names; // If set, only available if extension is enabled (i.e. XR_HTCX_vive_tracker_interaction)
}; };
struct IOPath { struct IOPath {
String display_name; // User friendly display name (i.e. Grip pose (left controller)) String display_name; // User friendly display name (i.e. Grip pose (left controller))
String top_level_path; // Top level path identifying the usage of the device in relation to this input/output String top_level_path; // Top level path identifying the usage of the device in relation to this input/output
String openxr_path; // Path in OpenXR (i.e. /user/hand/left/input/grip/pose) String openxr_path; // Path in OpenXR (i.e. /user/hand/left/input/grip/pose)
String openxr_extension_name; // If set, only available if extension is enabled (i.e. XR_EXT_palm_pose) String openxr_extension_names; // If set, only available if extension is enabled (i.e. XR_EXT_palm_pose)
OpenXRAction::ActionType action_type; // Type of input/output OpenXRAction::ActionType action_type; // Type of input/output
}; };
struct InteractionProfile { struct InteractionProfile {
String display_name; // User friendly display name (i.e. Simple controller) String display_name; // User friendly display name (i.e. Simple controller)
String openxr_path; // Path in OpenXR (i.e. /interaction_profiles/khr/simple_controller) String openxr_path; // Path in OpenXR (i.e. /interaction_profiles/khr/simple_controller)
String openxr_extension_name; // If set, only available if extension is enabled (i.e. XR_HTCX_vive_tracker_interaction) String openxr_extension_names; // If set, only available if extension is enabled (i.e. XR_HTCX_vive_tracker_interaction)
Vector<IOPath> io_paths; // Inputs and outputs for this device Vector<IOPath> io_paths; // Inputs and outputs for this device
bool has_io_path(const String &p_io_path) const; bool has_io_path(const String &p_io_path) const;
@@ -89,6 +89,8 @@ private:
static OpenXRInteractionProfileMetadata *singleton; static OpenXRInteractionProfileMetadata *singleton;
HashMap<String, String> profile_renames; HashMap<String, String> profile_renames;
HashMap<String, String> path_renames;
Vector<TopLevelPath> top_level_paths; Vector<TopLevelPath> top_level_paths;
Vector<InteractionProfile> interaction_profiles; Vector<InteractionProfile> interaction_profiles;
@@ -106,17 +108,20 @@ public:
void register_profile_rename(const String &p_old_name, const String &p_new_name); void register_profile_rename(const String &p_old_name, const String &p_new_name);
String check_profile_name(const String &p_name) const; String check_profile_name(const String &p_name) const;
void register_top_level_path(const String &p_display_name, const String &p_openxr_path, const String &p_openxr_extension_name); void register_path_rename(const String &p_old_name, const String &p_new_name);
String check_path_name(const String &p_name) const;
void register_top_level_path(const String &p_display_name, const String &p_openxr_path, const String &p_openxr_extension_names);
bool has_top_level_path(const String &p_openxr_path) const; bool has_top_level_path(const String &p_openxr_path) const;
String get_top_level_name(const String &p_openxr_path) const; String get_top_level_name(const String &p_openxr_path) const;
String get_top_level_extension(const String &p_openxr_path) const; String get_top_level_extensions(const String &p_openxr_path) const;
void register_interaction_profile(const String &p_display_name, const String &p_openxr_path, const String &p_openxr_extension_name); void register_interaction_profile(const String &p_display_name, const String &p_openxr_path, const String &p_openxr_extension_names);
bool has_interaction_profile(const String &p_openxr_path) const; bool has_interaction_profile(const String &p_openxr_path) const;
String get_interaction_profile_extension(const String &p_openxr_path) const; String get_interaction_profile_extensions(const String &p_openxr_path) const;
const InteractionProfile *get_profile(const String &p_openxr_path) const; const InteractionProfile *get_profile(const String &p_openxr_path) const;
PackedStringArray get_interaction_profile_paths() const; PackedStringArray get_interaction_profile_paths() const;
void register_io_path(const String &p_interaction_profile, const String &p_display_name, const String &p_toplevel_path, const String &p_openxr_path, const String &p_openxr_extension_name, OpenXRAction::ActionType p_action_type); void register_io_path(const String &p_interaction_profile, const String &p_display_name, const String &p_toplevel_path, const String &p_openxr_path, const String &p_openxr_extension_names, OpenXRAction::ActionType p_action_type);
const IOPath *get_io_path(const String &p_interaction_profile, const String &p_io_path) const; const IOPath *get_io_path(const String &p_interaction_profile, const String &p_io_path) const;
}; };

View File

@@ -85,6 +85,12 @@
Returns the predicted display timing for the next frame. Returns the predicted display timing for the next frame.
</description> </description>
</method> </method>
<method name="get_openxr_version">
<return type="int" />
<description>
Returns the version of OpenXR that was initialized. Only valid after the OpenXR instance has been created. See [url=https://registry.khronos.org/OpenXR/specs/1.1/html/xrspec.html#XR_MAKE_VERSION]XR_MAKE_VERSION[/url] for how the version is calculated.
</description>
</method>
<method name="get_play_space"> <method name="get_play_space">
<return type="int" /> <return type="int" />
<description> <description>

View File

@@ -42,8 +42,9 @@
</method> </method>
<method name="_get_requested_extensions" qualifiers="virtual"> <method name="_get_requested_extensions" qualifiers="virtual">
<return type="Dictionary" /> <return type="Dictionary" />
<param index="0" name="xr_version" type="int" />
<description> <description>
Returns a [Dictionary] of OpenXR extensions related to this extension. The [Dictionary] should contain the name of the extension, mapped to a [code]bool *[/code] cast to an integer: Returns a [Dictionary] of OpenXR extensions related to this extension. [param xr_version] specifies the OpenXR version we're instantiating. This will be zero if the editor requests this list to flag supported features. The [Dictionary] should contain the name of the extension, mapped to a [code]bool *[/code] cast to an integer:
- If the [code]bool *[/code] is a [code]nullptr[/code] this extension is mandatory. - If the [code]bool *[/code] is a [code]nullptr[/code] this extension is mandatory.
- If the [code]bool *[/code] points to a boolean, the boolean will be updated to [code]true[/code] if the extension is enabled. - If the [code]bool *[/code] points to a boolean, the boolean will be updated to [code]true[/code] if the extension is enabled.
</description> </description>
@@ -269,9 +270,10 @@
</method> </method>
<method name="_set_instance_create_info_and_get_next_pointer" qualifiers="virtual"> <method name="_set_instance_create_info_and_get_next_pointer" qualifiers="virtual">
<return type="int" /> <return type="int" />
<param index="0" name="next_pointer" type="void*" /> <param index="0" name="xr_version" type="int" />
<param index="1" name="next_pointer" type="void*" />
<description> <description>
Add additional data structures when the OpenXR instance is created. Add additional data structures when the OpenXR instance is created. [param xr_version] specifies the OpenXR version we're instantiating.
</description> </description>
</method> </method>
<method name="_set_projection_views_and_get_next_pointer" qualifiers="virtual"> <method name="_set_projection_views_and_get_next_pointer" qualifiers="virtual">

View File

@@ -13,10 +13,10 @@
<return type="void" /> <return type="void" />
<param index="0" name="display_name" type="String" /> <param index="0" name="display_name" type="String" />
<param index="1" name="openxr_path" type="String" /> <param index="1" name="openxr_path" type="String" />
<param index="2" name="openxr_extension_name" type="String" /> <param index="2" name="openxr_extension_names" type="String" />
<description> <description>
Registers an interaction profile using its OpenXR designation (e.g. [code]/interaction_profiles/khr/simple_controller[/code] is the profile for OpenXR's simple controller profile). Registers an interaction profile using its OpenXR designation (e.g. [code]/interaction_profiles/khr/simple_controller[/code] is the profile for OpenXR's simple controller profile).
[param display_name] is the description shown to the user. [param openxr_path] is the interaction profile path being registered. [param openxr_extension_name] optionally restricts this profile to the given extension being enabled/available. If the extension is not available, the profile and all related entries used in an action map are filtered out. [param display_name] is the description shown to the user. [param openxr_path] is the interaction profile path being registered. [param openxr_extension_names] optionally restricts this profile to the given extension being enabled/available. If the extension is not available, the profile and all related entries used in an action map are filtered out.
</description> </description>
</method> </method>
<method name="register_io_path"> <method name="register_io_path">
@@ -25,10 +25,18 @@
<param index="1" name="display_name" type="String" /> <param index="1" name="display_name" type="String" />
<param index="2" name="toplevel_path" type="String" /> <param index="2" name="toplevel_path" type="String" />
<param index="3" name="openxr_path" type="String" /> <param index="3" name="openxr_path" type="String" />
<param index="4" name="openxr_extension_name" type="String" /> <param index="4" name="openxr_extension_names" type="String" />
<param index="5" name="action_type" type="int" enum="OpenXRAction.ActionType" /> <param index="5" name="action_type" type="int" enum="OpenXRAction.ActionType" />
<description> <description>
Registers an input/output path for the given [param interaction_profile]. The profile should previously have been registered using [method register_interaction_profile]. [param display_name] is the description shown to the user. [param toplevel_path] specifies the bind path this input/output can be bound to (e.g. [code]/user/hand/left[/code] or [code]/user/hand/right[/code]). [param openxr_path] is the action input/output being registered (e.g. [code]/user/hand/left/input/aim/pose[/code]). [param openxr_extension_name] restricts this input/output to an enabled/available extension, this doesn't need to repeat the extension on the profile but relates to overlapping extension (e.g. [code]XR_EXT_palm_pose[/code] that introduces [code]…/input/palm_ext/pose[/code] input paths). [param action_type] defines the type of input or output provided by OpenXR. Registers an input/output path for the given [param interaction_profile]. The profile should previously have been registered using [method register_interaction_profile]. [param display_name] is the description shown to the user. [param toplevel_path] specifies the bind path this input/output can be bound to (e.g. [code]/user/hand/left[/code] or [code]/user/hand/right[/code]). [param openxr_path] is the action input/output being registered (e.g. [code]/user/hand/left/input/aim/pose[/code]). [param openxr_extension_names] restricts this input/output to an enabled/available extension, this doesn't need to repeat the extension on the profile but relates to overlapping extension (e.g. [code]XR_EXT_palm_pose[/code] that introduces [code]…/input/palm_ext/pose[/code] input paths). [param action_type] defines the type of input or output provided by OpenXR.
</description>
</method>
<method name="register_path_rename">
<return type="void" />
<param index="0" name="old_name" type="String" />
<param index="1" name="new_name" type="String" />
<description>
Allows for renaming old input/output paths to new paths in order to load and process older action maps.
</description> </description>
</method> </method>
<method name="register_profile_rename"> <method name="register_profile_rename">
@@ -36,17 +44,17 @@
<param index="0" name="old_name" type="String" /> <param index="0" name="old_name" type="String" />
<param index="1" name="new_name" type="String" /> <param index="1" name="new_name" type="String" />
<description> <description>
Allows for renaming old interaction profile paths to new paths to maintain backwards compatibility with older action maps. Allows for renaming old interaction profile paths to new paths in order to load and process older action maps.
</description> </description>
</method> </method>
<method name="register_top_level_path"> <method name="register_top_level_path">
<return type="void" /> <return type="void" />
<param index="0" name="display_name" type="String" /> <param index="0" name="display_name" type="String" />
<param index="1" name="openxr_path" type="String" /> <param index="1" name="openxr_path" type="String" />
<param index="2" name="openxr_extension_name" type="String" /> <param index="2" name="openxr_extension_names" type="String" />
<description> <description>
Registers a top level path to which profiles can be bound. For instance [code]/user/hand/left[/code] refers to the bind point for the player's left hand. Extensions can register additional top level paths, for instance a haptic vest extension might register [code]/user/body/vest[/code]. Registers a top level path to which profiles can be bound. For instance [code]/user/hand/left[/code] refers to the bind point for the player's left hand. Extensions can register additional top level paths, for instance a haptic vest extension might register [code]/user/body/vest[/code].
[param display_name] is the name shown to the user. [param openxr_path] is the top level path being registered. [param openxr_extension_name] is optional and ensures the top level path is only used if the specified extension is available/enabled. [param display_name] is the name shown to the user. [param openxr_path] is the top level path being registered. [param openxr_extension_names] is optional and ensures the top level path is only used if the specified extension is available/enabled.
When a top level path ends up being bound by OpenXR, an [XRPositionalTracker] is instantiated to manage the state of the device. When a top level path ends up being bound by OpenXR, an [XRPositionalTracker] is instantiated to manage the state of the device.
</description> </description>
</method> </method>

View File

@@ -198,10 +198,10 @@ void OpenXRInteractionProfileEditorBase::setup(const Ref<OpenXRActionMap> &p_act
if (profile_def != nullptr) { if (profile_def != nullptr) {
profile_name = profile_def->display_name; profile_name = profile_def->display_name;
if (!profile_def->openxr_extension_name.is_empty()) { if (!profile_def->openxr_extension_names.is_empty()) {
profile_name += "*"; profile_name += "*";
tooltip = vformat(TTR("Note: This interaction profile requires extension %s support."), profile_def->openxr_extension_name); tooltip = vformat(TTR("Note: This interaction profile requires extension %s support."), profile_def->openxr_extension_names);
} }
} }
@@ -242,11 +242,13 @@ void OpenXRInteractionProfileEditor::_add_io_path(VBoxContainer *p_container, co
Label *path_label = memnew(Label); Label *path_label = memnew(Label);
path_label->set_focus_mode(FOCUS_ACCESSIBILITY); path_label->set_focus_mode(FOCUS_ACCESSIBILITY);
if (p_io_path->openxr_extension_name.is_empty()) { if (p_io_path->openxr_extension_names.is_empty()) {
path_label->set_text(p_io_path->display_name); path_label->set_text(p_io_path->display_name);
} else { } else {
path_label->set_text(p_io_path->display_name + "*"); path_label->set_text(p_io_path->display_name + "*");
path_hb->set_tooltip_text(vformat(TTR("Note: This binding path requires extension %s support."), p_io_path->openxr_extension_name));
String extension_names = p_io_path->openxr_extension_names.replace(",", " or ").replace(XR_OPENXR_1_1_NAME, "OpenXR 1.1");
path_hb->set_tooltip_text(vformat(TTR("Note: This binding path requires extension %s support."), extension_names));
} }
path_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); path_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
path_hb->add_child(path_label); path_hb->add_child(path_label);
@@ -334,7 +336,7 @@ void OpenXRInteractionProfileEditor::_update_interaction_profile() {
return; return;
} }
PackedStringArray requested_extensions = OpenXRAPI::get_all_requested_extensions(); PackedStringArray requested_extensions = OpenXRAPI::get_all_requested_extensions(0);
// out with the old... // out with the old...
while (interaction_profile_hb->get_child_count() > 0) { while (interaction_profile_hb->get_child_count() > 0) {
@@ -369,7 +371,14 @@ void OpenXRInteractionProfileEditor::_update_interaction_profile() {
for (int j = 0; j < profile_def->io_paths.size(); j++) { for (int j = 0; j < profile_def->io_paths.size(); j++) {
const OpenXRInteractionProfileMetadata::IOPath *io_path = &profile_def->io_paths[j]; const OpenXRInteractionProfileMetadata::IOPath *io_path = &profile_def->io_paths[j];
if (io_path->top_level_path == top_level_paths[i] && (io_path->openxr_extension_name.is_empty() || requested_extensions.has(io_path->openxr_extension_name))) {
const Vector<String> extensions = io_path->openxr_extension_names.split(",", false);
bool extension_is_requested = extensions.is_empty(); // If none, then yes we can use this.
for (const String &extension : extensions) {
extension_is_requested |= requested_extensions.has(extension);
}
if (io_path->top_level_path == top_level_paths[i] && extension_is_requested) {
_add_io_path(container, io_path); _add_io_path(container, io_path);
} }
} }

View File

@@ -78,7 +78,7 @@ void OpenXRSelectInteractionProfileDialog::open(const PackedStringArray &p_do_no
memdelete(main_vb->get_child(1)); memdelete(main_vb->get_child(1));
} }
PackedStringArray requested_extensions = OpenXRAPI::get_all_requested_extensions(); PackedStringArray requested_extensions = OpenXRAPI::get_all_requested_extensions(0);
selected_interaction_profile = ""; selected_interaction_profile = "";
ip_buttons.clear(); ip_buttons.clear();
@@ -86,8 +86,12 @@ void OpenXRSelectInteractionProfileDialog::open(const PackedStringArray &p_do_no
// In with the new. // In with the new.
PackedStringArray interaction_profiles = meta_data->get_interaction_profile_paths(); PackedStringArray interaction_profiles = meta_data->get_interaction_profile_paths();
for (const String &path : interaction_profiles) { for (const String &path : interaction_profiles) {
const String extension = meta_data->get_interaction_profile_extension(path); const Vector<String> extensions = meta_data->get_interaction_profile_extensions(path).split(",", false);
if (!p_do_not_include.has(path) && (extension.is_empty() || requested_extensions.has(extension))) { bool extension_is_requested = extensions.is_empty(); // If none, then yes we can use this.
for (const String &extension : extensions) {
extension_is_requested |= requested_extensions.has(extension);
}
if (!p_do_not_include.has(path) && extension_is_requested) {
Button *ip_button = memnew(Button); Button *ip_button = memnew(Button);
ip_button->set_flat(true); ip_button->set_flat(true);
ip_button->set_text(meta_data->get_profile(path)->display_name); ip_button->set_text(meta_data->get_profile(path)->display_name);

View File

@@ -62,7 +62,7 @@ void OpenXRAndroidThreadSettingsExtension::_bind_methods() {
BIND_ENUM_CONSTANT(THREAD_TYPE_RENDERER_WORKER); BIND_ENUM_CONSTANT(THREAD_TYPE_RENDERER_WORKER);
} }
HashMap<String, bool *> OpenXRAndroidThreadSettingsExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRAndroidThreadSettingsExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
#ifdef XR_USE_PLATFORM_ANDROID #ifdef XR_USE_PLATFORM_ANDROID

View File

@@ -50,7 +50,7 @@ public:
OpenXRAndroidThreadSettingsExtension(); OpenXRAndroidThreadSettingsExtension();
virtual ~OpenXRAndroidThreadSettingsExtension() override; virtual ~OpenXRAndroidThreadSettingsExtension() override;
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
virtual void on_instance_created(XrInstance p_instance) override; virtual void on_instance_created(XrInstance p_instance) override;
virtual void on_session_created(XrSession p_session) override; virtual void on_session_created(XrSession p_session) override;

View File

@@ -44,7 +44,7 @@ OpenXRCompositionLayerDepthExtension::~OpenXRCompositionLayerDepthExtension() {
singleton = nullptr; singleton = nullptr;
} }
HashMap<String, bool *> OpenXRCompositionLayerDepthExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRCompositionLayerDepthExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
request_extensions[XR_KHR_COMPOSITION_LAYER_DEPTH_EXTENSION_NAME] = &available; request_extensions[XR_KHR_COMPOSITION_LAYER_DEPTH_EXTENSION_NAME] = &available;

View File

@@ -44,7 +44,7 @@ public:
OpenXRCompositionLayerDepthExtension(); OpenXRCompositionLayerDepthExtension();
virtual ~OpenXRCompositionLayerDepthExtension() override; virtual ~OpenXRCompositionLayerDepthExtension() override;
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
bool is_available(); bool is_available();
virtual int get_composition_layer_count() override; virtual int get_composition_layer_count() override;
virtual XrCompositionLayerBaseHeader *get_composition_layer(int p_index) override; virtual XrCompositionLayerBaseHeader *get_composition_layer(int p_index) override;

View File

@@ -56,7 +56,7 @@ OpenXRCompositionLayerExtension::~OpenXRCompositionLayerExtension() {
singleton = nullptr; singleton = nullptr;
} }
HashMap<String, bool *> OpenXRCompositionLayerExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRCompositionLayerExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
request_extensions[XR_KHR_COMPOSITION_LAYER_CYLINDER_EXTENSION_NAME] = &cylinder_ext_available; request_extensions[XR_KHR_COMPOSITION_LAYER_CYLINDER_EXTENSION_NAME] = &cylinder_ext_available;

View File

@@ -126,7 +126,7 @@ public:
OpenXRCompositionLayerExtension(); OpenXRCompositionLayerExtension();
virtual ~OpenXRCompositionLayerExtension() override; virtual ~OpenXRCompositionLayerExtension() override;
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
virtual void on_instance_created(const XrInstance p_instance) override; virtual void on_instance_created(const XrInstance p_instance) override;
virtual void on_session_created(const XrSession p_session) override; virtual void on_session_created(const XrSession p_session) override;
virtual void on_session_destroyed() override; virtual void on_session_destroyed() override;

View File

@@ -50,7 +50,7 @@ OpenXRDebugUtilsExtension::~OpenXRDebugUtilsExtension() {
singleton = nullptr; singleton = nullptr;
} }
HashMap<String, bool *> OpenXRDebugUtilsExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRDebugUtilsExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
request_extensions[XR_EXT_DEBUG_UTILS_EXTENSION_NAME] = &debug_utils_ext; request_extensions[XR_EXT_DEBUG_UTILS_EXTENSION_NAME] = &debug_utils_ext;

View File

@@ -45,7 +45,7 @@ public:
OpenXRDebugUtilsExtension(); OpenXRDebugUtilsExtension();
virtual ~OpenXRDebugUtilsExtension() override; virtual ~OpenXRDebugUtilsExtension() override;
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
virtual void on_instance_created(const XrInstance p_instance) override; virtual void on_instance_created(const XrInstance p_instance) override;
virtual void on_instance_destroyed() override; virtual void on_instance_destroyed() override;

View File

@@ -52,7 +52,7 @@ OpenXRDPadBindingExtension::~OpenXRDPadBindingExtension() {
singleton = nullptr; singleton = nullptr;
} }
HashMap<String, bool *> OpenXRDPadBindingExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRDPadBindingExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
// Note, we're dependent on the binding modifier extension, this may be requested by multiple extension wrappers. // Note, we're dependent on the binding modifier extension, this may be requested by multiple extension wrappers.

View File

@@ -48,7 +48,7 @@ public:
OpenXRDPadBindingExtension(); OpenXRDPadBindingExtension();
virtual ~OpenXRDPadBindingExtension() override; virtual ~OpenXRDPadBindingExtension() override;
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
bool is_available(); bool is_available();

View File

@@ -34,9 +34,9 @@
#include "../openxr_api_extension.h" #include "../openxr_api_extension.h"
void OpenXRExtensionWrapper::_bind_methods() { void OpenXRExtensionWrapper::_bind_methods() {
GDVIRTUAL_BIND(_get_requested_extensions); GDVIRTUAL_BIND(_get_requested_extensions, "xr_version");
GDVIRTUAL_BIND(_set_system_properties_and_get_next_pointer, "next_pointer"); GDVIRTUAL_BIND(_set_system_properties_and_get_next_pointer, "next_pointer");
GDVIRTUAL_BIND(_set_instance_create_info_and_get_next_pointer, "next_pointer"); GDVIRTUAL_BIND(_set_instance_create_info_and_get_next_pointer, "xr_version", "next_pointer");
GDVIRTUAL_BIND(_set_session_create_and_get_next_pointer, "next_pointer"); GDVIRTUAL_BIND(_set_session_create_and_get_next_pointer, "next_pointer");
GDVIRTUAL_BIND(_set_swapchain_create_info_and_get_next_pointer, "next_pointer"); GDVIRTUAL_BIND(_set_swapchain_create_info_and_get_next_pointer, "next_pointer");
GDVIRTUAL_BIND(_set_hand_joint_locations_and_get_next_pointer, "hand_index", "next_pointer"); GDVIRTUAL_BIND(_set_hand_joint_locations_and_get_next_pointer, "hand_index", "next_pointer");
@@ -79,14 +79,19 @@ void OpenXRExtensionWrapper::_bind_methods() {
GDVIRTUAL_BIND(_on_viewport_composition_layer_destroyed, "layer"); GDVIRTUAL_BIND(_on_viewport_composition_layer_destroyed, "layer");
GDVIRTUAL_BIND(_set_android_surface_swapchain_create_info_and_get_next_pointer, "property_values", "next_pointer"); GDVIRTUAL_BIND(_set_android_surface_swapchain_create_info_and_get_next_pointer, "property_values", "next_pointer");
#ifndef DISABLE_DEPRECATED
GDVIRTUAL_BIND_COMPAT(_get_requested_extensions_bind_compat_109302);
GDVIRTUAL_BIND_COMPAT(_set_instance_create_info_and_get_next_pointer_bind_compat_109302, "next_pointer");
#endif
ClassDB::bind_method(D_METHOD("get_openxr_api"), &OpenXRExtensionWrapper::_gdextension_get_openxr_api); ClassDB::bind_method(D_METHOD("get_openxr_api"), &OpenXRExtensionWrapper::_gdextension_get_openxr_api);
ClassDB::bind_method(D_METHOD("register_extension_wrapper"), &OpenXRExtensionWrapper::_gdextension_register_extension_wrapper); ClassDB::bind_method(D_METHOD("register_extension_wrapper"), &OpenXRExtensionWrapper::_gdextension_register_extension_wrapper);
} }
HashMap<String, bool *> OpenXRExtensionWrapper::get_requested_extensions() { HashMap<String, bool *> OpenXRExtensionWrapper::get_requested_extensions(XrVersion p_xr_version) {
Dictionary request_extension; Dictionary request_extension;
if (GDVIRTUAL_CALL(_get_requested_extensions, request_extension)) { if (GDVIRTUAL_CALL(_get_requested_extensions, (uint64_t)p_xr_version, request_extension)) {
HashMap<String, bool *> result; HashMap<String, bool *> result;
for (const KeyValue<Variant, Variant> &kv : request_extension) { for (const KeyValue<Variant, Variant> &kv : request_extension) {
GDExtensionPtr<bool> value = VariantCaster<GDExtensionPtr<bool>>::cast(kv.value); GDExtensionPtr<bool> value = VariantCaster<GDExtensionPtr<bool>>::cast(kv.value);
@@ -95,6 +100,17 @@ HashMap<String, bool *> OpenXRExtensionWrapper::get_requested_extensions() {
return result; return result;
} }
#ifndef DISABLE_DEPRECATED
if (GDVIRTUAL_CALL(_get_requested_extensions_bind_compat_109302, request_extension)) {
HashMap<String, bool *> result;
for (const KeyValue<Variant, Variant> &kv : request_extension) {
GDExtensionPtr<bool> value = VariantCaster<GDExtensionPtr<bool>>::cast(kv.value);
result.insert(kv.key, value);
}
return result;
}
#endif
return HashMap<String, bool *>(); return HashMap<String, bool *>();
} }
@@ -108,13 +124,19 @@ void *OpenXRExtensionWrapper::set_system_properties_and_get_next_pointer(void *p
return nullptr; return nullptr;
} }
void *OpenXRExtensionWrapper::set_instance_create_info_and_get_next_pointer(void *p_next_pointer) { void *OpenXRExtensionWrapper::set_instance_create_info_and_get_next_pointer(XrVersion p_xr_version, void *p_next_pointer) {
uint64_t pointer; uint64_t pointer;
if (GDVIRTUAL_CALL(_set_instance_create_info_and_get_next_pointer, GDExtensionPtr<void>(p_next_pointer), pointer)) { if (GDVIRTUAL_CALL(_set_instance_create_info_and_get_next_pointer, (uint64_t)p_xr_version, GDExtensionPtr<void>(p_next_pointer), pointer)) {
return reinterpret_cast<void *>(pointer); return reinterpret_cast<void *>(pointer);
} }
#ifndef DISABLE_DEPRECATED
if (GDVIRTUAL_CALL(_set_instance_create_info_and_get_next_pointer_bind_compat_109302, GDExtensionPtr<void>(p_next_pointer), pointer)) {
return reinterpret_cast<void *>(pointer);
}
#endif
return nullptr; return nullptr;
} }

View File

@@ -60,12 +60,15 @@ protected:
public: public:
// `get_requested_extensions` should return a list of OpenXR extensions related to this extension. // `get_requested_extensions` should return a list of OpenXR extensions related to this extension.
// This function can be called multiple times.
// p_xr_version is the OpenXR version which we're attempting to initialize.
// Note: when called from the editor, p_xr_version will be 0 and we should return any extension we may initialize.
// If the bool * is a nullptr this extension is mandatory // If the bool * is a nullptr this extension is mandatory
// If the bool * points to a boolean, the boolean will be updated // If the bool * points to a boolean, the boolean will be updated
// to true if the extension is enabled. // to true if the extension is enabled.
virtual HashMap<String, bool *> get_requested_extensions(); virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_xr_version);
GDVIRTUAL0R(Dictionary, _get_requested_extensions); GDVIRTUAL1R(Dictionary, _get_requested_extensions, uint64_t);
// These functions allow an extension to add entries to a struct chain. // These functions allow an extension to add entries to a struct chain.
// `p_next_pointer` points to the last struct that was created for this chain // `p_next_pointer` points to the last struct that was created for this chain
@@ -74,7 +77,7 @@ public:
// If you are not adding any structs, just return `p_next_pointer`. // If you are not adding any structs, just return `p_next_pointer`.
// See existing extensions for examples of this implementation. // See existing extensions for examples of this implementation.
virtual void *set_system_properties_and_get_next_pointer(void *p_next_pointer); // Add additional data structures when we interrogate OpenXR's system abilities. virtual void *set_system_properties_and_get_next_pointer(void *p_next_pointer); // Add additional data structures when we interrogate OpenXR's system abilities.
virtual void *set_instance_create_info_and_get_next_pointer(void *p_next_pointer); // Add additional data structures when we create our OpenXR instance. virtual void *set_instance_create_info_and_get_next_pointer(XrVersion p_xr_version, void *p_next_pointer); // Add additional data structures when we create our OpenXR instance.
virtual void *set_session_create_and_get_next_pointer(void *p_next_pointer); // Add additional data structures when we create our OpenXR session. virtual void *set_session_create_and_get_next_pointer(void *p_next_pointer); // Add additional data structures when we create our OpenXR session.
virtual void *set_swapchain_create_info_and_get_next_pointer(void *p_next_pointer); // Add additional data structures when creating OpenXR swap chains. virtual void *set_swapchain_create_info_and_get_next_pointer(void *p_next_pointer); // Add additional data structures when creating OpenXR swap chains.
virtual void *set_hand_joint_locations_and_get_next_pointer(int p_hand_index, void *p_next_pointer); virtual void *set_hand_joint_locations_and_get_next_pointer(int p_hand_index, void *p_next_pointer);
@@ -91,7 +94,7 @@ public:
//TODO workaround as GDExtensionPtr<void> return type results in build error in godot-cpp //TODO workaround as GDExtensionPtr<void> return type results in build error in godot-cpp
GDVIRTUAL1R(uint64_t, _set_system_properties_and_get_next_pointer, GDExtensionPtr<void>); GDVIRTUAL1R(uint64_t, _set_system_properties_and_get_next_pointer, GDExtensionPtr<void>);
GDVIRTUAL1R(uint64_t, _set_instance_create_info_and_get_next_pointer, GDExtensionPtr<void>); GDVIRTUAL2R(uint64_t, _set_instance_create_info_and_get_next_pointer, uint64_t, GDExtensionPtr<void>);
GDVIRTUAL1R(uint64_t, _set_session_create_and_get_next_pointer, GDExtensionPtr<void>); GDVIRTUAL1R(uint64_t, _set_session_create_and_get_next_pointer, GDExtensionPtr<void>);
GDVIRTUAL1R(uint64_t, _set_swapchain_create_info_and_get_next_pointer, GDExtensionPtr<void>); GDVIRTUAL1R(uint64_t, _set_swapchain_create_info_and_get_next_pointer, GDExtensionPtr<void>);
GDVIRTUAL2R(uint64_t, _set_hand_joint_locations_and_get_next_pointer, int, GDExtensionPtr<void>); GDVIRTUAL2R(uint64_t, _set_hand_joint_locations_and_get_next_pointer, int, GDExtensionPtr<void>);
@@ -107,6 +110,11 @@ public:
GDVIRTUAL2R(uint64_t, _set_view_configuration_and_get_next_pointer, uint32_t, GDExtensionPtr<void>); GDVIRTUAL2R(uint64_t, _set_view_configuration_and_get_next_pointer, uint32_t, GDExtensionPtr<void>);
GDVIRTUAL1C(_print_view_configuration_info, int); GDVIRTUAL1C(_print_view_configuration_info, int);
#ifndef DISABLE_DEPRECATED
GDVIRTUAL0R_COMPAT(_get_requested_extensions_bind_compat_109302, Dictionary, _get_requested_extensions);
GDVIRTUAL1R_COMPAT(_set_instance_create_info_and_get_next_pointer_bind_compat_109302, uint64_t, _set_instance_create_info_and_get_next_pointer, GDExtensionPtr<void>);
#endif
virtual PackedStringArray get_suggested_tracker_names(); virtual PackedStringArray get_suggested_tracker_names();
GDVIRTUAL0R(PackedStringArray, _get_suggested_tracker_names); GDVIRTUAL0R(PackedStringArray, _get_suggested_tracker_names);

View File

@@ -51,7 +51,7 @@ OpenXREyeGazeInteractionExtension::~OpenXREyeGazeInteractionExtension() {
singleton = nullptr; singleton = nullptr;
} }
HashMap<String, bool *> OpenXREyeGazeInteractionExtension::get_requested_extensions() { HashMap<String, bool *> OpenXREyeGazeInteractionExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
// Only enable this extension when requested. // Only enable this extension when requested.

View File

@@ -44,7 +44,7 @@ public:
OpenXREyeGazeInteractionExtension(); OpenXREyeGazeInteractionExtension();
~OpenXREyeGazeInteractionExtension(); ~OpenXREyeGazeInteractionExtension();
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
virtual void *set_system_properties_and_get_next_pointer(void *p_next_pointer) override; virtual void *set_system_properties_and_get_next_pointer(void *p_next_pointer) override;
PackedStringArray get_suggested_tracker_names() override; PackedStringArray get_suggested_tracker_names() override;

View File

@@ -45,7 +45,7 @@ OpenXRDisplayRefreshRateExtension::~OpenXRDisplayRefreshRateExtension() {
display_refresh_rate_ext = false; display_refresh_rate_ext = false;
} }
HashMap<String, bool *> OpenXRDisplayRefreshRateExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRDisplayRefreshRateExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
request_extensions[XR_FB_DISPLAY_REFRESH_RATE_EXTENSION_NAME] = &display_refresh_rate_ext; request_extensions[XR_FB_DISPLAY_REFRESH_RATE_EXTENSION_NAME] = &display_refresh_rate_ext;

View File

@@ -51,7 +51,7 @@ public:
OpenXRDisplayRefreshRateExtension(); OpenXRDisplayRefreshRateExtension();
virtual ~OpenXRDisplayRefreshRateExtension() override; virtual ~OpenXRDisplayRefreshRateExtension() override;
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
virtual void on_instance_created(const XrInstance p_instance) override; virtual void on_instance_created(const XrInstance p_instance) override;
virtual void on_instance_destroyed() override; virtual void on_instance_destroyed() override;

View File

@@ -75,7 +75,7 @@ OpenXRFBFoveationExtension::~OpenXRFBFoveationExtension() {
swapchain_update_state_ext = nullptr; swapchain_update_state_ext = nullptr;
} }
HashMap<String, bool *> OpenXRFBFoveationExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRFBFoveationExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
request_extensions[XR_FB_FOVEATION_EXTENSION_NAME] = &fb_foveation_ext; request_extensions[XR_FB_FOVEATION_EXTENSION_NAME] = &fb_foveation_ext;

View File

@@ -52,7 +52,7 @@ public:
OpenXRFBFoveationExtension(const String &p_rendering_driver); OpenXRFBFoveationExtension(const String &p_rendering_driver);
virtual ~OpenXRFBFoveationExtension() override; virtual ~OpenXRFBFoveationExtension() override;
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
virtual void on_instance_created(const XrInstance p_instance) override; virtual void on_instance_created(const XrInstance p_instance) override;
virtual void on_instance_destroyed() override; virtual void on_instance_destroyed() override;

View File

@@ -61,7 +61,7 @@ OpenXRFBUpdateSwapchainExtension::~OpenXRFBUpdateSwapchainExtension() {
singleton = nullptr; singleton = nullptr;
} }
HashMap<String, bool *> OpenXRFBUpdateSwapchainExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRFBUpdateSwapchainExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
request_extensions[XR_FB_SWAPCHAIN_UPDATE_STATE_EXTENSION_NAME] = &fb_swapchain_update_state_ext; request_extensions[XR_FB_SWAPCHAIN_UPDATE_STATE_EXTENSION_NAME] = &fb_swapchain_update_state_ext;

View File

@@ -54,7 +54,7 @@ public:
OpenXRFBUpdateSwapchainExtension(const String &p_rendering_driver); OpenXRFBUpdateSwapchainExtension(const String &p_rendering_driver);
virtual ~OpenXRFBUpdateSwapchainExtension() override; virtual ~OpenXRFBUpdateSwapchainExtension() override;
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
virtual void on_instance_created(const XrInstance p_instance) override; virtual void on_instance_created(const XrInstance p_instance) override;
virtual void on_instance_destroyed() override; virtual void on_instance_destroyed() override;

View File

@@ -68,7 +68,7 @@ OpenXRFrameSynthesisExtension::~OpenXRFrameSynthesisExtension() {
singleton = nullptr; singleton = nullptr;
} }
HashMap<String, bool *> OpenXRFrameSynthesisExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRFrameSynthesisExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
if (GLOBAL_GET("xr/openxr/extensions/frame_synthesis")) { if (GLOBAL_GET("xr/openxr/extensions/frame_synthesis")) {

View File

@@ -44,7 +44,7 @@ public:
OpenXRFrameSynthesisExtension(); OpenXRFrameSynthesisExtension();
virtual ~OpenXRFrameSynthesisExtension() override; virtual ~OpenXRFrameSynthesisExtension() override;
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
virtual void on_instance_created(const XrInstance p_instance) override; virtual void on_instance_created(const XrInstance p_instance) override;
virtual void on_instance_destroyed() override; virtual void on_instance_destroyed() override;

View File

@@ -129,7 +129,7 @@ void OpenXRFutureExtension::_bind_methods() {
ClassDB::bind_method(D_METHOD("cancel_future", "future"), &OpenXRFutureExtension::_cancel_future); ClassDB::bind_method(D_METHOD("cancel_future", "future"), &OpenXRFutureExtension::_cancel_future);
} }
HashMap<String, bool *> OpenXRFutureExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRFutureExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
request_extensions[XR_EXT_FUTURE_EXTENSION_NAME] = &future_ext; request_extensions[XR_EXT_FUTURE_EXTENSION_NAME] = &future_ext;

View File

@@ -104,7 +104,7 @@ public:
OpenXRFutureExtension(); OpenXRFutureExtension();
virtual ~OpenXRFutureExtension() override; virtual ~OpenXRFutureExtension() override;
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
virtual void on_instance_created(const XrInstance p_instance) override; virtual void on_instance_created(const XrInstance p_instance) override;
virtual void on_instance_destroyed() override; virtual void on_instance_destroyed() override;

View File

@@ -31,6 +31,7 @@
#include "openxr_hand_interaction_extension.h" #include "openxr_hand_interaction_extension.h"
#include "../action_map/openxr_interaction_profile_metadata.h" #include "../action_map/openxr_interaction_profile_metadata.h"
#include "../openxr_api.h"
#include "core/config/project_settings.h" #include "core/config/project_settings.h"
#include <openxr/openxr.h> #include <openxr/openxr.h>
@@ -49,7 +50,7 @@ OpenXRHandInteractionExtension::~OpenXRHandInteractionExtension() {
singleton = nullptr; singleton = nullptr;
} }
HashMap<String, bool *> OpenXRHandInteractionExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRHandInteractionExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
// Only enable this extension when requested. // Only enable this extension when requested.
@@ -78,7 +79,7 @@ void OpenXRHandInteractionExtension::on_register_metadata() {
openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Pinch pose", user_path, user_path + "/input/pinch_ext/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Pinch pose", user_path, user_path + "/input/pinch_ext/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Poke pose", user_path, user_path + "/input/poke_ext/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Poke pose", user_path, user_path + "/input/poke_ext/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Pinch", user_path, user_path + "/input/pinch_ext/value", "", OpenXRAction::OPENXR_ACTION_FLOAT); openxr_metadata->register_io_path(profile_path, "Pinch", user_path, user_path + "/input/pinch_ext/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
openxr_metadata->register_io_path(profile_path, "Pinch ready", user_path, user_path + "/input/pinch_ext/ready_ext", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "Pinch ready", user_path, user_path + "/input/pinch_ext/ready_ext", "", OpenXRAction::OPENXR_ACTION_BOOL);

View File

@@ -61,7 +61,7 @@ public:
OpenXRHandInteractionExtension(); OpenXRHandInteractionExtension();
virtual ~OpenXRHandInteractionExtension() override; virtual ~OpenXRHandInteractionExtension() override;
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
bool is_available(); bool is_available();

View File

@@ -55,7 +55,7 @@ OpenXRHandTrackingExtension::~OpenXRHandTrackingExtension() {
singleton = nullptr; singleton = nullptr;
} }
HashMap<String, bool *> OpenXRHandTrackingExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRHandTrackingExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
unobstructed_data_source = GLOBAL_GET("xr/openxr/extensions/hand_tracking_unobstructed_data_source"); unobstructed_data_source = GLOBAL_GET("xr/openxr/extensions/hand_tracking_unobstructed_data_source");

View File

@@ -76,7 +76,7 @@ public:
OpenXRHandTrackingExtension(); OpenXRHandTrackingExtension();
virtual ~OpenXRHandTrackingExtension() override; virtual ~OpenXRHandTrackingExtension() override;
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
virtual void on_instance_created(const XrInstance p_instance) override; virtual void on_instance_created(const XrInstance p_instance) override;
virtual void on_instance_destroyed() override; virtual void on_instance_destroyed() override;

View File

@@ -31,12 +31,17 @@
#include "openxr_htc_controller_extension.h" #include "openxr_htc_controller_extension.h"
#include "../action_map/openxr_interaction_profile_metadata.h" #include "../action_map/openxr_interaction_profile_metadata.h"
#include "../openxr_api.h"
HashMap<String, bool *> OpenXRHTCControllerExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRHTCControllerExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
request_extensions[XR_HTC_VIVE_COSMOS_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available[HTC_VIVE_COSMOS]; if (p_version < XR_API_VERSION_1_1_0) {
request_extensions[XR_HTC_VIVE_FOCUS3_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available[HTC_VIVE_FOCUS3]; // Extensions where promoted in OpenXR 1.1, only include it in OpenXR 1.0.
request_extensions[XR_HTC_VIVE_COSMOS_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available[HTC_VIVE_COSMOS];
request_extensions[XR_HTC_VIVE_FOCUS3_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available[HTC_VIVE_FOCUS3];
}
request_extensions[XR_HTC_HAND_INTERACTION_EXTENSION_NAME] = &available[HTC_HAND_INTERACTION]; request_extensions[XR_HTC_HAND_INTERACTION_EXTENSION_NAME] = &available[HTC_HAND_INTERACTION];
return request_extensions; return request_extensions;
@@ -63,11 +68,11 @@ void OpenXRHTCControllerExtension::on_register_metadata() {
{ // HTC Vive Cosmos controller { // HTC Vive Cosmos controller
const String profile_path = "/interaction_profiles/htc/vive_cosmos_controller"; const String profile_path = "/interaction_profiles/htc/vive_cosmos_controller";
openxr_metadata->register_interaction_profile("Vive Cosmos controller", profile_path, XR_HTC_VIVE_COSMOS_CONTROLLER_INTERACTION_EXTENSION_NAME); openxr_metadata->register_interaction_profile("Vive Cosmos controller", profile_path, XR_HTC_VIVE_COSMOS_CONTROLLER_INTERACTION_EXTENSION_NAME "," XR_OPENXR_1_1_NAME);
for (const String user_path : { "/user/hand/left", "/user/hand/right" }) { for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Shoulder click", user_path, user_path + "/input/shoulder/click", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "Shoulder click", user_path, user_path + "/input/shoulder/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
@@ -98,11 +103,11 @@ void OpenXRHTCControllerExtension::on_register_metadata() {
{ // HTC Vive Focus 3 controller { // HTC Vive Focus 3 controller
const String profile_path = "/interaction_profiles/htc/vive_focus3_controller"; const String profile_path = "/interaction_profiles/htc/vive_focus3_controller";
openxr_metadata->register_interaction_profile("Vive Focus 3 controller", profile_path, XR_HTC_VIVE_FOCUS3_CONTROLLER_INTERACTION_EXTENSION_NAME); openxr_metadata->register_interaction_profile("Vive Focus 3 controller", profile_path, XR_HTC_VIVE_FOCUS3_CONTROLLER_INTERACTION_EXTENSION_NAME "," XR_OPENXR_1_1_NAME);
for (const String user_path : { "/user/hand/left", "/user/hand/right" }) { for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Trigger", user_path, user_path + "/input/trigger/value", "", OpenXRAction::OPENXR_ACTION_FLOAT); openxr_metadata->register_io_path(profile_path, "Trigger", user_path, user_path + "/input/trigger/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
openxr_metadata->register_io_path(profile_path, "Trigger click", user_path, user_path + "/input/trigger/click", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "Trigger click", user_path, user_path + "/input/trigger/click", "", OpenXRAction::OPENXR_ACTION_BOOL);

View File

@@ -47,7 +47,7 @@ public:
HTC_MAX_CONTROLLERS HTC_MAX_CONTROLLERS
}; };
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
PackedStringArray get_suggested_tracker_names() override; PackedStringArray get_suggested_tracker_names() override;

View File

@@ -34,7 +34,7 @@
#include "core/string/print_string.h" #include "core/string/print_string.h"
HashMap<String, bool *> OpenXRHTCViveTrackerExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRHTCViveTrackerExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
request_extensions[XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME] = &available; request_extensions[XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME] = &available;

View File

@@ -39,7 +39,7 @@ protected:
static void _bind_methods() {} static void _bind_methods() {}
public: public:
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
PackedStringArray get_suggested_tracker_names() override; PackedStringArray get_suggested_tracker_names() override;

View File

@@ -31,8 +31,9 @@
#include "openxr_huawei_controller_extension.h" #include "openxr_huawei_controller_extension.h"
#include "../action_map/openxr_interaction_profile_metadata.h" #include "../action_map/openxr_interaction_profile_metadata.h"
#include "../openxr_api.h"
HashMap<String, bool *> OpenXRHuaweiControllerExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRHuaweiControllerExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
request_extensions[XR_HUAWEI_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available; request_extensions[XR_HUAWEI_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available;
@@ -55,6 +56,7 @@ void OpenXRHuaweiControllerExtension::on_register_metadata() {
openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Home click", user_path, user_path + "/input/home/click", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "Home click", user_path, user_path + "/input/home/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "Back click", user_path, user_path + "/input/back/click", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "Back click", user_path, user_path + "/input/back/click", "", OpenXRAction::OPENXR_ACTION_BOOL);

View File

@@ -39,7 +39,7 @@ protected:
static void _bind_methods() {} static void _bind_methods() {}
public: public:
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
bool is_available(); bool is_available();

View File

@@ -30,6 +30,8 @@
#include "openxr_local_floor_extension.h" #include "openxr_local_floor_extension.h"
#include "../openxr_api.h"
OpenXRLocalFloorExtension *OpenXRLocalFloorExtension::singleton = nullptr; OpenXRLocalFloorExtension *OpenXRLocalFloorExtension::singleton = nullptr;
OpenXRLocalFloorExtension *OpenXRLocalFloorExtension::get_singleton() { OpenXRLocalFloorExtension *OpenXRLocalFloorExtension::get_singleton() {
@@ -44,10 +46,13 @@ OpenXRLocalFloorExtension::~OpenXRLocalFloorExtension() {
singleton = nullptr; singleton = nullptr;
} }
HashMap<String, bool *> OpenXRLocalFloorExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRLocalFloorExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
request_extensions[XR_EXT_LOCAL_FLOOR_EXTENSION_NAME] = &available; if (p_version < XR_API_VERSION_1_1_0) {
// Extension was promoted in OpenXR 1.1, only include it in OpenXR 1.0.
request_extensions[XR_EXT_LOCAL_FLOOR_EXTENSION_NAME] = &available;
}
return request_extensions; return request_extensions;
} }

View File

@@ -44,7 +44,7 @@ public:
OpenXRLocalFloorExtension(); OpenXRLocalFloorExtension();
virtual ~OpenXRLocalFloorExtension() override; virtual ~OpenXRLocalFloorExtension() override;
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
bool is_available(); bool is_available();

View File

@@ -31,13 +31,30 @@
#include "openxr_meta_controller_extension.h" #include "openxr_meta_controller_extension.h"
#include "../action_map/openxr_interaction_profile_metadata.h" #include "../action_map/openxr_interaction_profile_metadata.h"
#include "../openxr_api.h"
HashMap<String, bool *> OpenXRMetaControllerExtension::get_requested_extensions() { const char *touch_controller = "/interaction_profiles/oculus/touch_controller";
const char *touch_pro_controller = "/interaction_profiles/meta/touch_pro_controller";
const char *touch_plus_controller = "/interaction_profiles/meta/touch_plus_controller";
const char *rift_cv1_controller = "/interaction_profiles/meta/touch_controller_rift_cv1";
const char *quest1_rift_s_controller = "/interaction_profiles/meta/touch_controller_quest_1_rift_s";
const char *quest2_controller = "/interaction_profiles/meta/touch_controller_quest_2";
// Vendor extension paths (promoted)
const char *touch_controller_pro_fb = "/interaction_profiles/facebook/touch_controller_pro";
const char *touch_controller_plus_fb = "/interaction_profiles/facebook/touch_controller_plus";
const char *touch_controller_plus_meta = "/interaction_profiles/meta/touch_controller_plus";
HashMap<String, bool *> OpenXRMetaControllerExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
if (p_version < XR_API_VERSION_1_1_0) {
// Extensions where promoted in OpenXR 1.1, only include it in OpenXR 1.0.
request_extensions[XR_FB_TOUCH_CONTROLLER_PRO_EXTENSION_NAME] = &available[META_TOUCH_PRO];
request_extensions[XR_META_TOUCH_CONTROLLER_PLUS_EXTENSION_NAME] = &available[META_TOUCH_PLUS];
}
request_extensions[XR_FB_TOUCH_CONTROLLER_PROXIMITY_EXTENSION_NAME] = &available[META_TOUCH_PROXIMITY]; request_extensions[XR_FB_TOUCH_CONTROLLER_PROXIMITY_EXTENSION_NAME] = &available[META_TOUCH_PROXIMITY];
request_extensions[XR_FB_TOUCH_CONTROLLER_PRO_EXTENSION_NAME] = &available[META_TOUCH_PRO];
request_extensions[XR_META_TOUCH_CONTROLLER_PLUS_EXTENSION_NAME] = &available[META_TOUCH_PLUS];
return request_extensions; return request_extensions;
} }
@@ -50,34 +67,69 @@ void OpenXRMetaControllerExtension::on_register_metadata() {
OpenXRInteractionProfileMetadata *openxr_metadata = OpenXRInteractionProfileMetadata::get_singleton(); OpenXRInteractionProfileMetadata *openxr_metadata = OpenXRInteractionProfileMetadata::get_singleton();
ERR_FAIL_NULL(openxr_metadata); ERR_FAIL_NULL(openxr_metadata);
// Note, we register controllers regardless if they are supported on the current hardware. // Note, we register controllers regardless if they are supported on the current hardware,
// this allows the editor to configure controllers for other platforms.
// Unsupported entries will be filtered out of the action map if applicable.
{ // Normal touch controller is part of the core spec, but we do have some extensions. // OpenXR 1.1 uses various new names for profile and input/output paths.
const String profile_path = "/interaction_profiles/oculus/touch_controller"; // We use these new names in our action map and translate back IF OpenXR 1.1 is not supported.
openxr_metadata->register_profile_rename(touch_controller_pro_fb, touch_pro_controller);
openxr_metadata->register_profile_rename(touch_controller_plus_fb, touch_controller_plus_meta); // This was an incorrect profile path that we need to correct.
openxr_metadata->register_profile_rename(touch_controller_plus_meta, touch_plus_controller);
openxr_metadata->register_path_rename("/user/hand/left/input/stylus_fb/force", "/user/hand/left/input/stylus/force");
openxr_metadata->register_path_rename("/user/hand/right/input/stylus_fb/force", "/user/hand/right/input/stylus/force");
openxr_metadata->register_path_rename("/user/hand/left/input/trigger/proximity_fb", "/user/hand/left/input/trigger/proximity");
openxr_metadata->register_path_rename("/user/hand/right/input/trigger/proximity_fb", "/user/hand/right/input/trigger/proximity");
openxr_metadata->register_path_rename("/user/hand/left/output/haptic_trigger_fb", "/user/hand/left/output/haptic_trigger");
openxr_metadata->register_path_rename("/user/hand/right/output/haptic_trigger_fb", "/user/hand/right/output/haptic_trigger");
openxr_metadata->register_path_rename("/user/hand/left/output/haptic_thumb_fb", "/user/hand/left/output/haptic_thumb");
openxr_metadata->register_path_rename("/user/hand/right/output/haptic_thumb_fb", "/user/hand/right/output/haptic_thumb");
openxr_metadata->register_path_rename("/user/hand/left/input/thumb_fb/proximity_fb", "/user/hand/left/input/thumb_resting_surfaces/proximity");
openxr_metadata->register_path_rename("/user/hand/right/input/thumb_fb/proximity_fb", "/user/hand/right/input/thumb_resting_surfaces/proximity");
openxr_metadata->register_path_rename("/user/hand/left/input/trigger/curl_fb", "/user/hand/left/input/trigger_curl/value");
openxr_metadata->register_path_rename("/user/hand/right/input/trigger/curl_fb", "/user/hand/right/input/trigger_curl/value");
openxr_metadata->register_path_rename("/user/hand/left/input/trigger/slide_fb", "/user/hand/left/input/trigger_slide/value");
openxr_metadata->register_path_rename("/user/hand/right/input/trigger/slide_fb", "/user/hand/right/input/trigger_slide/value");
openxr_metadata->register_path_rename("/user/hand/left/input/trigger/proximity_meta", "/user/hand/left/input/trigger/proximity");
openxr_metadata->register_path_rename("/user/hand/right/input/trigger/proximity_meta", "/user/hand/right/input/trigger/proximity");
openxr_metadata->register_path_rename("/user/hand/left/input/thumb_meta/proximity_meta", "/user/hand/left/input/thumb_resting_surfaces/proximity");
openxr_metadata->register_path_rename("/user/hand/right/input/thumb_meta/proximity_meta", "/user/hand/right/input/thumb_resting_surfaces/proximity");
openxr_metadata->register_path_rename("/user/hand/left/input/trigger/curl_meta", "/user/hand/left/input/trigger_curl/value");
openxr_metadata->register_path_rename("/user/hand/right/input/trigger/curl_meta", "/user/hand/right/input/trigger_curl/value");
openxr_metadata->register_path_rename("/user/hand/left/input/trigger/slide_meta", "/user/hand/left/input/trigger_slide/value");
openxr_metadata->register_path_rename("/user/hand/right/input/trigger/slide_meta", "/user/hand/right/input/trigger_slide/value");
{ // Normal touch controller is part of the core spec and still relies on the XR_FB_touch_controller_proximity extension for these two new paths.
const String profile_path = touch_controller;
for (const String user_path : { "/user/hand/left", "/user/hand/right" }) { for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
openxr_metadata->register_io_path(profile_path, "Trigger proximity", user_path, user_path + "/input/trigger/proximity_fb ", "XR_FB_touch_controller_proximity", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "Trigger proximity", user_path, user_path + "/input/trigger/proximity", XR_FB_TOUCH_CONTROLLER_PROXIMITY_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "Thumb proximity", user_path, user_path + "/input/thumb_fb/proximity_fb ", "XR_FB_touch_controller_proximity", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "Thumb proximity", user_path, user_path + "/input/thumb_resting_surfaces/proximity", XR_FB_TOUCH_CONTROLLER_PROXIMITY_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_BOOL);
} }
} }
{ // Touch controller pro (Quest Pro) { // Touch controller pro (Quest Pro)
const String profile_path = "/interaction_profiles/facebook/touch_controller_pro"; const String profile_path = touch_pro_controller;
openxr_metadata->register_interaction_profile("Touch controller pro", profile_path, "XR_FB_touch_controller_pro"); openxr_metadata->register_interaction_profile("Touch controller pro", profile_path, XR_FB_TOUCH_CONTROLLER_PRO_EXTENSION_NAME "," XR_OPENXR_1_1_NAME);
for (const String user_path : { "/user/hand/left", "/user/hand/right" }) { for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Pinch pose", user_path, user_path + "/input/pinch_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Poke pose", user_path, user_path + "/input/poke_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Trigger", user_path, user_path + "/input/trigger/value", "", OpenXRAction::OPENXR_ACTION_FLOAT); openxr_metadata->register_io_path(profile_path, "Trigger", user_path, user_path + "/input/trigger/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
openxr_metadata->register_io_path(profile_path, "Trigger touch", user_path, user_path + "/input/trigger/touch", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "Trigger touch", user_path, user_path + "/input/trigger/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "Trigger proximity", user_path, user_path + "/input/trigger/proximity_fb", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "Trigger proximity", user_path, user_path + "/input/trigger/proximity", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "Trigger curl", user_path, user_path + "/input/trigger/curl_fb", "", OpenXRAction::OPENXR_ACTION_FLOAT); openxr_metadata->register_io_path(profile_path, "Trigger curl", user_path, user_path + "/input/trigger_curl/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
openxr_metadata->register_io_path(profile_path, "Trigger slide", user_path, user_path + "/input/trigger/slide_fb", "", OpenXRAction::OPENXR_ACTION_FLOAT); openxr_metadata->register_io_path(profile_path, "Trigger slide", user_path, user_path + "/input/trigger_slide/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
openxr_metadata->register_io_path(profile_path, "Trigger force", user_path, user_path + "/input/trigger/force", "", OpenXRAction::OPENXR_ACTION_FLOAT); openxr_metadata->register_io_path(profile_path, "Trigger force", user_path, user_path + "/input/trigger/force", "", OpenXRAction::OPENXR_ACTION_FLOAT);
openxr_metadata->register_io_path(profile_path, "Squeeze", user_path, user_path + "/input/squeeze/value", "", OpenXRAction::OPENXR_ACTION_FLOAT); openxr_metadata->register_io_path(profile_path, "Squeeze", user_path, user_path + "/input/squeeze/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
openxr_metadata->register_io_path(profile_path, "Thumb proximity", user_path, user_path + "/input/thumb_fb/proximity_fb", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "Thumb proximity", user_path, user_path + "/input/thumb_resting_surfaces/proximity", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "Thumbstick", user_path, user_path + "/input/thumbstick", "", OpenXRAction::OPENXR_ACTION_VECTOR2); openxr_metadata->register_io_path(profile_path, "Thumbstick", user_path, user_path + "/input/thumbstick", "", OpenXRAction::OPENXR_ACTION_VECTOR2);
openxr_metadata->register_io_path(profile_path, "Thumbstick X", user_path, user_path + "/input/thumbstick/x", "", OpenXRAction::OPENXR_ACTION_FLOAT); openxr_metadata->register_io_path(profile_path, "Thumbstick X", user_path, user_path + "/input/thumbstick/x", "", OpenXRAction::OPENXR_ACTION_FLOAT);
@@ -92,11 +144,11 @@ void OpenXRMetaControllerExtension::on_register_metadata() {
openxr_metadata->register_io_path(profile_path, "Thumbrest touch", user_path, user_path + "/input/thumbrest/touch", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "Thumbrest touch", user_path, user_path + "/input/thumbrest/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "Thumbrest force", user_path, user_path + "/input/thumbrest/force", "", OpenXRAction::OPENXR_ACTION_FLOAT); openxr_metadata->register_io_path(profile_path, "Thumbrest force", user_path, user_path + "/input/thumbrest/force", "", OpenXRAction::OPENXR_ACTION_FLOAT);
openxr_metadata->register_io_path(profile_path, "Stylus force", user_path, user_path + "/input/stylus_fb/force", "", OpenXRAction::OPENXR_ACTION_FLOAT); openxr_metadata->register_io_path(profile_path, "Stylus force", user_path, user_path + "/input/stylus/force", "", OpenXRAction::OPENXR_ACTION_FLOAT);
openxr_metadata->register_io_path(profile_path, "Haptic output", user_path, user_path + "/output/haptic", "", OpenXRAction::OPENXR_ACTION_HAPTIC); openxr_metadata->register_io_path(profile_path, "Haptic output", user_path, user_path + "/output/haptic", "", OpenXRAction::OPENXR_ACTION_HAPTIC);
openxr_metadata->register_io_path(profile_path, "Haptic trigger output", user_path, user_path + "/output/haptic_trigger_fb", "", OpenXRAction::OPENXR_ACTION_HAPTIC); openxr_metadata->register_io_path(profile_path, "Haptic trigger output", user_path, user_path + "/output/haptic_trigger", "", OpenXRAction::OPENXR_ACTION_HAPTIC);
openxr_metadata->register_io_path(profile_path, "Haptic thumb output", user_path, user_path + "/output/haptic_thumb_fb", "", OpenXRAction::OPENXR_ACTION_HAPTIC); openxr_metadata->register_io_path(profile_path, "Haptic thumb output", user_path, user_path + "/output/haptic_thumb", "", OpenXRAction::OPENXR_ACTION_HAPTIC);
} }
openxr_metadata->register_io_path(profile_path, "Menu click", "/user/hand/left", "/user/hand/left/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "Menu click", "/user/hand/left", "/user/hand/left/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
@@ -112,24 +164,27 @@ void OpenXRMetaControllerExtension::on_register_metadata() {
openxr_metadata->register_io_path(profile_path, "B touch", "/user/hand/right", "/user/hand/right/input/b/touch", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "B touch", "/user/hand/right", "/user/hand/right/input/b/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
} }
{ // Touch controller plus (Quest 3) { // Touch controller plus (Quest 3 + 3S)
const String profile_path = "/interaction_profiles/meta/touch_controller_plus"; const String profile_path = touch_plus_controller;
openxr_metadata->register_interaction_profile("Touch controller plus", profile_path, "XR_META_touch_controller_plus"); openxr_metadata->register_interaction_profile("Touch controller plus", profile_path, XR_META_TOUCH_CONTROLLER_PLUS_EXTENSION_NAME "," XR_OPENXR_1_1_NAME);
for (const String user_path : { "/user/hand/left", "/user/hand/right" }) { for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Pinch pose", user_path, user_path + "/input/pinch_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Poke pose", user_path, user_path + "/input/poke_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Trigger", user_path, user_path + "/input/trigger/value", "", OpenXRAction::OPENXR_ACTION_FLOAT); openxr_metadata->register_io_path(profile_path, "Trigger", user_path, user_path + "/input/trigger/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
openxr_metadata->register_io_path(profile_path, "Trigger touch", user_path, user_path + "/input/trigger/touch", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "Trigger touch", user_path, user_path + "/input/trigger/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "Trigger proximity", user_path, user_path + "/input/trigger/proximity_meta", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "Trigger proximity", user_path, user_path + "/input/trigger/proximity", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "Trigger curl", user_path, user_path + "/input/trigger/curl_meta", "", OpenXRAction::OPENXR_ACTION_FLOAT); openxr_metadata->register_io_path(profile_path, "Trigger curl", user_path, user_path + "/input/trigger_curl/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
openxr_metadata->register_io_path(profile_path, "Trigger slide", user_path, user_path + "/input/trigger/slide_meta", "", OpenXRAction::OPENXR_ACTION_FLOAT); openxr_metadata->register_io_path(profile_path, "Trigger slide", user_path, user_path + "/input/trigger_slide/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
openxr_metadata->register_io_path(profile_path, "Trigger force", user_path, user_path + "/input/trigger/force", "", OpenXRAction::OPENXR_ACTION_FLOAT); openxr_metadata->register_io_path(profile_path, "Trigger force", user_path, user_path + "/input/trigger/force", "", OpenXRAction::OPENXR_ACTION_FLOAT);
openxr_metadata->register_io_path(profile_path, "Squeeze", user_path, user_path + "/input/squeeze/value", "", OpenXRAction::OPENXR_ACTION_FLOAT); openxr_metadata->register_io_path(profile_path, "Squeeze", user_path, user_path + "/input/squeeze/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
openxr_metadata->register_io_path(profile_path, "Thumb proximity", user_path, user_path + "/input/thumb_meta/proximity_meta", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "Thumb proximity", user_path, user_path + "/input/thumb_resting_surfaces/proximity", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "Thumbstick", user_path, user_path + "/input/thumbstick", "", OpenXRAction::OPENXR_ACTION_VECTOR2); openxr_metadata->register_io_path(profile_path, "Thumbstick", user_path, user_path + "/input/thumbstick", "", OpenXRAction::OPENXR_ACTION_VECTOR2);
openxr_metadata->register_io_path(profile_path, "Thumbstick X", user_path, user_path + "/input/thumbstick/x", "", OpenXRAction::OPENXR_ACTION_FLOAT); openxr_metadata->register_io_path(profile_path, "Thumbstick X", user_path, user_path + "/input/thumbstick/x", "", OpenXRAction::OPENXR_ACTION_FLOAT);
@@ -158,4 +213,57 @@ void OpenXRMetaControllerExtension::on_register_metadata() {
openxr_metadata->register_io_path(profile_path, "B click", "/user/hand/right", "/user/hand/right/input/b/click", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "B click", "/user/hand/right", "/user/hand/right/input/b/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "B touch", "/user/hand/right", "/user/hand/right/input/b/touch", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "B touch", "/user/hand/right", "/user/hand/right/input/b/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
} }
{
// In OpenXR 1.1 we have controller profiles for Meta legacy controllers. They are all the same as the normal touch controller profile.
openxr_metadata->register_interaction_profile("Touch controller Rift CV1", rift_cv1_controller, XR_OPENXR_1_1_NAME);
openxr_metadata->register_interaction_profile("Touch controller Quest 1 or Rift S", quest1_rift_s_controller, XR_OPENXR_1_1_NAME);
openxr_metadata->register_interaction_profile("Touch controller Quest 2", quest2_controller, XR_OPENXR_1_1_NAME);
for (const String profile_path : { rift_cv1_controller, quest1_rift_s_controller, quest2_controller }) {
for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Pinch pose", user_path, user_path + "/input/pinch_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Poke pose", user_path, user_path + "/input/poke_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Trigger", user_path, user_path + "/input/trigger/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
openxr_metadata->register_io_path(profile_path, "Trigger touch", user_path, user_path + "/input/trigger/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "Squeeze", user_path, user_path + "/input/squeeze/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);
// Note, unlike the default touch controller interaction profile, these are not dependent on the XR_FB_touch_controller_proximity extension!
openxr_metadata->register_io_path(profile_path, "Trigger proximity", user_path, user_path + "/input/trigger/proximity", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "Thumb proximity", user_path, user_path + "/input/thumb_resting_surfaces/proximity", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "Thumbstick", user_path, user_path + "/input/thumbstick", "", OpenXRAction::OPENXR_ACTION_VECTOR2);
openxr_metadata->register_io_path(profile_path, "Thumbstick X", user_path, user_path + "/input/thumbstick/x", "", OpenXRAction::OPENXR_ACTION_FLOAT);
openxr_metadata->register_io_path(profile_path, "Thumbstick Y", user_path, user_path + "/input/thumbstick/y", "", OpenXRAction::OPENXR_ACTION_FLOAT);
openxr_metadata->register_io_path(profile_path, "Thumbstick click", user_path, user_path + "/input/thumbstick/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "Thumbstick touch", user_path, user_path + "/input/thumbstick/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "Thumbstick Dpad Up", user_path, user_path + "/input/thumbstick/dpad_up", "XR_EXT_dpad_binding", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "Thumbstick Dpad Down", user_path, user_path + "/input/thumbstick/dpad_down", "XR_EXT_dpad_binding", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "Thumbstick Dpad Left", user_path, user_path + "/input/thumbstick/dpad_left", "XR_EXT_dpad_binding", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "Thumbstick Dpad Right", user_path, user_path + "/input/thumbstick/dpad_right", "XR_EXT_dpad_binding", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "Thumbrest touch", user_path, user_path + "/input/thumbrest/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "Haptic output", user_path, user_path + "/output/haptic", "", OpenXRAction::OPENXR_ACTION_HAPTIC);
}
openxr_metadata->register_io_path(profile_path, "Menu click", "/user/hand/left", "/user/hand/left/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "System click", "/user/hand/right", "/user/hand/right/input/system/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "X click", "/user/hand/left", "/user/hand/left/input/x/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "X touch", "/user/hand/left", "/user/hand/left/input/x/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "Y click", "/user/hand/left", "/user/hand/left/input/y/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "Y touch", "/user/hand/left", "/user/hand/left/input/y/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "A click", "/user/hand/right", "/user/hand/right/input/a/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "A touch", "/user/hand/right", "/user/hand/right/input/a/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "B click", "/user/hand/right", "/user/hand/right/input/b/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "B touch", "/user/hand/right", "/user/hand/right/input/b/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
}
}
} }

View File

@@ -46,7 +46,7 @@ public:
META_MAX_CONTROLLERS META_MAX_CONTROLLERS
}; };
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
bool is_available(MetaControllers p_type); bool is_available(MetaControllers p_type);

View File

@@ -31,11 +31,15 @@
#include "openxr_ml2_controller_extension.h" #include "openxr_ml2_controller_extension.h"
#include "../action_map/openxr_interaction_profile_metadata.h" #include "../action_map/openxr_interaction_profile_metadata.h"
#include "../openxr_api.h"
HashMap<String, bool *> OpenXRML2ControllerExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRML2ControllerExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
request_extensions[XR_ML_ML2_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available; if (p_version < XR_API_VERSION_1_1_0) {
// Extension was promoted in OpenXR 1.1, only include it in OpenXR 1.0.
request_extensions[XR_ML_ML2_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available;
}
return request_extensions; return request_extensions;
} }
@@ -50,7 +54,7 @@ void OpenXRML2ControllerExtension::on_register_metadata() {
// Magic Leap 2 Controller // Magic Leap 2 Controller
const String profile_path = "/interaction_profiles/ml/ml2_controller"; const String profile_path = "/interaction_profiles/ml/ml2_controller";
openxr_metadata->register_interaction_profile("Magic Leap 2 controller", profile_path, XR_ML_ML2_CONTROLLER_INTERACTION_EXTENSION_NAME); openxr_metadata->register_interaction_profile("Magic Leap 2 controller", profile_path, XR_ML_ML2_CONTROLLER_INTERACTION_EXTENSION_NAME "," XR_OPENXR_1_1_NAME);
for (const String user_path : { "/user/hand/left", "/user/hand/right" }) { for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);

View File

@@ -39,7 +39,7 @@ protected:
static void _bind_methods() {} static void _bind_methods() {}
public: public:
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
bool is_available(); bool is_available();

View File

@@ -35,7 +35,7 @@
// Not in base XR libs needs def // Not in base XR libs needs def
#define XR_LOGITECH_MX_INK_STYLUS_INTERACTION_EXTENSION_NAME "XR_LOGITECH_mx_ink_stylus_interaction" #define XR_LOGITECH_MX_INK_STYLUS_INTERACTION_EXTENSION_NAME "XR_LOGITECH_mx_ink_stylus_interaction"
HashMap<String, bool *> OpenXRMxInkExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRMxInkExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
request_extensions[XR_LOGITECH_MX_INK_STYLUS_INTERACTION_EXTENSION_NAME] = &available; request_extensions[XR_LOGITECH_MX_INK_STYLUS_INTERACTION_EXTENSION_NAME] = &available;

View File

@@ -39,7 +39,7 @@ protected:
static void _bind_methods() {} static void _bind_methods() {}
public: public:
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
bool is_available(); bool is_available();

View File

@@ -30,6 +30,8 @@
#include "openxr_palm_pose_extension.h" #include "openxr_palm_pose_extension.h"
#include "../openxr_api.h"
OpenXRPalmPoseExtension *OpenXRPalmPoseExtension::singleton = nullptr; OpenXRPalmPoseExtension *OpenXRPalmPoseExtension::singleton = nullptr;
OpenXRPalmPoseExtension *OpenXRPalmPoseExtension::get_singleton() { OpenXRPalmPoseExtension *OpenXRPalmPoseExtension::get_singleton() {
@@ -44,10 +46,13 @@ OpenXRPalmPoseExtension::~OpenXRPalmPoseExtension() {
singleton = nullptr; singleton = nullptr;
} }
HashMap<String, bool *> OpenXRPalmPoseExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRPalmPoseExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
request_extensions[XR_EXT_PALM_POSE_EXTENSION_NAME] = &available; if (p_version < XR_API_VERSION_1_1_0) {
// Extension was promoted in OpenXR 1.1, only include it in OpenXR 1.0.
request_extensions[XR_EXT_PALM_POSE_EXTENSION_NAME] = &available;
}
return request_extensions; return request_extensions;
} }

View File

@@ -44,7 +44,7 @@ public:
OpenXRPalmPoseExtension(); OpenXRPalmPoseExtension();
virtual ~OpenXRPalmPoseExtension() override; virtual ~OpenXRPalmPoseExtension() override;
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
bool is_available(); bool is_available();

View File

@@ -46,7 +46,7 @@ OpenXRPerformanceSettingsExtension::~OpenXRPerformanceSettingsExtension() {
singleton = nullptr; singleton = nullptr;
} }
HashMap<String, bool *> OpenXRPerformanceSettingsExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRPerformanceSettingsExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
request_extensions[XR_EXT_PERFORMANCE_SETTINGS_EXTENSION_NAME] = &available; request_extensions[XR_EXT_PERFORMANCE_SETTINGS_EXTENSION_NAME] = &available;

View File

@@ -41,7 +41,7 @@ public:
OpenXRPerformanceSettingsExtension(); OpenXRPerformanceSettingsExtension();
virtual ~OpenXRPerformanceSettingsExtension() override; virtual ~OpenXRPerformanceSettingsExtension() override;
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
virtual void on_instance_created(const XrInstance p_instance) override; virtual void on_instance_created(const XrInstance p_instance) override;
virtual bool on_event_polled(const XrEventDataBuffer &event) override; virtual bool on_event_polled(const XrEventDataBuffer &event) override;

View File

@@ -31,15 +31,20 @@
#include "openxr_pico_controller_extension.h" #include "openxr_pico_controller_extension.h"
#include "../action_map/openxr_interaction_profile_metadata.h" #include "../action_map/openxr_interaction_profile_metadata.h"
#include "../openxr_api.h"
HashMap<String, bool *> OpenXRPicoControllerExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRPicoControllerExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
// Note, this used to be XR_PICO_controller_interaction but that has since been retired // Note, this used to be XR_PICO_controller_interaction but that has since been retired
// and was never part of the OpenXX specification. // and was never part of the OpenXX specification.
// All PICO devices should be updated to an OS supporting the official extension. // All PICO devices should be updated to an OS supporting the official extension.
request_extensions[XR_BD_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available; if (true || p_version < XR_API_VERSION_1_1_0) {
// Extension was promoted in OpenXR 1.1, only include it in OpenXR 1.0.
// Note, we still need it for pico4_interaction, hence the temporary `if (true || ...`
request_extensions[XR_BD_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available;
}
return request_extensions; return request_extensions;
} }
@@ -57,11 +62,11 @@ void OpenXRPicoControllerExtension::on_register_metadata() {
{ // Pico neo 3 controller. { // Pico neo 3 controller.
const String profile_path = "/interaction_profiles/bytedance/pico_neo3_controller"; const String profile_path = "/interaction_profiles/bytedance/pico_neo3_controller";
openxr_metadata->register_interaction_profile("Pico Neo3 controller", profile_path, XR_BD_CONTROLLER_INTERACTION_EXTENSION_NAME); openxr_metadata->register_interaction_profile("Pico Neo3 controller", profile_path, XR_BD_CONTROLLER_INTERACTION_EXTENSION_NAME "," XR_OPENXR_1_1_NAME);
for (const String user_path : { "/user/hand/left", "/user/hand/right" }) { for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
openxr_metadata->register_io_path(profile_path, "System click", user_path, user_path + "/input/system/click", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "System click", user_path, user_path + "/input/system/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
@@ -94,11 +99,11 @@ void OpenXRPicoControllerExtension::on_register_metadata() {
{ // Pico 4 controller. { // Pico 4 controller.
const String profile_path = "/interaction_profiles/bytedance/pico4_controller"; const String profile_path = "/interaction_profiles/bytedance/pico4_controller";
openxr_metadata->register_interaction_profile("Pico 4 controller", profile_path, XR_BD_CONTROLLER_INTERACTION_EXTENSION_NAME); openxr_metadata->register_interaction_profile("Pico 4 controller", profile_path, XR_BD_CONTROLLER_INTERACTION_EXTENSION_NAME "," XR_OPENXR_1_1_NAME);
for (const String user_path : { "/user/hand/left", "/user/hand/right" }) { for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "System click", user_path, user_path + "/input/system/click", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "System click", user_path, user_path + "/input/system/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
@@ -131,13 +136,13 @@ void OpenXRPicoControllerExtension::on_register_metadata() {
openxr_metadata->register_io_path(profile_path, "B touch", "/user/hand/right", "/user/hand/right/input/b/touch", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "B touch", "/user/hand/right", "/user/hand/right/input/b/touch", "", OpenXRAction::OPENXR_ACTION_BOOL);
} }
{ // Pico 4 Ultra controller. { // Pico 4 Ultra controller, note: not provided by OpenXR 1.1
const String profile_path = "/interaction_profiles/bytedance/pico4s_controller"; const String profile_path = "/interaction_profiles/bytedance/pico4s_controller";
openxr_metadata->register_interaction_profile("Pico 4 Ultra controller", profile_path, XR_BD_CONTROLLER_INTERACTION_EXTENSION_NAME); openxr_metadata->register_interaction_profile("Pico 4 Ultra controller", profile_path, XR_BD_CONTROLLER_INTERACTION_EXTENSION_NAME);
for (const String user_path : { "/user/hand/left", "/user/hand/right" }) { for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "System click", user_path, user_path + "/input/system/click", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "System click", user_path, user_path + "/input/system/click", "", OpenXRAction::OPENXR_ACTION_BOOL);

View File

@@ -39,7 +39,7 @@ protected:
static void _bind_methods() {} static void _bind_methods() {}
public: public:
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
bool is_available(); bool is_available();

View File

@@ -71,11 +71,14 @@ OpenXRRenderModelExtension::~OpenXRRenderModelExtension() {
singleton = nullptr; singleton = nullptr;
} }
HashMap<String, bool *> OpenXRRenderModelExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRRenderModelExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
if (GLOBAL_GET("xr/openxr/extensions/render_model")) { if (GLOBAL_GET("xr/openxr/extensions/render_model")) {
request_extensions[XR_EXT_UUID_EXTENSION_NAME] = &uuid_ext; if (p_version < XR_API_VERSION_1_1_0) {
// Extension was promoted in OpenXR 1.1, only include it in OpenXR 1.0.
request_extensions[XR_EXT_UUID_EXTENSION_NAME] = &uuid_ext;
}
request_extensions[XR_EXT_RENDER_MODEL_EXTENSION_NAME] = &render_model_ext; request_extensions[XR_EXT_RENDER_MODEL_EXTENSION_NAME] = &render_model_ext;
request_extensions[XR_EXT_INTERACTION_RENDER_MODEL_EXTENSION_NAME] = &interaction_render_model_ext; request_extensions[XR_EXT_INTERACTION_RENDER_MODEL_EXTENSION_NAME] = &interaction_render_model_ext;
} }

View File

@@ -74,7 +74,7 @@ public:
OpenXRRenderModelExtension(); OpenXRRenderModelExtension();
virtual ~OpenXRRenderModelExtension() override; virtual ~OpenXRRenderModelExtension() override;
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
virtual void on_instance_created(const XrInstance p_instance) override; virtual void on_instance_created(const XrInstance p_instance) override;
virtual void on_session_created(const XrSession p_session) override; virtual void on_session_created(const XrSession p_session) override;

View File

@@ -53,7 +53,7 @@ OpenXRValveAnalogThresholdExtension::~OpenXRValveAnalogThresholdExtension() {
singleton = nullptr; singleton = nullptr;
} }
HashMap<String, bool *> OpenXRValveAnalogThresholdExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRValveAnalogThresholdExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
// Note, we're dependent on the binding modifier extension, this may be requested by multiple extension wrappers. // Note, we're dependent on the binding modifier extension, this may be requested by multiple extension wrappers.

View File

@@ -48,7 +48,7 @@ public:
OpenXRValveAnalogThresholdExtension(); OpenXRValveAnalogThresholdExtension();
virtual ~OpenXRValveAnalogThresholdExtension() override; virtual ~OpenXRValveAnalogThresholdExtension() override;
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
bool is_available(); bool is_available();

View File

@@ -69,7 +69,7 @@ OpenXRVisibilityMaskExtension::~OpenXRVisibilityMaskExtension() {
singleton = nullptr; singleton = nullptr;
} }
HashMap<String, bool *> OpenXRVisibilityMaskExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRVisibilityMaskExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
request_extensions[XR_KHR_VISIBILITY_MASK_EXTENSION_NAME] = &available; request_extensions[XR_KHR_VISIBILITY_MASK_EXTENSION_NAME] = &available;

View File

@@ -58,7 +58,7 @@ public:
OpenXRVisibilityMaskExtension(); OpenXRVisibilityMaskExtension();
virtual ~OpenXRVisibilityMaskExtension() override; virtual ~OpenXRVisibilityMaskExtension() override;
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
virtual void on_instance_created(const XrInstance p_instance) override; virtual void on_instance_created(const XrInstance p_instance) override;

View File

@@ -31,13 +31,17 @@
#include "openxr_wmr_controller_extension.h" #include "openxr_wmr_controller_extension.h"
#include "../action_map/openxr_interaction_profile_metadata.h" #include "../action_map/openxr_interaction_profile_metadata.h"
#include "../openxr_api.h"
HashMap<String, bool *> OpenXRWMRControllerExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRWMRControllerExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
// Note HP G2 is available on WMR and SteamVR, but Odessey is only available on WMR // Note HP G2 is available on WMR and SteamVR, but Odessey is only available on WMR
request_extensions[XR_EXT_HP_MIXED_REALITY_CONTROLLER_EXTENSION_NAME] = &available[WMR_HPMR]; if (p_version < XR_API_VERSION_1_1_0) {
request_extensions[XR_EXT_SAMSUNG_ODYSSEY_CONTROLLER_EXTENSION_NAME] = &available[WMR_SAMSUNG_ODESSY]; // Extensions where promoted in OpenXR 1.1, only include it in OpenXR 1.0.
request_extensions[XR_EXT_HP_MIXED_REALITY_CONTROLLER_EXTENSION_NAME] = &available[WMR_HPMR];
request_extensions[XR_EXT_SAMSUNG_ODYSSEY_CONTROLLER_EXTENSION_NAME] = &available[WMR_SAMSUNG_ODESSY];
}
request_extensions[XR_MSFT_HAND_INTERACTION_EXTENSION_NAME] = &available[WMR_HAND_INTERACTION]; request_extensions[XR_MSFT_HAND_INTERACTION_EXTENSION_NAME] = &available[WMR_HAND_INTERACTION];
return request_extensions; return request_extensions;
@@ -53,11 +57,11 @@ void OpenXRWMRControllerExtension::on_register_metadata() {
{ // HP MR controller (newer G2 controllers) { // HP MR controller (newer G2 controllers)
const String profile_path = "/interaction_profiles/hp/mixed_reality_controller"; const String profile_path = "/interaction_profiles/hp/mixed_reality_controller";
openxr_metadata->register_interaction_profile("HPMR controller", profile_path, XR_EXT_HP_MIXED_REALITY_CONTROLLER_EXTENSION_NAME); openxr_metadata->register_interaction_profile("HPMR controller", profile_path, XR_EXT_HP_MIXED_REALITY_CONTROLLER_EXTENSION_NAME "," XR_OPENXR_1_1_NAME);
for (const String user_path : { "/user/hand/left", "/user/hand/right" }) { for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
@@ -84,11 +88,11 @@ void OpenXRWMRControllerExtension::on_register_metadata() {
{ // Samsung Odyssey controller { // Samsung Odyssey controller
const String profile_path = "/interaction_profiles/samsung/odyssey_controller"; const String profile_path = "/interaction_profiles/samsung/odyssey_controller";
openxr_metadata->register_interaction_profile("Samsung Odyssey controller", profile_path, XR_EXT_SAMSUNG_ODYSSEY_CONTROLLER_EXTENSION_NAME); openxr_metadata->register_interaction_profile("Samsung Odyssey controller", profile_path, XR_EXT_SAMSUNG_ODYSSEY_CONTROLLER_EXTENSION_NAME "," XR_OPENXR_1_1_NAME);
for (const String user_path : { "/user/hand/left", "/user/hand/right" }) { for (const String user_path : { "/user/hand/left", "/user/hand/right" }) {
openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Grip pose", user_path, user_path + "/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "Menu click", user_path, user_path + "/input/menu/click", "", OpenXRAction::OPENXR_ACTION_BOOL);
@@ -125,7 +129,7 @@ void OpenXRWMRControllerExtension::on_register_metadata() {
openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Aim pose", user_path, user_path + "/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Pinch pose", user_path, user_path + "/input/pinch_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Pinch pose", user_path, user_path + "/input/pinch_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Poke pose", user_path, user_path + "/input/poke_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Poke pose", user_path, user_path + "/input/poke_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Palm pose", user_path, user_path + "/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); openxr_metadata->register_io_path(profile_path, "Grip surface pose", user_path, user_path + "/input/grip_surface/pose", XR_EXT_PALM_POSE_EXTENSION_NAME "," XR_KHR_MAINTENANCE1_EXTENSION_NAME "," XR_OPENXR_1_1_NAME, OpenXRAction::OPENXR_ACTION_POSE);
openxr_metadata->register_io_path(profile_path, "Select (pinch)", user_path, user_path + "/input/select/value", "", OpenXRAction::OPENXR_ACTION_FLOAT); openxr_metadata->register_io_path(profile_path, "Select (pinch)", user_path, user_path + "/input/select/value", "", OpenXRAction::OPENXR_ACTION_FLOAT);

View File

@@ -46,7 +46,7 @@ public:
WMR_MAX_CONTROLLERS WMR_MAX_CONTROLLERS
}; };
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
bool is_available(WMRControllers p_type); bool is_available(WMRControllers p_type);

View File

@@ -55,7 +55,7 @@ OpenXRAndroidExtension::OpenXRAndroidExtension() {
activity_object = env->NewGlobalRef(static_cast<OS_Android *>(OS::get_singleton())->get_godot_java()->get_activity()); activity_object = env->NewGlobalRef(static_cast<OS_Android *>(OS::get_singleton())->get_godot_java()->get_activity());
} }
HashMap<String, bool *> OpenXRAndroidExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRAndroidExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
// XR_KHR_LOADER_INIT_EXTENSION_NAME is a dependency of XR_KHR_LOADER_INIT_ANDROID_EXTENSION_NAME // XR_KHR_LOADER_INIT_EXTENSION_NAME is a dependency of XR_KHR_LOADER_INIT_ANDROID_EXTENSION_NAME
@@ -87,7 +87,7 @@ void OpenXRAndroidExtension::on_before_instance_created() {
// This is reasonably safe as the struct is only used during initialization and the extension is a singleton. // This is reasonably safe as the struct is only used during initialization and the extension is a singleton.
static XrInstanceCreateInfoAndroidKHR instance_create_info; static XrInstanceCreateInfoAndroidKHR instance_create_info;
void *OpenXRAndroidExtension::set_instance_create_info_and_get_next_pointer(void *p_next_pointer) { void *OpenXRAndroidExtension::set_instance_create_info_and_get_next_pointer(XrVersion p_xr_version, void *p_next_pointer) {
if (!create_instance_extension_available) { if (!create_instance_extension_available) {
if (!loader_init_android_extension_available) { if (!loader_init_android_extension_available) {
WARN_PRINT("No Android extensions available, couldn't pass JVM and Activity to OpenXR"); WARN_PRINT("No Android extensions available, couldn't pass JVM and Activity to OpenXR");

View File

@@ -41,9 +41,9 @@ public:
OpenXRAndroidExtension(); OpenXRAndroidExtension();
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
virtual void on_before_instance_created() override; virtual void on_before_instance_created() override;
virtual void *set_instance_create_info_and_get_next_pointer(void *p_next_pointer) override; virtual void *set_instance_create_info_and_get_next_pointer(XrVersion p_xr_version, void *p_next_pointer) override;
virtual ~OpenXRAndroidExtension() override; virtual ~OpenXRAndroidExtension() override;

View File

@@ -37,7 +37,7 @@
#include "servers/rendering/rendering_server.h" #include "servers/rendering/rendering_server.h"
#include "servers/rendering/rendering_server_globals.h" #include "servers/rendering/rendering_server_globals.h"
HashMap<String, bool *> OpenXRD3D12Extension::get_requested_extensions() { HashMap<String, bool *> OpenXRD3D12Extension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
request_extensions[XR_KHR_D3D12_ENABLE_EXTENSION_NAME] = nullptr; request_extensions[XR_KHR_D3D12_ENABLE_EXTENSION_NAME] = nullptr;

View File

@@ -44,7 +44,7 @@
class OpenXRD3D12Extension : public OpenXRGraphicsExtensionWrapper, D3D12Hooks { class OpenXRD3D12Extension : public OpenXRGraphicsExtensionWrapper, D3D12Hooks {
public: public:
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
virtual void on_instance_created(const XrInstance p_instance) override; virtual void on_instance_created(const XrInstance p_instance) override;
virtual void *set_session_create_and_get_next_pointer(void *p_next_pointer) override; virtual void *set_session_create_and_get_next_pointer(void *p_next_pointer) override;

View File

@@ -41,7 +41,7 @@
class OpenXRMetalExtension : public OpenXRGraphicsExtensionWrapper { class OpenXRMetalExtension : public OpenXRGraphicsExtensionWrapper {
public: public:
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
virtual void on_instance_created(const XrInstance p_instance) override; virtual void on_instance_created(const XrInstance p_instance) override;
virtual void *set_session_create_and_get_next_pointer(void *p_next_pointer) override; virtual void *set_session_create_and_get_next_pointer(void *p_next_pointer) override;

View File

@@ -35,7 +35,7 @@
#import "drivers/metal/rendering_device_driver_metal.h" #import "drivers/metal/rendering_device_driver_metal.h"
#include "servers/rendering/rendering_server_globals.h" #include "servers/rendering/rendering_server_globals.h"
HashMap<String, bool *> OpenXRMetalExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRMetalExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
request_extensions[XR_KHR_METAL_ENABLE_EXTENSION_NAME] = nullptr; request_extensions[XR_KHR_METAL_ENABLE_EXTENSION_NAME] = nullptr;

View File

@@ -56,7 +56,7 @@
// feature off. // feature off.
// See: https://registry.khronos.org/OpenGL/extensions/EXT/EXT_sRGB_write_control.txt // See: https://registry.khronos.org/OpenGL/extensions/EXT/EXT_sRGB_write_control.txt
HashMap<String, bool *> OpenXROpenGLExtension::get_requested_extensions() { HashMap<String, bool *> OpenXROpenGLExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
#ifdef ANDROID_ENABLED #ifdef ANDROID_ENABLED

View File

@@ -43,7 +43,7 @@
class OpenXROpenGLExtension : public OpenXRGraphicsExtensionWrapper { class OpenXROpenGLExtension : public OpenXRGraphicsExtensionWrapper {
public: public:
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
virtual void on_instance_created(const XrInstance p_instance) override; virtual void on_instance_created(const XrInstance p_instance) override;
virtual void *set_session_create_and_get_next_pointer(void *p_next_pointer) override; virtual void *set_session_create_and_get_next_pointer(void *p_next_pointer) override;

View File

@@ -39,7 +39,7 @@
#include "servers/rendering/rendering_server.h" #include "servers/rendering/rendering_server.h"
#include "servers/rendering/rendering_server_globals.h" #include "servers/rendering/rendering_server_globals.h"
HashMap<String, bool *> OpenXRVulkanExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRVulkanExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
request_extensions[XR_KHR_VULKAN_ENABLE2_EXTENSION_NAME] = nullptr; // must be available request_extensions[XR_KHR_VULKAN_ENABLE2_EXTENSION_NAME] = nullptr; // must be available

View File

@@ -45,7 +45,7 @@ public:
OpenXRVulkanExtension() = default; OpenXRVulkanExtension() = default;
virtual ~OpenXRVulkanExtension() override = default; virtual ~OpenXRVulkanExtension() override = default;
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
virtual void on_instance_created(const XrInstance p_instance) override; virtual void on_instance_created(const XrInstance p_instance) override;
virtual void *set_session_create_and_get_next_pointer(void *p_next_pointer) override; virtual void *set_session_create_and_get_next_pointer(void *p_next_pointer) override;

View File

@@ -332,7 +332,7 @@ void OpenXRSpatialAnchorCapability::_bind_methods() {
BIND_ENUM_CONSTANT(PERSISTENCE_SCOPE_LOCAL_ANCHORS); BIND_ENUM_CONSTANT(PERSISTENCE_SCOPE_LOCAL_ANCHORS);
} }
HashMap<String, bool *> OpenXRSpatialAnchorCapability::get_requested_extensions() { HashMap<String, bool *> OpenXRSpatialAnchorCapability::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
if (GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enabled") && GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enable_spatial_anchors")) { if (GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enabled") && GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enable_spatial_anchors")) {

View File

@@ -158,7 +158,7 @@ public:
OpenXRSpatialAnchorCapability(); OpenXRSpatialAnchorCapability();
virtual ~OpenXRSpatialAnchorCapability() override; virtual ~OpenXRSpatialAnchorCapability() override;
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
virtual void on_instance_created(const XrInstance p_instance) override; virtual void on_instance_created(const XrInstance p_instance) override;
virtual void on_instance_destroyed() override; virtual void on_instance_destroyed() override;

View File

@@ -106,7 +106,7 @@ OpenXRSpatialEntityExtension::~OpenXRSpatialEntityExtension() {
singleton = nullptr; singleton = nullptr;
} }
HashMap<String, bool *> OpenXRSpatialEntityExtension::get_requested_extensions() { HashMap<String, bool *> OpenXRSpatialEntityExtension::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
if (GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enabled")) { if (GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enabled")) {

View File

@@ -69,7 +69,7 @@ public:
OpenXRSpatialEntityExtension(); OpenXRSpatialEntityExtension();
virtual ~OpenXRSpatialEntityExtension() override; virtual ~OpenXRSpatialEntityExtension() override;
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
virtual void on_instance_created(const XrInstance p_instance) override; virtual void on_instance_created(const XrInstance p_instance) override;
virtual void on_instance_destroyed() override; virtual void on_instance_destroyed() override;

View File

@@ -444,7 +444,7 @@ void OpenXRSpatialMarkerTrackingCapability::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_april_tag_supported"), &OpenXRSpatialMarkerTrackingCapability::is_april_tag_supported); ClassDB::bind_method(D_METHOD("is_april_tag_supported"), &OpenXRSpatialMarkerTrackingCapability::is_april_tag_supported);
} }
HashMap<String, bool *> OpenXRSpatialMarkerTrackingCapability::get_requested_extensions() { HashMap<String, bool *> OpenXRSpatialMarkerTrackingCapability::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
if (GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enabled") && GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enable_marker_tracking")) { if (GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enabled") && GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enable_marker_tracking")) {

View File

@@ -228,7 +228,7 @@ public:
OpenXRSpatialMarkerTrackingCapability(); OpenXRSpatialMarkerTrackingCapability();
virtual ~OpenXRSpatialMarkerTrackingCapability() override; virtual ~OpenXRSpatialMarkerTrackingCapability() override;
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
virtual void on_session_created(const XrSession p_session) override; virtual void on_session_created(const XrSession p_session) override;
virtual void on_session_destroyed() override; virtual void on_session_destroyed() override;

View File

@@ -583,7 +583,7 @@ void OpenXRSpatialPlaneTrackingCapability::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_supported"), &OpenXRSpatialPlaneTrackingCapability::is_supported); ClassDB::bind_method(D_METHOD("is_supported"), &OpenXRSpatialPlaneTrackingCapability::is_supported);
} }
HashMap<String, bool *> OpenXRSpatialPlaneTrackingCapability::get_requested_extensions() { HashMap<String, bool *> OpenXRSpatialPlaneTrackingCapability::get_requested_extensions(XrVersion p_version) {
HashMap<String, bool *> request_extensions; HashMap<String, bool *> request_extensions;
if (GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enabled") && GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enable_plane_tracking")) { if (GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enabled") && GLOBAL_GET_CACHED(bool, "xr/openxr/extensions/spatial_entity/enable_plane_tracking")) {

View File

@@ -219,7 +219,7 @@ public:
OpenXRSpatialPlaneTrackingCapability(); OpenXRSpatialPlaneTrackingCapability();
virtual ~OpenXRSpatialPlaneTrackingCapability() override; virtual ~OpenXRSpatialPlaneTrackingCapability() override;
virtual HashMap<String, bool *> get_requested_extensions() override; virtual HashMap<String, bool *> get_requested_extensions(XrVersion p_version) override;
virtual void on_session_created(const XrSession p_session) override; virtual void on_session_created(const XrSession p_session) override;
virtual void on_session_destroyed() override; virtual void on_session_destroyed() override;

View File

@@ -445,11 +445,14 @@ bool OpenXRAPI::is_extension_supported(const String &p_extension) const {
return false; return false;
} }
bool OpenXRAPI::is_extension_enabled(const String &p_extension) const { bool OpenXRAPI::is_any_extension_enabled(const String &p_extensions) const {
CharString extension = p_extension.ascii(); // We allow a comma separated list of extensions here, only one needs to be supported.
// This allows us to check for extensions that were renamed or that were embedded in core
// at a specific OpenXR version.
for (const String &name : p_extensions.split(",", false)) {
CharString extension = name.utf8();
for (int i = 0; i < enabled_extensions.size(); i++) { if (enabled_extensions.has(extension)) {
if (strcmp(enabled_extensions[i].ptr(), extension.ptr()) == 0) {
return true; return true;
} }
} }
@@ -458,19 +461,19 @@ bool OpenXRAPI::is_extension_enabled(const String &p_extension) const {
} }
bool OpenXRAPI::is_top_level_path_supported(const String &p_toplevel_path) { bool OpenXRAPI::is_top_level_path_supported(const String &p_toplevel_path) {
String required_extension = OpenXRInteractionProfileMetadata::get_singleton()->get_top_level_extension(p_toplevel_path); String required_extensions = OpenXRInteractionProfileMetadata::get_singleton()->get_top_level_extensions(p_toplevel_path);
// If unsupported is returned we likely have a misspelled interaction profile path in our action map. Always output that as an error. // If unsupported is returned we likely have a misspelled interaction profile path in our action map. Always output that as an error.
ERR_FAIL_COND_V_MSG(required_extension == XR_PATH_UNSUPPORTED_NAME, false, "OpenXR: Unsupported toplevel path " + p_toplevel_path); ERR_FAIL_COND_V_MSG(required_extensions == XR_PATH_UNSUPPORTED_NAME, false, "OpenXR: Unsupported toplevel path " + p_toplevel_path);
if (required_extension == "") { if (required_extensions == "") {
// no extension needed, core top level are always "supported", they just won't be used if not really supported // no extension needed, core top level are always "supported", they just won't be used if not really supported
return true; return true;
} }
if (!is_extension_enabled(required_extension)) { if (!is_any_extension_enabled(required_extensions)) {
// It is very likely we have top level paths for which the extension is not available so don't flood the logs with unnecessary spam. // It is very likely we have top level paths for which the extension is not available so don't flood the logs with unnecessary spam.
print_verbose("OpenXR: Top level path " + p_toplevel_path + " requires extension " + required_extension); print_verbose("OpenXR: Top level path " + p_toplevel_path + " requires extension " + required_extensions.replace(",", " or "));
return false; return false;
} }
@@ -478,19 +481,19 @@ bool OpenXRAPI::is_top_level_path_supported(const String &p_toplevel_path) {
} }
bool OpenXRAPI::is_interaction_profile_supported(const String &p_ip_path) { bool OpenXRAPI::is_interaction_profile_supported(const String &p_ip_path) {
String required_extension = OpenXRInteractionProfileMetadata::get_singleton()->get_interaction_profile_extension(p_ip_path); String required_extensions = OpenXRInteractionProfileMetadata::get_singleton()->get_interaction_profile_extensions(p_ip_path);
// If unsupported is returned we likely have a misspelled interaction profile path in our action map. Always output that as an error. // If unsupported is returned we likely have a misspelled interaction profile path in our action map. Always output that as an error.
ERR_FAIL_COND_V_MSG(required_extension == XR_PATH_UNSUPPORTED_NAME, false, "OpenXR: Unsupported interaction profile " + p_ip_path); ERR_FAIL_COND_V_MSG(required_extensions == XR_PATH_UNSUPPORTED_NAME, false, "OpenXR: Unsupported interaction profile " + p_ip_path);
if (required_extension == "") { if (required_extensions == "") {
// no extension needed, core interaction profiles are always "supported", they just won't be used if not really supported // no extension needed, core interaction profiles are always "supported", they just won't be used if not really supported
return true; return true;
} }
if (!is_extension_enabled(required_extension)) { if (!is_any_extension_enabled(required_extensions)) {
// It is very likely we have interaction profiles for which the extension is not available so don't flood the logs with unnecessary spam. // It is very likely we have interaction profiles for which the extension is not available so don't flood the logs with unnecessary spam.
print_verbose("OpenXR: Interaction profile " + p_ip_path + " requires extension " + required_extension); print_verbose("OpenXR: Interaction profile " + p_ip_path + " requires extension " + required_extensions.replace(",", " or "));
return false; return false;
} }
@@ -507,14 +510,14 @@ bool OpenXRAPI::interaction_profile_supports_io_path(const String &p_ip_path, co
// If the io_path is not part of our metadata we've likely got a misspelled name or a bad action map, report // If the io_path is not part of our metadata we've likely got a misspelled name or a bad action map, report
ERR_FAIL_NULL_V_MSG(io_path, false, "OpenXR: Unsupported io path " + String(p_ip_path) + String(p_io_path)); ERR_FAIL_NULL_V_MSG(io_path, false, "OpenXR: Unsupported io path " + String(p_ip_path) + String(p_io_path));
if (io_path->openxr_extension_name == "") { if (io_path->openxr_extension_names == "") {
// no extension needed, core io paths are always "supported", they just won't be used if not really supported // no extension needed, core io paths are always "supported", they just won't be used if not really supported
return true; return true;
} }
if (!is_extension_enabled(io_path->openxr_extension_name)) { if (!is_any_extension_enabled(io_path->openxr_extension_names)) {
// It is very likely we have io paths for which the extension is not available so don't flood the logs with unnecessary spam. // It is very likely we have io paths for which the extension is not available so don't flood the logs with unnecessary spam.
print_verbose("OpenXR: IO path " + String(p_ip_path) + String(p_io_path) + " requires extension " + io_path->openxr_extension_name); print_verbose("OpenXR: IO path " + String(p_ip_path) + String(p_io_path) + " requires extension " + io_path->openxr_extension_names.replace(",", " or "));
return false; return false;
} }
@@ -534,13 +537,13 @@ void OpenXRAPI::copy_string_to_char_buffer(const String &p_string, char *p_buffe
} }
} }
PackedStringArray OpenXRAPI::get_all_requested_extensions() { PackedStringArray OpenXRAPI::get_all_requested_extensions(XrVersion p_xr_version) {
// This returns all extensions we will request regardless of whether they are available. // This returns all extensions we will request regardless of whether they are available.
// This is mostly used by the editor to filter features not enabled through project settings. // This is used by the editor to filter features not enabled through project settings.
PackedStringArray requested_extensions; PackedStringArray requested_extensions;
for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) { for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
const HashMap<String, bool *> &wrapper_request_extensions = wrapper->get_requested_extensions(); const HashMap<String, bool *> &wrapper_request_extensions = wrapper->get_requested_extensions(p_xr_version);
for (const KeyValue<String, bool *> &requested_extension : wrapper_request_extensions) { for (const KeyValue<String, bool *> &requested_extension : wrapper_request_extensions) {
if (!requested_extensions.has(requested_extension.key)) { if (!requested_extensions.has(requested_extension.key)) {
@@ -549,36 +552,30 @@ PackedStringArray OpenXRAPI::get_all_requested_extensions() {
} }
} }
// Also add in our OpenXR Version "extension", so we can switch logic on that.
requested_extensions.push_back(XR_OPENXR_1_1_NAME);
return requested_extensions; return requested_extensions;
} }
bool OpenXRAPI::create_instance() { XrResult OpenXRAPI::attempt_create_instance(XrVersion p_version) {
// Create our OpenXR instance, this will query any registered extension wrappers for extensions we need to enable. enabled_extensions.clear();
// We can request an extension multiple times if there are dependencies // Find all extensions we wish to enable for the requested OpenXR version.
struct RequestExtension { LocalVector<RequestExtension> requested_extensions;
String name;
bool *enabled;
};
// Find all extensions we wish to enable.
Vector<RequestExtension> requested_extensions;
for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) { for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
const HashMap<String, bool *> &wrapper_request_extensions = wrapper->get_requested_extensions(); const HashMap<String, bool *> &wrapper_request_extensions = wrapper->get_requested_extensions(p_version);
for (const KeyValue<String, bool *> &requested_extension : wrapper_request_extensions) { for (const KeyValue<String, bool *> &requested_extension : wrapper_request_extensions) {
requested_extensions.push_back({ requested_extension.key, requested_extension.value }); requested_extensions.push_back({ requested_extension.key, requested_extension.value });
} }
} }
// Check which extensions are supported. for (const RequestExtension &requested_extension : requested_extensions) {
enabled_extensions.clear();
for (RequestExtension &requested_extension : requested_extensions) {
if (!is_extension_supported(requested_extension.name)) { if (!is_extension_supported(requested_extension.name)) {
if (requested_extension.enabled == nullptr) { if (requested_extension.enabled == nullptr) {
// Null means this is a mandatory extension so we fail. // Null means this is a mandatory extension so we fail.
ERR_FAIL_V_MSG(false, String("OpenXR: OpenXR Runtime does not support ") + requested_extension.name + String(" extension!")); ERR_FAIL_V_MSG(XR_ERROR_INITIALIZATION_FAILED, String("OpenXR: OpenXR Runtime does not support ") + requested_extension.name + String(" extension!"));
} else { } else {
// Set this extension as not supported. // Set this extension as not supported.
*requested_extension.enabled = false; *requested_extension.enabled = false;
@@ -590,41 +587,41 @@ bool OpenXRAPI::create_instance() {
} }
// And record that we want to enable it (dependent extensions may be requested multiple times). // And record that we want to enable it (dependent extensions may be requested multiple times).
CharString ext_name = requested_extension.name.ascii(); CharString ext_name = requested_extension.name.utf8();
if (!enabled_extensions.has(ext_name)) { if (!enabled_extensions.has(ext_name)) {
enabled_extensions.push_back(ext_name); enabled_extensions.push_back(ext_name);
} }
} }
} }
Vector<const char *> extension_ptrs; // Convert our enabled extensions so we can send it to OpenXR.
for (int i = 0; i < enabled_extensions.size(); i++) { LocalVector<const char *> extension_ptrs;
print_verbose(String("OpenXR: Enabling extension ") + String(enabled_extensions[i].get_data())); extension_ptrs.reserve(enabled_extensions.size());
extension_ptrs.push_back(enabled_extensions[i].get_data());
for (const CharString &enabled_extension : enabled_extensions) {
const char *extension = enabled_extension.get_data();
extension_ptrs.push_back(extension);
} }
// We explicitly set the version to 1.0.48 in order to workaround a bug (see #108850) in Meta's runtime. // Attempt to create our OpenXR instance for the requested version.
// Once that is fixed, restore this to using XR_API_VERSION_1_0, which is the version associated with the
// OpenXR headers that we're using.
XrVersion openxr_version = XR_MAKE_VERSION(1, 0, 48);
// Create our OpenXR instance
XrApplicationInfo application_info{ XrApplicationInfo application_info{
"Godot Engine", // applicationName, if we're running a game we'll update this down below. "Godot Engine", // applicationName, if we're running a game we'll update this down below.
1, // applicationVersion, we don't currently have this 1, // applicationVersion, we don't currently have this
"Godot Engine", // engineName "Godot Engine", // engineName
GODOT_VERSION_MAJOR * 10000 + GODOT_VERSION_MINOR * 100 + GODOT_VERSION_PATCH, // engineVersion 4.0 -> 40000, 4.0.1 -> 40001, 4.1 -> 40100, etc. GODOT_VERSION_MAJOR * 10000 + GODOT_VERSION_MINOR * 100 + GODOT_VERSION_PATCH, // engineVersion 4.0 -> 40000, 4.0.1 -> 40001, 4.1 -> 40100, etc.
openxr_version, // apiVersion p_version // apiVersion
}; };
// Get additional entries from our extension wrappers.
void *next_pointer = nullptr; void *next_pointer = nullptr;
for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) { for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
void *np = wrapper->set_instance_create_info_and_get_next_pointer(next_pointer); void *np = wrapper->set_instance_create_info_and_get_next_pointer(p_version, next_pointer);
if (np != nullptr) { if (np != nullptr) {
next_pointer = np; next_pointer = np;
} }
} }
// Try and create this instance.
XrInstanceCreateInfo instance_create_info = { XrInstanceCreateInfo instance_create_info = {
XR_TYPE_INSTANCE_CREATE_INFO, // type XR_TYPE_INSTANCE_CREATE_INFO, // type
next_pointer, // next next_pointer, // next
@@ -636,16 +633,44 @@ bool OpenXRAPI::create_instance() {
extension_ptrs.ptr() // enabledExtensionNames extension_ptrs.ptr() // enabledExtensionNames
}; };
// Get our project name // Get our project name.
String project_name = GLOBAL_GET("application/config/name"); String project_name = GLOBAL_GET("application/config/name");
if (!project_name.is_empty()) { if (!project_name.is_empty()) {
copy_string_to_char_buffer(project_name, instance_create_info.applicationInfo.applicationName, XR_MAX_APPLICATION_NAME_SIZE); copy_string_to_char_buffer(project_name, instance_create_info.applicationInfo.applicationName, XR_MAX_APPLICATION_NAME_SIZE);
} }
XrResult result = xrCreateInstance(&instance_create_info, &instance); XrResult result = xrCreateInstance(&instance_create_info, &instance);
ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "Failed to create XR instance [" + get_error_string(result) + "]."); if (XR_SUCCEEDED(result)) {
// Record version we've successfully enabled.
openxr_version = p_version;
print_line("OpenXR: Created instance for OpenXR", OpenXRUtil::make_xr_version_string(openxr_version));
// from this point on we can use get_error_string to get more info about our errors... if (is_print_verbose_enabled()) {
// Print out enabled extensions.
for (const char *extension : extension_ptrs) {
print_line("OpenXR: Enabled extension ", extension);
}
}
}
return result;
}
bool OpenXRAPI::create_instance() {
// Create our OpenXR instance, this will query any registered extension wrappers for extensions we need to enable.
// We explicitly set the version to 1.x.48 in order to workaround a bug (see #108850) in Meta's runtime.
// Once that is fixed, restore this to using XR_API_VERSION_1_x, which is the version associated with the
// OpenXR headers that we're using.
XrResult result = attempt_create_instance(XR_MAKE_VERSION(1, 1, 48)); // Replace with XR_API_VERSION_1_1
if (result == XR_ERROR_API_VERSION_UNSUPPORTED) {
// Couldn't initialize OpenXR 1.1, try 1.0
print_verbose("OpenXR: Falling back to OpenXR 1.0");
result = attempt_create_instance(XR_MAKE_VERSION(1, 0, 48)); // Replace with XR_API_VERSION_1_0
}
ERR_FAIL_COND_V_MSG(XR_FAILED(result), false, "Failed to create XR instance [" + get_error_string(result) + "].");
XrInstanceProperties instanceProps = { XrInstanceProperties instanceProps = {
XR_TYPE_INSTANCE_PROPERTIES, // type; XR_TYPE_INSTANCE_PROPERTIES, // type;
@@ -669,6 +694,12 @@ bool OpenXRAPI::create_instance() {
print_line("OpenXR: Running on OpenXR runtime: ", runtime_name, " ", runtime_version); print_line("OpenXR: Running on OpenXR runtime: ", runtime_name, " ", runtime_version);
} }
// We add an extension string to indicate we're on OpenXR 1.1,
// this makes it easier to check for this in various places where we're already checking on extensions.
if (XR_VERSION_MAJOR(openxr_version) == 1 && XR_VERSION_MINOR(openxr_version) == 1) {
enabled_extensions.push_back(XR_OPENXR_1_1_NAME);
}
for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) { for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
wrapper->on_instance_created(instance); wrapper->on_instance_created(instance);
} }
@@ -979,6 +1010,8 @@ bool OpenXRAPI::setup_play_space() {
} else if (is_reference_space_supported(requested_reference_space)) { } else if (is_reference_space_supported(requested_reference_space)) {
new_reference_space = requested_reference_space; new_reference_space = requested_reference_space;
} else if (requested_reference_space == XR_REFERENCE_SPACE_TYPE_LOCAL_FLOOR_EXT && is_reference_space_supported(XR_REFERENCE_SPACE_TYPE_STAGE)) { } else if (requested_reference_space == XR_REFERENCE_SPACE_TYPE_LOCAL_FLOOR_EXT && is_reference_space_supported(XR_REFERENCE_SPACE_TYPE_STAGE)) {
// Note, in OpenXR 1.0 XR_EXT_LOCAL_FLOOR_EXTENSION_NAME needs to be enabled
// but from OpenXR 1.1 onwards this should always be available.
print_verbose("OpenXR: LOCAL_FLOOR space isn't supported, emulating using STAGE and LOCAL spaces."); print_verbose("OpenXR: LOCAL_FLOOR space isn't supported, emulating using STAGE and LOCAL spaces.");
new_reference_space = XR_REFERENCE_SPACE_TYPE_LOCAL; new_reference_space = XR_REFERENCE_SPACE_TYPE_LOCAL;
@@ -3410,7 +3443,9 @@ RID OpenXRAPI::interaction_profile_create(const String &p_name) {
InteractionProfile new_interaction_profile; InteractionProfile new_interaction_profile;
XrResult result = xrStringToPath(instance, p_name.utf8().get_data(), &new_interaction_profile.path); new_interaction_profile.internal_name = get_interaction_profile_internal_name(p_name);
XrResult result = xrStringToPath(instance, new_interaction_profile.internal_name.get_data(), &new_interaction_profile.path);
if (XR_FAILED(result)) { if (XR_FAILED(result)) {
print_line("OpenXR: failed to get path for ", p_name, "! [", get_error_string(result), "]"); print_line("OpenXR: failed to get path for ", p_name, "! [", get_error_string(result), "]");
return RID(); return RID();
@@ -3443,6 +3478,93 @@ void OpenXRAPI::interaction_profile_clear_bindings(RID p_interaction_profile) {
ip->bindings.clear(); ip->bindings.clear();
} }
CharString OpenXRAPI::get_interaction_profile_internal_name(const String &p_interaction_profile_name) const {
CharString internal_name = p_interaction_profile_name.utf8();
if (openxr_version < XR_API_VERSION_1_1_0) {
// These interaction profiles were renamed in OpenXR 1.1,
// if we don't support OpenXR 1.1, rename them back.
if (internal_name == "/interaction_profiles/meta/touch_pro_controller") {
return "/interaction_profiles/facebook/touch_controller_pro";
} else if (internal_name == "/interaction_profiles/meta/touch_plus_controller") {
return "/interaction_profiles/meta/touch_controller_plus";
}
}
return internal_name;
}
const char *OpenXRAPI::check_profile_path(const CharString &p_interaction_profile_name, const char *p_path) const {
// We store the new names of these paths in our action map, so if we're on older versions of OpenXR,
// we need to use the old names.
struct RenameMap {
const XrVersion before_version; // If we're on an older version of OpenXR than this (if none zero).
const char *from; // Rename from this
const char *to; // to this
const char *profile; // limiting to this profile (unless nullptr)
};
// The order of entries is important as we early exit when we encounter a before_version value before our current value (excluding 0).
const RenameMap renames[] = {
// The touch_controller is an exception where it is still using the vendor names because they were introduced after OpenXR 1.1 was defined.
{ 0, "/user/hand/left/input/trigger/proximity", "/user/hand/left/input/trigger/proximity_fb", "/interaction_profiles/oculus/touch_controller" },
{ 0, "/user/hand/right/input/trigger/proximity", "/user/hand/right/input/trigger/proximity_fb", "/interaction_profiles/oculus/touch_controller" },
{ 0, "/user/hand/left/input/thumb_resting_surfaces/proximity", "/user/hand/left/input/thumb_fb/proximity_fb", "/interaction_profiles/oculus/touch_controller" },
{ 0, "/user/hand/right/input/thumb_resting_surfaces/proximity", "/user/hand/right/input/thumb_fb/proximity_fb", "/interaction_profiles/oculus/touch_controller" },
// Once applicable, add XR_API_VERSION_1_2 here.
// Before OpenXR 1.1 we're using palm_ext/pose (we're checking for enabled palm pose extension elsewhere).
{ XR_API_VERSION_1_1_0, "/user/hand/left/input/grip_surface/pose", "/user/hand/left/input/palm_ext/pose", nullptr },
{ XR_API_VERSION_1_1_0, "/user/hand/right/input/grip_surface/pose", "/user/hand/right/input/palm_ext/pose", nullptr },
// Specific renames for touch_controller_pro, note that we would have already renamed it to the old name.
{ XR_API_VERSION_1_1_0, "/user/hand/left/input/grip_surface/pose", "/user/hand/left/input/palm_ext/pose", "/interaction_profiles/facebook/touch_controller_pro" },
{ XR_API_VERSION_1_1_0, "/user/hand/right/input/grip_surface/pose", "/user/hand/right/input/palm_ext/pose", "/interaction_profiles/facebook/touch_controller_pro" },
{ XR_API_VERSION_1_1_0, "/user/hand/left/input/stylus/force", "/user/hand/left/input/stylus_fb/force", "/interaction_profiles/facebook/touch_controller_pro" },
{ XR_API_VERSION_1_1_0, "/user/hand/right/input/stylus/force", "/user/hand/right/input/stylus_fb/force", "/interaction_profiles/facebook/touch_controller_pro" },
{ XR_API_VERSION_1_1_0, "/user/hand/left/input/trigger/proximity", "/user/hand/left/input/trigger/proximity_fb", "/interaction_profiles/facebook/touch_controller_pro" },
{ XR_API_VERSION_1_1_0, "/user/hand/right/input/trigger/proximity", "/user/hand/right/input/trigger/proximity_fb", "/interaction_profiles/facebook/touch_controller_pro" },
{ XR_API_VERSION_1_1_0, "/user/hand/left/output/haptic_trigger", "/user/hand/left/output/haptic_trigger_fb", "/interaction_profiles/facebook/touch_controller_pro" },
{ XR_API_VERSION_1_1_0, "/user/hand/right/output/haptic_trigger", "/user/hand/right/output/haptic_trigger_fb", "/interaction_profiles/facebook/touch_controller_pro" },
{ XR_API_VERSION_1_1_0, "/user/hand/left/output/haptic_thumb", "/user/hand/left/output/haptic_thumb_fb", "/interaction_profiles/facebook/touch_controller_pro" },
{ XR_API_VERSION_1_1_0, "/user/hand/right/output/haptic_thumb", "/user/hand/right/output/haptic_thumb_fb", "/interaction_profiles/facebook/touch_controller_pro" },
{ XR_API_VERSION_1_1_0, "/user/hand/left/input/thumb_resting_surfaces/proximity", "/user/hand/left/input/thumb_fb/proximity_fb", "/interaction_profiles/facebook/touch_controller_pro" },
{ XR_API_VERSION_1_1_0, "/user/hand/right/input/thumb_resting_surfaces/proximity", "/user/hand/right/input/thumb_fb/proximity_fb", "/interaction_profiles/facebook/touch_controller_pro" },
{ XR_API_VERSION_1_1_0, "/user/hand/left/input/trigger_curl/value", "/user/hand/left/input/trigger/curl_fb", "/interaction_profiles/facebook/touch_controller_pro" },
{ XR_API_VERSION_1_1_0, "/user/hand/right/input/trigger_curl/value", "/user/hand/right/input/trigger/curl_fb", "/interaction_profiles/facebook/touch_controller_pro" },
{ XR_API_VERSION_1_1_0, "/user/hand/left/input/trigger_slide/value", "/user/hand/left/input/trigger/slide_fb", "/interaction_profiles/facebook/touch_controller_pro" },
{ XR_API_VERSION_1_1_0, "/user/hand/right/input/trigger_slide/value", "/user/hand/right/input/trigger/slide_fb", "/interaction_profiles/facebook/touch_controller_pro" },
// Specific renames for touch_controller_plus, note that we would have already renamed it to the old name.
{ XR_API_VERSION_1_1_0, "/user/hand/left/input/trigger/proximity", "/user/hand/left/input/trigger/proximity_meta", "/interaction_profiles/facebook/touch_controller_plus" },
{ XR_API_VERSION_1_1_0, "/user/hand/right/input/trigger/proximity", "/user/hand/right/input/trigger/proximity_meta", "/interaction_profiles/facebook/touch_controller_plus" },
{ XR_API_VERSION_1_1_0, "/user/hand/left/input/thumb_resting_surfaces/proximity", "/user/hand/left/input/thumb_meta/proximity_meta", "/interaction_profiles/facebook/touch_controller_plus" },
{ XR_API_VERSION_1_1_0, "/user/hand/right/input/thumb_resting_surfaces/proximity", "/user/hand/right/input/thumb_meta/proximity_meta", "/interaction_profiles/facebook/touch_controller_plus" },
{ XR_API_VERSION_1_1_0, "/user/hand/left/input/trigger_curl/value", "/user/hand/left/input/trigger/curl_meta", "/interaction_profiles/facebook/touch_controller_plus" },
{ XR_API_VERSION_1_1_0, "/user/hand/right/input/trigger_curl/value", "/user/hand/right/input/trigger/curl_meta", "/interaction_profiles/facebook/touch_controller_plus" },
{ XR_API_VERSION_1_1_0, "/user/hand/left/input/trigger_slide/value", "/user/hand/left/input/trigger/slide_meta", "/interaction_profiles/facebook/touch_controller_plus" },
{ XR_API_VERSION_1_1_0, "/user/hand/right/input/trigger_slide/value", "/user/hand/right/input/trigger/slide_meta", "/interaction_profiles/facebook/touch_controller_plus" },
};
constexpr size_t length = sizeof(renames) / sizeof(renames[0]);
for (size_t i = 0; i < length; i++) {
const RenameMap &rename = renames[i];
if (rename.before_version != 0 && openxr_version >= rename.before_version) {
// We're done, we are on a new version than this, no need to check further.
return p_path;
}
if ((rename.profile == nullptr || p_interaction_profile_name == rename.profile) && strcmp(p_path, rename.from) == 0) {
return rename.to;
}
}
return p_path;
}
int OpenXRAPI::interaction_profile_add_binding(RID p_interaction_profile, RID p_action, const String &p_path) { int OpenXRAPI::interaction_profile_add_binding(RID p_interaction_profile, RID p_action, const String &p_path) {
InteractionProfile *ip = interaction_profile_owner.get_or_null(p_interaction_profile); InteractionProfile *ip = interaction_profile_owner.get_or_null(p_interaction_profile);
ERR_FAIL_NULL_V(ip, -1); ERR_FAIL_NULL_V(ip, -1);
@@ -3458,7 +3580,7 @@ int OpenXRAPI::interaction_profile_add_binding(RID p_interaction_profile, RID p_
binding.action = action->handle; binding.action = action->handle;
XrResult result = xrStringToPath(instance, p_path.utf8().get_data(), &binding.binding); XrResult result = xrStringToPath(instance, check_profile_path(ip->internal_name, p_path.utf8().get_data()), &binding.binding);
if (XR_FAILED(result)) { if (XR_FAILED(result)) {
print_line("OpenXR: failed to get path for ", p_path, "! [", get_error_string(result), "]"); print_line("OpenXR: failed to get path for ", p_path, "! [", get_error_string(result), "]");
return -1; return -1;

View File

@@ -46,6 +46,11 @@
#include <openxr/openxr.h> #include <openxr/openxr.h>
// Name we add to our extensions if OpenXR 1.1 context is available.
#define XR_OPENXR_1_1_NAME "OPENXR_1_1"
#define XR_API_VERSION_1_1_0 XR_MAKE_VERSION(1, 1, 0)
// forward declarations, we don't want to include these fully // forward declarations, we don't want to include these fully
class OpenXRInterface; class OpenXRInterface;
@@ -91,7 +96,7 @@ private:
// extensions // extensions
LocalVector<XrExtensionProperties> supported_extensions; LocalVector<XrExtensionProperties> supported_extensions;
Vector<CharString> enabled_extensions; LocalVector<CharString> enabled_extensions;
// composition layer providers // composition layer providers
Vector<OpenXRExtensionWrapper *> composition_layer_providers; Vector<OpenXRExtensionWrapper *> composition_layer_providers;
@@ -112,6 +117,7 @@ private:
PackedInt64Array supported_swapchain_formats; PackedInt64Array supported_swapchain_formats;
// system info // system info
XrVersion openxr_version;
String runtime_name; String runtime_name;
String runtime_version; String runtime_version;
@@ -180,7 +186,13 @@ private:
bool load_layer_properties(); bool load_layer_properties();
bool load_supported_extensions(); bool load_supported_extensions();
bool is_extension_supported(const String &p_extension) const; bool is_extension_supported(const String &p_extension) const;
bool is_extension_enabled(const String &p_extension) const; bool is_any_extension_enabled(const String &p_extensions) const;
struct RequestExtension {
String name;
bool *enabled;
};
XrResult attempt_create_instance(XrVersion p_version);
bool openxr_loader_init(); bool openxr_loader_init();
bool resolve_instance_openxr_symbols(); bool resolve_instance_openxr_symbols();
@@ -299,6 +311,7 @@ private:
struct InteractionProfile { // Interaction profiles define suggested bindings between the physical inputs on controller types and our actions struct InteractionProfile { // Interaction profiles define suggested bindings between the physical inputs on controller types and our actions
String name; // Name of the interaction profile (i.e. "/interaction_profiles/valve/index_controller") String name; // Name of the interaction profile (i.e. "/interaction_profiles/valve/index_controller")
CharString internal_name; // Internal name of the interaction profile (translated if required)
XrPath path; // OpenXR path for this profile XrPath path; // OpenXR path for this profile
Vector<XrActionSuggestedBinding> bindings; // OpenXR action bindings Vector<XrActionSuggestedBinding> bindings; // OpenXR action bindings
Vector<PackedByteArray> modifiers; // Array of modifiers we'll add into XrBindingModificationsKHR Vector<PackedByteArray> modifiers; // Array of modifiers we'll add into XrBindingModificationsKHR
@@ -307,6 +320,9 @@ private:
RID get_interaction_profile_rid(XrPath p_path); RID get_interaction_profile_rid(XrPath p_path);
XrPath get_interaction_profile_path(RID p_interaction_profile); XrPath get_interaction_profile_path(RID p_interaction_profile);
CharString get_interaction_profile_internal_name(const String &p_interaction_profile_name) const;
const char *check_profile_path(const CharString &p_interaction_profile_name, const char *p_path) const;
struct OrderedCompositionLayer { struct OrderedCompositionLayer {
const XrCompositionLayerBaseHeader *composition_layer; const XrCompositionLayerBaseHeader *composition_layer;
int sort_order; int sort_order;
@@ -436,6 +452,7 @@ public:
rendering_server->call_on_render_thread(callable_mp_static(&OpenXRAPI::_update_main_swapchain_size_rt)); rendering_server->call_on_render_thread(callable_mp_static(&OpenXRAPI::_update_main_swapchain_size_rt));
} }
XrVersion get_openxr_version() const { return openxr_version; }
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; }
@@ -480,7 +497,7 @@ public:
static const Vector<OpenXRExtensionWrapper *> &get_registered_extension_wrappers(); static const Vector<OpenXRExtensionWrapper *> &get_registered_extension_wrappers();
static void register_extension_metadata(); static void register_extension_metadata();
static void cleanup_extension_wrappers(); static void cleanup_extension_wrappers();
static PackedStringArray get_all_requested_extensions(); static PackedStringArray get_all_requested_extensions(XrVersion p_xr_version);
void set_form_factor(XrFormFactor p_form_factor); void set_form_factor(XrFormFactor p_form_factor);
XrFormFactor get_form_factor() const { return form_factor; } XrFormFactor get_form_factor() const { return form_factor; }

View File

@@ -34,6 +34,7 @@
#include "openxr_api_extension.compat.inc" #include "openxr_api_extension.compat.inc"
void OpenXRAPIExtension::_bind_methods() { void OpenXRAPIExtension::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_openxr_version"), &OpenXRAPIExtension::get_openxr_version);
ClassDB::bind_method(D_METHOD("get_instance"), &OpenXRAPIExtension::get_instance); ClassDB::bind_method(D_METHOD("get_instance"), &OpenXRAPIExtension::get_instance);
ClassDB::bind_method(D_METHOD("get_system_id"), &OpenXRAPIExtension::get_system_id); ClassDB::bind_method(D_METHOD("get_system_id"), &OpenXRAPIExtension::get_system_id);
ClassDB::bind_method(D_METHOD("get_session"), &OpenXRAPIExtension::get_session); ClassDB::bind_method(D_METHOD("get_session"), &OpenXRAPIExtension::get_session);
@@ -102,6 +103,11 @@ void OpenXRAPIExtension::_bind_methods() {
BIND_ENUM_CONSTANT(OPENXR_ALPHA_BLEND_MODE_SUPPORT_EMULATING); BIND_ENUM_CONSTANT(OPENXR_ALPHA_BLEND_MODE_SUPPORT_EMULATING);
} }
uint64_t OpenXRAPIExtension::get_openxr_version() {
ERR_FAIL_NULL_V(OpenXRAPI::get_singleton(), 0);
return (uint64_t)OpenXRAPI::get_singleton()->get_openxr_version();
}
uint64_t OpenXRAPIExtension::get_instance() { uint64_t OpenXRAPIExtension::get_instance() {
ERR_FAIL_NULL_V(OpenXRAPI::get_singleton(), 0); ERR_FAIL_NULL_V(OpenXRAPI::get_singleton(), 0);
return (uint64_t)OpenXRAPI::get_singleton()->get_instance(); return (uint64_t)OpenXRAPI::get_singleton()->get_instance();

View File

@@ -56,6 +56,7 @@ protected:
#endif #endif
public: public:
uint64_t get_openxr_version();
uint64_t get_instance(); uint64_t get_instance();
uint64_t get_system_id(); uint64_t get_system_id();
uint64_t get_session(); uint64_t get_session();