Skip to content

Commit

Permalink
Add additional export options for Meta Quest features (GodotVR#82)
Browse files Browse the repository at this point in the history
A lot of Meta Quest features are gated by AndroidManifest flags. Adding export options to support:
- Experimental Features: https://developer.oculus.com/experimental/experimental-overview/
- Overlay Keyboard: https://developer.oculus.com/documentation/unity/unity-keyboard-overlay/
- Boundary Modes (can't find documentation, but already used by a few apps on the Quest Store)

Co-authored-by: Mauricio Narvaez <nvz@meta.com>
  • Loading branch information
m4gr3d and Mauricio Narvaez authored Feb 3, 2024
1 parent e946c3a commit a783e3d
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 0 deletions.
61 changes: 61 additions & 0 deletions godotopenxrmeta/src/main/cpp/export/meta_export_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,36 @@ MetaEditorExportPlugin::MetaEditorExportPlugin() {
false,
false
);
_use_overlay_keyboard_option = _generate_export_option(
"meta_xr_features/use_overlay_keyboard",
"",
Variant::Type::BOOL,
PROPERTY_HINT_NONE,
"",
PROPERTY_USAGE_DEFAULT,
false,
false
);
_use_experimental_features_option = _generate_export_option(
"meta_xr_features/use_experimental_features",
"",
Variant::Type::BOOL,
PROPERTY_HINT_NONE,
"",
PROPERTY_USAGE_DEFAULT,
false,
false
);
_boundary_mode_option = _generate_export_option(
"meta_xr_features/boundary_mode",
"",
Variant::Type::INT,
PROPERTY_HINT_ENUM,
"Enabled,Disabled,Contextual",
PROPERTY_USAGE_DEFAULT,
BOUNDARY_ENABLED_VALUE,
false
);
_support_quest_1_option = _generate_export_option(
"meta_xr_features/quest_1_support",
"",
Expand Down Expand Up @@ -168,6 +198,9 @@ TypedArray<Dictionary> MetaEditorExportPlugin::_get_export_options(const Ref<Edi
export_options.append(_passthrough_option);
export_options.append(_use_anchor_api_option);
export_options.append(_use_scene_api_option);
export_options.append(_use_overlay_keyboard_option);
export_options.append(_use_experimental_features_option);
export_options.append(_boundary_mode_option);
export_options.append(_support_quest_1_option);
export_options.append(_support_quest_2_option);
export_options.append(_support_quest_3_option);
Expand Down Expand Up @@ -250,6 +283,14 @@ String MetaEditorExportPlugin::_get_export_option_warning(const Ref<EditorExport
if (!openxr_enabled && _get_bool_option(option)) {
return "\"Use scene API\" is only valid when \"XR Mode\" is \"OpenXR\".\n";
}
} else if (option == "meta_xr_features/use_experimental_features") {
if (!openxr_enabled && _get_bool_option(option)) {
return "\"Use experimental features\" is only valid when \"XR Mode\" is \"OpenXR\".\n";
}
} else if (option == "meta_xr_features/boundary_mode") {
if (!openxr_enabled && _get_int_option(option, BOUNDARY_ENABLED_VALUE) > BOUNDARY_ENABLED_VALUE) {
return "Boundary mode changes require \"XR Mode\" to be \"OpenXR\".\n";
}
}

return OpenXREditorExportPlugin::_get_export_option_warning(platform, option);
Expand Down Expand Up @@ -305,6 +346,26 @@ String MetaEditorExportPlugin::_get_android_manifest_element_contents(const Ref<
contents += " <uses-permission android:name=\"com.oculus.permission.USE_SCENE\" />\n";
}

// Check for overlay keyboard
bool use_overlay_keyboard_option = _get_bool_option("meta_xr_features/use_overlay_keyboard");
if (use_overlay_keyboard_option) {
contents += " <uses-feature android:name=\"oculus.software.overlay_keyboard\" android:required=\"true\" />\n";
}

// Check for experimental features
bool use_experimental_features = _get_bool_option("meta_xr_features/use_experimental_features");
if (use_experimental_features) {
contents += " <uses-feature android:name=\"com.oculus.experimental.enabled\" />\n";
}

// Check for boundary mode
int boundary_mode = _get_int_option("meta_xr_features/boundary_mode", BOUNDARY_ENABLED_VALUE);
if (boundary_mode == BOUNDARY_DISABLED_VALUE) {
contents += " <uses-feature tools:node=\"replace\" android:name=\"com.oculus.feature.BOUNDARYLESS_APP\" android:required=\"true\" />\n";
} else if (boundary_mode == BOUNDARY_CONTEXTUAL_VALUE) {
contents += " <uses-feature tools:node=\"replace\" android:name=\"com.oculus.feature.CONTEXTUAL_BOUNDARYLESS_APP\" android:required=\"true\" />\n";
}

return contents;
}

Expand Down
7 changes: 7 additions & 0 deletions godotopenxrmeta/src/main/cpp/export/meta_export_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ static const int HAND_TRACKING_REQUIRED_VALUE = 2;
static const int HAND_TRACKING_FREQUENCY_LOW_VALUE = 0;
static const int HAND_TRACKING_FREQUENCY_HIGH_VALUE = 1;

static const int BOUNDARY_ENABLED_VALUE = 0;
static const int BOUNDARY_DISABLED_VALUE = 1;
static const int BOUNDARY_CONTEXTUAL_VALUE = 2;

} // namespace

class MetaEditorExportPlugin : public OpenXREditorExportPlugin {
Expand Down Expand Up @@ -84,6 +88,9 @@ class MetaEditorExportPlugin : public OpenXREditorExportPlugin {
Dictionary _passthrough_option;
Dictionary _use_anchor_api_option;
Dictionary _use_scene_api_option;
Dictionary _use_overlay_keyboard_option;
Dictionary _use_experimental_features_option;
Dictionary _boundary_mode_option;
Dictionary _support_quest_1_option;
Dictionary _support_quest_2_option;
Dictionary _support_quest_3_option;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class GodotOpenXRMeta(godot: Godot?) : GodotPlugin(godot) {
}
// Request the scene API permission if it's included in the manifest
if (PermissionsUtil.hasManifestPermission(activity, SCENE_PERMISSION)) {
Log.d(TAG, "Requesting permission '${SCENE_PERMISSION}'")
PermissionsUtil.requestPermission(SCENE_PERMISSION, activity)
}
return null
Expand Down

0 comments on commit a783e3d

Please sign in to comment.