From 698fcf0bddd184340cd5fdeca3e10b74fe9d9081 Mon Sep 17 00:00:00 2001 From: Fredia Huya-Kouadio Date: Mon, 27 Nov 2023 13:25:41 -0800 Subject: [PATCH] Migrate the export scripts from gdscript to C++ via gdextension --- .gitignore | 1 - SConstruct | 51 +-- common/CMakeLists.txt | 70 ++++ common/src/main/cpp/export/export_plugin.cpp | 204 +++++++++++ common/src/main/cpp/export/export_plugin.h | 141 ++++++++ .../src/main/cpp/util.h | 0 demo/addons/godotopenxrvendors/globals.gd | 19 - .../godot_openxr_export_plugin.gd | 186 ---------- ...dot_openxr_khronos_editor_export_plugin.gd | 23 -- .../khronos/plugin.gdextension | 20 ++ .../godot_openxr_lynx_editor_export_plugin.gd | 20 -- .../lynx/plugin.gdextension | 20 ++ .../godot_openxr_meta_editor_export_plugin.gd | 300 ---------------- .../godot_openxr_pico_editor_export_plugin.gd | 20 -- .../pico/plugin.gdextension | 20 ++ demo/addons/godotopenxrvendors/plugin.cfg | 7 - demo/project.godot | 4 - godotopenxrkhronos/CMakeLists.txt | 46 +++ godotopenxrkhronos/SConstruct | 48 +++ godotopenxrkhronos/build.gradle | 6 + .../khronos_openxr_sdk}/arm64-v8a/abi.json | 0 .../arm64-v8a/libopenxr_loader.so | Bin .../khronos_openxr_sdk}/armeabi-v7a/abi.json | 0 .../armeabi-v7a/libopenxr_loader.so | Bin .../khronos_openxr_sdk}/x86/abi.json | 0 .../x86/libopenxr_loader.so | Bin .../khronos_openxr_sdk}/x86_64/abi.json | 0 .../x86_64/libopenxr_loader.so | Bin .../main/cpp/export/khronos_export_plugin.cpp | 76 ++++ .../main/cpp/export/khronos_export_plugin.h | 62 ++++ .../src/main/cpp/register_types.cpp | 72 ++++ .../src/main/cpp/register_types.h | 37 ++ godotopenxrlynx/CMakeLists.txt | 46 +++ godotopenxrlynx/SConstruct | 48 +++ godotopenxrlynx/build.gradle | 6 + .../lynx_openxr_sdk}/arm64-v8a/abi.json | 0 .../arm64-v8a/libopenxr_loader.so | Bin .../main/cpp/export/lynx_export_plugin.cpp | 51 +++ .../src/main/cpp/export/lynx_export_plugin.h | 50 +++ .../src/main/cpp/register_types.cpp | 71 ++++ godotopenxrlynx/src/main/cpp/register_types.h | 37 ++ godotopenxrmeta/CMakeLists.txt | 79 +---- godotopenxrmeta/SConstruct | 50 +++ .../main/cpp/export/meta_export_plugin.cpp | 332 ++++++++++++++++++ .../src/main/cpp/export/meta_export_plugin.h | 105 ++++++ ...penxr_fb_scene_capture_extension_wrapper.h | 2 +- .../src/main/cpp/register_types.cpp | 27 +- godotopenxrpico/CMakeLists.txt | 46 +++ godotopenxrpico/SConstruct | 48 +++ godotopenxrpico/build.gradle | 6 + .../pico_openxr_sdk}/arm64-v8a/README.md | 0 .../arm64-v8a/libopenxr_loader.so | Bin .../main/cpp/export/pico_export_plugin.cpp | 51 +++ .../src/main/cpp/export/pico_export_plugin.h | 50 +++ .../src/main/cpp/register_types.cpp | 71 ++++ godotopenxrpico/src/main/cpp/register_types.h | 37 ++ 56 files changed, 1965 insertions(+), 701 deletions(-) create mode 100644 common/src/main/cpp/export/export_plugin.cpp create mode 100644 common/src/main/cpp/export/export_plugin.h rename {godotopenxrmeta => common}/src/main/cpp/util.h (100%) delete mode 100644 demo/addons/godotopenxrvendors/globals.gd delete mode 100644 demo/addons/godotopenxrvendors/godot_openxr_export_plugin.gd delete mode 100644 demo/addons/godotopenxrvendors/khronos/godot_openxr_khronos_editor_export_plugin.gd create mode 100644 demo/addons/godotopenxrvendors/khronos/plugin.gdextension delete mode 100644 demo/addons/godotopenxrvendors/lynx/godot_openxr_lynx_editor_export_plugin.gd create mode 100644 demo/addons/godotopenxrvendors/lynx/plugin.gdextension delete mode 100644 demo/addons/godotopenxrvendors/meta/godot_openxr_meta_editor_export_plugin.gd delete mode 100644 demo/addons/godotopenxrvendors/pico/godot_openxr_pico_editor_export_plugin.gd create mode 100644 demo/addons/godotopenxrvendors/pico/plugin.gdextension delete mode 100644 demo/addons/godotopenxrvendors/plugin.cfg create mode 100644 godotopenxrkhronos/CMakeLists.txt create mode 100644 godotopenxrkhronos/SConstruct rename godotopenxrkhronos/{src/main/jniLibs => libs/khronos_openxr_sdk}/arm64-v8a/abi.json (100%) rename godotopenxrkhronos/{src/main/jniLibs => libs/khronos_openxr_sdk}/arm64-v8a/libopenxr_loader.so (100%) rename godotopenxrkhronos/{src/main/jniLibs => libs/khronos_openxr_sdk}/armeabi-v7a/abi.json (100%) rename godotopenxrkhronos/{src/main/jniLibs => libs/khronos_openxr_sdk}/armeabi-v7a/libopenxr_loader.so (100%) rename godotopenxrkhronos/{src/main/jniLibs => libs/khronos_openxr_sdk}/x86/abi.json (100%) rename godotopenxrkhronos/{src/main/jniLibs => libs/khronos_openxr_sdk}/x86/libopenxr_loader.so (100%) rename godotopenxrkhronos/{src/main/jniLibs => libs/khronos_openxr_sdk}/x86_64/abi.json (100%) rename godotopenxrkhronos/{src/main/jniLibs => libs/khronos_openxr_sdk}/x86_64/libopenxr_loader.so (100%) create mode 100644 godotopenxrkhronos/src/main/cpp/export/khronos_export_plugin.cpp create mode 100644 godotopenxrkhronos/src/main/cpp/export/khronos_export_plugin.h create mode 100644 godotopenxrkhronos/src/main/cpp/register_types.cpp create mode 100644 godotopenxrkhronos/src/main/cpp/register_types.h create mode 100644 godotopenxrlynx/CMakeLists.txt create mode 100644 godotopenxrlynx/SConstruct rename godotopenxrlynx/{src/main/jniLibs => libs/lynx_openxr_sdk}/arm64-v8a/abi.json (100%) rename godotopenxrlynx/{src/main/jniLibs => libs/lynx_openxr_sdk}/arm64-v8a/libopenxr_loader.so (100%) create mode 100644 godotopenxrlynx/src/main/cpp/export/lynx_export_plugin.cpp create mode 100644 godotopenxrlynx/src/main/cpp/export/lynx_export_plugin.h create mode 100644 godotopenxrlynx/src/main/cpp/register_types.cpp create mode 100644 godotopenxrlynx/src/main/cpp/register_types.h create mode 100644 godotopenxrmeta/SConstruct create mode 100644 godotopenxrmeta/src/main/cpp/export/meta_export_plugin.cpp create mode 100644 godotopenxrmeta/src/main/cpp/export/meta_export_plugin.h create mode 100644 godotopenxrpico/CMakeLists.txt create mode 100644 godotopenxrpico/SConstruct rename godotopenxrpico/{src/main/jniLibs => libs/pico_openxr_sdk}/arm64-v8a/README.md (100%) rename godotopenxrpico/{src/main/jniLibs => libs/pico_openxr_sdk}/arm64-v8a/libopenxr_loader.so (100%) create mode 100644 godotopenxrpico/src/main/cpp/export/pico_export_plugin.cpp create mode 100644 godotopenxrpico/src/main/cpp/export/pico_export_plugin.h create mode 100644 godotopenxrpico/src/main/cpp/register_types.cpp create mode 100644 godotopenxrpico/src/main/cpp/register_types.h diff --git a/.gitignore b/.gitignore index 1c924703..817a2c2c 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,6 @@ local.properties # Binaries *.o *.os -*.so *.obj *.bc *.pyc diff --git a/SConstruct b/SConstruct index d0bcdd3b..c44a2cbe 100644 --- a/SConstruct +++ b/SConstruct @@ -7,47 +7,18 @@ env = SConscript("thirdparty/godot-cpp/SConstruct") opts = Variables('custom.py') opts.Update(env) -# Add source files. +# Add common includes env.Append(CPPPATH=[ -# Meta includes - "godotopenxrmeta/src/main/cpp", - "godotopenxrmeta/src/main/cpp/include", - "godotopenxrmeta/libs/ovr_openxr_mobile_sdk/OpenXR/Include", -# Common includes - "thirdparty/openxr/include/", + "#common/src/main/cpp", + "#thirdparty/openxr/include/", ]) -# Meta source files -sources = Glob("godotopenxrmeta/src/main/cpp/*.cpp") +common_objects = [] +common_objects.append(env.SharedObject(Glob("#common/src/main/cpp/export/*.cpp"))) -meta_binary_path = 'demo/addons/godotopenxrvendors/meta/.bin' -meta_project_name = 'godotopenxrmeta' - -# Create the library target -if env["platform"] == "android": - print("Use gradle to generate the Android binaries") - Exit(255) -elif env["platform"] == "macos": - meta_library = env.SharedLibrary( - "{0}/lib{1}.{2}.{3}.framework/{1}.{2}.{3}".format( - meta_binary_path, - meta_project_name, - env["platform"], - env["target"], - ), - source=sources, - ) -else: - meta_library = env.SharedLibrary( - "{}/lib{}.{}.{}.{}{}".format( - meta_binary_path, - meta_project_name, - env["platform"], - env["target"], - env["arch"], - env["SHLIBSUFFIX"], - ), - source=sources, - ) - -Default(meta_library) +SConscript([ + "godotopenxrmeta/SConstruct", + "godotopenxrpico/SConstruct", + "godotopenxrlynx/SConstruct", + "godotopenxrkhronos/SConstruct", + ], 'env common_objects') \ No newline at end of file diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index e2baf29b..ae87aa69 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -17,6 +17,15 @@ else () set(GODOT_CPP_LIB_ABI "arm64") endif () +# Default android platform is android-21 +if (NOT ANDROID_PLATFORM) + set(ANDROID_PLATFORM "android-21") +endif (NOT ANDROID_PLATFORM) + +if (NOT (ANDROID_STL STREQUAL "c++_shared")) + set(ANDROID_STL "c++_shared") +endif (NOT (ANDROID_STL STREQUAL "c++_shared")) + # Default build type is Debug if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Debug) @@ -32,9 +41,63 @@ else () set(OPENXR_MOBILE_LIB_BUILD_TYPE Release) endif (CMAKE_BUILD_TYPE MATCHES Debug) +# Check if ANDROID_NDK is set. +if (NOT ANDROID_NDK) + # Set to ANDROID_NDK_HOME environment variable if it's set. + if (DEFINED ENV{ANDROID_NDK_HOME}) + set(ANDROID_NDK $ENV{ANDROID_NDK_HOME}) + else (DEFINED ENV{ANDROID_NDK_HOME}) + message(WARNING "ANDROID_NDK_HOME is not set") + endif (DEFINED ENV{ANDROID_NDK_HOME}) +endif (NOT ANDROID_NDK) + +# Check if CMAKE_TOOLCHAIN_FILE is set. +if (NOT CMAKE_TOOLCHAIN_FILE) + set(CMAKE_TOOLCHAIN_FILE "${ANDROID_NDK}/build/cmake/android.toolchain.cmake") +endif (NOT CMAKE_TOOLCHAIN_FILE) + +if (NOT DEFINED BITS) + set(BITS 32) + if (CMAKE_SIZEOF_VOID_P EQUAL 8) + set(BITS 64) + endif (CMAKE_SIZEOF_VOID_P EQUAL 8) +endif (NOT DEFINED BITS) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + project(common LANGUAGES CXX) +add_definitions(-DANDROID) + +set(GODOT_COMPILE_FLAGS) +set(GODOT_LINKER_FLAGS) + +set(GODOT_LINKER_FLAGS "-Wl") + +set(GODOT_COMPILE_FLAGS "-fPIC -g -Wwrite-strings") +set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wchar-subscripts -Wcomment -Wdisabled-optimization") +set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wformat -Wformat=2 -Wformat-security -Wformat-y2k") +set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wimport -Winit-self -Winline -Winvalid-pch") +set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wlong-long -Wmissing-braces -Wmissing-format-attribute") +set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wmissing-include-dirs -Wmissing-noreturn -Wpacked -Wpointer-arith") +set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wredundant-decls -Wreturn-type -Wsequence-point") +set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wswitch -Wswitch-enum -Wtrigraphs") +set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wuninitialized -Wunknown-pragmas -Wunreachable-code -Wunused-label") +set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wunused-value -Wvariadic-macros -Wvolatile-register-var -Wno-error=attributes") + +if (NOT CMAKE_SYSTEM_NAME STREQUAL "Android") + set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wno-ignored-attributes") +endif () + +if (CMAKE_BUILD_TYPE MATCHES Debug) + set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -fno-omit-frame-pointer -O0") +else () + set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -O3") +endif (CMAKE_BUILD_TYPE MATCHES Debug) + ## godot-cpp library set(GODOT_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../thirdparty/godot-cpp") set(GODOT-CPP "godot-cpp") @@ -56,3 +119,10 @@ set_target_properties(${GODOT-CPP} PROPERTIES IMPORTED_LOCATION ${GODOT_CPP_STAT ## OpenXR headers set(OPENXR_HEADERS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../thirdparty/openxr/include") + + +# Common lib +set(COMMON_LIB_HEADERS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../common/src/main/cpp) + +file(GLOB_RECURSE COMMON_LIB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../common/src/main/cpp/*.c**) +file(GLOB_RECURSE COMMON_LIB_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../common/src/main/cpp/*.h**) diff --git a/common/src/main/cpp/export/export_plugin.cpp b/common/src/main/cpp/export/export_plugin.cpp new file mode 100644 index 00000000..fb7a9fe2 --- /dev/null +++ b/common/src/main/cpp/export/export_plugin.cpp @@ -0,0 +1,204 @@ +/**************************************************************************/ +/* export_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_plugin.h" + +#include + +using namespace godot; + +OpenXREditorExportPlugin::OpenXREditorExportPlugin() {} + +void OpenXREditorExportPlugin::_bind_methods() {} + +Dictionary OpenXREditorExportPlugin::_generate_export_option(const String &name, const String &class_name, + Variant::Type type, + PropertyHint property_hint, + const String &hint_string, + PropertyUsageFlags property_usage, + const Variant &default_value, + bool update_visibility) { + Dictionary option_info; + option_info["name"] = name; + option_info["class_name"] = class_name; + option_info["type"] = type; + option_info["hint"] = property_hint; + option_info["hint_string"] = hint_string; + option_info["usage"] = property_usage; + + Dictionary export_option; + export_option["option"] = option_info; + export_option["default_value"] = default_value; + export_option["update_visibility"] = update_visibility; + + return export_option; +} + +String OpenXREditorExportPlugin::_get_name() const { + return "GodotOpenXR" + _vendor.capitalize(); +} + +String OpenXREditorExportPlugin::_get_android_aar_file_path(bool debug) const { + const String debug_label = debug ? "debug" : "release"; + return "res://addons/godotopenxrvendors/" + _vendor + "/.bin/" + debug_label + "/godotopenxr" + _vendor + "-" + debug_label + ".aar"; +} + +String OpenXREditorExportPlugin::_get_android_maven_central_dependency() const { + return "org.godotengine:godot-openxr-vendors-" + _vendor + ":" + _plugin_version; +} + +String OpenXREditorExportPlugin::_get_vendor_toggle_option_name(const String &vendor_name) const { + return "xr_features/enable_" + vendor_name + "_plugin"; +} + +Dictionary OpenXREditorExportPlugin::_get_vendor_toggle_option(const String &vendor_name) const { + return _generate_export_option( + _get_vendor_toggle_option_name(vendor_name), + "", + Variant::Type::BOOL, + PROPERTY_HINT_NONE, + "", + PROPERTY_USAGE_DEFAULT, + false, + false + ); +} + +bool OpenXREditorExportPlugin::_is_openxr_enabled() const { + return _get_int_option("xr_features/xr_mode", REGULAR_MODE_VALUE) == OPENXR_MODE_VALUE; +} + +TypedArray OpenXREditorExportPlugin::_get_export_options(const Ref &platform) const { + TypedArray export_options; + if (!_supports_platform(platform)) { + return export_options; + } + + export_options.append(_get_vendor_toggle_option()); + return export_options; +} + +String OpenXREditorExportPlugin::_get_export_option_warning(const Ref &platform, const String &option) const { + if (!_supports_platform(platform)) { + return ""; + } + + if (option != _get_vendor_toggle_option_name()) { + return ""; + } + + if (!_is_openxr_enabled() && _get_bool_option(option)) { + return "\"Enable " + _vendor.capitalize() + " Plugin\" requires \"XR Mode\" to be \"OpenXR\".\n"; + } + + if (_is_vendor_plugin_enabled()) { + for (const String vendor_name : VENDORS_LIST) { + if (vendor_name != _vendor && _is_vendor_plugin_enabled(vendor_name)) { + return "\"Disable " + _vendor.capitalize() + " Plugin before enabling another. Multiple plugins are not supported!\""; + } + } + } + + return ""; +} + +bool OpenXREditorExportPlugin::_supports_platform(const Ref &platform) const { + return platform->is_class(EditorExportPlatformAndroid::get_class_static()); +} + +bool OpenXREditorExportPlugin::_get_bool_option(const String &option) const { + Variant option_enabled = get_option(option); + if (option_enabled.get_type() == Variant::Type::BOOL) { + return option_enabled; + } + return false; +} + +int OpenXREditorExportPlugin::_get_int_option(const String &option, int default_value) const { + Variant option_value = get_option(option); + if (option_value.get_type() == Variant::Type::INT) { + return option_value; + } + return default_value; +} + +PackedStringArray OpenXREditorExportPlugin::_get_android_dependencies(const Ref &platform, bool debug) const { + PackedStringArray dependencies; + if (!_supports_platform(platform)) { + return dependencies; + } + + if (_is_vendor_plugin_enabled() && !_is_android_aar_file_available(debug)) { + dependencies.append(_get_android_maven_central_dependency()); + } + + return dependencies; +} + +PackedStringArray OpenXREditorExportPlugin::_get_android_libraries(const Ref &platform, bool debug) const { + PackedStringArray dependencies; + if (!_supports_platform(platform)) { + return dependencies; + } + + if (_is_vendor_plugin_enabled() && _is_android_aar_file_available(debug)) { + dependencies.append(_get_android_aar_file_path(debug)); + } + + return dependencies; +} + +PackedStringArray OpenXREditorExportPlugin::_get_android_dependencies_maven_repos(const Ref &platform, bool debug) const { + PackedStringArray maven_repos; + if (!_supports_platform(platform)) { + return maven_repos; + } + + if (_is_vendor_plugin_enabled() && !_is_android_aar_file_available(debug) && _plugin_version.ends_with("-SNAPSHOT")) { + maven_repos.append("https://s01.oss.sonatype.org/content/repositories/snapshots/"); + } + return maven_repos; +} + +String OpenXREditorExportPlugin::_get_android_manifest_activity_element_contents(const Ref &platform, bool debug) const { + if (!_supports_platform(platform) || !_is_vendor_plugin_enabled()) { + return ""; + } + + return R"( + + + + + + + +)"; +} diff --git a/common/src/main/cpp/export/export_plugin.h b/common/src/main/cpp/export/export_plugin.h new file mode 100644 index 00000000..62e69eb3 --- /dev/null +++ b/common/src/main/cpp/export/export_plugin.h @@ -0,0 +1,141 @@ +/**************************************************************************/ +/* export_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 +#include +#include +#include +#include + +using namespace godot; + +// Set of supported vendors +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 *VENDORS_LIST[] = { + META_VENDOR_NAME, + PICO_VENDOR_NAME, + LYNX_VENDOR_NAME, + KHRONOS_VENDOR_NAME, +}; + +// Set of custom feature tags supported by the plugin +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; + +/// Base class for the vendor editor export plugin +class OpenXREditorExportPlugin: public EditorExportPlugin { + GDCLASS(OpenXREditorExportPlugin, EditorExportPlugin) + +public: + OpenXREditorExportPlugin(); + + String _get_name() const override; + + TypedArray _get_export_options(const Ref &platform) const override; + + String _get_export_option_warning(const Ref &platform, const String &option) const override; + + bool _supports_platform(const Ref &platform) const override; + + PackedStringArray _get_android_dependencies(const Ref &platform, bool debug) const override; + PackedStringArray _get_android_dependencies_maven_repos(const Ref &platform, bool debug) const override; + PackedStringArray _get_android_libraries(const Ref &platform, bool debug) const override; + + String _get_android_manifest_activity_element_contents(const Ref &platform, bool debug) const override; + + void set_vendor_name(const String &vendor_name) { + _vendor = vendor_name; + } + + void set_plugin_version(const String &plugin_version) { + _plugin_version = plugin_version; + } + +protected: + static void _bind_methods(); + + static Dictionary _generate_export_option(const String &name, const String &class_name, + Variant::Type type, + PropertyHint property_hint, + const String &hint_string, + PropertyUsageFlags property_usage, + const Variant &default_value, + bool update_visibility); + + Dictionary _get_vendor_toggle_option() const { + return _get_vendor_toggle_option(_vendor); + } + + Dictionary _get_vendor_toggle_option(const String &vendor_name) const; + + bool _is_openxr_enabled() const; + + bool _get_bool_option(const String &option) const; + + int _get_int_option(const String &option, int default_value) const; + + bool _is_vendor_plugin_enabled(const String &vendor_name) const { + return _get_bool_option(_get_vendor_toggle_option_name(vendor_name)); + } + + bool _is_vendor_plugin_enabled() const { + return _is_vendor_plugin_enabled(_vendor); + } + + bool _is_android_aar_file_available(bool debug) const { + return FileAccess::file_exists(_get_android_aar_file_path(debug)); + } + +private: + /// Path to the Android library aar file. If the return file path is not available, we + /// fall back to the maven central dependency. + String _get_android_aar_file_path(bool debug) const; + + /// Maven central dependency used as fall back when the Android library aar file is not + /// available. + String _get_android_maven_central_dependency() const; + + String _get_vendor_toggle_option_name() const { + return _get_vendor_toggle_option_name(_vendor); + } + + String _get_vendor_toggle_option_name(const String &vendor_name) const; + + + String _vendor; + String _plugin_version; +}; diff --git a/godotopenxrmeta/src/main/cpp/util.h b/common/src/main/cpp/util.h similarity index 100% rename from godotopenxrmeta/src/main/cpp/util.h rename to common/src/main/cpp/util.h diff --git a/demo/addons/godotopenxrvendors/globals.gd b/demo/addons/godotopenxrvendors/globals.gd deleted file mode 100644 index 4964c2f0..00000000 --- a/demo/addons/godotopenxrvendors/globals.gd +++ /dev/null @@ -1,19 +0,0 @@ -@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/demo/addons/godotopenxrvendors/godot_openxr_export_plugin.gd b/demo/addons/godotopenxrvendors/godot_openxr_export_plugin.gd deleted file mode 100644 index ab35812e..00000000 --- a/demo/addons/godotopenxrvendors/godot_openxr_export_plugin.gd +++ /dev/null @@ -1,186 +0,0 @@ -@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/demo/addons/godotopenxrvendors/khronos/godot_openxr_khronos_editor_export_plugin.gd b/demo/addons/godotopenxrvendors/khronos/godot_openxr_khronos_editor_export_plugin.gd deleted file mode 100644 index 00905e41..00000000 --- a/demo/addons/godotopenxrvendors/khronos/godot_openxr_khronos_editor_export_plugin.gd +++ /dev/null @@ -1,23 +0,0 @@ -@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/demo/addons/godotopenxrvendors/khronos/plugin.gdextension b/demo/addons/godotopenxrvendors/khronos/plugin.gdextension new file mode 100644 index 00000000..7420e70f --- /dev/null +++ b/demo/addons/godotopenxrvendors/khronos/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/khronos/.bin/debug/arm64-v8a/libgodotopenxrkhronos.so" +android.release.arm64 = "res://addons/godotopenxrvendors/khronos/.bin/release/arm64-v8a/libgodotopenxrkhronos.so" +macos.debug = "res://addons/godotopenxrvendors/khronos/.bin/libgodotopenxrkhronos.macos.template_debug.framework" +macos.release = "res://addons/godotopenxrvendors/khronos/.bin/libgodotopenxrkhronos.macos.template_release.framework" +windows.debug.x86_64 = "res://addons/godotopenxrvendors/khronos/.bin/libgodotopenxrkhronos.windows.template_debug.x86_64.dll" +windows.release.x86_64 = "res://addons/godotopenxrvendors/khronos/.bin/libgodotopenxrkhronos.windows.template_release.x86_64.dll" +linux.debug.x86_64 = "res://addons/godotopenxrvendors/khronos/.bin/libgodotopenxrkhronos.linux.template_debug.x86_64.so" +linux.release.x86_64 = "res://addons/godotopenxrvendors/khronos/.bin/libgodotopenxrkhronos.linux.template_release.x86_64.so" +linux.debug.arm64 = "res://addons/godotopenxrvendors/khronos/.bin/libgodotopenxrkhronos.linux.template_debug.arm64.so" +linux.release.arm64 = "res://addons/godotopenxrvendors/khronos/.bin/libgodotopenxrkhronos.linux.template_release.arm64.so" +linux.debug.rv64 = "res://addons/godotopenxrvendors/khronos/.bin/libgodotopenxrkhronos.linux.template_debug.rv64.so" +linux.release.rv64 = "res://addons/godotopenxrvendors/khronos/.bin/libgodotopenxrkhronos.linux.template_release.rv64.so" diff --git a/demo/addons/godotopenxrvendors/lynx/godot_openxr_lynx_editor_export_plugin.gd b/demo/addons/godotopenxrvendors/lynx/godot_openxr_lynx_editor_export_plugin.gd deleted file mode 100644 index fb13ce9d..00000000 --- a/demo/addons/godotopenxrvendors/lynx/godot_openxr_lynx_editor_export_plugin.gd +++ /dev/null @@ -1,20 +0,0 @@ -@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/demo/addons/godotopenxrvendors/lynx/plugin.gdextension b/demo/addons/godotopenxrvendors/lynx/plugin.gdextension new file mode 100644 index 00000000..fbd7d3a1 --- /dev/null +++ b/demo/addons/godotopenxrvendors/lynx/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/lynx/.bin/debug/arm64-v8a/libgodotopenxrlynx.so" +android.release.arm64 = "res://addons/godotopenxrvendors/lynx/.bin/release/arm64-v8a/libgodotopenxrlynx.so" +macos.debug = "res://addons/godotopenxrvendors/lynx/.bin/libgodotopenxrlynx.macos.template_debug.framework" +macos.release = "res://addons/godotopenxrvendors/lynx/.bin/libgodotopenxrlynx.macos.template_release.framework" +windows.debug.x86_64 = "res://addons/godotopenxrvendors/lynx/.bin/libgodotopenxrlynx.windows.template_debug.x86_64.dll" +windows.release.x86_64 = "res://addons/godotopenxrvendors/lynx/.bin/libgodotopenxrlynx.windows.template_release.x86_64.dll" +linux.debug.x86_64 = "res://addons/godotopenxrvendors/lynx/.bin/libgodotopenxrlynx.linux.template_debug.x86_64.so" +linux.release.x86_64 = "res://addons/godotopenxrvendors/lynx/.bin/libgodotopenxrlynx.linux.template_release.x86_64.so" +linux.debug.arm64 = "res://addons/godotopenxrvendors/lynx/.bin/libgodotopenxrlynx.linux.template_debug.arm64.so" +linux.release.arm64 = "res://addons/godotopenxrvendors/lynx/.bin/libgodotopenxrlynx.linux.template_release.arm64.so" +linux.debug.rv64 = "res://addons/godotopenxrvendors/lynx/.bin/libgodotopenxrlynx.linux.template_debug.rv64.so" +linux.release.rv64 = "res://addons/godotopenxrvendors/lynx/.bin/libgodotopenxrlynx.linux.template_release.rv64.so" diff --git a/demo/addons/godotopenxrvendors/meta/godot_openxr_meta_editor_export_plugin.gd b/demo/addons/godotopenxrvendors/meta/godot_openxr_meta_editor_export_plugin.gd deleted file mode 100644 index 5c9a3ebd..00000000 --- a/demo/addons/godotopenxrvendors/meta/godot_openxr_meta_editor_export_plugin.gd +++ /dev/null @@ -1,300 +0,0 @@ -@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/demo/addons/godotopenxrvendors/pico/godot_openxr_pico_editor_export_plugin.gd b/demo/addons/godotopenxrvendors/pico/godot_openxr_pico_editor_export_plugin.gd deleted file mode 100644 index fb13ce9d..00000000 --- a/demo/addons/godotopenxrvendors/pico/godot_openxr_pico_editor_export_plugin.gd +++ /dev/null @@ -1,20 +0,0 @@ -@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/demo/addons/godotopenxrvendors/pico/plugin.gdextension b/demo/addons/godotopenxrvendors/pico/plugin.gdextension new file mode 100644 index 00000000..28eff5d5 --- /dev/null +++ b/demo/addons/godotopenxrvendors/pico/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/pico/.bin/debug/arm64-v8a/libgodotopenxrpico.so" +android.release.arm64 = "res://addons/godotopenxrvendors/pico/.bin/release/arm64-v8a/libgodotopenxrpico.so" +macos.debug = "res://addons/godotopenxrvendors/pico/.bin/libgodotopenxrpico.macos.template_debug.framework" +macos.release = "res://addons/godotopenxrvendors/pico/.bin/libgodotopenxrpico.macos.template_release.framework" +windows.debug.x86_64 = "res://addons/godotopenxrvendors/pico/.bin/libgodotopenxrpico.windows.template_debug.x86_64.dll" +windows.release.x86_64 = "res://addons/godotopenxrvendors/pico/.bin/libgodotopenxrpico.windows.template_release.x86_64.dll" +linux.debug.x86_64 = "res://addons/godotopenxrvendors/pico/.bin/libgodotopenxrpico.linux.template_debug.x86_64.so" +linux.release.x86_64 = "res://addons/godotopenxrvendors/pico/.bin/libgodotopenxrpico.linux.template_release.x86_64.so" +linux.debug.arm64 = "res://addons/godotopenxrvendors/pico/.bin/libgodotopenxrpico.linux.template_debug.arm64.so" +linux.release.arm64 = "res://addons/godotopenxrvendors/pico/.bin/libgodotopenxrpico.linux.template_release.arm64.so" +linux.debug.rv64 = "res://addons/godotopenxrvendors/pico/.bin/libgodotopenxrpico.linux.template_debug.rv64.so" +linux.release.rv64 = "res://addons/godotopenxrvendors/pico/.bin/libgodotopenxrpico.linux.template_release.rv64.so" diff --git a/demo/addons/godotopenxrvendors/plugin.cfg b/demo/addons/godotopenxrvendors/plugin.cfg deleted file mode 100644 index 9a693b7d..00000000 --- a/demo/addons/godotopenxrvendors/plugin.cfg +++ /dev/null @@ -1,7 +0,0 @@ -[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/demo/project.godot b/demo/project.godot index abb4d381..8911bfa4 100644 --- a/demo/project.godot +++ b/demo/project.godot @@ -19,10 +19,6 @@ config/icon="res://icon.svg" settings/stdout/verbose_stdout=true -[editor_plugins] - -enabled=PackedStringArray("res://addons/godotopenxrvendors/plugin.cfg") - [rendering] renderer/rendering_method="gl_compatibility" diff --git a/godotopenxrkhronos/CMakeLists.txt b/godotopenxrkhronos/CMakeLists.txt new file mode 100644 index 00000000..b8fb8525 --- /dev/null +++ b/godotopenxrkhronos/CMakeLists.txt @@ -0,0 +1,46 @@ +cmake_minimum_required(VERSION 3.22.1) + +## Common dependencies +include(${CMAKE_SOURCE_DIR}/../common/CMakeLists.txt) + + +## Project definition +project(godotopenxrkhronos LANGUAGES CXX) + +## khronos OpenXR loader library +set(KHRONOS_OPENXR_LIB_PATH "${CMAKE_SOURCE_DIR}/libs/khronos_openxr_sdk/${ANDROID_ABI}/libopenxr_loader.so") +add_library(openxr_loader + SHARED + IMPORTED GLOBAL + ) +set_target_properties(openxr_loader PROPERTIES IMPORTED_LOCATION ${KHRONOS_OPENXR_LIB_PATH}) + +## Setup the project sources +file(GLOB_RECURSE ANDROID_SOURCES ${CMAKE_SOURCE_DIR}/src/main/cpp/*.c**) +file(GLOB_RECURSE ANDROID_HEADERS ${CMAKE_SOURCE_DIR}/src/main/cpp/*.h**) + +add_library(${CMAKE_PROJECT_NAME} + SHARED + ${ANDROID_SOURCES} + ${ANDROID_HEADERS} + ${COMMON_LIB_SOURCES} + ${COMMON_LIB_HEADERS} + ) + +target_include_directories(${CMAKE_PROJECT_NAME} + SYSTEM PUBLIC + ${GODOT_CPP_INCLUDE_DIRECTORIES} + ${OPENXR_HEADERS_DIR} + ${COMMON_LIB_HEADERS_DIR} + ) + +target_link_libraries(${CMAKE_PROJECT_NAME} + android + log + ${GODOT-CPP} + openxr_loader + ) + +# Add the compile flags +set_property(TARGET ${CMAKE_PROJECT_NAME} APPEND_STRING PROPERTY COMPILE_FLAGS ${GODOT_COMPILE_FLAGS}) +set_property(TARGET ${CMAKE_PROJECT_NAME} APPEND_STRING PROPERTY LINK_FLAGS ${GODOT_LINKER_FLAGS}) diff --git a/godotopenxrkhronos/SConstruct b/godotopenxrkhronos/SConstruct new file mode 100644 index 00000000..c77ab709 --- /dev/null +++ b/godotopenxrkhronos/SConstruct @@ -0,0 +1,48 @@ +#!/usr/bin/env python +from glob import glob +from pathlib import Path + +Import("env", "common_objects") + +env_khronos = env.Clone() + +env_khronos.Append(CPPPATH=[ + "src/main/cpp", + ]) + +# Source files +sources = common_objects.copy() +sources += Glob("src/main/cpp/*.cpp") +sources += Glob("src/main/cpp/export/*.cpp") + +binary_path = '#demo/addons/godotopenxrvendors/khronos/.bin' +project_name = 'godotopenxrkhronos' + +# Create the library target +if env_khronos["platform"] == "android": + print("Use gradle to generate the Android binaries") + Exit(255) +elif env_khronos["platform"] == "macos": + library = env_khronos.SharedLibrary( + "{0}/lib{1}.{2}.{3}.framework/{1}.{2}.{3}".format( + binary_path, + project_name, + env_khronos["platform"], + env_khronos["target"], + ), + source=sources, + ) +else: + library = env_khronos.SharedLibrary( + "{}/lib{}.{}.{}.{}{}".format( + binary_path, + project_name, + env_khronos["platform"], + env_khronos["target"], + env_khronos["arch"], + env_khronos["SHLIBSUFFIX"], + ), + source=sources, + ) + +Default(library) diff --git a/godotopenxrkhronos/build.gradle b/godotopenxrkhronos/build.gradle index ece1d515..4b069d89 100644 --- a/godotopenxrkhronos/build.gradle +++ b/godotopenxrkhronos/build.gradle @@ -22,6 +22,12 @@ android { abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64' } } + externalNativeBuild { + cmake { + path file('CMakeLists.txt') + version versions.cmakeVersion + } + } namespace = "org.godotengine.openxr.vendors.khronos" diff --git a/godotopenxrkhronos/src/main/jniLibs/arm64-v8a/abi.json b/godotopenxrkhronos/libs/khronos_openxr_sdk/arm64-v8a/abi.json similarity index 100% rename from godotopenxrkhronos/src/main/jniLibs/arm64-v8a/abi.json rename to godotopenxrkhronos/libs/khronos_openxr_sdk/arm64-v8a/abi.json diff --git a/godotopenxrkhronos/src/main/jniLibs/arm64-v8a/libopenxr_loader.so b/godotopenxrkhronos/libs/khronos_openxr_sdk/arm64-v8a/libopenxr_loader.so similarity index 100% rename from godotopenxrkhronos/src/main/jniLibs/arm64-v8a/libopenxr_loader.so rename to godotopenxrkhronos/libs/khronos_openxr_sdk/arm64-v8a/libopenxr_loader.so diff --git a/godotopenxrkhronos/src/main/jniLibs/armeabi-v7a/abi.json b/godotopenxrkhronos/libs/khronos_openxr_sdk/armeabi-v7a/abi.json similarity index 100% rename from godotopenxrkhronos/src/main/jniLibs/armeabi-v7a/abi.json rename to godotopenxrkhronos/libs/khronos_openxr_sdk/armeabi-v7a/abi.json diff --git a/godotopenxrkhronos/src/main/jniLibs/armeabi-v7a/libopenxr_loader.so b/godotopenxrkhronos/libs/khronos_openxr_sdk/armeabi-v7a/libopenxr_loader.so similarity index 100% rename from godotopenxrkhronos/src/main/jniLibs/armeabi-v7a/libopenxr_loader.so rename to godotopenxrkhronos/libs/khronos_openxr_sdk/armeabi-v7a/libopenxr_loader.so diff --git a/godotopenxrkhronos/src/main/jniLibs/x86/abi.json b/godotopenxrkhronos/libs/khronos_openxr_sdk/x86/abi.json similarity index 100% rename from godotopenxrkhronos/src/main/jniLibs/x86/abi.json rename to godotopenxrkhronos/libs/khronos_openxr_sdk/x86/abi.json diff --git a/godotopenxrkhronos/src/main/jniLibs/x86/libopenxr_loader.so b/godotopenxrkhronos/libs/khronos_openxr_sdk/x86/libopenxr_loader.so similarity index 100% rename from godotopenxrkhronos/src/main/jniLibs/x86/libopenxr_loader.so rename to godotopenxrkhronos/libs/khronos_openxr_sdk/x86/libopenxr_loader.so diff --git a/godotopenxrkhronos/src/main/jniLibs/x86_64/abi.json b/godotopenxrkhronos/libs/khronos_openxr_sdk/x86_64/abi.json similarity index 100% rename from godotopenxrkhronos/src/main/jniLibs/x86_64/abi.json rename to godotopenxrkhronos/libs/khronos_openxr_sdk/x86_64/abi.json diff --git a/godotopenxrkhronos/src/main/jniLibs/x86_64/libopenxr_loader.so b/godotopenxrkhronos/libs/khronos_openxr_sdk/x86_64/libopenxr_loader.so similarity index 100% rename from godotopenxrkhronos/src/main/jniLibs/x86_64/libopenxr_loader.so rename to godotopenxrkhronos/libs/khronos_openxr_sdk/x86_64/libopenxr_loader.so diff --git a/godotopenxrkhronos/src/main/cpp/export/khronos_export_plugin.cpp b/godotopenxrkhronos/src/main/cpp/export/khronos_export_plugin.cpp new file mode 100644 index 00000000..0d757994 --- /dev/null +++ b/godotopenxrkhronos/src/main/cpp/export/khronos_export_plugin.cpp @@ -0,0 +1,76 @@ +/**************************************************************************/ +/* khronos_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 "khronos_export_plugin.h" + +using namespace godot; + +void KhronosEditorPlugin::_bind_methods() {} + +void KhronosEditorPlugin::_enter_tree() { + // Initialize the editor export plugin + khronos_export_plugin = memnew(KhronosEditorExportPlugin); + khronos_export_plugin->set_plugin_version(get_plugin_version()); + + add_export_plugin(khronos_export_plugin); +} + +void KhronosEditorPlugin::_exit_tree() { + // Clean up the editor export plugin + remove_export_plugin(khronos_export_plugin); + + memfree(khronos_export_plugin); + khronos_export_plugin = nullptr; +} + +KhronosEditorExportPlugin::KhronosEditorExportPlugin() { + set_vendor_name(KHRONOS_VENDOR_NAME); +} + +void KhronosEditorExportPlugin::_bind_methods() {} + +String KhronosEditorExportPlugin::_get_android_manifest_activity_element_contents(const Ref &platform, bool debug) const { + if (!_supports_platform(platform) || !_is_vendor_plugin_enabled()) { + return ""; + } + + return R"( + + + + + + + + + + +)"; +} \ No newline at end of file diff --git a/godotopenxrkhronos/src/main/cpp/export/khronos_export_plugin.h b/godotopenxrkhronos/src/main/cpp/export/khronos_export_plugin.h new file mode 100644 index 00000000..ef761d6a --- /dev/null +++ b/godotopenxrkhronos/src/main/cpp/export/khronos_export_plugin.h @@ -0,0 +1,62 @@ +/**************************************************************************/ +/* khronos_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 + +#include "export/export_plugin.h" + +using namespace godot; + +class KhronosEditorExportPlugin : public OpenXREditorExportPlugin { + GDCLASS(KhronosEditorExportPlugin, OpenXREditorExportPlugin) + +public: + KhronosEditorExportPlugin(); + + String _get_android_manifest_activity_element_contents(const Ref &platform, bool debug) const override; + +protected: + static void _bind_methods(); +}; + +class KhronosEditorPlugin : public EditorPlugin { + GDCLASS(KhronosEditorPlugin, EditorPlugin) + +public: + void _enter_tree() override; + void _exit_tree() override; + +protected: + static void _bind_methods(); + +private: + KhronosEditorExportPlugin *khronos_export_plugin = nullptr; +}; \ No newline at end of file diff --git a/godotopenxrkhronos/src/main/cpp/register_types.cpp b/godotopenxrkhronos/src/main/cpp/register_types.cpp new file mode 100644 index 00000000..50fd8ac6 --- /dev/null +++ b/godotopenxrkhronos/src/main/cpp/register_types.cpp @@ -0,0 +1,72 @@ +/**************************************************************************/ +/* register_types.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 "register_types.h" + +#include + +#include +#include +#include +#include + +#include "export/export_plugin.h" +#include "export/khronos_export_plugin.h" + +using namespace godot; + +void initialize_plugin_module(ModuleInitializationLevel p_level) { + switch (p_level) { + case MODULE_INITIALIZATION_LEVEL_EDITOR: { + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + + EditorPlugins::add_by_type(); + } break; + } +} + +void terminate_plugin_module(ModuleInitializationLevel p_level) +{ +} + +extern "C" +{ +GDExtensionBool GDE_EXPORT plugin_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) +{ + godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization); + + init_obj.register_initializer(initialize_plugin_module); + init_obj.register_terminator(terminate_plugin_module); + init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_EDITOR); + + return init_obj.init(); +} +} diff --git a/godotopenxrkhronos/src/main/cpp/register_types.h b/godotopenxrkhronos/src/main/cpp/register_types.h new file mode 100644 index 00000000..cdf62ca1 --- /dev/null +++ b/godotopenxrkhronos/src/main/cpp/register_types.h @@ -0,0 +1,37 @@ +/**************************************************************************/ +/* register_types.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 + +using namespace godot; + +void initialize_plugin_module(ModuleInitializationLevel p_level); +void terminate_plugin_module(ModuleInitializationLevel p_level); diff --git a/godotopenxrlynx/CMakeLists.txt b/godotopenxrlynx/CMakeLists.txt new file mode 100644 index 00000000..e86578dd --- /dev/null +++ b/godotopenxrlynx/CMakeLists.txt @@ -0,0 +1,46 @@ +cmake_minimum_required(VERSION 3.22.1) + +## Common dependencies +include(${CMAKE_SOURCE_DIR}/../common/CMakeLists.txt) + + +## Project definition +project(godotopenxrlynx LANGUAGES CXX) + +## lynx OpenXR loader library +set(LYNX_OPENXR_LIB_PATH "${CMAKE_SOURCE_DIR}/libs/lynx_openxr_sdk/${ANDROID_ABI}/libopenxr_loader.so") +add_library(openxr_loader + SHARED + IMPORTED GLOBAL + ) +set_target_properties(openxr_loader PROPERTIES IMPORTED_LOCATION ${LYNX_OPENXR_LIB_PATH}) + +## Setup the project sources +file(GLOB_RECURSE ANDROID_SOURCES ${CMAKE_SOURCE_DIR}/src/main/cpp/*.c**) +file(GLOB_RECURSE ANDROID_HEADERS ${CMAKE_SOURCE_DIR}/src/main/cpp/*.h**) + +add_library(${CMAKE_PROJECT_NAME} + SHARED + ${ANDROID_SOURCES} + ${ANDROID_HEADERS} + ${COMMON_LIB_SOURCES} + ${COMMON_LIB_HEADERS} + ) + +target_include_directories(${CMAKE_PROJECT_NAME} + SYSTEM PUBLIC + ${GODOT_CPP_INCLUDE_DIRECTORIES} + ${OPENXR_HEADERS_DIR} + ${COMMON_LIB_HEADERS_DIR} + ) + +target_link_libraries(${CMAKE_PROJECT_NAME} + android + log + ${GODOT-CPP} + openxr_loader + ) + +# Add the compile flags +set_property(TARGET ${CMAKE_PROJECT_NAME} APPEND_STRING PROPERTY COMPILE_FLAGS ${GODOT_COMPILE_FLAGS}) +set_property(TARGET ${CMAKE_PROJECT_NAME} APPEND_STRING PROPERTY LINK_FLAGS ${GODOT_LINKER_FLAGS}) diff --git a/godotopenxrlynx/SConstruct b/godotopenxrlynx/SConstruct new file mode 100644 index 00000000..917f9bef --- /dev/null +++ b/godotopenxrlynx/SConstruct @@ -0,0 +1,48 @@ +#!/usr/bin/env python +from glob import glob +from pathlib import Path + +Import("env", "common_objects") + +env_lynx = env.Clone() + +env_lynx.Append(CPPPATH=[ + "src/main/cpp", + ]) + +# Source files +sources = common_objects.copy() +sources += Glob("src/main/cpp/*.cpp") +sources += Glob("src/main/cpp/export/*.cpp") + +binary_path = '#demo/addons/godotopenxrvendors/lynx/.bin' +project_name = 'godotopenxrlynx' + +# Create the library target +if env_lynx["platform"] == "android": + print("Use gradle to generate the Android binaries") + Exit(255) +elif env_lynx["platform"] == "macos": + library = env_lynx.SharedLibrary( + "{0}/lib{1}.{2}.{3}.framework/{1}.{2}.{3}".format( + binary_path, + project_name, + env_lynx["platform"], + env_lynx["target"], + ), + source=sources, + ) +else: + library = env_lynx.SharedLibrary( + "{}/lib{}.{}.{}.{}{}".format( + binary_path, + project_name, + env_lynx["platform"], + env_lynx["target"], + env_lynx["arch"], + env_lynx["SHLIBSUFFIX"], + ), + source=sources, + ) + +Default(library) diff --git a/godotopenxrlynx/build.gradle b/godotopenxrlynx/build.gradle index bf01c034..32ca7405 100644 --- a/godotopenxrlynx/build.gradle +++ b/godotopenxrlynx/build.gradle @@ -22,6 +22,12 @@ android { abiFilters 'arm64-v8a' } } + externalNativeBuild { + cmake { + path file('CMakeLists.txt') + version versions.cmakeVersion + } + } namespace = "org.godotengine.openxr.vendors.lynx" diff --git a/godotopenxrlynx/src/main/jniLibs/arm64-v8a/abi.json b/godotopenxrlynx/libs/lynx_openxr_sdk/arm64-v8a/abi.json similarity index 100% rename from godotopenxrlynx/src/main/jniLibs/arm64-v8a/abi.json rename to godotopenxrlynx/libs/lynx_openxr_sdk/arm64-v8a/abi.json diff --git a/godotopenxrlynx/src/main/jniLibs/arm64-v8a/libopenxr_loader.so b/godotopenxrlynx/libs/lynx_openxr_sdk/arm64-v8a/libopenxr_loader.so similarity index 100% rename from godotopenxrlynx/src/main/jniLibs/arm64-v8a/libopenxr_loader.so rename to godotopenxrlynx/libs/lynx_openxr_sdk/arm64-v8a/libopenxr_loader.so diff --git a/godotopenxrlynx/src/main/cpp/export/lynx_export_plugin.cpp b/godotopenxrlynx/src/main/cpp/export/lynx_export_plugin.cpp new file mode 100644 index 00000000..f180605b --- /dev/null +++ b/godotopenxrlynx/src/main/cpp/export/lynx_export_plugin.cpp @@ -0,0 +1,51 @@ +/**************************************************************************/ +/* lynx_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 "lynx_export_plugin.h" + +using namespace godot; + +void LynxEditorPlugin::_bind_methods() {} + +void LynxEditorPlugin::_enter_tree() { + // Initialize the editor export plugin + lynx_export_plugin = memnew(OpenXREditorExportPlugin); + lynx_export_plugin->set_vendor_name(LYNX_VENDOR_NAME); + lynx_export_plugin->set_plugin_version(get_plugin_version()); + + add_export_plugin(lynx_export_plugin); +} + +void LynxEditorPlugin::_exit_tree() { + // Clean up the editor export plugin + remove_export_plugin(lynx_export_plugin); + + memfree(lynx_export_plugin); + lynx_export_plugin = nullptr; +} \ No newline at end of file diff --git a/godotopenxrlynx/src/main/cpp/export/lynx_export_plugin.h b/godotopenxrlynx/src/main/cpp/export/lynx_export_plugin.h new file mode 100644 index 00000000..23cd869c --- /dev/null +++ b/godotopenxrlynx/src/main/cpp/export/lynx_export_plugin.h @@ -0,0 +1,50 @@ +/**************************************************************************/ +/* lynx_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 + +#include "export/export_plugin.h" + +using namespace godot; + +class LynxEditorPlugin : public EditorPlugin { + GDCLASS(LynxEditorPlugin, EditorPlugin) + +public: + void _enter_tree() override; + void _exit_tree() override; + +protected: + static void _bind_methods(); + +private: + OpenXREditorExportPlugin *lynx_export_plugin = nullptr; +}; \ No newline at end of file diff --git a/godotopenxrlynx/src/main/cpp/register_types.cpp b/godotopenxrlynx/src/main/cpp/register_types.cpp new file mode 100644 index 00000000..ba3491c7 --- /dev/null +++ b/godotopenxrlynx/src/main/cpp/register_types.cpp @@ -0,0 +1,71 @@ +/**************************************************************************/ +/* register_types.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 "register_types.h" + +#include + +#include +#include +#include +#include + +#include "export/export_plugin.h" +#include "export/lynx_export_plugin.h" + +using namespace godot; + +void initialize_plugin_module(ModuleInitializationLevel p_level) { + switch (p_level) { + case MODULE_INITIALIZATION_LEVEL_EDITOR: { + ClassDB::register_class(); + ClassDB::register_class(); + + EditorPlugins::add_by_type(); + } break; + } +} + +void terminate_plugin_module(ModuleInitializationLevel p_level) +{ +} + +extern "C" +{ +GDExtensionBool GDE_EXPORT plugin_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) +{ + godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization); + + init_obj.register_initializer(initialize_plugin_module); + init_obj.register_terminator(terminate_plugin_module); + init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_EDITOR); + + return init_obj.init(); +} +} diff --git a/godotopenxrlynx/src/main/cpp/register_types.h b/godotopenxrlynx/src/main/cpp/register_types.h new file mode 100644 index 00000000..cdf62ca1 --- /dev/null +++ b/godotopenxrlynx/src/main/cpp/register_types.h @@ -0,0 +1,37 @@ +/**************************************************************************/ +/* register_types.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 + +using namespace godot; + +void initialize_plugin_module(ModuleInitializationLevel p_level); +void terminate_plugin_module(ModuleInitializationLevel p_level); diff --git a/godotopenxrmeta/CMakeLists.txt b/godotopenxrmeta/CMakeLists.txt index 7439e540..55d30c3b 100644 --- a/godotopenxrmeta/CMakeLists.txt +++ b/godotopenxrmeta/CMakeLists.txt @@ -1,52 +1,5 @@ cmake_minimum_required(VERSION 3.22.1) -## Default configs -# Default android abi is arm64-v8a -if (NOT ANDROID_ABI) - set(ANDROID_ABI "arm64-v8a") -endif (NOT ANDROID_ABI) - -# Default android platform is android-21 -if (NOT ANDROID_PLATFORM) - set(ANDROID_PLATFORM "android-21") -endif (NOT ANDROID_PLATFORM) - -# Default build type is Debug -if (NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Debug) -endif (NOT CMAKE_BUILD_TYPE) - -if (NOT (ANDROID_STL STREQUAL "c++_shared")) - set(ANDROID_STL "c++_shared") -endif (NOT (ANDROID_STL STREQUAL "c++_shared")) - -# Check if ANDROID_NDK is set. -if (NOT ANDROID_NDK) - # Set to ANDROID_NDK_HOME environment variable if it's set. - if (DEFINED ENV{ANDROID_NDK_HOME}) - set(ANDROID_NDK $ENV{ANDROID_NDK_HOME}) - else (DEFINED ENV{ANDROID_NDK_HOME}) - message(WARNING "ANDROID_NDK_HOME is not set") - endif (DEFINED ENV{ANDROID_NDK_HOME}) -endif (NOT ANDROID_NDK) - -# Check if CMAKE_TOOLCHAIN_FILE is set. -if (NOT CMAKE_TOOLCHAIN_FILE) - set(CMAKE_TOOLCHAIN_FILE "${ANDROID_NDK}/build/cmake/android.toolchain.cmake") -endif (NOT CMAKE_TOOLCHAIN_FILE) - -if (NOT DEFINED BITS) - set(BITS 32) - if (CMAKE_SIZEOF_VOID_P EQUAL 8) - set(BITS 64) - endif (CMAKE_SIZEOF_VOID_P EQUAL 8) -endif (NOT DEFINED BITS) - -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS OFF) - - ## Common dependencies include(${CMAKE_SOURCE_DIR}/../common/CMakeLists.txt) @@ -54,35 +7,6 @@ include(${CMAKE_SOURCE_DIR}/../common/CMakeLists.txt) ## Project definition project(godotopenxrmeta LANGUAGES CXX) -add_definitions(-DANDROID) - -set(GODOT_COMPILE_FLAGS) -set(GODOT_LINKER_FLAGS) - -set(GODOT_LINKER_FLAGS "-Wl") - -set(GODOT_COMPILE_FLAGS "-fPIC -g -Wwrite-strings") -set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wchar-subscripts -Wcomment -Wdisabled-optimization") -set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wformat -Wformat=2 -Wformat-security -Wformat-y2k") -set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wimport -Winit-self -Winline -Winvalid-pch") -set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wlong-long -Wmissing-braces -Wmissing-format-attribute") -set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wmissing-include-dirs -Wmissing-noreturn -Wpacked -Wpointer-arith") -set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wredundant-decls -Wreturn-type -Wsequence-point") -set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wswitch -Wswitch-enum -Wtrigraphs") -set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wuninitialized -Wunknown-pragmas -Wunreachable-code -Wunused-label") -set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wunused-value -Wvariadic-macros -Wvolatile-register-var -Wno-error=attributes") - -if (NOT CMAKE_SYSTEM_NAME STREQUAL "Android") - set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -Wno-ignored-attributes") -endif () - -if (CMAKE_BUILD_TYPE MATCHES Debug) - set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -fno-omit-frame-pointer -O0") -else () - set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -O3") -endif (CMAKE_BUILD_TYPE MATCHES Debug) - - ## OpenXR Mobile loader library # Sets the path to the OpenXR mobile library directory. set(OPENXR_MOBILE_ROOT_DIR "${CMAKE_SOURCE_DIR}/libs/ovr_openxr_mobile_sdk/OpenXR") @@ -104,6 +28,8 @@ add_library(${CMAKE_PROJECT_NAME} SHARED ${ANDROID_SOURCES} ${ANDROID_HEADERS} + ${COMMON_LIB_SOURCES} + ${COMMON_LIB_HEADERS} ) target_include_directories(${CMAKE_PROJECT_NAME} @@ -111,6 +37,7 @@ target_include_directories(${CMAKE_PROJECT_NAME} ${GODOT_CPP_INCLUDE_DIRECTORIES} ${OPENXR_HEADERS_DIR} ${OPENXR_MOBILE_HEADERS_DIR} + ${COMMON_LIB_HEADERS_DIR} ) target_link_libraries(${CMAKE_PROJECT_NAME} diff --git a/godotopenxrmeta/SConstruct b/godotopenxrmeta/SConstruct new file mode 100644 index 00000000..abc71a9e --- /dev/null +++ b/godotopenxrmeta/SConstruct @@ -0,0 +1,50 @@ +#!/usr/bin/env python +from glob import glob +from pathlib import Path + +Import("env", "common_objects") + +env_meta = env.Clone() + +env_meta.Append(CPPPATH=[ + "src/main/cpp", + "src/main/cpp/include", + "libs/ovr_openxr_mobile_sdk/OpenXR/Include", + ]) + +# Source files +sources = common_objects.copy() +sources += Glob("src/main/cpp/*.cpp") +sources += Glob("src/main/cpp/export/*.cpp") + +binary_path = '#demo/addons/godotopenxrvendors/meta/.bin' +project_name = 'godotopenxrmeta' + +# Create the library target +if env_meta["platform"] == "android": + print("Use gradle to generate the Android binaries") + Exit(255) +elif env_meta["platform"] == "macos": + library = env_meta.SharedLibrary( + "{0}/lib{1}.{2}.{3}.framework/{1}.{2}.{3}".format( + binary_path, + project_name, + env_meta["platform"], + env_meta["target"], + ), + source=sources, + ) +else: + library = env_meta.SharedLibrary( + "{}/lib{}.{}.{}.{}{}".format( + binary_path, + project_name, + env_meta["platform"], + env_meta["target"], + env_meta["arch"], + env_meta["SHLIBSUFFIX"], + ), + source=sources, + ) + +Default(library) diff --git a/godotopenxrmeta/src/main/cpp/export/meta_export_plugin.cpp b/godotopenxrmeta/src/main/cpp/export/meta_export_plugin.cpp new file mode 100644 index 00000000..8f452adf --- /dev/null +++ b/godotopenxrmeta/src/main/cpp/export/meta_export_plugin.cpp @@ -0,0 +1,332 @@ +/**************************************************************************/ +/* meta_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 "meta_export_plugin.h" + +#include + +using namespace godot; + +void MetaEditorPlugin::_bind_methods() {} + +void MetaEditorPlugin::_enter_tree() { + // Initialize the editor export plugin + meta_export_plugin = memnew(MetaEditorExportPlugin); + meta_export_plugin->set_plugin_version(get_plugin_version()); + + add_export_plugin(meta_export_plugin); +} + +void MetaEditorPlugin::_exit_tree() { + // Clean up the editor export plugin + remove_export_plugin(meta_export_plugin); + + memfree(meta_export_plugin); + meta_export_plugin = nullptr; +} + +MetaEditorExportPlugin::MetaEditorExportPlugin() { + set_vendor_name(META_VENDOR_NAME); + + _eye_tracking_option = _generate_export_option( + "meta_xr_features/eye_tracking", + "", + Variant::Type::INT, + PROPERTY_HINT_ENUM, + "None,Optional,Required", + PROPERTY_USAGE_DEFAULT, + EYE_TRACKING_NONE_VALUE, + false + ); + _hand_tracking_option = _generate_export_option( + "meta_xr_features/hand_tracking", + "", + Variant::Type::INT, + PROPERTY_HINT_ENUM, + "None,Optional,Required", + PROPERTY_USAGE_DEFAULT, + HAND_TRACKING_NONE_VALUE, + false + ); + _hand_tracking_frequency_option = _generate_export_option( + "meta_xr_features/hand_tracking_frequency", + "", + Variant::Type::INT, + PROPERTY_HINT_ENUM, + "Low,High", + PROPERTY_USAGE_DEFAULT, + HAND_TRACKING_FREQUENCY_LOW_VALUE, + false + ); + _passthrough_option = _generate_export_option( + "meta_xr_features/passthrough", + "", + Variant::Type::INT, + PROPERTY_HINT_ENUM, + "None,Optional,Required", + PROPERTY_USAGE_DEFAULT, + PASSTHROUGH_NONE_VALUE, + false + ); + _use_anchor_api_option = _generate_export_option( + "meta_xr_features/use_anchor_api", + "", + Variant::Type::BOOL, + PROPERTY_HINT_NONE, + "", + PROPERTY_USAGE_DEFAULT, + false, + false + ); + _support_quest_1_option = _generate_export_option( + "meta_xr_features/quest_1_support", + "", + Variant::Type::BOOL, + PROPERTY_HINT_NONE, + "", + PROPERTY_USAGE_DEFAULT, + false, + false + ); + _support_quest_2_option = _generate_export_option( + "meta_xr_features/quest_2_support", + "", + Variant::Type::BOOL, + PROPERTY_HINT_NONE, + "", + PROPERTY_USAGE_DEFAULT, + true, + false + ); + _support_quest_3_option = _generate_export_option( + "meta_xr_features/quest_3_support", + "", + Variant::Type::BOOL, + PROPERTY_HINT_NONE, + "", + PROPERTY_USAGE_DEFAULT, + true, + false + ); + _support_quest_pro_option = _generate_export_option( + "meta_xr_features/quest_pro_support", + "", + Variant::Type::BOOL, + PROPERTY_HINT_NONE, + "", + PROPERTY_USAGE_DEFAULT, + true, + false + ); +} + +void MetaEditorExportPlugin::_bind_methods() {} + +TypedArray MetaEditorExportPlugin::_get_export_options(const Ref &platform) const { + TypedArray export_options; + if (!_supports_platform(platform)) { + return export_options; + } + + export_options.append(_get_vendor_toggle_option()); + export_options.append(_eye_tracking_option); + export_options.append(_hand_tracking_option); + export_options.append(_hand_tracking_frequency_option); + export_options.append(_passthrough_option); + export_options.append(_use_anchor_api_option); + export_options.append(_support_quest_1_option); + export_options.append(_support_quest_2_option); + export_options.append(_support_quest_3_option); + export_options.append(_support_quest_pro_option); + + return export_options; +} + +PackedStringArray MetaEditorExportPlugin::_get_supported_devices() const { + PackedStringArray supported_devices; + + 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; +} + +bool MetaEditorExportPlugin::_is_eye_tracking_enabled() const { + bool eye_tracking_project_setting_enabled = ProjectSettings::get_singleton()->get_setting_with_override("xr/openxr/extensions/eye_gaze_interaction"); + if (!eye_tracking_project_setting_enabled) { + return false; + } + + int 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; +} + +PackedStringArray MetaEditorExportPlugin::_get_export_features(const Ref &platform, bool debug) const { + PackedStringArray features; + if (!_supports_platform(platform)) { + return features; + } + + // Add the eye tracking feature if necessary + if (_is_eye_tracking_enabled()) { + features.append(EYE_GAZE_INTERACTION_FEATURE); + } + + return features; +} + +String MetaEditorExportPlugin::_get_export_option_warning(const Ref &platform, const String &option) const { + if (!_supports_platform(platform)) { + return ""; + } + + bool openxr_enabled = _is_openxr_enabled(); + if (option == "meta_xr_features/eye_tracking") { + bool eye_tracking_project_setting_enabled = ProjectSettings::get_singleton()->get_setting_with_override("xr/openxr/extensions/eye_gaze_interaction"); + int 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 && !eye_tracking_project_setting_enabled) { + return "\"Eye Tracking\" project setting must be enabled!\n"; + } + } else if (option == "meta_xr_features/hand_tracking") { + if (!openxr_enabled && _get_int_option(option, HAND_TRACKING_NONE_VALUE) > HAND_TRACKING_NONE_VALUE) { + return "\"Hand Tracking\" requires \"XR Mode\" to be \"OpenXR\".\n"; + } + } else if (option == "meta_xr_features/passthrough") { + if (!openxr_enabled && _get_int_option(option, PASSTHROUGH_NONE_VALUE) > PASSTHROUGH_NONE_VALUE) { + return "\"Passthrough\" requires \"XR Mode\" to be \"OpenXR\".\n"; + } + } else if (option == "meta_xr_features/use_anchor_api") { + if (!openxr_enabled && _get_bool_option(option)) { + return "\"Use anchor API\" is only valid when \"XR Mode\" is \"OpenXR\".\n"; + } + } + + return OpenXREditorExportPlugin::_get_export_option_warning(platform, option); +} + +String MetaEditorExportPlugin::_get_android_manifest_element_contents(const Ref &platform, bool debug) const { + String contents; + if (!_supports_platform(platform) || !_is_vendor_plugin_enabled()) { + return contents; + } + + // Check for eye tracking + if (_is_eye_tracking_enabled()) { + contents += " \n"; + + int 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"; + } else if (eye_tracking_value == EYE_TRACKING_REQUIRED_VALUE) { + contents += " \n"; + } + } + + // Check for hand tracking + int 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"; + } else if (hand_tracking_value == HAND_TRACKING_REQUIRED_VALUE) { + contents += " \n"; + } + } + + // Check for passthrough + int passthrough_mode = _get_int_option("meta_xr_features/passthrough", PASSTHROUGH_NONE_VALUE); + if (passthrough_mode == PASSTHROUGH_OPTIONAL_VALUE) { + contents += " \n"; + } else if (passthrough_mode == PASSTHROUGH_REQUIRED_VALUE) { + contents += " \n"; + } + + // Check for anchor api + bool use_anchor_api = _get_bool_option("meta_xr_features/use_anchor_api"); + if (use_anchor_api) { + contents += " \n"; + } + + return contents; +} + +String MetaEditorExportPlugin::_get_android_manifest_application_element_contents(const Ref &platform, bool debug) const { + String contents; + if (!_supports_platform(platform) || !_is_vendor_plugin_enabled()) { + return contents; + } + + const String supported_devices = String("|").join(_get_supported_devices()); + contents += " \n"; + + bool hand_tracking_enabled = _get_int_option("meta_xr_features/hand_tracking", HAND_TRACKING_NONE_VALUE) > HAND_TRACKING_NONE_VALUE; + if (hand_tracking_enabled) { + int hand_tracking_frequency = _get_int_option("meta_xr_features/hand_tracking_frequency", HAND_TRACKING_FREQUENCY_LOW_VALUE); + const String hand_tracking_frequency_label = (hand_tracking_frequency == HAND_TRACKING_FREQUENCY_LOW_VALUE) ? "LOW" : "HIGH"; + contents += " \n"; + contents += " \n"; + } + + return contents; +} + +String MetaEditorExportPlugin::_get_android_manifest_activity_element_contents(const Ref &platform, bool debug) const { + if (!_supports_platform(platform) || !_is_vendor_plugin_enabled()) { + return ""; + } + + return R"( + + + + + + + + + + +)"; +} diff --git a/godotopenxrmeta/src/main/cpp/export/meta_export_plugin.h b/godotopenxrmeta/src/main/cpp/export/meta_export_plugin.h new file mode 100644 index 00000000..33c202ce --- /dev/null +++ b/godotopenxrmeta/src/main/cpp/export/meta_export_plugin.h @@ -0,0 +1,105 @@ +/**************************************************************************/ +/* meta_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 + +#include "export/export_plugin.h" + +using namespace godot; + +namespace { + +static const int EYE_TRACKING_NONE_VALUE = 0; +static const int EYE_TRACKING_OPTIONAL_VALUE = 1; +static const int EYE_TRACKING_REQUIRED_VALUE = 2; + +static const int PASSTHROUGH_NONE_VALUE = 0; +static const int PASSTHROUGH_OPTIONAL_VALUE = 1; +static const int PASSTHROUGH_REQUIRED_VALUE = 2; + +static const int HAND_TRACKING_NONE_VALUE = 0; +static const int HAND_TRACKING_OPTIONAL_VALUE = 1; +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; + +} // namespace + +class MetaEditorExportPlugin : public OpenXREditorExportPlugin { + GDCLASS(MetaEditorExportPlugin, OpenXREditorExportPlugin) + +public: + MetaEditorExportPlugin(); + + TypedArray _get_export_options(const Ref &platform) const override; + + PackedStringArray _get_export_features(const Ref &platform, bool debug) const override; + + String _get_export_option_warning(const Ref &platform, const String &option) const override; + + String _get_android_manifest_activity_element_contents(const Ref &platform, bool debug) const override; + String _get_android_manifest_application_element_contents(const Ref &platform, bool debug) const override; + String _get_android_manifest_element_contents(const Ref &platform, bool debug) const override; + +protected: + static void _bind_methods(); + +private: + PackedStringArray _get_supported_devices() const; + + bool _is_eye_tracking_enabled() const; + + Dictionary _eye_tracking_option; + Dictionary _hand_tracking_option; + Dictionary _hand_tracking_frequency_option; + Dictionary _passthrough_option; + Dictionary _use_anchor_api_option; + Dictionary _support_quest_1_option; + Dictionary _support_quest_2_option; + Dictionary _support_quest_3_option; + Dictionary _support_quest_pro_option; +}; + +class MetaEditorPlugin : public EditorPlugin { + GDCLASS(MetaEditorPlugin, EditorPlugin) + +public: + void _enter_tree() override; + void _exit_tree() override; + +protected: + static void _bind_methods(); + +private: + MetaEditorExportPlugin *meta_export_plugin = nullptr; + +}; diff --git a/godotopenxrmeta/src/main/cpp/include/openxr_fb_scene_capture_extension_wrapper.h b/godotopenxrmeta/src/main/cpp/include/openxr_fb_scene_capture_extension_wrapper.h index 47d4dca3..5bb07558 100644 --- a/godotopenxrmeta/src/main/cpp/include/openxr_fb_scene_capture_extension_wrapper.h +++ b/godotopenxrmeta/src/main/cpp/include/openxr_fb_scene_capture_extension_wrapper.h @@ -38,7 +38,7 @@ #include #include -#include "../util.h" +#include "util.h" #include diff --git a/godotopenxrmeta/src/main/cpp/register_types.cpp b/godotopenxrmeta/src/main/cpp/register_types.cpp index 30e61c36..98544747 100644 --- a/godotopenxrmeta/src/main/cpp/register_types.cpp +++ b/godotopenxrmeta/src/main/cpp/register_types.cpp @@ -38,15 +38,34 @@ #include "include/openxr_fb_scene_capture_extension_wrapper.h" +#include "export/export_plugin.h" +#include "export/meta_export_plugin.h" + using namespace godot; void initialize_plugin_module(ModuleInitializationLevel p_level) { - if (p_level == MODULE_INITIALIZATION_LEVEL_CORE) - { - ClassDB::register_class(); - OpenXRFbSceneCaptureExtensionWrapper::get_singleton()->register_extension_wrapper(); + switch(p_level) { + case MODULE_INITIALIZATION_LEVEL_CORE: { + ClassDB::register_class(); + OpenXRFbSceneCaptureExtensionWrapper::get_singleton()->register_extension_wrapper(); + } break; + + case MODULE_INITIALIZATION_LEVEL_EDITOR: { + ClassDB::register_class(); + ClassDB::register_class(); + ClassDB::register_class(); + + EditorPlugins::add_by_type(); + } break; + + case MODULE_INITIALIZATION_LEVEL_SERVERS: + case MODULE_INITIALIZATION_LEVEL_SCENE: + case MODULE_INITIALIZATION_LEVEL_MAX: + break; } + + } void terminate_plugin_module(ModuleInitializationLevel p_level) diff --git a/godotopenxrpico/CMakeLists.txt b/godotopenxrpico/CMakeLists.txt new file mode 100644 index 00000000..b8dcabc6 --- /dev/null +++ b/godotopenxrpico/CMakeLists.txt @@ -0,0 +1,46 @@ +cmake_minimum_required(VERSION 3.22.1) + +## Common dependencies +include(${CMAKE_SOURCE_DIR}/../common/CMakeLists.txt) + + +## Project definition +project(godotopenxrpico LANGUAGES CXX) + +## Pico OpenXR loader library +set(PICO_OPENXR_LIB_PATH "${CMAKE_SOURCE_DIR}/libs/pico_openxr_sdk/${ANDROID_ABI}/libopenxr_loader.so") +add_library(openxr_loader + SHARED + IMPORTED GLOBAL + ) +set_target_properties(openxr_loader PROPERTIES IMPORTED_LOCATION ${PICO_OPENXR_LIB_PATH}) + +## Setup the project sources +file(GLOB_RECURSE ANDROID_SOURCES ${CMAKE_SOURCE_DIR}/src/main/cpp/*.c**) +file(GLOB_RECURSE ANDROID_HEADERS ${CMAKE_SOURCE_DIR}/src/main/cpp/*.h**) + +add_library(${CMAKE_PROJECT_NAME} + SHARED + ${ANDROID_SOURCES} + ${ANDROID_HEADERS} + ${COMMON_LIB_SOURCES} + ${COMMON_LIB_HEADERS} + ) + +target_include_directories(${CMAKE_PROJECT_NAME} + SYSTEM PUBLIC + ${GODOT_CPP_INCLUDE_DIRECTORIES} + ${OPENXR_HEADERS_DIR} + ${COMMON_LIB_HEADERS_DIR} + ) + +target_link_libraries(${CMAKE_PROJECT_NAME} + android + log + ${GODOT-CPP} + openxr_loader + ) + +# Add the compile flags +set_property(TARGET ${CMAKE_PROJECT_NAME} APPEND_STRING PROPERTY COMPILE_FLAGS ${GODOT_COMPILE_FLAGS}) +set_property(TARGET ${CMAKE_PROJECT_NAME} APPEND_STRING PROPERTY LINK_FLAGS ${GODOT_LINKER_FLAGS}) diff --git a/godotopenxrpico/SConstruct b/godotopenxrpico/SConstruct new file mode 100644 index 00000000..11014347 --- /dev/null +++ b/godotopenxrpico/SConstruct @@ -0,0 +1,48 @@ +#!/usr/bin/env python +from glob import glob +from pathlib import Path + +Import("env", "common_objects") + +env_pico = env.Clone() + +env_pico.Append(CPPPATH=[ + "src/main/cpp", + ]) + +# Source files +sources = common_objects.copy() +sources += Glob("src/main/cpp/*.cpp") +sources += Glob("src/main/cpp/export/*.cpp") + +binary_path = '#demo/addons/godotopenxrvendors/pico/.bin' +project_name = 'godotopenxrpico' + +# Create the library target +if env_pico["platform"] == "android": + print("Use gradle to generate the Android binaries") + Exit(255) +elif env_pico["platform"] == "macos": + library = env_pico.SharedLibrary( + "{0}/lib{1}.{2}.{3}.framework/{1}.{2}.{3}".format( + binary_path, + project_name, + env_pico["platform"], + env_pico["target"], + ), + source=sources, + ) +else: + library = env_pico.SharedLibrary( + "{}/lib{}.{}.{}.{}{}".format( + binary_path, + project_name, + env_pico["platform"], + env_pico["target"], + env_pico["arch"], + env_pico["SHLIBSUFFIX"], + ), + source=sources, + ) + +Default(library) diff --git a/godotopenxrpico/build.gradle b/godotopenxrpico/build.gradle index 19d38972..d502501f 100644 --- a/godotopenxrpico/build.gradle +++ b/godotopenxrpico/build.gradle @@ -22,6 +22,12 @@ android { abiFilters "arm64-v8a" } } + externalNativeBuild { + cmake { + path file('CMakeLists.txt') + version versions.cmakeVersion + } + } namespace = "org.godotengine.openxr.vendors.pico" diff --git a/godotopenxrpico/src/main/jniLibs/arm64-v8a/README.md b/godotopenxrpico/libs/pico_openxr_sdk/arm64-v8a/README.md similarity index 100% rename from godotopenxrpico/src/main/jniLibs/arm64-v8a/README.md rename to godotopenxrpico/libs/pico_openxr_sdk/arm64-v8a/README.md diff --git a/godotopenxrpico/src/main/jniLibs/arm64-v8a/libopenxr_loader.so b/godotopenxrpico/libs/pico_openxr_sdk/arm64-v8a/libopenxr_loader.so similarity index 100% rename from godotopenxrpico/src/main/jniLibs/arm64-v8a/libopenxr_loader.so rename to godotopenxrpico/libs/pico_openxr_sdk/arm64-v8a/libopenxr_loader.so diff --git a/godotopenxrpico/src/main/cpp/export/pico_export_plugin.cpp b/godotopenxrpico/src/main/cpp/export/pico_export_plugin.cpp new file mode 100644 index 00000000..a045c3a5 --- /dev/null +++ b/godotopenxrpico/src/main/cpp/export/pico_export_plugin.cpp @@ -0,0 +1,51 @@ +/**************************************************************************/ +/* pico_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 "pico_export_plugin.h" + +using namespace godot; + +void PicoEditorPlugin::_bind_methods() {} + +void PicoEditorPlugin::_enter_tree() { + // Initialize the editor export plugin + pico_export_plugin = memnew(OpenXREditorExportPlugin); + pico_export_plugin->set_vendor_name(PICO_VENDOR_NAME); + pico_export_plugin->set_plugin_version(get_plugin_version()); + + add_export_plugin(pico_export_plugin); +} + +void PicoEditorPlugin::_exit_tree() { + // Clean up the editor export plugin + remove_export_plugin(pico_export_plugin); + + memfree(pico_export_plugin); + pico_export_plugin = nullptr; +} \ No newline at end of file diff --git a/godotopenxrpico/src/main/cpp/export/pico_export_plugin.h b/godotopenxrpico/src/main/cpp/export/pico_export_plugin.h new file mode 100644 index 00000000..e4a3496e --- /dev/null +++ b/godotopenxrpico/src/main/cpp/export/pico_export_plugin.h @@ -0,0 +1,50 @@ +/**************************************************************************/ +/* pico_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 + +#include "export/export_plugin.h" + +using namespace godot; + +class PicoEditorPlugin : public EditorPlugin { + GDCLASS(PicoEditorPlugin, EditorPlugin) + +public: + void _enter_tree() override; + void _exit_tree() override; + +protected: + static void _bind_methods(); + +private: + OpenXREditorExportPlugin *pico_export_plugin = nullptr; +}; \ No newline at end of file diff --git a/godotopenxrpico/src/main/cpp/register_types.cpp b/godotopenxrpico/src/main/cpp/register_types.cpp new file mode 100644 index 00000000..d6eceefc --- /dev/null +++ b/godotopenxrpico/src/main/cpp/register_types.cpp @@ -0,0 +1,71 @@ +/**************************************************************************/ +/* register_types.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 "register_types.h" + +#include + +#include +#include +#include +#include + +#include "export/export_plugin.h" +#include "export/pico_export_plugin.h" + +using namespace godot; + +void initialize_plugin_module(ModuleInitializationLevel p_level) { + switch (p_level) { + case MODULE_INITIALIZATION_LEVEL_EDITOR: { + ClassDB::register_class(); + ClassDB::register_class(); + + EditorPlugins::add_by_type(); + } break; + } +} + +void terminate_plugin_module(ModuleInitializationLevel p_level) +{ +} + +extern "C" +{ +GDExtensionBool GDE_EXPORT plugin_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) +{ + godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization); + + init_obj.register_initializer(initialize_plugin_module); + init_obj.register_terminator(terminate_plugin_module); + init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_EDITOR); + + return init_obj.init(); +} +} diff --git a/godotopenxrpico/src/main/cpp/register_types.h b/godotopenxrpico/src/main/cpp/register_types.h new file mode 100644 index 00000000..cdf62ca1 --- /dev/null +++ b/godotopenxrpico/src/main/cpp/register_types.h @@ -0,0 +1,37 @@ +/**************************************************************************/ +/* register_types.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 + +using namespace godot; + +void initialize_plugin_module(ModuleInitializationLevel p_level); +void terminate_plugin_module(ModuleInitializationLevel p_level);