From d99a58da9e42af572e68942da41fb68efca55ff3 Mon Sep 17 00:00:00 2001 From: galister <22305755+galister@users.noreply.github.com> Date: Sun, 14 Apr 2024 17:17:20 +0900 Subject: [PATCH] feat: improve screen alighment on show/hide --- src/backend/common.rs | 20 +++++++++++++++ src/backend/input.rs | 11 ++++----- src/backend/overlay.rs | 51 +++++++++++++++++++-------------------- src/gui/modular/button.rs | 7 +++--- src/overlays/watch.rs | 2 +- 5 files changed, 54 insertions(+), 37 deletions(-) diff --git a/src/backend/common.rs b/src/backend/common.rs index c0d4c81..7b03bf8 100644 --- a/src/backend/common.rs +++ b/src/backend/common.rs @@ -499,3 +499,23 @@ pub fn raycast_cylinder( Some((t, hit_local.xy())) } + +pub fn snap_upright(transform: Affine3A, up_dir: Vec3A) -> Affine3A { + if transform.x_axis.dot(up_dir).abs() < 0.2 { + let scale = transform.x_axis.length(); + let col_z = transform.z_axis.normalize(); + let col_y = up_dir; + let col_x = col_y.cross(col_z); + let col_y = col_z.cross(col_x).normalize(); + let col_x = col_x.normalize(); + + Affine3A::from_cols( + col_x * scale, + col_y * scale, + col_z * scale, + transform.translation, + ) + } else { + transform + } +} diff --git a/src/backend/input.rs b/src/backend/input.rs index 17f1dfc..3ba3a18 100644 --- a/src/backend/input.rs +++ b/src/backend/input.rs @@ -6,6 +6,7 @@ use glam::{Affine3A, Vec2, Vec3A}; use ovr_overlay::TrackedDeviceIndex; use smallvec::{smallvec, SmallVec}; +use crate::backend::common::snap_upright; use crate::config::{save_state, AStrMapExt, GeneralConfig}; use crate::state::AppState; @@ -286,11 +287,11 @@ fn interact_hand( where O: Default, { - let hmd = &app.input_state.hmd; + let hmd = app.input_state.hmd; let mut pointer = &mut app.input_state.pointers[idx]; if let Some(grab_data) = pointer.interaction.grabbed { if let Some(grabbed) = overlays.mut_by_id(grab_data.grabbed_id) { - pointer.handle_grabbed(grabbed, hmd, &mut app.session.config); + pointer.handle_grabbed(grabbed, &hmd, &mut app.session.config); } else { log::warn!("Grabbed overlay {} does not exist", grab_data.grabbed_id); pointer.interaction.grabbed = None; @@ -512,10 +513,8 @@ impl Pointer { self.interaction.grabbed = None; } } else { - overlay.state.saved_point = Some( - hmd.inverse() - .transform_point3a(overlay.state.transform.translation), - ); + overlay.state.saved_transform = + Some(snap_upright(*hmd, Vec3A::Y).inverse() * overlay.state.transform); if let Some(grab_data) = self.interaction.grabbed.as_ref() { let mut state_dirty = false; diff --git a/src/backend/overlay.rs b/src/backend/overlay.rs index c75768f..ea69cea 100644 --- a/src/backend/overlay.rs +++ b/src/backend/overlay.rs @@ -12,7 +12,10 @@ use vulkano::image::view::ImageView; use crate::state::AppState; -use super::input::{DummyInteractionHandler, Haptics, InteractionHandler, PointerHit}; +use super::{ + common::snap_upright, + input::{DummyInteractionHandler, Haptics, InteractionHandler, PointerHit}, +}; static AUTO_INCREMENT: AtomicUsize = AtomicUsize::new(0); @@ -32,11 +35,10 @@ pub struct OverlayState { pub dirty: bool, pub alpha: f32, pub transform: Affine3A, - pub saved_point: Option, - pub saved_scale: Option, pub spawn_scale: f32, // aka width pub spawn_point: Vec3A, pub spawn_rotation: Quat, + pub saved_transform: Option, pub relative_to: RelativeTo, pub curvature: Option, pub primary_pointer: Option, @@ -58,11 +60,10 @@ impl Default for OverlayState { alpha: 1.0, relative_to: RelativeTo::None, curvature: None, - saved_point: None, - saved_scale: None, spawn_scale: 1.0, spawn_point: Vec3A::NEG_Z, spawn_rotation: Quat::IDENTITY, + saved_transform: None, transform: Affine3A::IDENTITY, primary_pointer: None, interaction_transform: Affine2::IDENTITY, @@ -104,38 +105,37 @@ impl OverlayState { } } + fn get_transform(&self) -> Affine3A { + self.saved_transform.unwrap_or_else(|| { + Affine3A::from_scale_rotation_translation( + Vec3::ONE * self.spawn_scale, + self.spawn_rotation, + self.spawn_point.into(), + ) + }) + } + pub fn auto_movement(&mut self, app: &mut AppState) { if let Some(parent) = self.parent_transform(app) { - let scale = self.saved_scale.unwrap_or(self.spawn_scale); - let point = self.saved_point.unwrap_or(self.spawn_point); - self.transform = parent - * Affine3A::from_scale_rotation_translation( - Vec3::ONE * scale, - self.spawn_rotation, - point.into(), - ); - + self.transform = parent * self.get_transform(); self.dirty = true; } } pub fn reset(&mut self, app: &mut AppState, hard_reset: bool) { if hard_reset { - self.saved_point = None; - self.saved_scale = None; + self.saved_transform = None; } - let scale = self.saved_scale.unwrap_or(self.spawn_scale); - let point = self.saved_point.unwrap_or(self.spawn_point); + let hmd = snap_upright(app.input_state.hmd, Vec3A::Y); + self.transform = hmd * self.get_transform(); - let translation = app.input_state.hmd.transform_point3a(point); - self.transform = Affine3A::from_scale_rotation_translation( - Vec3::ONE * scale, - Quat::IDENTITY, - translation.into(), - ); if self.grabbable { - self.realign(&app.input_state.hmd); + if hard_reset { + self.realign(&app.input_state.hmd); + } else { + //self.transform = snap_upright(self.transform, app.input_state.hmd.y_axis); + } } self.dirty = true; } @@ -168,7 +168,6 @@ impl OverlayState { } let scale = self.transform.x_axis.length(); - self.saved_scale = Some(scale); let col_z = (self.transform.translation - hmd.translation).normalize(); let col_y = up_dir; diff --git a/src/gui/modular/button.rs b/src/gui/modular/button.rs index 31c0d42..9f0ff68 100644 --- a/src/gui/modular/button.rs +++ b/src/gui/modular/button.rs @@ -459,10 +459,9 @@ fn run_watch(data: &WatchAction, app: &mut AppState) { app.tasks.enqueue(TaskType::Overlay( OverlaySelector::Name(WATCH_NAME.into()), Box::new(|app, o| { - if o.saved_scale.is_none() { - o.saved_scale = Some(o.spawn_scale); + if o.saved_transform.is_none() { o.want_visible = false; - o.saved_scale = Some(0.0); + o.saved_transform = Some(o.transform); Toast::new( ToastTopic::System, "Watch hidden".into(), @@ -472,7 +471,7 @@ fn run_watch(data: &WatchAction, app: &mut AppState) { .submit(app); } else { o.want_visible = true; - o.saved_scale = None; + o.saved_transform = None; Toast::new(ToastTopic::System, "Watch restored".into(), "".into()) .submit(app); } diff --git a/src/overlays/watch.rs b/src/overlays/watch.rs index 9d5f2b0..85ed668 100644 --- a/src/overlays/watch.rs +++ b/src/overlays/watch.rs @@ -50,7 +50,7 @@ pub fn watch_fade(app: &mut AppState, watch: &mut OverlayData) where D: Default, { - if watch.state.saved_scale.is_some_and(|s| s < f32::EPSILON) { + if watch.state.saved_transform.is_some() { watch.state.want_visible = false; return; }