From 37696fb38f9d1196b91b37982984de2c65b18832 Mon Sep 17 00:00:00 2001 From: praydog Date: Sun, 10 Dec 2023 00:30:45 -0800 Subject: [PATCH] VR: Possible fix for player view being flung out of existence --- src/mods/VR.cpp | 16 ++++------------ src/mods/vr/runtimes/OpenVR.cpp | 1 + src/mods/vr/runtimes/OpenXR.cpp | 6 +++++- src/mods/vr/runtimes/VRRuntime.hpp | 1 + 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/mods/VR.cpp b/src/mods/VR.cpp index 11087879b..bf2994f69 100644 --- a/src/mods/VR.cpp +++ b/src/mods/VR.cpp @@ -1342,24 +1342,16 @@ void VR::update_hmd_state() { // Update the poses used for the game // If we used the data directly from the WaitGetPoses call, we would have to lock a different mutex and wait a long time // This is because the WaitGetPoses call is blocking, and we don't want to block any game logic - { + if (runtime->wants_reset_origin && runtime->ready() && runtime->got_first_valid_poses) { std::unique_lock _{ runtime->pose_mtx }; + set_rotation_offset(glm::identity()); + m_standing_origin = get_position_unsafe(vr::k_unTrackedDeviceIndex_Hmd); - if (runtime->wants_reset_origin && runtime->ready()) { - set_rotation_offset(glm::identity()); - m_standing_origin = get_position_unsafe(vr::k_unTrackedDeviceIndex_Hmd); - - runtime->wants_reset_origin = false; - } + runtime->wants_reset_origin = false; } runtime->update_matrices(m_nearz, m_farz); - // On first run, set the standing origin to the headset position - if (!runtime->got_first_poses) { - m_standing_origin = get_position(vr::k_unTrackedDeviceIndex_Hmd); - } - runtime->got_first_poses = true; // Forcefully update the camera transform after submitting the frame diff --git a/src/mods/vr/runtimes/OpenVR.cpp b/src/mods/vr/runtimes/OpenVR.cpp index 65c427bcd..94ed8dd36 100644 --- a/src/mods/vr/runtimes/OpenVR.cpp +++ b/src/mods/vr/runtimes/OpenVR.cpp @@ -12,6 +12,7 @@ VRRuntime::Error OpenVR::synchronize_frame() { auto ret = vr::VRCompositor()->WaitGetPoses(this->real_render_poses.data(), vr::k_unMaxTrackedDeviceCount, this->real_game_poses.data(), vr::k_unMaxTrackedDeviceCount); if (ret == vr::VRCompositorError_None) { + this->got_first_valid_poses = true; this->got_first_sync = true; } diff --git a/src/mods/vr/runtimes/OpenXR.cpp b/src/mods/vr/runtimes/OpenXR.cpp index ab86f8d2e..21bf3126d 100644 --- a/src/mods/vr/runtimes/OpenXR.cpp +++ b/src/mods/vr/runtimes/OpenXR.cpp @@ -63,7 +63,7 @@ VRRuntime::Error OpenXR::update_poses() { const auto display_time = this->frame_state.predictedDisplayTime + (XrDuration)(this->frame_state.predictedDisplayPeriod * this->prediction_scale); - if (display_time == 0) { + if (display_time <= 1000) { return VRRuntime::Error::SUCCESS; } @@ -108,6 +108,10 @@ VRRuntime::Error OpenXR::update_poses() { } } + if (!this->got_first_valid_poses) { + this->got_first_valid_poses = (this->view_space_location.locationFlags & (XR_SPACE_LOCATION_POSITION_VALID_BIT | XR_SPACE_LOCATION_ORIENTATION_VALID_BIT)) != 0; + } + this->needs_pose_update = false; this->got_first_poses = true; return VRRuntime::Error::SUCCESS; diff --git a/src/mods/vr/runtimes/VRRuntime.hpp b/src/mods/vr/runtimes/VRRuntime.hpp index 783b97fed..6fb56fdc1 100644 --- a/src/mods/vr/runtimes/VRRuntime.hpp +++ b/src/mods/vr/runtimes/VRRuntime.hpp @@ -111,6 +111,7 @@ struct VRRuntime { // will return VRCompositorError_DoNotHaveFocus bool needs_pose_update{true}; bool got_first_poses{false}; + bool got_first_valid_poses{false}; bool got_first_sync{false}; bool handle_pause{false}; bool wants_reset_origin{true};