Skip to content

Commit

Permalink
Add settings for HTC (#148)
Browse files Browse the repository at this point in the history
  • Loading branch information
BastiaanOlij authored May 22, 2024
1 parent b3ccf3c commit 71b383a
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- Add XR_FB_hand_tracking_capsules extension wrapper
- Add OpenXRFbPassthroughGeometry node
- Add OpenXRMetaPassthroughColorLut
- Add feature flags to Khronos loader for HTC

## 2.0.3
- Migrate the export scripts from gdscript to C++ via gdextension
Expand Down
122 changes: 122 additions & 0 deletions common/src/main/cpp/export/khronos_export_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,103 @@ void KhronosEditorPlugin::_exit_tree() {

KhronosEditorExportPlugin::KhronosEditorExportPlugin() {
set_vendor_name(KHRONOS_VENDOR_NAME);

_hand_tracking_option = _generate_export_option(
"khronos_xr_features/htc/hand_tracking",
"",
Variant::Type::INT,
PROPERTY_HINT_ENUM,
"No,Yes",
PROPERTY_USAGE_DEFAULT,
MANIFEST_FALSE_VALUE,
false);
_tracker_option = _generate_export_option(
"khronos_xr_features/htc/tracker",
"",
Variant::Type::INT,
PROPERTY_HINT_ENUM,
"No,Yes",
PROPERTY_USAGE_DEFAULT,
MANIFEST_FALSE_VALUE,
false);
_eye_tracking_option = _generate_export_option(
"khronos_xr_features/htc/eye_tracking",
"",
Variant::Type::INT,
PROPERTY_HINT_ENUM,
"No,Yes",
PROPERTY_USAGE_DEFAULT,
MANIFEST_FALSE_VALUE,
false);
_lip_expression_option = _generate_export_option(
"khronos_xr_features/htc/lip_expression",
"",
Variant::Type::INT,
PROPERTY_HINT_ENUM,
"No,Yes",
PROPERTY_USAGE_DEFAULT,
MANIFEST_FALSE_VALUE,
false);
}

void KhronosEditorExportPlugin::_bind_methods() {}

TypedArray<Dictionary> KhronosEditorExportPlugin::_get_export_options(const Ref<EditorExportPlatform> &platform) const {
TypedArray<Dictionary> export_options;
if (!_supports_platform(platform)) {
return export_options;
}

export_options.append(_get_vendor_toggle_option());
export_options.append(_hand_tracking_option);
export_options.append(_tracker_option);
export_options.append(_eye_tracking_option);
export_options.append(_lip_expression_option);

return export_options;
}

PackedStringArray KhronosEditorExportPlugin::_get_export_features(const Ref<EditorExportPlatform> &platform, bool debug) const {
PackedStringArray features;
if (!_supports_platform(platform)) {
return features;
}

// Add the eye tracking feature if necessary
if (_get_int_option("khronos_xr_features/htc/eye_tracking", MANIFEST_FALSE_VALUE) == MANIFEST_TRUE_VALUE) {
features.append(EYE_GAZE_INTERACTION_FEATURE);
}

return features;
}

String KhronosEditorExportPlugin::_get_export_option_warning(const Ref<EditorExportPlatform> &platform, const String &option) const {
if (!_supports_platform(platform)) {
return "";
}

bool openxr_enabled = _is_openxr_enabled();
if (option == "khronos_xr_features/htc/hand_tracking") {
if (!openxr_enabled && _get_int_option(option, MANIFEST_FALSE_VALUE) == MANIFEST_TRUE_VALUE) {
return "\"Hand Tracking\" requires \"XR Mode\" to be \"OpenXR\".\n";
}
} else if (option == "khronos_xr_features/htc/tracker") {
if (!openxr_enabled && _get_int_option(option, MANIFEST_FALSE_VALUE) == MANIFEST_TRUE_VALUE) {
return "\"Tracker\" requires \"XR Mode\" to be \"OpenXR\".\n";
}
} else if (option == "khronos_xr_features/htc/eye_tracking") {
if (!openxr_enabled && _get_int_option(option, MANIFEST_FALSE_VALUE) == MANIFEST_TRUE_VALUE) {
return "\"Eye tracking\" requires \"XR Mode\" to be \"OpenXR\".\n";
}
} else if (option == "khronos_xr_features/htc/lip_expression") {
if (!openxr_enabled && _get_int_option(option, MANIFEST_FALSE_VALUE) == MANIFEST_TRUE_VALUE) {
return "\"Lip expression\" requires \"XR Mode\" to be \"OpenXR\".\n";
}
}

return OpenXREditorExportPlugin::_get_export_option_warning(platform, option);
}

String KhronosEditorExportPlugin::_get_android_manifest_activity_element_contents(const Ref<EditorExportPlatform> &platform, bool debug) const {
if (!_supports_platform(platform) || !_is_vendor_plugin_enabled()) {
return "";
Expand All @@ -71,3 +164,32 @@ String KhronosEditorExportPlugin::_get_android_manifest_activity_element_content
</intent-filter>
)";
}

String KhronosEditorExportPlugin::_get_android_manifest_element_contents(const Ref<EditorExportPlatform> &platform, bool debug) const {
String contents;
if (!_supports_platform(platform) || !_is_vendor_plugin_enabled()) {
return contents;
}

// Check for hand tracking
if (_get_int_option("khronos_xr_features/htc/hand_tracking", MANIFEST_FALSE_VALUE) == MANIFEST_TRUE_VALUE) {
contents += " <uses-feature tools:node=\"replace\" android:name=\"wave.feature.handtracking\" android:required=\"true\" />\n";
}

// Check for tracker
if (_get_int_option("khronos_xr_features/htc/tracker", MANIFEST_FALSE_VALUE) == MANIFEST_TRUE_VALUE) {
contents += " <uses-feature tools:node=\"replace\" android:name=\"wave.feature.tracker\" android:required=\"true\" />\n";
}

// Check for eye tracking
if (_get_int_option("khronos_xr_features/htc/eye_tracking", MANIFEST_FALSE_VALUE) == MANIFEST_TRUE_VALUE) {
contents += " <uses-feature tools:node=\"replace\" android:name=\"wave.feature.eyetracking\" android:required=\"true\" />\n";
}

// Check for lip expression
if (_get_int_option("khronos_xr_features/htc/lip_expression", MANIFEST_FALSE_VALUE) == MANIFEST_TRUE_VALUE) {
contents += " <uses-feature tools:node=\"replace\" android:name=\"wave.feature.lipexpression\" android:required=\"true\" />\n";
}

return contents;
}
15 changes: 15 additions & 0 deletions common/src/main/cpp/include/export/khronos_export_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,31 @@

using namespace godot;

static const int MANIFEST_FALSE_VALUE = 0;
static const int MANIFEST_TRUE_VALUE = 1;

class KhronosEditorExportPlugin : public OpenXREditorExportPlugin {
GDCLASS(KhronosEditorExportPlugin, OpenXREditorExportPlugin)

public:
KhronosEditorExportPlugin();

TypedArray<Dictionary> _get_export_options(const Ref<EditorExportPlatform> &platform) const override;

PackedStringArray _get_export_features(const Ref<EditorExportPlatform> &platform, bool debug) const override;

String _get_export_option_warning(const Ref<EditorExportPlatform> &platform, const String &option) const override;

String _get_android_manifest_activity_element_contents(const Ref<EditorExportPlatform> &platform, bool debug) const override;
String _get_android_manifest_element_contents(const Ref<EditorExportPlatform> &platform, bool debug) const override;

protected:
static void _bind_methods();

Dictionary _hand_tracking_option;
Dictionary _tracker_option;
Dictionary _eye_tracking_option;
Dictionary _lip_expression_option;
};

class KhronosEditorPlugin : public EditorPlugin {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,12 @@ class GodotOpenXRKhronos(godot: Godot?) : GodotPlugin(godot) {
override fun getPluginName(): String {
return "GodotOpenXRKhronos"
}

override fun supportsFeature(featureTag: String): Boolean {
if ("PERMISSION_XR_EXT_eye_gaze_interaction" == featureTag) {
/* HTC doesn't require permission, if other headsets that use the Khronos loader do, we need to figure out how to tell them apart... */
return true
}
return false
}
}

0 comments on commit 71b383a

Please sign in to comment.