Skip to content

Commit

Permalink
Migrate the export scripts from gdscript to C++ via gdextension
Browse files Browse the repository at this point in the history
  • Loading branch information
m4gr3d committed Nov 30, 2023
1 parent c06c2c3 commit 698fcf0
Show file tree
Hide file tree
Showing 56 changed files with 1,965 additions and 701 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ local.properties
# Binaries
*.o
*.os
*.so
*.obj
*.bc
*.pyc
Expand Down
51 changes: 11 additions & 40 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -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')
70 changes: 70 additions & 0 deletions common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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")
Expand All @@ -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**)
204 changes: 204 additions & 0 deletions common/src/main/cpp/export/export_plugin.cpp
Original file line number Diff line number Diff line change
@@ -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 <godot_cpp/classes/editor_export_platform_android.hpp>

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<Dictionary> OpenXREditorExportPlugin::_get_export_options(const Ref<EditorExportPlatform> &platform) const {
TypedArray<Dictionary> export_options;
if (!_supports_platform(platform)) {
return export_options;
}

export_options.append(_get_vendor_toggle_option());
return export_options;
}

String OpenXREditorExportPlugin::_get_export_option_warning(const Ref<EditorExportPlatform> &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<EditorExportPlatform> &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<EditorExportPlatform> &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<EditorExportPlatform> &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<EditorExportPlatform> &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<EditorExportPlatform> &platform, bool debug) const {
if (!_supports_platform(platform) || !_is_vendor_plugin_enabled()) {
return "";
}

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

0 comments on commit 698fcf0

Please sign in to comment.