diff --git a/addons/godotopenxrvendors/GodotOpenXRVendors_CHANGES.md b/addons/godotopenxrvendors/GodotOpenXRVendors_CHANGES.md
new file mode 100644
index 0000000..75d57d3
--- /dev/null
+++ b/addons/godotopenxrvendors/GodotOpenXRVendors_CHANGES.md
@@ -0,0 +1,30 @@
+# Change history for the Godot OpenXR loaders asset
+
+## 2.0.0
+- Update to the new Godot 4.2 Android plugin packaging format
+- Update the plugin to Godot v2 Android plugin
+- Update to the Godot 4.2 Android library
+- Add warning when multiple loaders are selected
+- Add configs for the OpenXR Eye gaze interaction extension
+- Add the ability to customize supported Meta devices
+- Add support for Quest 3 devices
+- Update the directory structure for the v2 plugin
+- Update Meta OpenXR mobile SDK to version 57
+- Update the java version to 17
+- Rename the plugin to 'Godot OpenXR Vendors'
+- Add godot-cpp dependency
+- Add OpenXR 1.0.30 headers
+- Add support for the Meta scene capture API (Donated by [Migeran](https://migeran.com))
+
+## 1.1.0
+- Update Meta OpenXR loader to version 54
+- Update PICO OpenXR loader to version 2.2.0
+- Bump dependencies versions to match the latest Godot 4.x stable version (v4.0.3)
+
+## 1.0.0
+- First version
+- Added support for Meta Quest loader
+- Added support for Pico loader
+- Added support for Khronos loader (Magic Leap 2, HTC, etc.)
+- Added support for Lynx loader
+- Add logic to automatically publish the Godot OpenXR loaders libraries to mavencentral on release
diff --git a/addons/godotopenxrvendors/globals.gd b/addons/godotopenxrvendors/globals.gd
new file mode 100644
index 0000000..4964c2f
--- /dev/null
+++ b/addons/godotopenxrvendors/globals.gd
@@ -0,0 +1,19 @@
+@tool
+
+# Set of supported vendors
+const META_VENDOR_NAME = "meta"
+const PICO_VENDOR_NAME = "pico"
+const LYNX_VENDOR_NAME = "lynx"
+const KHRONOS_VENDOR_NAME = "khronos"
+
+const VENDORS_LIST = [
+ META_VENDOR_NAME,
+ PICO_VENDOR_NAME,
+ LYNX_VENDOR_NAME,
+ KHRONOS_VENDOR_NAME,
+ ]
+
+# Set of custom feature tags supported by the plugin
+const EYE_GAZE_INTERACTION_FEATURE = "XR_EXT_eye_gaze_interaction"
+
+const OPENXR_MODE_VALUE = 1
diff --git a/addons/godotopenxrvendors/godot_openxr_export_plugin.gd b/addons/godotopenxrvendors/godot_openxr_export_plugin.gd
new file mode 100644
index 0000000..ab35812
--- /dev/null
+++ b/addons/godotopenxrvendors/godot_openxr_export_plugin.gd
@@ -0,0 +1,186 @@
+@tool
+extends EditorPlugin
+
+var globals = preload("globals.gd")
+
+# A class member to hold the export plugin during its lifecycle.
+var meta_export_plugin : GodotOpenXREditorExportPlugin
+var pico_export_plugin : GodotOpenXREditorExportPlugin
+var lynx_export_plugin : GodotOpenXREditorExportPlugin
+var khronos_export_plugin : GodotOpenXREditorExportPlugin
+
+
+func _enter_tree():
+ var plugin_version = get_plugin_version()
+
+ # Initializing the export plugins
+ meta_export_plugin = preload("meta/godot_openxr_meta_editor_export_plugin.gd").new()
+ meta_export_plugin._setup(globals.META_VENDOR_NAME, plugin_version)
+
+ pico_export_plugin = preload("pico/godot_openxr_pico_editor_export_plugin.gd").new()
+ pico_export_plugin._setup(globals.PICO_VENDOR_NAME, plugin_version)
+
+ lynx_export_plugin = preload("lynx/godot_openxr_lynx_editor_export_plugin.gd").new()
+ lynx_export_plugin._setup(globals.LYNX_VENDOR_NAME, plugin_version)
+
+ khronos_export_plugin = preload("khronos/godot_openxr_khronos_editor_export_plugin.gd").new()
+ khronos_export_plugin._setup(globals.KHRONOS_VENDOR_NAME, plugin_version)
+
+ add_export_plugin(meta_export_plugin)
+ add_export_plugin(pico_export_plugin)
+ add_export_plugin(lynx_export_plugin)
+ add_export_plugin(khronos_export_plugin)
+
+
+func _exit_tree():
+ # Cleaning up the export plugins
+ remove_export_plugin(meta_export_plugin)
+ remove_export_plugin(pico_export_plugin)
+ remove_export_plugin(lynx_export_plugin)
+ remove_export_plugin(khronos_export_plugin)
+
+ meta_export_plugin = null
+ pico_export_plugin = null
+ lynx_export_plugin = null
+ khronos_export_plugin = null
+
+
+class GodotOpenXREditorExportPlugin extends EditorExportPlugin:
+
+ ## Base class for the vendor editor export plugin
+
+ var globals = preload("globals.gd")
+
+ var _vendor: String
+ var _plugin_version: String
+
+ func _setup(vendor: String, version: String):
+ _vendor = vendor
+ _plugin_version = version
+
+
+ func _get_name() -> String:
+ return "GodotOpenXR" + _vendor.capitalize()
+
+
+ # Path to the Android library aar file
+ # If this is not available, we fall back to the maven central dependency
+ func _get_android_aar_file_path(debug: bool) -> String:
+ var debug_label = "debug" if debug else "release"
+ return "res://addons/godotopenxrvendors/" + _vendor + "/.bin/" + debug_label + "/godotopenxr" + _vendor + "-" + debug_label + ".aar"
+
+
+ # Maven central dependency used as fall back when the Android library aar file is not available
+ func _get_android_maven_central_dependency() -> String:
+ return "org.godotengine:godot-openxr-vendors-" + _vendor + ":" + _plugin_version
+
+
+ func _get_vendor_toggle_option_name(vendor_name: String = _vendor) -> String:
+ return "xr_features/enable_" + vendor_name + "_plugin"
+
+
+ func _get_vendor_toggle_option(vendor_name: String = _vendor) -> Dictionary:
+ var toggle_option = {
+ "option": {
+ "name": _get_vendor_toggle_option_name(vendor_name),
+ "class_name": "",
+ "type": TYPE_BOOL,
+ "hint": PROPERTY_HINT_NONE,
+ "hint_string": "",
+ "usage": PROPERTY_USAGE_DEFAULT,
+ },
+ "default_value": false,
+ "update_visibility": false,
+ }
+ return toggle_option
+
+
+ func _is_openxr_enabled() -> bool:
+ return _get_int_option("xr_features/xr_mode", 0) == globals.OPENXR_MODE_VALUE
+
+
+ func _get_export_options(platform) -> Array[Dictionary]:
+ if not _supports_platform(platform):
+ return []
+
+ return [
+ _get_vendor_toggle_option(),
+ ]
+
+
+ func _get_export_option_warning(platform, option) -> String:
+ if not _supports_platform(platform):
+ return ""
+
+ if option != _get_vendor_toggle_option_name():
+ return ""
+
+ if not(_is_openxr_enabled()) and _get_bool_option(option):
+ return "\"Enable " + _vendor.capitalize() + " Plugin\" requires \"XR Mode\" to be \"OpenXR\".\n"
+
+ if _is_vendor_plugin_enabled():
+ for vendor_name in globals.VENDORS_LIST:
+ if (vendor_name != _vendor) and _is_vendor_plugin_enabled(vendor_name):
+ return "\"Disable " + _vendor.capitalize() + " Plugin before enabling another. Multiple plugins are not supported!\""
+
+ return ""
+
+
+ func _supports_platform(platform) -> bool:
+ if platform is EditorExportPlatformAndroid:
+ return true
+ return false
+
+
+ func _get_bool_option(option: String) -> bool:
+ var option_enabled = get_option(option)
+ if option_enabled is bool:
+ return option_enabled
+ return false
+
+
+ func _get_int_option(option: String, default_value: int) -> int:
+ var option_value = get_option(option)
+ if option_value is int:
+ return option_value
+ return default_value
+
+
+ func _is_vendor_plugin_enabled(vendor_name: String = _vendor) -> bool:
+ return _get_bool_option(_get_vendor_toggle_option_name(vendor_name))
+
+
+ func _is_android_aar_file_available(debug: bool) -> bool:
+ return FileAccess.file_exists(_get_android_aar_file_path(debug))
+
+
+ func _get_android_dependencies(platform, debug) -> PackedStringArray:
+ if not _supports_platform(platform):
+ return PackedStringArray()
+
+ if _is_vendor_plugin_enabled() and not _is_android_aar_file_available(debug):
+ return PackedStringArray([_get_android_maven_central_dependency()])
+
+ return PackedStringArray()
+
+
+ func _get_android_libraries(platform, debug) -> PackedStringArray:
+ if not _supports_platform(platform):
+ return PackedStringArray()
+
+ if _is_vendor_plugin_enabled() and _is_android_aar_file_available(debug):
+ return PackedStringArray([_get_android_aar_file_path(debug)])
+
+ return PackedStringArray()
+
+
+ func _get_android_dependencies_maven_repos(platform, debug) -> PackedStringArray:
+ var maven_repos = PackedStringArray()
+
+ if not _supports_platform(platform):
+ return maven_repos
+
+ if _is_vendor_plugin_enabled() and not _is_android_aar_file_available(debug) and _plugin_version.ends_with("-SNAPSHOT"):
+ maven_repos.append("https://s01.oss.sonatype.org/content/repositories/snapshots/")
+
+ return maven_repos
diff --git a/android/plugins/godotopenxrkhr/godotopenxrkhr-release.aar b/addons/godotopenxrvendors/khronos/.bin/debug/godotopenxrkhronos-debug.aar
similarity index 99%
rename from android/plugins/godotopenxrkhr/godotopenxrkhr-release.aar
rename to addons/godotopenxrvendors/khronos/.bin/debug/godotopenxrkhronos-debug.aar
index cc5f719..4599d45 100644
Binary files a/android/plugins/godotopenxrkhr/godotopenxrkhr-release.aar and b/addons/godotopenxrvendors/khronos/.bin/debug/godotopenxrkhronos-debug.aar differ
diff --git a/addons/godotopenxrvendors/khronos/.bin/release/godotopenxrkhronos-release.aar b/addons/godotopenxrvendors/khronos/.bin/release/godotopenxrkhronos-release.aar
new file mode 100644
index 0000000..61232b7
Binary files /dev/null and b/addons/godotopenxrvendors/khronos/.bin/release/godotopenxrkhronos-release.aar differ
diff --git a/android/plugins/godotopenxrkhr/LICENSE b/addons/godotopenxrvendors/khronos/LICENSE
similarity index 100%
rename from android/plugins/godotopenxrkhr/LICENSE
rename to addons/godotopenxrvendors/khronos/LICENSE
diff --git a/addons/godotopenxrvendors/khronos/godot_openxr_khronos_editor_export_plugin.gd b/addons/godotopenxrvendors/khronos/godot_openxr_khronos_editor_export_plugin.gd
new file mode 100644
index 0000000..00905e4
--- /dev/null
+++ b/addons/godotopenxrvendors/khronos/godot_openxr_khronos_editor_export_plugin.gd
@@ -0,0 +1,23 @@
+@tool
+extends "../godot_openxr_export_plugin.gd".GodotOpenXREditorExportPlugin
+
+
+func _get_android_manifest_activity_element_contents(platform, debug) -> String:
+ if not _supports_platform(platform) or not(_is_vendor_plugin_enabled()):
+ return ""
+
+ var contents = """
+ \n
+ \n
+ \n
+ \n
+ \n
+ \n
+ \n
+ \n
+ \n
+ \n
+ """
+
+ return contents
diff --git a/addons/godotopenxrvendors/lynx/.bin/debug/godotopenxrlynx-debug.aar b/addons/godotopenxrvendors/lynx/.bin/debug/godotopenxrlynx-debug.aar
new file mode 100644
index 0000000..cc48c6a
Binary files /dev/null and b/addons/godotopenxrvendors/lynx/.bin/debug/godotopenxrlynx-debug.aar differ
diff --git a/android/plugins/godotopenxrlynx/godotopenxrlynx-release.aar b/addons/godotopenxrvendors/lynx/.bin/release/godotopenxrlynx-release.aar
similarity index 99%
rename from android/plugins/godotopenxrlynx/godotopenxrlynx-release.aar
rename to addons/godotopenxrvendors/lynx/.bin/release/godotopenxrlynx-release.aar
index 3fcef3d..362f38a 100644
Binary files a/android/plugins/godotopenxrlynx/godotopenxrlynx-release.aar and b/addons/godotopenxrvendors/lynx/.bin/release/godotopenxrlynx-release.aar differ
diff --git a/addons/godotopenxrvendors/lynx/godot_openxr_lynx_editor_export_plugin.gd b/addons/godotopenxrvendors/lynx/godot_openxr_lynx_editor_export_plugin.gd
new file mode 100644
index 0000000..fb13ce9
--- /dev/null
+++ b/addons/godotopenxrvendors/lynx/godot_openxr_lynx_editor_export_plugin.gd
@@ -0,0 +1,20 @@
+@tool
+extends "../godot_openxr_export_plugin.gd".GodotOpenXREditorExportPlugin
+
+
+func _get_android_manifest_activity_element_contents(platform, debug) -> String:
+ if not _supports_platform(platform) or not(_is_vendor_plugin_enabled()):
+ return ""
+
+ var contents = """
+ \n
+ \n
+ \n
+ \n
+ \n
+ \n
+ \n
+ """
+
+ return contents
diff --git a/addons/godotopenxrvendors/meta/.bin/debug/godotopenxrmeta-debug.aar b/addons/godotopenxrvendors/meta/.bin/debug/godotopenxrmeta-debug.aar
new file mode 100644
index 0000000..41906b1
Binary files /dev/null and b/addons/godotopenxrvendors/meta/.bin/debug/godotopenxrmeta-debug.aar differ
diff --git a/addons/godotopenxrvendors/meta/.bin/release/godotopenxrmeta-release.aar b/addons/godotopenxrvendors/meta/.bin/release/godotopenxrmeta-release.aar
new file mode 100644
index 0000000..100886c
Binary files /dev/null and b/addons/godotopenxrvendors/meta/.bin/release/godotopenxrmeta-release.aar differ
diff --git a/android/plugins/godotopenxrmeta/LICENSE.txt b/addons/godotopenxrvendors/meta/LICENSE.txt
similarity index 100%
rename from android/plugins/godotopenxrmeta/LICENSE.txt
rename to addons/godotopenxrvendors/meta/LICENSE.txt
diff --git a/addons/godotopenxrvendors/meta/godot_openxr_meta_editor_export_plugin.gd b/addons/godotopenxrvendors/meta/godot_openxr_meta_editor_export_plugin.gd
new file mode 100644
index 0000000..5c9a3eb
--- /dev/null
+++ b/addons/godotopenxrvendors/meta/godot_openxr_meta_editor_export_plugin.gd
@@ -0,0 +1,300 @@
+@tool
+extends "../godot_openxr_export_plugin.gd".GodotOpenXREditorExportPlugin
+
+const EYE_TRACKING_NONE_VALUE = 0
+const EYE_TRACKING_OPTIONAL_VALUE = 1
+const EYE_TRACKING_REQUIRED_VALUE = 2
+
+const PASSTHROUGH_NONE_VALUE = 0
+const PASSTHROUGH_OPTIONAL_VALUE = 1
+const PASSTHROUGH_REQUIRED_VALUE = 2
+
+const HAND_TRACKING_NONE_VALUE = 0
+const HAND_TRACKING_OPTIONAL_VALUE = 1
+const HAND_TRACKING_REQUIRED_VALUE = 2
+
+const HAND_TRACKING_FREQUENCY_LOW_VALUE = 0
+const HAND_TRACKING_FREQUENCY_HIGH_VALUE = 1
+
+const EYE_TRACKING_OPTION = {
+ "option": {
+ "name": "meta_xr_features/eye_tracking",
+ "class_name": "",
+ "type": TYPE_INT,
+ "hint": PROPERTY_HINT_ENUM,
+ "hint_string": "None,Optional,Required",
+ "usage": PROPERTY_USAGE_DEFAULT,
+ },
+ "default_value": EYE_TRACKING_NONE_VALUE,
+ "update_visibility": false,
+}
+
+const HAND_TRACKING_OPTION = {
+ "option": {
+ "name": "meta_xr_features/hand_tracking",
+ "class_name": "",
+ "type": TYPE_INT,
+ "hint": PROPERTY_HINT_ENUM,
+ "hint_string": "None,Optional,Required",
+ "usage": PROPERTY_USAGE_DEFAULT,
+ },
+ "default_value": HAND_TRACKING_NONE_VALUE,
+ "update_visibility": false,
+}
+
+const HAND_TRACKING_FREQUENCY_OPTION = {
+ "option": {
+ "name": "meta_xr_features/hand_tracking_frequency",
+ "class_name": "",
+ "type": TYPE_INT,
+ "hint": PROPERTY_HINT_ENUM,
+ "hint_string": "Low,High",
+ "usage": PROPERTY_USAGE_DEFAULT,
+ },
+ "default_value": HAND_TRACKING_FREQUENCY_LOW_VALUE,
+ "update_visibility": false,
+}
+
+const PASSTHROUGH_OPTION = {
+ "option": {
+ "name": "meta_xr_features/passthrough",
+ "class_name": "",
+ "type": TYPE_INT,
+ "hint": PROPERTY_HINT_ENUM,
+ "hint_string": "None,Optional,Required",
+ "usage": PROPERTY_USAGE_DEFAULT,
+ },
+ "default_value": PASSTHROUGH_NONE_VALUE,
+ "update_visibility": false,
+}
+
+const USE_ANCHOR_API_OPTION = {
+ "option": {
+ "name": "meta_xr_features/use_anchor_api",
+ "class_name": "",
+ "type": TYPE_BOOL,
+ "hint": PROPERTY_HINT_NONE,
+ "hint_string": "",
+ "usage": PROPERTY_USAGE_DEFAULT,
+ },
+ "default_value": false,
+ "update_visibility": false,
+}
+
+const SUPPORT_QUEST_1_OPTION = {
+ "option": {
+ "name": "meta_xr_features/quest_1_support",
+ "class_name": "",
+ "type": TYPE_BOOL,
+ "hint": PROPERTY_HINT_NONE,
+ "hint_string": "",
+ "usage": PROPERTY_USAGE_DEFAULT,
+ },
+ "default_value": false,
+ "update_visibility": false,
+}
+
+const SUPPORT_QUEST_2_OPTION = {
+ "option": {
+ "name": "meta_xr_features/quest_2_support",
+ "class_name": "",
+ "type": TYPE_BOOL,
+ "hint": PROPERTY_HINT_NONE,
+ "hint_string": "",
+ "usage": PROPERTY_USAGE_DEFAULT,
+ },
+ "default_value": true,
+ "update_visibility": false,
+}
+
+const SUPPORT_QUEST_3_OPTION = {
+ "option": {
+ "name": "meta_xr_features/quest_3_support",
+ "class_name": "",
+ "type": TYPE_BOOL,
+ "hint": PROPERTY_HINT_NONE,
+ "hint_string": "",
+ "usage": PROPERTY_USAGE_DEFAULT,
+ },
+ "default_value": true,
+ "update_visibility": false,
+}
+
+const SUPPORT_QUEST_PRO_OPTION = {
+ "option": {
+ "name": "meta_xr_features/quest_pro_support",
+ "class_name": "",
+ "type": TYPE_BOOL,
+ "hint": PROPERTY_HINT_NONE,
+ "hint_string": "",
+ "usage": PROPERTY_USAGE_DEFAULT,
+ },
+ "default_value": true,
+ "update_visibility": false,
+}
+
+func _get_export_options(platform) -> Array[Dictionary]:
+ if not _supports_platform(platform):
+ return []
+
+ return [
+ _get_vendor_toggle_option(),
+ EYE_TRACKING_OPTION,
+ HAND_TRACKING_OPTION,
+ HAND_TRACKING_FREQUENCY_OPTION,
+ PASSTHROUGH_OPTION,
+ USE_ANCHOR_API_OPTION,
+ SUPPORT_QUEST_1_OPTION,
+ SUPPORT_QUEST_2_OPTION,
+ SUPPORT_QUEST_3_OPTION,
+ SUPPORT_QUEST_PRO_OPTION,
+ ]
+
+
+func _get_supported_devices() -> PackedStringArray:
+ var supported_devices = PackedStringArray()
+
+ if _get_bool_option("meta_xr_features/quest_1_support"):
+ supported_devices.append("quest")
+ if _get_bool_option("meta_xr_features/quest_2_support"):
+ supported_devices.append("quest2")
+ if _get_bool_option("meta_xr_features/quest_3_support"):
+ supported_devices.append("quest3")
+ if _get_bool_option("meta_xr_features/quest_pro_support"):
+ supported_devices.append("questpro")
+
+ return supported_devices
+
+
+func _is_eye_tracking_enabled() -> bool:
+ var eye_tracking_project_setting_enabled = ProjectSettings.get_setting_with_override("xr/openxr/extensions/eye_gaze_interaction")
+ if not(eye_tracking_project_setting_enabled):
+ return false
+
+ var eye_tracking_option_value = _get_int_option("meta_xr_features/eye_tracking", EYE_TRACKING_NONE_VALUE)
+ return eye_tracking_option_value > EYE_TRACKING_NONE_VALUE
+
+
+func _get_export_features(platform, debug) -> PackedStringArray:
+ var features = PackedStringArray()
+
+ if not _supports_platform(platform):
+ return features
+
+ # Add the eye tracking feature if necessary
+ if _is_eye_tracking_enabled():
+ features.append(globals.EYE_GAZE_INTERACTION_FEATURE)
+
+ return features
+
+
+func _get_export_option_warning(platform, option) -> String:
+ if not _supports_platform(platform):
+ return ""
+
+ var warning = ""
+ var openxr_enabled = _is_openxr_enabled()
+ match (option):
+ "meta_xr_features/eye_tracking":
+ var eye_tracking_project_setting_enabled = ProjectSettings.get_setting_with_override("xr/openxr/extensions/eye_gaze_interaction")
+ var eye_tracking_option_value = _get_int_option("meta_xr_features/eye_tracking", EYE_TRACKING_NONE_VALUE)
+ if eye_tracking_option_value > EYE_TRACKING_NONE_VALUE and not(eye_tracking_project_setting_enabled):
+ warning = "\"Eye Tracking\" project setting must be enabled!\n"
+
+ "meta_xr_features/hand_tracking":
+ if not(openxr_enabled) and _get_int_option(option, HAND_TRACKING_NONE_VALUE) > HAND_TRACKING_NONE_VALUE:
+ warning = "\"Hand Tracking\" requires \"XR Mode\" to be \"OpenXR\".\n"
+
+ "meta_xr_features/passthrough":
+ if not(openxr_enabled) and _get_int_option(option, PASSTHROUGH_NONE_VALUE) > PASSTHROUGH_NONE_VALUE:
+ warning = "\"Passthrough\" requires \"XR Mode\" to be \"OpenXR\".\n"
+
+ "meta_xr_features/use_anchor_api":
+ if not(openxr_enabled) and _get_bool_option(option):
+ warning = "\"Use anchor API\" is only valid when \"XR Mode\" is \"OpenXR\"."
+
+ _:
+ warning = super._get_export_option_warning(platform, option)
+
+ return warning
+
+
+func _get_android_manifest_element_contents(platform, debug) -> String:
+ if not _supports_platform(platform) or not(_is_vendor_plugin_enabled()):
+ return ""
+
+ var contents = ""
+
+ # Check for eye tracking
+ if _is_eye_tracking_enabled():
+ contents += " \n"
+
+ var eye_tracking_value = _get_int_option("meta_xr_features/eye_tracking", EYE_TRACKING_NONE_VALUE)
+ if eye_tracking_value == EYE_TRACKING_OPTIONAL_VALUE:
+ contents += " \n"
+ elif eye_tracking_value == EYE_TRACKING_REQUIRED_VALUE:
+ contents += " \n"
+
+
+ # Check for hand tracking
+ var hand_tracking_value = _get_int_option("meta_xr_features/hand_tracking", HAND_TRACKING_NONE_VALUE)
+ if hand_tracking_value > HAND_TRACKING_NONE_VALUE:
+ contents += " \n"
+ if hand_tracking_value == HAND_TRACKING_OPTIONAL_VALUE:
+ contents += " \n"
+ elif hand_tracking_value == HAND_TRACKING_REQUIRED_VALUE:
+ contents += " \n"
+
+ # Check for passthrough
+ var passthrough_mode = _get_int_option("meta_xr_features/passthrough", PASSTHROUGH_NONE_VALUE)
+ if passthrough_mode == PASSTHROUGH_OPTIONAL_VALUE:
+ contents += " \n"
+ elif passthrough_mode == PASSTHROUGH_REQUIRED_VALUE:
+ contents += " \n"
+
+ # Check for anchor api
+ var use_anchor_api = _get_bool_option("meta_xr_features/use_anchor_api")
+ if use_anchor_api:
+ contents += " \n"
+
+ return contents
+
+
+func _get_android_manifest_application_element_contents(platform, debug) -> String:
+ if not _supports_platform(platform) or not(_is_vendor_plugin_enabled()):
+ return ""
+
+ var contents = ""
+
+ var supported_devices = "|".join(_get_supported_devices())
+ contents += " \n" % supported_devices
+
+ var hand_tracking_enabled = _get_int_option("meta_xr_features/hand_tracking", HAND_TRACKING_NONE_VALUE) > HAND_TRACKING_NONE_VALUE
+ if hand_tracking_enabled:
+ var hand_tracking_frequency = _get_int_option("meta_xr_features/hand_tracking_frequency", HAND_TRACKING_FREQUENCY_LOW_VALUE)
+ var hand_tracking_frequency_label = "LOW" if hand_tracking_frequency == HAND_TRACKING_FREQUENCY_LOW_VALUE else "HIGH"
+ contents += " \n" % hand_tracking_frequency_label
+ contents += " \n"
+
+ return contents
+
+func _get_android_manifest_activity_element_contents(platform, debug) -> String:
+ if not _supports_platform(platform) or not(_is_vendor_plugin_enabled()):
+ return ""
+
+ var contents = """
+ \n
+ \n
+ \n
+ \n
+ \n
+ \n
+ \n
+ \n
+ \n
+ \n
+ """
+
+ return contents
diff --git a/addons/godotopenxrvendors/meta/plugin.gdextension b/addons/godotopenxrvendors/meta/plugin.gdextension
new file mode 100644
index 0000000..12dce86
--- /dev/null
+++ b/addons/godotopenxrvendors/meta/plugin.gdextension
@@ -0,0 +1,20 @@
+[configuration]
+
+entry_symbol = "plugin_library_init"
+compatibility_minimum = "4.2"
+android_aar_plugin = true
+
+[libraries]
+
+android.debug.arm64 = "res://addons/godotopenxrvendors/meta/.bin/debug/arm64-v8a/libgodotopenxrmeta.so"
+android.release.arm64 = "res://addons/godotopenxrvendors/meta/.bin/release/arm64-v8a/libgodotopenxrmeta.so"
+macos.debug = "res://addons/godotopenxrvendors/meta/.bin/libgodotopenxrmeta.macos.template_debug.framework"
+macos.release = "res://addons/godotopenxrvendors/meta/.bin/libgodotopenxrmeta.macos.template_release.framework"
+windows.debug.x86_64 = "res://addons/godotopenxrvendors/meta/.bin/libgodotopenxrmeta.windows.template_debug.x86_64.dll"
+windows.release.x86_64 = "res://addons/godotopenxrvendors/meta/.bin/libgodotopenxrmeta.windows.template_release.x86_64.dll"
+linux.debug.x86_64 = "res://addons/godotopenxrvendors/meta/.bin/libgodotopenxrmeta.linux.template_debug.x86_64.so"
+linux.release.x86_64 = "res://addons/godotopenxrvendors/meta/.bin/libgodotopenxrmeta.linux.template_release.x86_64.so"
+linux.debug.arm64 = "res://addons/godotopenxrvendors/meta/.bin/libgodotopenxrmeta.linux.template_debug.arm64.so"
+linux.release.arm64 = "res://addons/godotopenxrvendors/meta/.bin/libgodotopenxrmeta.linux.template_release.arm64.so"
+linux.debug.rv64 = "res://addons/godotopenxrvendors/meta/.bin/libgodotopenxrmeta.linux.template_debug.rv64.so"
+linux.release.rv64 = "res://addons/godotopenxrvendors/meta/.bin/libgodotopenxrmeta.linux.template_release.rv64.so"
diff --git a/addons/godotopenxrvendors/pico/.bin/debug/godotopenxrpico-debug.aar b/addons/godotopenxrvendors/pico/.bin/debug/godotopenxrpico-debug.aar
new file mode 100644
index 0000000..16f2b0c
Binary files /dev/null and b/addons/godotopenxrvendors/pico/.bin/debug/godotopenxrpico-debug.aar differ
diff --git a/android/plugins/godotopenxrpico/godotopenxrpico-release.aar b/addons/godotopenxrvendors/pico/.bin/release/godotopenxrpico-release.aar
similarity index 99%
rename from android/plugins/godotopenxrpico/godotopenxrpico-release.aar
rename to addons/godotopenxrvendors/pico/.bin/release/godotopenxrpico-release.aar
index 309d11f..2b16611 100644
Binary files a/android/plugins/godotopenxrpico/godotopenxrpico-release.aar and b/addons/godotopenxrvendors/pico/.bin/release/godotopenxrpico-release.aar differ
diff --git a/android/plugins/godotopenxrpico/LICENSE.md b/addons/godotopenxrvendors/pico/LICENSE.md
similarity index 100%
rename from android/plugins/godotopenxrpico/LICENSE.md
rename to addons/godotopenxrvendors/pico/LICENSE.md
diff --git a/addons/godotopenxrvendors/pico/godot_openxr_pico_editor_export_plugin.gd b/addons/godotopenxrvendors/pico/godot_openxr_pico_editor_export_plugin.gd
new file mode 100644
index 0000000..fb13ce9
--- /dev/null
+++ b/addons/godotopenxrvendors/pico/godot_openxr_pico_editor_export_plugin.gd
@@ -0,0 +1,20 @@
+@tool
+extends "../godot_openxr_export_plugin.gd".GodotOpenXREditorExportPlugin
+
+
+func _get_android_manifest_activity_element_contents(platform, debug) -> String:
+ if not _supports_platform(platform) or not(_is_vendor_plugin_enabled()):
+ return ""
+
+ var contents = """
+ \n
+ \n
+ \n
+ \n
+ \n
+ \n
+ \n
+ """
+
+ return contents
diff --git a/addons/godotopenxrvendors/plugin.cfg b/addons/godotopenxrvendors/plugin.cfg
new file mode 100644
index 0000000..9a693b7
--- /dev/null
+++ b/addons/godotopenxrvendors/plugin.cfg
@@ -0,0 +1,7 @@
+[plugin]
+
+name="GodotOpenXRVendors"
+description="Godot OpenXR Vendors plugin"
+author="https://github.com/GodotVR/godot_openxr_vendors/blob/master/CONTRIBUTORS.md"
+version="2.0.1-stable"
+script="godot_openxr_export_plugin.gd"
diff --git a/android/.build_version b/android/.build_version
index ca5fccb..32d2ab7 100644
--- a/android/.build_version
+++ b/android/.build_version
@@ -1 +1 @@
-4.1.3.stable
+4.2.stable
diff --git a/android/plugins/GodotOpenXRKHR.gdap b/android/plugins/GodotOpenXRKHR.gdap
deleted file mode 100644
index d15effb..0000000
--- a/android/plugins/GodotOpenXRKHR.gdap
+++ /dev/null
@@ -1,7 +0,0 @@
-[config]
-
-name="GodotOpenXRKHR"
-binary_type="local"
-binary="godotopenxrkhr/godotopenxrkhr-release.aar"
-
-[dependencies]
diff --git a/android/plugins/GodotOpenXRLoaders_CHANGES.md b/android/plugins/GodotOpenXRLoaders_CHANGES.md
deleted file mode 100644
index cb5d87b..0000000
--- a/android/plugins/GodotOpenXRLoaders_CHANGES.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# Change history for the Godot OpenXR loaders asset
-
-## 1.1.0
-- Update Meta OpenXR loader to version 54
-- Update PICO OpenXR loader to version 2.2.0
-- Bump dependencies versions to match the latest Godot 4.x stable version (v4.0.3)
-
-## 1.0.0
-- First version
-- Added support for Meta Quest loader
-- Added support for Pico loader
-- Added support for Khronos loader (Magic Leap 2, HTC, etc.)
-- Added support for Lynx loader
-- Add logic to automatically publish the Godot OpenXR loaders libraries to mavencentral on release
diff --git a/android/plugins/GodotOpenXRLynx.gdap b/android/plugins/GodotOpenXRLynx.gdap
deleted file mode 100644
index c674fdf..0000000
--- a/android/plugins/GodotOpenXRLynx.gdap
+++ /dev/null
@@ -1,7 +0,0 @@
-[config]
-
-name="GodotOpenXRLynx"
-binary_type="local"
-binary="godotopenxrlynx/godotopenxrlynx-release.aar"
-
-[dependencies]
diff --git a/android/plugins/GodotOpenXRMeta.gdap b/android/plugins/GodotOpenXRMeta.gdap
deleted file mode 100644
index 2549f8d..0000000
--- a/android/plugins/GodotOpenXRMeta.gdap
+++ /dev/null
@@ -1,7 +0,0 @@
-[config]
-
-name="GodotOpenXRMeta"
-binary_type="local"
-binary="godotopenxrmeta/godotopenxrmeta-debug.aar"
-
-[dependencies]
diff --git a/android/plugins/GodotOpenXRPico.gdap b/android/plugins/GodotOpenXRPico.gdap
deleted file mode 100644
index 4fb7033..0000000
--- a/android/plugins/GodotOpenXRPico.gdap
+++ /dev/null
@@ -1,7 +0,0 @@
-[config]
-
-name="GodotOpenXRPico"
-binary_type="local"
-binary="godotopenxrpico/godotopenxrpico-release.aar"
-
-[dependencies]
diff --git a/android/plugins/godotopenxrmeta/godotopenxrmeta-debug.aar b/android/plugins/godotopenxrmeta/godotopenxrmeta-debug.aar
deleted file mode 100644
index b4550f9..0000000
Binary files a/android/plugins/godotopenxrmeta/godotopenxrmeta-debug.aar and /dev/null differ
diff --git a/android/plugins/godotopenxrmeta/godotopenxrmeta-release.aar b/android/plugins/godotopenxrmeta/godotopenxrmeta-release.aar
deleted file mode 100644
index d592ff8..0000000
Binary files a/android/plugins/godotopenxrmeta/godotopenxrmeta-release.aar and /dev/null differ
diff --git a/content/main_golf.tscn b/content/main_golf.tscn
deleted file mode 100644
index 89d8588..0000000
--- a/content/main_golf.tscn
+++ /dev/null
@@ -1,129 +0,0 @@
-[gd_scene load_steps=18 format=3 uid="uid://fap7m74qctpl"]
-
-[ext_resource type="Script" path="res://content/main.gd" id="1_d7nko"]
-[ext_resource type="PackedScene" uid="uid://c3kdssrmv84kv" path="res://content/ui/menu/menu.tscn" id="2_1ns4p"]
-[ext_resource type="Script" path="res://content/raycast.gd" id="3_raorn"]
-[ext_resource type="PackedScene" uid="uid://clc5dre31iskm" path="res://addons/godot-xr-tools/xr/start_xr.tscn" id="4_6x466"]
-[ext_resource type="Material" uid="uid://bf5ina366dwm6" path="res://assets/materials/sky.material" id="5_o7oeh"]
-[ext_resource type="PackedScene" uid="uid://ctltchlf2j2r4" path="res://addons/xr-simulator/XRSimulator.tscn" id="6_yj6uv"]
-
-[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_m58yb"]
-ao_enabled = true
-
-[sub_resource type="BoxMesh" id="BoxMesh_ir3co"]
-material = SubResource("StandardMaterial3D_m58yb")
-size = Vector3(0.01, 0.01, 0.01)
-
-[sub_resource type="Sky" id="Sky_vhymk"]
-sky_material = ExtResource("5_o7oeh")
-
-[sub_resource type="Environment" id="Environment_7ghp0"]
-background_mode = 2
-background_color = Color(0.466667, 0.47451, 0.462745, 0)
-sky = SubResource("Sky_vhymk")
-ambient_light_color = Color(1, 1, 1, 1)
-ambient_light_sky_contribution = 0.72
-
-[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_5qi0p"]
-rough = true
-
-[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_i18hv"]
-
-[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_t7p2m"]
-rough = true
-
-[sub_resource type="SphereShape3D" id="SphereShape3D_wckr8"]
-radius = 0.1
-
-[sub_resource type="SphereMesh" id="SphereMesh_5b0e3"]
-radius = 0.1
-height = 0.2
-
-[sub_resource type="BoxMesh" id="BoxMesh_4w3j6"]
-size = Vector3(0.02, 1, 0.02)
-
-[sub_resource type="BoxShape3D" id="BoxShape3D_huggw"]
-size = Vector3(0.02, 1, 0.02)
-
-[node name="Main" type="Node3D"]
-transform = Transform3D(1, -0.000296142, 0.000270963, 0.000296143, 1, -4.61078e-06, -0.000270962, 4.67014e-06, 1, 0, 0, 0)
-script = ExtResource("1_d7nko")
-
-[node name="XROrigin3D" type="XROrigin3D" parent="."]
-
-[node name="XRCamera3D" type="XRCamera3D" parent="XROrigin3D"]
-transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.798091, 0.311748)
-
-[node name="XRControllerLeft" type="XRController3D" parent="XROrigin3D"]
-transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.469893, 0.597213, -0.251112)
-tracker = &"left_hand"
-pose = &"aim"
-
-[node name="MeshInstance3D" type="MeshInstance3D" parent="XROrigin3D/XRControllerLeft"]
-mesh = SubResource("BoxMesh_ir3co")
-
-[node name="Menu" parent="XROrigin3D/XRControllerLeft" instance=ExtResource("2_1ns4p")]
-transform = Transform3D(-4.37114e-08, 0, -1, -0.707107, 0.707107, 3.09086e-08, 0.707107, 0.707107, -3.09086e-08, 0.183517, 0, -0.0534939)
-
-[node name="XRControllerRight" type="XRController3D" parent="XROrigin3D"]
-transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.488349, 0.559219, -0.2988)
-tracker = &"right_hand"
-pose = &"aim"
-
-[node name="MeshInstance3D" type="MeshInstance3D" parent="XROrigin3D/XRControllerRight"]
-mesh = SubResource("BoxMesh_ir3co")
-
-[node name="Raycast" type="Node3D" parent="XROrigin3D/XRControllerRight" node_paths=PackedStringArray("ray")]
-script = ExtResource("3_raorn")
-ray = NodePath("RayCast3D")
-
-[node name="RayCast3D" type="RayCast3D" parent="XROrigin3D/XRControllerRight/Raycast"]
-transform = Transform3D(-2.58078e-11, 4.3714e-08, 1, 1, -4.37117e-08, 9.27469e-12, 4.37112e-08, 1, -4.3714e-08, 0, 0, 0)
-target_position = Vector3(0, -5, 0)
-
-[node name="RemoteTransform3D" type="RemoteTransform3D" parent="XROrigin3D/XRControllerRight"]
-remote_path = NodePath("../../../Club (AnimatableBody3D)")
-
-[node name="StartXR" parent="." instance=ExtResource("4_6x466")]
-enable_passthrough = true
-
-[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
-environment = SubResource("Environment_7ghp0")
-
-[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
-transform = Transform3D(0.834925, -0.386727, -0.39159, 0.550364, 0.586681, 0.594058, 0, -0.711511, 0.702675, 0, 7.21041, 2.06458)
-shadow_enabled = true
-
-[node name="XRSimulator" parent="." instance=ExtResource("6_yj6uv")]
-xr_origin = NodePath("../XROrigin3D")
-
-[node name="Ground (StaticBody3D)" type="StaticBody3D" parent="."]
-transform = Transform3D(1, -1.39636e-11, 0, 9.47997e-12, 1, 0, 0, 0, 1, 0, 0, 0)
-physics_material_override = SubResource("PhysicsMaterial_5qi0p")
-
-[node name="CollisionShape3D" type="CollisionShape3D" parent="Ground (StaticBody3D)"]
-transform = Transform3D(0.999999, -1.39631e-11, 0, 9.48108e-12, 0.999999, -4.54747e-13, 0, -4.54747e-13, 0.999999, 0, 0, 0)
-shape = SubResource("WorldBoundaryShape3D_i18hv")
-
-[node name="Ball (RigidBody3D)" type="RigidBody3D" parent="."]
-transform = Transform3D(0.999997, -1.39633e-11, 0, 9.48364e-12, 0.999998, -1.81899e-12, 0, 5.91172e-12, 0.999998, 0.487249, 1.15211, -0.679336)
-physics_material_override = SubResource("PhysicsMaterial_t7p2m")
-angular_damp = 4.0
-
-[node name="CollisionShape3D" type="CollisionShape3D" parent="Ball (RigidBody3D)"]
-shape = SubResource("SphereShape3D_wckr8")
-
-[node name="MeshInstance3D" type="MeshInstance3D" parent="Ball (RigidBody3D)"]
-transform = Transform3D(1, -1.39641e-11, 0, 9.47986e-12, 1, 0, 2.91038e-11, 0, 1, 0, 0, 0)
-mesh = SubResource("SphereMesh_5b0e3")
-
-[node name="Club (AnimatableBody3D)" type="AnimatableBody3D" parent="."]
-transform = Transform3D(1, -1.39637e-11, 0, 9.47975e-12, 1, 0, 0, 0, 1, 0.488349, 0.559219, -0.2988)
-
-[node name="MeshInstance3D" type="MeshInstance3D" parent="Club (AnimatableBody3D)"]
-transform = Transform3D(1, -0.000567105, -2.51786e-05, -2.51789e-05, 4.39913e-08, -0.999999, 0.000567105, 1, 2.97096e-08, 0.000972658, -0.00257713, -0.524774)
-mesh = SubResource("BoxMesh_4w3j6")
-
-[node name="CollisionShape3D" type="CollisionShape3D" parent="Club (AnimatableBody3D)"]
-transform = Transform3D(1, -0.000567105, -2.51788e-05, -2.51788e-05, 4.39918e-08, -1, 0.000567105, 1, 2.97127e-08, 0.000972658, -0.00257713, -0.524774)
-shape = SubResource("BoxShape3D_huggw")
diff --git a/export_presets.cfg b/export_presets.cfg
index 7f41361..952470b 100644
--- a/export_presets.cfg
+++ b/export_presets.cfg
@@ -22,10 +22,6 @@ gradle_build/use_gradle_build=true
gradle_build/export_format=0
gradle_build/min_sdk=""
gradle_build/target_sdk=""
-plugins/GodotOpenXRKHR=false
-plugins/GodotOpenXRLynx=false
-plugins/GodotOpenXRMeta=true
-plugins/GodotOpenXRPico=false
architectures/armeabi-v7a=false
architectures/arm64-v8a=true
architectures/x86=false
@@ -38,14 +34,14 @@ package/signed=true
package/app_category=2
package/retain_data_on_uninstall=false
package/exclude_from_recents=false
+package/show_in_android_tv=false
+package/show_in_app_library=true
+package/show_as_launcher_app=false
launcher_icons/main_192x192=""
launcher_icons/adaptive_foreground_432x432=""
launcher_icons/adaptive_background_432x432=""
graphics/opengl_debug=false
xr_features/xr_mode=1
-xr_features/hand_tracking=1
-xr_features/hand_tracking_frequency=1
-xr_features/passthrough=2
screen/immersive_mode=true
screen/support_small=true
screen/support_normal=true
@@ -203,6 +199,23 @@ permissions/write_sms=false
permissions/write_social_stream=false
permissions/write_sync_settings=false
permissions/write_user_dictionary=false
-package/show_in_android_tv=false
-package/show_in_app_library=true
-package/show_as_launcher_app=false
+plugins/GodotOpenXRKHR=false
+plugins/GodotOpenXRLynx=false
+plugins/GodotOpenXRMeta=true
+plugins/GodotOpenXRPico=false
+xr_features/hand_tracking=1
+xr_features/hand_tracking_frequency=1
+xr_features/passthrough=2
+xr_features/enable_meta_plugin=true
+meta_xr_features/eye_tracking=0
+meta_xr_features/hand_tracking=1
+meta_xr_features/hand_tracking_frequency=1
+meta_xr_features/passthrough=2
+meta_xr_features/use_anchor_api=false
+meta_xr_features/quest_1_support=false
+meta_xr_features/quest_2_support=true
+meta_xr_features/quest_3_support=true
+meta_xr_features/quest_pro_support=true
+xr_features/enable_pico_plugin=false
+xr_features/enable_lynx_plugin=false
+xr_features/enable_khronos_plugin=false
diff --git a/export_presets_prod.cfg b/export_presets_prod.cfg
index 8311756..8222d14 100644
--- a/export_presets_prod.cfg
+++ b/export_presets_prod.cfg
@@ -22,10 +22,6 @@ gradle_build/use_gradle_build=true
gradle_build/export_format=0
gradle_build/min_sdk=""
gradle_build/target_sdk="32"
-plugins/GodotOpenXRKHR=false
-plugins/GodotOpenXRLynx=false
-plugins/GodotOpenXRMeta=true
-plugins/GodotOpenXRPico=false
architectures/armeabi-v7a=false
architectures/arm64-v8a=true
architectures/x86=false
@@ -38,14 +34,14 @@ package/signed=true
package/app_category=2
package/retain_data_on_uninstall=false
package/exclude_from_recents=false
+package/show_in_android_tv=false
+package/show_in_app_library=true
+package/show_as_launcher_app=false
launcher_icons/main_192x192=""
launcher_icons/adaptive_foreground_432x432=""
launcher_icons/adaptive_background_432x432=""
graphics/opengl_debug=false
xr_features/xr_mode=1
-xr_features/hand_tracking=1
-xr_features/hand_tracking_frequency=1
-xr_features/passthrough=2
screen/immersive_mode=true
screen/support_small=true
screen/support_normal=true
@@ -203,6 +199,23 @@ permissions/write_sms=false
permissions/write_social_stream=false
permissions/write_sync_settings=false
permissions/write_user_dictionary=false
-package/show_in_android_tv=false
-package/show_in_app_library=true
-package/show_as_launcher_app=false
+plugins/GodotOpenXRKHR=false
+plugins/GodotOpenXRLynx=false
+plugins/GodotOpenXRMeta=true
+plugins/GodotOpenXRPico=false
+xr_features/hand_tracking=1
+xr_features/hand_tracking_frequency=1
+xr_features/passthrough=2
+xr_features/enable_meta_plugin=true
+meta_xr_features/eye_tracking=0
+meta_xr_features/hand_tracking=1
+meta_xr_features/hand_tracking_frequency=1
+meta_xr_features/passthrough=2
+meta_xr_features/use_anchor_api=false
+meta_xr_features/quest_1_support=false
+meta_xr_features/quest_2_support=true
+meta_xr_features/quest_3_support=true
+meta_xr_features/quest_pro_support=true
+xr_features/enable_pico_plugin=false
+xr_features/enable_lynx_plugin=false
+xr_features/enable_khronos_plugin=false
\ No newline at end of file
diff --git a/project.godot b/project.godot
index 4965a39..8398d86 100644
--- a/project.godot
+++ b/project.godot
@@ -26,7 +26,7 @@ EventSystem="*res://lib/globals/event_system.gd"
[editor_plugins]
-enabled=PackedStringArray("res://addons/godot-xr-tools/plugin.cfg")
+enabled=PackedStringArray("res://addons/godot-xr-tools/plugin.cfg", "res://addons/godotopenxrvendors/plugin.cfg")
[filesystem]