Add support for OpenXR export configurations.

This commit is contained in:
Fredia Huya-Kouadio 2021-11-19 13:15:01 -08:00
parent c6d2768a19
commit 882ec0d611
7 changed files with 83 additions and 19 deletions

View File

@ -751,9 +751,9 @@ void EditorExportPlatformAndroid::_get_permissions(const Ref<EditorExportPreset>
} }
int xr_mode_index = p_preset->get("xr_features/xr_mode"); int xr_mode_index = p_preset->get("xr_features/xr_mode");
if (xr_mode_index == 1 /* XRMode.OVR */) { if (xr_mode_index == XR_MODE_OPENXR) {
int hand_tracking_index = p_preset->get("xr_features/hand_tracking"); // 0: none, 1: optional, 2: required int hand_tracking_index = p_preset->get("xr_features/hand_tracking"); // 0: none, 1: optional, 2: required
if (hand_tracking_index > 0) { if (hand_tracking_index > XR_HAND_TRACKING_NONE) {
if (r_permissions.find("com.oculus.permission.HAND_TRACKING") == -1) { if (r_permissions.find("com.oculus.permission.HAND_TRACKING") == -1) {
r_permissions.push_back("com.oculus.permission.HAND_TRACKING"); r_permissions.push_back("com.oculus.permission.HAND_TRACKING");
} }
@ -964,6 +964,20 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
} }
} }
if (tname == "meta-data" && attrname == "name" && value == "xr_mode_metadata_name") {
// Update the meta-data 'android:name' attribute based on the selected XR mode.
if (xr_mode_index == XR_MODE_OPENXR) {
string_table.write[attr_value] = "com.samsung.android.vr.application.mode";
}
}
if (tname == "meta-data" && attrname == "value" && value == "xr_mode_metadata_value") {
// Update the meta-data 'android:value' attribute based on the selected XR mode.
if (xr_mode_index == XR_MODE_OPENXR) {
string_table.write[attr_value] = "vr_only";
}
}
iofs += 20; iofs += 20;
} }
@ -978,7 +992,7 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
Vector<bool> feature_required_list; Vector<bool> feature_required_list;
Vector<int> feature_versions; Vector<int> feature_versions;
if (xr_mode_index == 1 /* XRMode.OVR */) { if (xr_mode_index == XR_MODE_OPENXR) {
// Set degrees of freedom // Set degrees of freedom
feature_names.push_back("android.hardware.vr.headtracking"); feature_names.push_back("android.hardware.vr.headtracking");
feature_required_list.push_back(true); feature_required_list.push_back(true);
@ -986,11 +1000,19 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
// Check for hand tracking // Check for hand tracking
int hand_tracking_index = p_preset->get("xr_features/hand_tracking"); // 0: none, 1: optional, 2: required int hand_tracking_index = p_preset->get("xr_features/hand_tracking"); // 0: none, 1: optional, 2: required
if (hand_tracking_index > 0) { if (hand_tracking_index > XR_HAND_TRACKING_NONE) {
feature_names.push_back("oculus.software.handtracking"); feature_names.push_back("oculus.software.handtracking");
feature_required_list.push_back(hand_tracking_index == 2); feature_required_list.push_back(hand_tracking_index == XR_HAND_TRACKING_REQUIRED);
feature_versions.push_back(-1); // no version attribute should be added. feature_versions.push_back(-1); // no version attribute should be added.
} }
// Check for passthrough
int passthrough_mode = p_preset->get("xr_features/passthrough");
if (passthrough_mode > XR_PASSTHROUGH_NONE) {
feature_names.push_back("com.oculus.feature.PASSTHROUGH");
feature_required_list.push_back(passthrough_mode == XR_PASSTHROUGH_REQUIRED);
feature_versions.push_back(-1);
}
} }
if (feature_names.size() > 0) { if (feature_names.size() > 0) {
@ -1669,8 +1691,9 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/opengl_debug"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/opengl_debug"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/xr_mode", PROPERTY_HINT_ENUM, "Regular,Oculus Mobile VR"), 0)); r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/xr_mode", PROPERTY_HINT_ENUM, "Regular,OpenXR"), 0));
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/hand_tracking", PROPERTY_HINT_ENUM, "None,Optional,Required"), 0)); r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/hand_tracking", PROPERTY_HINT_ENUM, "None,Optional,Required"), 0));
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/passthrough", PROPERTY_HINT_ENUM, "None,Optional,Required"), 0));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/immersive_mode"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/immersive_mode"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_small"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_small"), true));
@ -2137,10 +2160,17 @@ bool EditorExportPlatformAndroid::can_export(const Ref<EditorExportPreset> &p_pr
// Validate the Xr features are properly populated // Validate the Xr features are properly populated
int xr_mode_index = p_preset->get("xr_features/xr_mode"); int xr_mode_index = p_preset->get("xr_features/xr_mode");
int hand_tracking = p_preset->get("xr_features/hand_tracking"); int hand_tracking = p_preset->get("xr_features/hand_tracking");
if (xr_mode_index != /* XRMode.OVR*/ 1) { int passthrough_mode = p_preset->get("xr_features/passthrough");
if (hand_tracking > 0) { if (xr_mode_index != XR_MODE_OPENXR) {
if (hand_tracking > XR_HAND_TRACKING_NONE) {
valid = false; valid = false;
err += TTR("\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR\"."); err += TTR("\"Hand Tracking\" is only valid when \"Xr Mode\" is \"OpenXR\".");
err += "\n";
}
if (passthrough_mode > XR_PASSTHROUGH_NONE) {
valid = false;
err += TTR("\"Passthrough\" is only valid when \"Xr Mode\" is \"OpenXR\".");
err += "\n"; err += "\n";
} }
} }
@ -2202,8 +2232,8 @@ void EditorExportPlatformAndroid::get_command_line_flags(const Ref<EditorExportP
} }
int xr_mode_index = p_preset->get("xr_features/xr_mode"); int xr_mode_index = p_preset->get("xr_features/xr_mode");
if (xr_mode_index == 1) { if (xr_mode_index == XR_MODE_OPENXR) {
command_line_strings.push_back("--xr_mode_ovr"); command_line_strings.push_back("--xr_mode_openxr");
} else { // XRMode.REGULAR is the default. } else { // XRMode.REGULAR is the default.
command_line_strings.push_back("--xr_mode_regular"); command_line_strings.push_back("--xr_mode_regular");
} }

View File

@ -211,16 +211,24 @@ String _get_screen_sizes_tag(const Ref<EditorExportPreset> &p_preset) {
String _get_xr_features_tag(const Ref<EditorExportPreset> &p_preset) { String _get_xr_features_tag(const Ref<EditorExportPreset> &p_preset) {
String manifest_xr_features; String manifest_xr_features;
bool uses_xr = (int)(p_preset->get("xr_features/xr_mode")) == 1; int xr_mode_index = (int)(p_preset->get("xr_features/xr_mode"));
bool uses_xr = xr_mode_index == XR_MODE_OPENXR;
if (uses_xr) { if (uses_xr) {
manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"android.hardware.vr.headtracking\" android:required=\"true\" android:version=\"1\" />\n"; manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"android.hardware.vr.headtracking\" android:required=\"true\" android:version=\"1\" />\n";
int hand_tracking_index = p_preset->get("xr_features/hand_tracking"); // 0: none, 1: optional, 2: required int hand_tracking_index = p_preset->get("xr_features/hand_tracking"); // 0: none, 1: optional, 2: required
if (hand_tracking_index == 1) { if (hand_tracking_index == XR_HAND_TRACKING_OPTIONAL) {
manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"oculus.software.handtracking\" android:required=\"false\" />\n"; manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"oculus.software.handtracking\" android:required=\"false\" />\n";
} else if (hand_tracking_index == 2) { } else if (hand_tracking_index == XR_HAND_TRACKING_REQUIRED) {
manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"oculus.software.handtracking\" android:required=\"true\" />\n"; manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"oculus.software.handtracking\" android:required=\"true\" />\n";
} }
int passthrough_mode = p_preset->get("xr_features/passthrough");
if (passthrough_mode == XR_PASSTHROUGH_OPTIONAL) {
manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"com.oculus.feature.PASSTHROUGH\" android:required=\"false\" />\n";
} else if (passthrough_mode == XR_PASSTHROUGH_REQUIRED) {
manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"com.oculus.feature.PASSTHROUGH\" android:required=\"true\" />\n";
}
} }
return manifest_xr_features; return manifest_xr_features;
} }
@ -239,7 +247,8 @@ String _get_instrumentation_tag(const Ref<EditorExportPreset> &p_preset) {
} }
String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) { String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) {
bool uses_xr = (int)(p_preset->get("xr_features/xr_mode")) == 1; int xr_mode_index = (int)(p_preset->get("xr_features/xr_mode"));
bool uses_xr = xr_mode_index == XR_MODE_OPENXR;
String orientation = _get_android_orientation_label(DisplayServer::ScreenOrientation(int(GLOBAL_GET("display/window/handheld/orientation")))); String orientation = _get_android_orientation_label(DisplayServer::ScreenOrientation(int(GLOBAL_GET("display/window/handheld/orientation"))));
String manifest_activity_text = vformat( String manifest_activity_text = vformat(
" <activity android:name=\"com.godot.game.GodotApp\" " " <activity android:name=\"com.godot.game.GodotApp\" "
@ -256,6 +265,8 @@ String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) {
} }
String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_storage_permission) { String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_storage_permission) {
int xr_mode_index = (int)(p_preset->get("xr_features/xr_mode"));
bool uses_xr = xr_mode_index == XR_MODE_OPENXR;
String manifest_application_text = vformat( String manifest_application_text = vformat(
" <application android:label=\"@string/godot_project_name_string\"\n" " <application android:label=\"@string/godot_project_name_string\"\n"
" android:allowBackup=\"%s\"\n" " android:allowBackup=\"%s\"\n"
@ -270,6 +281,9 @@ String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_
bool_to_string(p_preset->get("package/retain_data_on_uninstall")), bool_to_string(p_preset->get("package/retain_data_on_uninstall")),
bool_to_string(p_has_storage_permission)); bool_to_string(p_has_storage_permission));
if (uses_xr) {
manifest_application_text += " <meta-data tools:node=\"replace\" android:name=\"com.samsung.android.vr.application.mode\" android:value=\"vr_only\" />\n";
}
manifest_application_text += _get_activity_tag(p_preset); manifest_application_text += _get_activity_tag(p_preset);
manifest_application_text += " </application>\n"; manifest_application_text += " </application>\n";
return manifest_application_text; return manifest_application_text;

View File

@ -44,6 +44,21 @@ const String godot_project_name_xml_string = R"(<?xml version="1.0" encoding="ut
</resources> </resources>
)"; )";
// Supported XR modes.
// This should match the entries in 'platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java'
static const int XR_MODE_REGULAR = 0;
static const int XR_MODE_OPENXR = 1;
// Supported XR hand tracking modes.
static const int XR_HAND_TRACKING_NONE = 0;
static const int XR_HAND_TRACKING_OPTIONAL = 1;
static const int XR_HAND_TRACKING_REQUIRED = 2;
// Supported XR passthrough modes.
static const int XR_PASSTHROUGH_NONE = 0;
static const int XR_PASSTHROUGH_OPTIONAL = 1;
static const int XR_PASSTHROUGH_REQUIRED = 2;
struct CustomExportData { struct CustomExportData {
String assets_directory; String assets_directory;
bool debug; bool debug;

View File

@ -33,6 +33,11 @@
<!-- The following metadata values are replaced when Godot exports, modifying them here has no effect. --> <!-- The following metadata values are replaced when Godot exports, modifying them here has no effect. -->
<!-- Do these changes in the export preset. Adding new ones is fine. --> <!-- Do these changes in the export preset. Adding new ones is fine. -->
<!-- XR mode metadata. This is modified by the exporter based on the selected xr mode. DO NOT CHANGE the values here. -->
<meta-data
android:name="xr_mode_metadata_name"
android:value="xr_mode_metadata_value" />
<activity <activity
android:name=".GodotApp" android:name=".GodotApp"
android:label="@string/godot_project_name_string" android:label="@string/godot_project_name_string"

View File

@ -502,8 +502,8 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
boolean has_extra = i < command_line.length - 1; boolean has_extra = i < command_line.length - 1;
if (command_line[i].equals(XRMode.REGULAR.cmdLineArg)) { if (command_line[i].equals(XRMode.REGULAR.cmdLineArg)) {
xrMode = XRMode.REGULAR; xrMode = XRMode.REGULAR;
} else if (command_line[i].equals(XRMode.OVR.cmdLineArg)) { } else if (command_line[i].equals(XRMode.OPENXR.cmdLineArg)) {
xrMode = XRMode.OVR; xrMode = XRMode.OPENXR;
} else if (command_line[i].equals("--debug_opengl")) { } else if (command_line[i].equals("--debug_opengl")) {
use_debug_opengl = true; use_debug_opengl = true;
} else if (command_line[i].equals("--use_immersive")) { } else if (command_line[i].equals("--use_immersive")) {

View File

@ -174,7 +174,7 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView
setPreserveEGLContextOnPause(true); setPreserveEGLContextOnPause(true);
setFocusableInTouchMode(true); setFocusableInTouchMode(true);
switch (xrMode) { switch (xrMode) {
case OVR: case OPENXR:
// Replace the default egl config chooser. // Replace the default egl config chooser.
setEGLConfigChooser(new OvrConfigChooser()); setEGLConfigChooser(new OvrConfigChooser());

View File

@ -35,7 +35,7 @@ package org.godotengine.godot.xr;
*/ */
public enum XRMode { public enum XRMode {
REGULAR(0, "Regular", "--xr_mode_regular", "Default Android Gamepad"), // Regular/flatscreen REGULAR(0, "Regular", "--xr_mode_regular", "Default Android Gamepad"), // Regular/flatscreen
OVR(1, "Oculus Mobile VR", "--xr_mode_ovr", ""); OPENXR(1, "OpenXR", "--xr_mode_openxr", "");
final int index; final int index;
final String label; final String label;