overlays stay in place after reset/recenter/fix_floor

This commit is contained in:
galister 2026-07-23 18:58:28 +09:00
parent b82f781757
commit 0613f94be6
4 changed files with 122 additions and 21 deletions

View File

@ -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) => {

View File

@ -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<OpenVrOverlayData>,
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<OpenVrOverlayData>,
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<OpenVrOverlayData>,
) {
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<OpenVrOverlayData>,
) {
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(

View File

@ -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) => {

View File

@ -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<OpenXrOverlayData>,
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<OpenXrOverlayData>,
) {
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<OpenXrOverlayData>,
) {
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<OpenXrOverlayData>,
) {
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) {