Allow unbundling OpenXR (for Linux distros)
Copy XrMatrix4x4f_CreateProjectionFov to our OpenXRUtil, instead of relying on a private header.
This commit is contained in:
parent
598378513b
commit
34a07b81ae
|
@ -244,6 +244,7 @@ opts.Add(BoolVariable("builtin_libwebp", "Use the built-in libwebp library", Tru
|
|||
opts.Add(BoolVariable("builtin_wslay", "Use the built-in wslay library", True))
|
||||
opts.Add(BoolVariable("builtin_mbedtls", "Use the built-in mbedTLS library", True))
|
||||
opts.Add(BoolVariable("builtin_miniupnpc", "Use the built-in miniupnpc library", True))
|
||||
opts.Add(BoolVariable("builtin_openxr", "Use the built-in OpenXR library", True))
|
||||
opts.Add(BoolVariable("builtin_pcre2", "Use the built-in PCRE2 library", True))
|
||||
opts.Add(BoolVariable("builtin_pcre2_with_jit", "Use JIT compiler for the built-in PCRE2 library", True))
|
||||
opts.Add(BoolVariable("builtin_recastnavigation", "Use the built-in Recast navigation library", True))
|
||||
|
|
|
@ -5,22 +5,13 @@ Import("env_modules")
|
|||
|
||||
env_openxr = env_modules.Clone()
|
||||
|
||||
#################################################
|
||||
# Add in our Khronos OpenXR loader
|
||||
# Thirdparty source files
|
||||
|
||||
thirdparty_obj = []
|
||||
thirdparty_dir = "#thirdparty/openxr"
|
||||
|
||||
env_openxr.Prepend(
|
||||
CPPPATH=[
|
||||
thirdparty_dir,
|
||||
thirdparty_dir + "/include",
|
||||
thirdparty_dir + "/src",
|
||||
thirdparty_dir + "/src/common",
|
||||
thirdparty_dir + "/src/external/jsoncpp/include",
|
||||
]
|
||||
)
|
||||
# Khronos OpenXR loader
|
||||
|
||||
# Needs even for build against shared library, at least the defines used in public headers.
|
||||
if env["platform"] == "android":
|
||||
# may need to set OPENXR_ANDROID_VERSION_SUFFIX
|
||||
env_openxr.AppendUnique(CPPDEFINES=["XR_OS_ANDROID", "XR_USE_PLATFORM_ANDROID"])
|
||||
|
@ -41,21 +32,35 @@ elif env["platform"] == "windows":
|
|||
# may need to check and set:
|
||||
# - XR_USE_TIMESPEC
|
||||
|
||||
env_thirdparty = env_openxr.Clone()
|
||||
env_thirdparty.disable_warnings()
|
||||
env_thirdparty.AppendUnique(CPPDEFINES=["DISABLE_STD_FILESYSTEM"])
|
||||
if env["builtin_openxr"]:
|
||||
thirdparty_dir = "#thirdparty/openxr"
|
||||
|
||||
if "-fno-exceptions" in env_thirdparty["CXXFLAGS"]:
|
||||
env_openxr.Prepend(
|
||||
CPPPATH=[
|
||||
thirdparty_dir,
|
||||
thirdparty_dir + "/include",
|
||||
thirdparty_dir + "/src",
|
||||
thirdparty_dir + "/src/common",
|
||||
thirdparty_dir + "/src/external/jsoncpp/include",
|
||||
]
|
||||
)
|
||||
|
||||
env_thirdparty = env_openxr.Clone()
|
||||
env_thirdparty.disable_warnings()
|
||||
env_thirdparty.AppendUnique(CPPDEFINES=["DISABLE_STD_FILESYSTEM"])
|
||||
|
||||
if "-fno-exceptions" in env_thirdparty["CXXFLAGS"]:
|
||||
env_thirdparty["CXXFLAGS"].remove("-fno-exceptions")
|
||||
env_thirdparty.Append(CPPPATH=[thirdparty_dir + "/src/loader"])
|
||||
env_thirdparty.Append(CPPPATH=[thirdparty_dir + "/src/loader"])
|
||||
|
||||
# add in external jsoncpp dependency
|
||||
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/external/jsoncpp/src/lib_json/json_reader.cpp")
|
||||
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/external/jsoncpp/src/lib_json/json_value.cpp")
|
||||
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/external/jsoncpp/src/lib_json/json_writer.cpp")
|
||||
# add in external jsoncpp dependency
|
||||
thirdparty_jsoncpp_dir = thirdparty_dir + "/src/external/jsoncpp/src/lib_json/"
|
||||
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_jsoncpp_dir + "json_reader.cpp")
|
||||
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_jsoncpp_dir + "json_value.cpp")
|
||||
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_jsoncpp_dir + "json_writer.cpp")
|
||||
|
||||
# add in load
|
||||
if env["platform"] != "android":
|
||||
# add in load
|
||||
if env["platform"] != "android":
|
||||
# On Android the openxr_loader is provided by separate plugins for each device
|
||||
# Build the engine using object files
|
||||
khrloader_obj = []
|
||||
|
@ -74,10 +79,10 @@ if env["platform"] != "android":
|
|||
env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/xr_generated_loader.cpp")
|
||||
env.modules_sources += khrloader_obj
|
||||
|
||||
env.modules_sources += thirdparty_obj
|
||||
env.modules_sources += thirdparty_obj
|
||||
|
||||
#################################################
|
||||
# And include our module source
|
||||
|
||||
# Godot source files
|
||||
|
||||
module_obj = []
|
||||
|
||||
|
|
|
@ -36,8 +36,6 @@
|
|||
#include "core/templates/hash_map.h"
|
||||
#include "core/templates/rid.h"
|
||||
|
||||
#include "thirdparty/openxr/src/common/xr_linear.h"
|
||||
|
||||
#include <openxr/openxr.h>
|
||||
|
||||
class OpenXRAPI;
|
||||
|
|
|
@ -278,8 +278,8 @@ bool OpenXROpenGLExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in
|
|||
}
|
||||
|
||||
bool OpenXROpenGLExtension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) {
|
||||
XrMatrix4x4f matrix;
|
||||
XrMatrix4x4f_CreateProjectionFov(&matrix, GRAPHICS_OPENGL, p_fov, (float)p_z_near, (float)p_z_far);
|
||||
OpenXRUtil::XrMatrix4x4f matrix;
|
||||
OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, OpenXRUtil::GRAPHICS_OPENGL, p_fov, (float)p_z_near, (float)p_z_far);
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
|
|
|
@ -381,8 +381,8 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in
|
|||
|
||||
bool OpenXRVulkanExtension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) {
|
||||
// Even though this is a Vulkan renderer we're using OpenGL coordinate systems
|
||||
XrMatrix4x4f matrix;
|
||||
XrMatrix4x4f_CreateProjectionFov(&matrix, GRAPHICS_OPENGL, p_fov, (float)p_z_near, (float)p_z_far);
|
||||
OpenXRUtil::XrMatrix4x4f matrix;
|
||||
OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(&matrix, OpenXRUtil::GRAPHICS_OPENGL, p_fov, (float)p_z_near, (float)p_z_far);
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
|
|
|
@ -48,8 +48,6 @@
|
|||
#include "core/templates/vector.h"
|
||||
#include "servers/xr/xr_pose.h"
|
||||
|
||||
#include "thirdparty/openxr/src/common/xr_linear.h"
|
||||
|
||||
#include <openxr/openxr.h>
|
||||
|
||||
// Note, OpenXR code that we wrote for our plugin makes use of C++20 notation for initializing structs which ensures zeroing out unspecified members.
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
|
||||
#include <openxr/openxr_reflection.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define XR_ENUM_CASE_STR(name, val) \
|
||||
case name: \
|
||||
return #name;
|
||||
|
@ -75,3 +77,89 @@ String OpenXRUtil::make_xr_version_string(XrVersion p_version) {
|
|||
|
||||
return version;
|
||||
}
|
||||
|
||||
// Copied from OpenXR xr_linear.h private header, so we can still link against
|
||||
// system-provided packages without relying on our `thirdparty` code.
|
||||
|
||||
// Copyright (c) 2017 The Khronos Group Inc.
|
||||
// Copyright (c) 2016 Oculus VR, LLC.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Creates a projection matrix based on the specified dimensions.
|
||||
// The projection matrix transforms -Z=forward, +Y=up, +X=right to the appropriate clip space for the graphics API.
|
||||
// The far plane is placed at infinity if farZ <= nearZ.
|
||||
// An infinite projection matrix is preferred for rasterization because, except for
|
||||
// things *right* up against the near plane, it always provides better precision:
|
||||
// "Tightening the Precision of Perspective Rendering"
|
||||
// Paul Upchurch, Mathieu Desbrun
|
||||
// Journal of Graphics Tools, Volume 16, Issue 1, 2012
|
||||
void OpenXRUtil::XrMatrix4x4f_CreateProjection(XrMatrix4x4f *result, GraphicsAPI graphicsApi, const float tanAngleLeft,
|
||||
const float tanAngleRight, const float tanAngleUp, float const tanAngleDown,
|
||||
const float nearZ, const float farZ) {
|
||||
const float tanAngleWidth = tanAngleRight - tanAngleLeft;
|
||||
|
||||
// Set to tanAngleDown - tanAngleUp for a clip space with positive Y down (Vulkan).
|
||||
// Set to tanAngleUp - tanAngleDown for a clip space with positive Y up (OpenGL / D3D / Metal).
|
||||
const float tanAngleHeight = graphicsApi == GRAPHICS_VULKAN ? (tanAngleDown - tanAngleUp) : (tanAngleUp - tanAngleDown);
|
||||
|
||||
// Set to nearZ for a [-1,1] Z clip space (OpenGL / OpenGL ES).
|
||||
// Set to zero for a [0,1] Z clip space (Vulkan / D3D / Metal).
|
||||
const float offsetZ = (graphicsApi == GRAPHICS_OPENGL || graphicsApi == GRAPHICS_OPENGL_ES) ? nearZ : 0;
|
||||
|
||||
if (farZ <= nearZ) {
|
||||
// place the far plane at infinity
|
||||
result->m[0] = 2.0f / tanAngleWidth;
|
||||
result->m[4] = 0.0f;
|
||||
result->m[8] = (tanAngleRight + tanAngleLeft) / tanAngleWidth;
|
||||
result->m[12] = 0.0f;
|
||||
|
||||
result->m[1] = 0.0f;
|
||||
result->m[5] = 2.0f / tanAngleHeight;
|
||||
result->m[9] = (tanAngleUp + tanAngleDown) / tanAngleHeight;
|
||||
result->m[13] = 0.0f;
|
||||
|
||||
result->m[2] = 0.0f;
|
||||
result->m[6] = 0.0f;
|
||||
result->m[10] = -1.0f;
|
||||
result->m[14] = -(nearZ + offsetZ);
|
||||
|
||||
result->m[3] = 0.0f;
|
||||
result->m[7] = 0.0f;
|
||||
result->m[11] = -1.0f;
|
||||
result->m[15] = 0.0f;
|
||||
} else {
|
||||
// normal projection
|
||||
result->m[0] = 2.0f / tanAngleWidth;
|
||||
result->m[4] = 0.0f;
|
||||
result->m[8] = (tanAngleRight + tanAngleLeft) / tanAngleWidth;
|
||||
result->m[12] = 0.0f;
|
||||
|
||||
result->m[1] = 0.0f;
|
||||
result->m[5] = 2.0f / tanAngleHeight;
|
||||
result->m[9] = (tanAngleUp + tanAngleDown) / tanAngleHeight;
|
||||
result->m[13] = 0.0f;
|
||||
|
||||
result->m[2] = 0.0f;
|
||||
result->m[6] = 0.0f;
|
||||
result->m[10] = -(farZ + offsetZ) / (farZ - nearZ);
|
||||
result->m[14] = -(farZ * (nearZ + offsetZ)) / (farZ - nearZ);
|
||||
|
||||
result->m[3] = 0.0f;
|
||||
result->m[7] = 0.0f;
|
||||
result->m[11] = -1.0f;
|
||||
result->m[15] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a projection matrix based on the specified FOV.
|
||||
void OpenXRUtil::XrMatrix4x4f_CreateProjectionFov(XrMatrix4x4f *result, GraphicsAPI graphicsApi, const XrFovf fov,
|
||||
const float nearZ, const float farZ) {
|
||||
const float tanLeft = tanf(fov.angleLeft);
|
||||
const float tanRight = tanf(fov.angleRight);
|
||||
|
||||
const float tanDown = tanf(fov.angleDown);
|
||||
const float tanUp = tanf(fov.angleUp);
|
||||
|
||||
XrMatrix4x4f_CreateProjection(result, graphicsApi, tanLeft, tanRight, tanUp, tanDown, nearZ, farZ);
|
||||
}
|
||||
|
|
|
@ -44,6 +44,27 @@ public:
|
|||
static String get_action_type_name(XrActionType p_action_type);
|
||||
static String get_environment_blend_mode_name(XrEnvironmentBlendMode p_blend_mode);
|
||||
static String make_xr_version_string(XrVersion p_version);
|
||||
|
||||
// Copied from OpenXR xr_linear.h private header, so we can still link against
|
||||
// system-provided packages without relying on our `thirdparty` code.
|
||||
|
||||
// Column-major, pre-multiplied. This type does not exist in the OpenXR API and is provided for convenience.
|
||||
typedef struct XrMatrix4x4f {
|
||||
float m[16];
|
||||
} XrMatrix4x4f;
|
||||
|
||||
typedef enum GraphicsAPI {
|
||||
GRAPHICS_VULKAN,
|
||||
GRAPHICS_OPENGL,
|
||||
GRAPHICS_OPENGL_ES,
|
||||
GRAPHICS_D3D
|
||||
} GraphicsAPI;
|
||||
|
||||
static void XrMatrix4x4f_CreateProjection(XrMatrix4x4f *result, GraphicsAPI graphicsApi, const float tanAngleLeft,
|
||||
const float tanAngleRight, const float tanAngleUp, float const tanAngleDown,
|
||||
const float nearZ, const float farZ);
|
||||
static void XrMatrix4x4f_CreateProjectionFov(XrMatrix4x4f *result, GraphicsAPI graphicsApi, const XrFovf fov,
|
||||
const float nearZ, const float farZ);
|
||||
};
|
||||
|
||||
#endif // OPENXR_UTIL_H
|
||||
|
|
|
@ -291,6 +291,9 @@ def configure(env: "Environment"):
|
|||
# No pkgconfig file so far, hardcode expected lib name.
|
||||
env.Append(LIBS=["embree3"])
|
||||
|
||||
if not env["builtin_openxr"]:
|
||||
env.ParseConfig("pkg-config openxr --cflags --libs")
|
||||
|
||||
if env["fontconfig"]:
|
||||
if not env["use_sowrap"]:
|
||||
if os.system("pkg-config --exists fontconfig") == 0: # 0 means found
|
||||
|
|
Loading…
Reference in New Issue