diff --git a/wayvr/src/backend/openvr/mod.rs b/wayvr/src/backend/openvr/mod.rs index e9406825..bf08d1d9 100644 --- a/wayvr/src/backend/openvr/mod.rs +++ b/wayvr/src/backend/openvr/mod.rs @@ -229,7 +229,7 @@ pub fn openvr_run(args: &Args) -> Result<(), BackendError> { overlays.handle_task(&mut app, task)?; } TaskType::Playspace(task) => { - playspace.handle_task(&app, &mut chaperone_mgr, task); + playspace.handle_task(&mut app, &mut chaperone_mgr, &mut overlays, task); } TaskType::OpenVR(task) => match task { OpenVrTask::ColorGain(channel, value) => { diff --git a/wayvr/src/backend/openvr/playspace.rs b/wayvr/src/backend/openvr/playspace.rs index 62458229..0cfcdd51 100644 --- a/wayvr/src/backend/openvr/playspace.rs +++ b/wayvr/src/backend/openvr/playspace.rs @@ -7,7 +7,7 @@ use ovr_overlay::{ use wgui::log::LogErr; use crate::{ - backend::{input::InputState, playspace_common, task::PlayspaceTask}, + backend::{playspace_common, task::PlayspaceTask}, state::{AppState, PlayspaceState, load_playspace_state, save_playspace_state}, windowing::manager::OverlayWindowManager, }; @@ -39,19 +39,20 @@ impl PlayspaceMover { pub fn handle_task( &mut self, - app: &AppState, + app: &mut AppState, chaperone_mgr: &mut ChaperoneSetupManager, + overlays: &mut OverlayWindowManager, task: PlayspaceTask, ) { match task { PlayspaceTask::FixFloor => { - self.fix_floor(chaperone_mgr, &app.input_state); + self.fix_floor(chaperone_mgr, app, overlays); } PlayspaceTask::Reset => { - self.reset_offset(chaperone_mgr); + self.reset_offset(chaperone_mgr, overlays, &mut app.anchor); } PlayspaceTask::Recenter => { - self.recenter(chaperone_mgr, &app.input_state); + self.recenter(chaperone_mgr, app, overlays); } PlayspaceTask::SaveCenter => { self.save_center(chaperone_mgr); @@ -178,14 +179,24 @@ impl PlayspaceMover { for pointer in &app.input_state.pointers { if pointer.now.space_reset && !pointer.before.space_reset { - self.reset_offset(chaperone_mgr); + self.reset_offset(chaperone_mgr, overlays, &mut app.anchor); log::info!("Space reset"); return; } } } - pub fn reset_offset(&mut self, chaperone_mgr: &mut ChaperoneSetupManager) { + pub fn reset_offset( + &mut self, + chaperone_mgr: &mut ChaperoneSetupManager, + overlays: &mut OverlayWindowManager, + anchor: &mut Affine3A, + ) { + let Some(before) = get_working_copy(&self.universe, chaperone_mgr) else { + log::warn!("Can't reset offset - failed to get zero pose"); + return; + }; + let mut xform = self.playspace_state.openvr_space_center; if self.universe == ETrackingUniverseOrigin::TrackingUniverseSeated { xform.translation.y -= 1.7; @@ -194,6 +205,8 @@ impl PlayspaceMover { set_working_copy(&self.universe, chaperone_mgr, &xform); chaperone_mgr.commit_working_copy(EChaperoneConfigFile::EChaperoneConfigFile_Live); + playspace_common::shift_world(overlays, anchor, &before, &xform); + if self.drag.is_some() { log::info!("Space drag interrupted by manual reset"); self.drag = None; @@ -204,7 +217,14 @@ impl PlayspaceMover { } } - pub fn fix_floor(&mut self, chaperone_mgr: &mut ChaperoneSetupManager, input: &InputState) { + pub fn fix_floor( + &mut self, + chaperone_mgr: &mut ChaperoneSetupManager, + app: &mut AppState, + overlays: &mut OverlayWindowManager, + ) { + let input = &app.input_state; + let anchor = &mut app.anchor; let y1 = input.pointers[0].pose.translation.y; let y2 = input.pointers[1].pose.translation.y; let Some(mut mat) = get_working_copy(&self.universe, chaperone_mgr) else { @@ -212,12 +232,15 @@ impl PlayspaceMover { return; }; let offset = y1.min(y2) - 0.03; + let before = mat; mat.translation.y += offset; self.playspace_state.openvr_space_center.translation.y = mat.translation.y; set_working_copy(&self.universe, chaperone_mgr, &mat); chaperone_mgr.commit_working_copy(EChaperoneConfigFile::EChaperoneConfigFile_Live); + playspace_common::shift_world(overlays, anchor, &before, &mat); + if self.drag.is_some() { log::info!("Space drag interrupted by fix floor"); self.drag = None; @@ -228,7 +251,12 @@ impl PlayspaceMover { } } - pub fn recenter(&mut self, chaperone_mgr: &mut ChaperoneSetupManager, input: &InputState) { + pub fn recenter( + &mut self, + chaperone_mgr: &mut ChaperoneSetupManager, + app: &mut AppState, + overlays: &mut OverlayWindowManager, + ) { if self.drag.is_some() { log::info!("Space drag interrupted by recenter"); self.drag = None; @@ -238,11 +266,16 @@ impl PlayspaceMover { self.rotate = None; } + let input = &app.input_state; + let anchor = &mut app.anchor; + let Some(mat) = get_working_copy(&self.universe, chaperone_mgr) else { log::warn!("Can't recenter - failed to get zero pose"); return; }; + let before = mat; + let cur_rot: Quat = Quat::from_affine3(&mat); let cur_pos: Vec3 = Vec3::from(mat.translation); @@ -276,6 +309,8 @@ impl PlayspaceMover { set_working_copy(&self.universe, chaperone_mgr, &new_mat); chaperone_mgr.commit_working_copy(EChaperoneConfigFile::EChaperoneConfigFile_Live); + + playspace_common::shift_world(overlays, anchor, &before, &new_mat); } pub fn playspace_changed( diff --git a/wayvr/src/backend/openxr/mod.rs b/wayvr/src/backend/openxr/mod.rs index 557f156d..fd37819a 100644 --- a/wayvr/src/backend/openxr/mod.rs +++ b/wayvr/src/backend/openxr/mod.rs @@ -484,7 +484,7 @@ pub fn openxr_run(args: &Args) -> Result<(), BackendError> { } TaskType::Playspace(task) => { if let Some(playspace_mover) = playspace_mover.as_mut() { - playspace_mover.handle_task(&mut app, task); + playspace_mover.handle_task(&mut app, &mut overlays, task); } } TaskType::OpenXR(task) => { diff --git a/wayvr/src/backend/openxr/playspace.rs b/wayvr/src/backend/openxr/playspace.rs index 8cc8fb30..b2f8e570 100644 --- a/wayvr/src/backend/openxr/playspace.rs +++ b/wayvr/src/backend/openxr/playspace.rs @@ -4,7 +4,6 @@ use wgui::log::LogErr; use crate::{ backend::{ - input::InputState, playspace_common::{self, SpaceGravity, SpaceGravityUpdateParams}, task::PlayspaceTask, }, @@ -39,20 +38,25 @@ impl PlayspaceMover { }) } - pub fn handle_task(&mut self, app: &mut AppState, task: PlayspaceTask) { + pub fn handle_task( + &mut self, + app: &mut AppState, + overlays: &mut OverlayWindowManager, + task: PlayspaceTask, + ) { let Some(monado) = &mut app.monado_state else { return; // monado not available }; match task { PlayspaceTask::FixFloor => { - self.fix_floor(&app.input_state, &mut monado.ipc); + self.fix_floor(app, overlays); } PlayspaceTask::Reset => { - self.reset_offset(&mut monado.ipc); + self.reset_offset(app, overlays); } PlayspaceTask::Recenter => { - self.recenter(&app.input_state, &mut monado.ipc); + self.recenter(app, overlays); } PlayspaceTask::SaveCenter => { self.save_center(&mut monado.ipc); @@ -76,7 +80,7 @@ impl PlayspaceMover { if pointer.now.space_reset { if !pointer.before.space_reset { log::info!("Space reset"); - self.reset_offset(&mut monado.ipc); + self.reset_offset(app, overlays); } return; } @@ -226,7 +230,15 @@ impl PlayspaceMover { } } - pub fn recenter(&mut self, input: &InputState, monado: &mut Monado) { + pub fn recenter( + &mut self, + app: &mut AppState, + overlays: &mut OverlayWindowManager, + ) { + let Some(monado) = &mut app.monado_state else { + return; + }; + if self.drag.is_some() { log::info!("Space drag interrupted by recenter"); self.drag = None; @@ -236,13 +248,20 @@ impl PlayspaceMover { self.rotate = None; } + let input = &app.input_state; + let anchor = &mut app.anchor; + let Ok(mut pose) = monado + .ipc .get_reference_space_offset(ReferenceSpaceType::Stage) .inspect_err(|e| log::warn!("Could not recenter due to libmonado error: {e:?}")) else { return; }; + let before = + Affine3A::from_rotation_translation(pose.orientation.into(), pose.position.into()); + let cur_rot: Quat = pose.orientation.into(); let cur_pos: Vec3 = pose.position.into(); @@ -273,13 +292,26 @@ impl PlayspaceMover { } let _ = monado + .ipc .set_reference_space_offset(ReferenceSpaceType::Stage, pose) .inspect_err(|e| log::warn!("Could not recenter due to libmonado error: {e:?}")); self.gravity.reset(); + + let after = + Affine3A::from_rotation_translation(pose.orientation.into(), pose.position.into()); + playspace_common::shift_world(overlays, anchor, &before, &after); } - pub fn reset_offset(&mut self, monado: &mut Monado) { + pub fn reset_offset( + &mut self, + app: &mut AppState, + overlays: &mut OverlayWindowManager, + ) { + let Some(monado) = &mut app.monado_state else { + return; + }; + if self.drag.is_some() { log::info!("Space drag interrupted by manual reset"); self.drag = None; @@ -289,12 +321,34 @@ impl PlayspaceMover { self.rotate = None; } + let Ok(pose) = monado + .ipc + .get_reference_space_offset(ReferenceSpaceType::Stage) + .inspect_err(|e| log::warn!("Could not reset offset due to libmonado error: {e:?}")) + else { + return; + }; + + let before = + Affine3A::from_rotation_translation(pose.orientation.into(), pose.position.into()); + self.gravity.reset(); let offset = self.playspace_state.openxr_space_center; - apply_offset(offset, monado); + apply_offset(offset, &mut monado.ipc); + + let after = offset; + playspace_common::shift_world(overlays, &mut app.anchor, &before, &after); } - pub fn fix_floor(&mut self, input: &InputState, monado: &mut Monado) { + pub fn fix_floor( + &mut self, + app: &mut AppState, + overlays: &mut OverlayWindowManager, + ) { + let Some(monado) = &mut app.monado_state else { + return; + }; + if self.drag.is_some() { log::info!("Space drag interrupted by fix floor"); self.drag = None; @@ -304,13 +358,20 @@ impl PlayspaceMover { self.rotate = None; } + let input = &app.input_state; + let anchor = &mut app.anchor; + let Ok(mut pose) = monado + .ipc .get_reference_space_offset(ReferenceSpaceType::Stage) .inspect_err(|e| log::warn!("Could not fix floor due to libmonado error: {e:?}")) else { return; }; + let before = + Affine3A::from_rotation_translation(pose.orientation.into(), pose.position.into()); + let y1 = input.pointers[0].raw_pose.translation.y; let y2 = input.pointers[1].raw_pose.translation.y; let delta = y1.min(y2) - 0.05; @@ -320,8 +381,13 @@ impl PlayspaceMover { self.playspace_state.openxr_space_center.translation.y = pose.position.y; let _ = monado + .ipc .set_reference_space_offset(ReferenceSpaceType::Stage, pose) .inspect_err(|e| log::warn!("Could not fix floor due to libmonado error: {e:?}")); + + let after = + Affine3A::from_rotation_translation(pose.orientation.into(), pose.position.into()); + playspace_common::shift_world(overlays, anchor, &before, &after); } pub fn save_center(&mut self, monado: &mut Monado) {