Skip to content

Commit

Permalink
Added export plugin for Magic Leap
Browse files Browse the repository at this point in the history
  • Loading branch information
BastiaanOlij committed Aug 21, 2024
1 parent 8f9488b commit 0feace8
Show file tree
Hide file tree
Showing 19 changed files with 750 additions and 10 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/build-addon-on-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ jobs:
mkdir -p asset/addons/godotopenxrvendors/khronos/
cp aar/thirdparty/khronos_openxr_sdk/LICENSE asset/addons/godotopenxrvendors/khronos/LICENSE
mkdir -p asset/addons/godotopenxrvendors/magicleap/
cp aar/thirdparty/khronos_openxr_sdk/LICENSE asset/addons/godotopenxrvendors/magicleap/LICENSE
- name: Copying artifacts
run: |
mkdir -p asset/addons/godotopenxrvendors/.bin/android/
Expand Down
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
- Add XR_HTC_passthrough extension wrapper
- Add manifest entries to Pico and switch Pico to using the Khronos Loader
- Add Meta Passthrough tutorial doc
- Add export profile for Magic Leap 2

## 2.0.3
- Migrate the export scripts from gdscript to C++ via gdextension
Expand Down
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ task clean(type: Delete) {
dependsOn ':godotopenxrlynx:clean'
dependsOn ':godotopenxrmeta:clean'
dependsOn ':godotopenxrpico:clean'
dependsOn ':godotopenxrmagicleap:clean'
}

/**
Expand All @@ -56,6 +57,7 @@ task buildPlugin {
dependsOn ":godotopenxrlynx:build"
dependsOn ":godotopenxrmeta:build"
dependsOn ":godotopenxrpico:build"
dependsOn ":godotopenxrmagicleap:build"

finalizedBy "copyBuildToSamples"
}
Expand Down
148 changes: 148 additions & 0 deletions common/src/main/cpp/export/magicleap_export_plugin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/**************************************************************************/
/* magicleap_editor_plugin.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT XR */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2022-present Godot XR contributors (see CONTRIBUTORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

#include "export/magicleap_export_plugin.h"

using namespace godot;

void MagicleapEditorPlugin::_bind_methods() {}

void MagicleapEditorPlugin::_enter_tree() {
// Initialize the editor export plugin
magicleap_export_plugin.instantiate();
add_export_plugin(magicleap_export_plugin);
}

void MagicleapEditorPlugin::_exit_tree() {
// Clean up the editor export plugin
remove_export_plugin(magicleap_export_plugin);

magicleap_export_plugin.unref();
}

MagicleapEditorExportPlugin::MagicleapEditorExportPlugin() {
set_vendor_name(MAGICLEAP_VENDOR_NAME);

_ml2_hand_tracking_option = _generate_export_option(
"magicleap_xr_features/hand_tracking",
"",
Variant::Type::INT,
PROPERTY_HINT_ENUM,
"No,Yes",
PROPERTY_USAGE_DEFAULT,
MANIFEST_FALSE_VALUE,
false);
}

void MagicleapEditorExportPlugin::_bind_methods() {}

TypedArray<Dictionary> MagicleapEditorExportPlugin::_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(_ml2_hand_tracking_option);

return export_options;
}

Dictionary MagicleapEditorExportPlugin::_get_export_options_overrides(const Ref<godot::EditorExportPlatform> &p_platform) const {
Dictionary overrides;
if (!_supports_platform(p_platform)) {
return overrides;
}

return overrides;
}

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

return features;
}

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

bool openxr_enabled = _is_openxr_enabled();
if (option == "magicleap_xr_features/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";
}
}

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

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

contents += R"(
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<!-- OpenXR category tag to indicate the activity starts in an immersive OpenXR mode.
See https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#android-runtime-category. -->
<category android:name="org.khronos.openxr.intent.category.IMMERSIVE_HMD" />
)";

contents += R"(
</intent-filter>
)";
return contents;
}

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

if (_get_int_option("magicleap_xr_features/hand_tracking", MANIFEST_FALSE_VALUE) == MANIFEST_TRUE_VALUE) {
contents += " <uses-permission android:name=\"com.magicleap.permission.HAND_TRACKING\" />\n";
}

// Always include this.
contents += " <uses-feature android:name=\"com.magicleap.api_level\" android:version=\"20\" />\n";

return contents;
}
5 changes: 5 additions & 0 deletions common/src/main/cpp/include/export/export_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,14 @@ static const char *META_VENDOR_NAME = "meta";
static const char *PICO_VENDOR_NAME = "pico";
static const char *LYNX_VENDOR_NAME = "lynx";
static const char *KHRONOS_VENDOR_NAME = "khronos";
static const char *MAGICLEAP_VENDOR_NAME = "magicleap";

static const char *VENDORS_LIST[] = {
META_VENDOR_NAME,
PICO_VENDOR_NAME,
LYNX_VENDOR_NAME,
KHRONOS_VENDOR_NAME,
MAGICLEAP_VENDOR_NAME,
};

// Set of custom feature tags supported by the plugin
Expand All @@ -58,6 +60,9 @@ static const char *EYE_GAZE_INTERACTION_FEATURE = "XR_EXT_eye_gaze_interaction";
static const int REGULAR_MODE_VALUE = 0;
static const int OPENXR_MODE_VALUE = 1;

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

/// Base class for the vendor editor export plugin
class OpenXREditorExportPlugin : public EditorExportPlugin {
GDCLASS(OpenXREditorExportPlugin, EditorExportPlugin)
Expand Down
3 changes: 0 additions & 3 deletions common/src/main/cpp/include/export/khronos_export_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@ using namespace godot;
static const int KHRONOS_VENDOR_OTHER = 0;
static const int KHRONOS_VENDOR_HTC = 1;

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

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

Expand Down
73 changes: 73 additions & 0 deletions common/src/main/cpp/include/export/magicleap_export_plugin.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**************************************************************************/
/* magicleap_editor_plugin.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT XR */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2022-present Godot XR contributors (see CONTRIBUTORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

#pragma once

#include <godot_cpp/classes/editor_plugin.hpp>

#include "export_plugin.h"

using namespace godot;

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

public:
MagicleapEditorExportPlugin();

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

Dictionary _get_export_options_overrides(const Ref<EditorExportPlatform> &p_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 _ml2_hand_tracking_option;
};

class MagicleapEditorPlugin : public EditorPlugin {
GDCLASS(MagicleapEditorPlugin, EditorPlugin)

public:
void _enter_tree() override;
void _exit_tree() override;

protected:
static void _bind_methods();

private:
Ref<MagicleapEditorExportPlugin> magicleap_export_plugin;
};
5 changes: 5 additions & 0 deletions common/src/main/cpp/register_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "export/lynx_export_plugin.h"
#include "export/meta_export_plugin.h"
#include "export/pico_export_plugin.h"
#include "export/magicleap_export_plugin.h"

#include "extensions/openxr_fb_body_tracking_extension_wrapper.h"
#include "extensions/openxr_fb_composition_layer_alpha_blend_extension_wrapper.h"
Expand Down Expand Up @@ -199,6 +200,10 @@ void initialize_plugin_module(ModuleInitializationLevel p_level) {
ClassDB::register_class<PicoEditorExportPlugin>();
ClassDB::register_class<PicoEditorPlugin>();
EditorPlugins::add_by_type<PicoEditorPlugin>();

ClassDB::register_class<MagicleapEditorExportPlugin>();
ClassDB::register_class<MagicleapEditorPlugin>();
EditorPlugins::add_by_type<MagicleapEditorPlugin>();
} break;

case MODULE_INITIALIZATION_LEVEL_MAX:
Expand Down
Loading

0 comments on commit 0feace8

Please sign in to comment.