diff options
author | David Snopek <dsnopek@gmail.com> | 2024-01-30 10:30:54 -0600 |
---|---|---|
committer | David Snopek <dsnopek@gmail.com> | 2024-01-31 12:58:22 -0600 |
commit | 5935bfa8603b7c22df4ea777a688723a408e6c5d (patch) | |
tree | 5cb3c3453fbb5a2e74442e7902b93e5d3cd35191 /modules/openxr/openxr_api.cpp | |
parent | 51991e20143a39e9ef0107163eaf283ca0a761ea (diff) | |
download | redot-engine-5935bfa8603b7c22df4ea777a688723a408e6c5d.tar.gz |
OpenXR: Allow changing play area mode during active session
Diffstat (limited to 'modules/openxr/openxr_api.cpp')
-rw-r--r-- | modules/openxr/openxr_api.cpp | 127 |
1 files changed, 75 insertions, 52 deletions
diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp index eafabe03e7..126a27bb75 100644 --- a/modules/openxr/openxr_api.cpp +++ b/modules/openxr/openxr_api.cpp @@ -680,71 +680,85 @@ bool OpenXRAPI::is_reference_space_supported(XrReferenceSpaceType p_reference_sp return false; } -bool OpenXRAPI::setup_spaces() { - XrResult result; +bool OpenXRAPI::setup_play_space() { + ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false); XrPosef identityPose = { { 0.0, 0.0, 0.0, 1.0 }, { 0.0, 0.0, 0.0 } }; - ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false); + XrReferenceSpaceType new_reference_space; + XrSpace new_play_space = XR_NULL_HANDLE; + bool will_emulate_local_floor = false; - // create play space - { - emulating_local_floor = false; + if (is_reference_space_supported(requested_reference_space)) { + new_reference_space = requested_reference_space; + } else if (requested_reference_space == XR_REFERENCE_SPACE_TYPE_LOCAL_FLOOR_EXT && is_reference_space_supported(XR_REFERENCE_SPACE_TYPE_STAGE)) { + print_verbose("OpenXR: LOCAL_FLOOR space isn't supported, emulating using STAGE and LOCAL spaces."); - if (is_reference_space_supported(requested_reference_space)) { - reference_space = requested_reference_space; - } else if (requested_reference_space == XR_REFERENCE_SPACE_TYPE_LOCAL_FLOOR_EXT && is_reference_space_supported(XR_REFERENCE_SPACE_TYPE_STAGE)) { - print_verbose("OpenXR: LOCAL_FLOOR space isn't supported, emulating using STAGE and LOCAL spaces."); + new_reference_space = XR_REFERENCE_SPACE_TYPE_LOCAL; + will_emulate_local_floor = true; + } else { + // Fallback on LOCAL, which all OpenXR runtimes are required to support. + print_verbose(String("OpenXR: ") + OpenXRUtil::get_reference_space_name(requested_reference_space) + String(" isn't supported, defaulting to LOCAL space.")); + new_reference_space = XR_REFERENCE_SPACE_TYPE_LOCAL; + } - reference_space = XR_REFERENCE_SPACE_TYPE_LOCAL; - emulating_local_floor = true; + XrReferenceSpaceCreateInfo play_space_create_info = { + XR_TYPE_REFERENCE_SPACE_CREATE_INFO, // type + nullptr, // next + new_reference_space, // referenceSpaceType + identityPose, // poseInReferenceSpace + }; - // We'll use the STAGE space to get the floor height, but we can't do that until - // after xrWaitFrame(), so just set this flag for now. - should_reset_emulated_floor_height = true; + XrResult result = xrCreateReferenceSpace(session, &play_space_create_info, &new_play_space); + if (XR_FAILED(result)) { + print_line("OpenXR: Failed to create play space [", get_error_string(result), "]"); + return false; + } - } else { - // Fallback on LOCAL, which all OpenXR runtimes are required to support. - print_verbose(String("OpenXR: ") + OpenXRUtil::get_reference_space_name(requested_reference_space) + String(" isn't supported, defaulting to LOCAL space.")); - reference_space = XR_REFERENCE_SPACE_TYPE_LOCAL; - } + // If we've previously created a play space, clean it up first. + if (play_space != XR_NULL_HANDLE) { + xrDestroySpace(play_space); + } + play_space = new_play_space; + reference_space = new_reference_space; - XrReferenceSpaceCreateInfo play_space_create_info = { - XR_TYPE_REFERENCE_SPACE_CREATE_INFO, // type - nullptr, // next - reference_space, // referenceSpaceType - identityPose, // poseInReferenceSpace - }; + emulating_local_floor = will_emulate_local_floor; + if (emulating_local_floor) { + // We'll use the STAGE space to get the floor height, but we can't do that until + // after xrWaitFrame(), so just set this flag for now. + should_reset_emulated_floor_height = true; + } - result = xrCreateReferenceSpace(session, &play_space_create_info, &play_space); - if (XR_FAILED(result)) { - print_line("OpenXR: Failed to create play space [", get_error_string(result), "]"); - return false; - } + return true; +} + +bool OpenXRAPI::setup_view_space() { + ERR_FAIL_COND_V(session == XR_NULL_HANDLE, false); + + if (!is_reference_space_supported(XR_REFERENCE_SPACE_TYPE_VIEW)) { + print_line("OpenXR: reference space XR_REFERENCE_SPACE_TYPE_VIEW is not supported."); + return false; } - // create view space - { - if (!is_reference_space_supported(XR_REFERENCE_SPACE_TYPE_VIEW)) { - print_line("OpenXR: reference space XR_REFERENCE_SPACE_TYPE_VIEW is not supported."); - return false; - } + XrPosef identityPose = { + { 0.0, 0.0, 0.0, 1.0 }, + { 0.0, 0.0, 0.0 } + }; - XrReferenceSpaceCreateInfo view_space_create_info = { - XR_TYPE_REFERENCE_SPACE_CREATE_INFO, // type - nullptr, // next - XR_REFERENCE_SPACE_TYPE_VIEW, // referenceSpaceType - identityPose // poseInReferenceSpace - }; + XrReferenceSpaceCreateInfo view_space_create_info = { + XR_TYPE_REFERENCE_SPACE_CREATE_INFO, // type + nullptr, // next + XR_REFERENCE_SPACE_TYPE_VIEW, // referenceSpaceType + identityPose // poseInReferenceSpace + }; - result = xrCreateReferenceSpace(session, &view_space_create_info, &view_space); - if (XR_FAILED(result)) { - print_line("OpenXR: Failed to create view space [", get_error_string(result), "]"); - return false; - } + XrResult result = xrCreateReferenceSpace(session, &view_space_create_info, &view_space); + if (XR_FAILED(result)) { + print_line("OpenXR: Failed to create view space [", get_error_string(result), "]"); + return false; } return true; @@ -1262,10 +1276,14 @@ void OpenXRAPI::set_view_configuration(XrViewConfigurationType p_view_configurat view_configuration = p_view_configuration; } -void OpenXRAPI::set_requested_reference_space(XrReferenceSpaceType p_requested_reference_space) { - ERR_FAIL_COND(is_initialized()); - +bool OpenXRAPI::set_requested_reference_space(XrReferenceSpaceType p_requested_reference_space) { requested_reference_space = p_requested_reference_space; + + if (is_initialized()) { + return setup_play_space(); + } + + return true; } void OpenXRAPI::set_submit_depth_buffer(bool p_submit_depth_buffer) { @@ -1466,7 +1484,12 @@ bool OpenXRAPI::initialize_session() { return false; } - if (!setup_spaces()) { + if (!setup_play_space()) { + destroy_session(); + return false; + } + + if (!setup_view_space()) { destroy_session(); return false; } |