From 03f2eaf97f47f07f0dc3a852b9d92bcf1cea9550 Mon Sep 17 00:00:00 2001 From: galister <22305755+galister@users.noreply.github.com> Date: Mon, 16 Sep 2024 07:05:26 +0900 Subject: [PATCH] fps-stabilize openxr smoothing --- src/backend/openxr/input.rs | 5 ++--- src/backend/openxr/mod.rs | 25 ++++++++++++++++++++++--- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/backend/openxr/input.rs b/src/backend/openxr/input.rs index 7f68f6a..3b97803 100644 --- a/src/backend/openxr/input.rs +++ b/src/backend/openxr/input.rs @@ -324,9 +324,8 @@ impl OpenXrHand { transmute::(location.pose.position), ) }; - let lerp_factor = (1.0 / (xr.predicted_display_period.as_nanos() / 10_000_000) as f32 - * session.config.pointer_lerp_factor) - .clamp(0.1, 1.0); + let lerp_factor = + (1.0 / (xr.fps / 100.0) * session.config.pointer_lerp_factor).clamp(0.1, 1.0); pointer.raw_pose = Affine3A::from_rotation_translation(new_quat, new_pos); pointer.pose = Affine3A::from_rotation_translation( cur_quat.lerp(new_quat, lerp_factor), diff --git a/src/backend/openxr/mod.rs b/src/backend/openxr/mod.rs index 6b249aa..2e47fba 100644 --- a/src/backend/openxr/mod.rs +++ b/src/backend/openxr/mod.rs @@ -48,7 +48,7 @@ struct XrState { system: xr::SystemId, session: xr::Session, predicted_display_time: xr::Time, - predicted_display_period: xr::Duration, + fps: f32, stage: Arc, view: Arc, stage_offset: Affine3A, @@ -132,7 +132,7 @@ pub fn openxr_run(running: Arc, show_by_default: bool) -> Result<(), system, session, predicted_display_time: xr::Time::from_nanos(0), - predicted_display_period: xr::Duration::from_nanos(10_000_000), + fps: 30.0, stage: Arc::new(stage), view: Arc::new(view), stage_offset: Affine3A::IDENTITY, @@ -155,6 +155,8 @@ pub fn openxr_run(running: Arc, show_by_default: bool) -> Result<(), let mut next_device_update = Instant::now(); let mut due_tasks = VecDeque::with_capacity(4); + let mut fps_counter: VecDeque = VecDeque::new(); + let mut main_session_visible = false; 'main_loop: loop { @@ -233,7 +235,24 @@ pub fn openxr_run(running: Arc, show_by_default: bool) -> Result<(), frame_stream.begin()?; xr_state.predicted_display_time = xr_frame_state.predicted_display_time; - xr_state.predicted_display_period = xr_frame_state.predicted_display_period; + xr_state.fps = { + fps_counter.push_back(Instant::now()); + + while let Some(time) = fps_counter.front() { + if time.elapsed().as_secs_f32() > 1. { + fps_counter.pop_front(); + } else { + break; + } + } + + let total_elapsed = fps_counter + .front() + .map(|time| time.elapsed().as_secs_f32()) + .unwrap_or(0f32); + + fps_counter.len() as f32 / total_elapsed + }; if !xr_frame_state.should_render { frame_stream.end(