feat: improve screen alighment on show/hide

This commit is contained in:
galister
2024-04-14 17:17:20 +09:00
parent 8e799d1b8f
commit d99a58da9e
5 changed files with 54 additions and 37 deletions

View File

@@ -499,3 +499,23 @@ pub fn raycast_cylinder(
Some((t, hit_local.xy())) 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
}
}

View File

@@ -6,6 +6,7 @@ use glam::{Affine3A, Vec2, Vec3A};
use ovr_overlay::TrackedDeviceIndex; use ovr_overlay::TrackedDeviceIndex;
use smallvec::{smallvec, SmallVec}; use smallvec::{smallvec, SmallVec};
use crate::backend::common::snap_upright;
use crate::config::{save_state, AStrMapExt, GeneralConfig}; use crate::config::{save_state, AStrMapExt, GeneralConfig};
use crate::state::AppState; use crate::state::AppState;
@@ -286,11 +287,11 @@ fn interact_hand<O>(
where where
O: Default, O: Default,
{ {
let hmd = &app.input_state.hmd; let hmd = app.input_state.hmd;
let mut pointer = &mut app.input_state.pointers[idx]; let mut pointer = &mut app.input_state.pointers[idx];
if let Some(grab_data) = pointer.interaction.grabbed { if let Some(grab_data) = pointer.interaction.grabbed {
if let Some(grabbed) = overlays.mut_by_id(grab_data.grabbed_id) { 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 { } else {
log::warn!("Grabbed overlay {} does not exist", grab_data.grabbed_id); log::warn!("Grabbed overlay {} does not exist", grab_data.grabbed_id);
pointer.interaction.grabbed = None; pointer.interaction.grabbed = None;
@@ -512,10 +513,8 @@ impl Pointer {
self.interaction.grabbed = None; self.interaction.grabbed = None;
} }
} else { } else {
overlay.state.saved_point = Some( overlay.state.saved_transform =
hmd.inverse() Some(snap_upright(*hmd, Vec3A::Y).inverse() * overlay.state.transform);
.transform_point3a(overlay.state.transform.translation),
);
if let Some(grab_data) = self.interaction.grabbed.as_ref() { if let Some(grab_data) = self.interaction.grabbed.as_ref() {
let mut state_dirty = false; let mut state_dirty = false;

View File

@@ -12,7 +12,10 @@ use vulkano::image::view::ImageView;
use crate::state::AppState; 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); static AUTO_INCREMENT: AtomicUsize = AtomicUsize::new(0);
@@ -32,11 +35,10 @@ pub struct OverlayState {
pub dirty: bool, pub dirty: bool,
pub alpha: f32, pub alpha: f32,
pub transform: Affine3A, pub transform: Affine3A,
pub saved_point: Option<Vec3A>,
pub saved_scale: Option<f32>,
pub spawn_scale: f32, // aka width pub spawn_scale: f32, // aka width
pub spawn_point: Vec3A, pub spawn_point: Vec3A,
pub spawn_rotation: Quat, pub spawn_rotation: Quat,
pub saved_transform: Option<Affine3A>,
pub relative_to: RelativeTo, pub relative_to: RelativeTo,
pub curvature: Option<f32>, pub curvature: Option<f32>,
pub primary_pointer: Option<usize>, pub primary_pointer: Option<usize>,
@@ -58,11 +60,10 @@ impl Default for OverlayState {
alpha: 1.0, alpha: 1.0,
relative_to: RelativeTo::None, relative_to: RelativeTo::None,
curvature: None, curvature: None,
saved_point: None,
saved_scale: None,
spawn_scale: 1.0, spawn_scale: 1.0,
spawn_point: Vec3A::NEG_Z, spawn_point: Vec3A::NEG_Z,
spawn_rotation: Quat::IDENTITY, spawn_rotation: Quat::IDENTITY,
saved_transform: None,
transform: Affine3A::IDENTITY, transform: Affine3A::IDENTITY,
primary_pointer: None, primary_pointer: None,
interaction_transform: Affine2::IDENTITY, 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) { pub fn auto_movement(&mut self, app: &mut AppState) {
if let Some(parent) = self.parent_transform(app) { if let Some(parent) = self.parent_transform(app) {
let scale = self.saved_scale.unwrap_or(self.spawn_scale); self.transform = parent * self.get_transform();
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.dirty = true; self.dirty = true;
} }
} }
pub fn reset(&mut self, app: &mut AppState, hard_reset: bool) { pub fn reset(&mut self, app: &mut AppState, hard_reset: bool) {
if hard_reset { if hard_reset {
self.saved_point = None; self.saved_transform = None;
self.saved_scale = None;
} }
let scale = self.saved_scale.unwrap_or(self.spawn_scale); let hmd = snap_upright(app.input_state.hmd, Vec3A::Y);
let point = self.saved_point.unwrap_or(self.spawn_point); 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 { if self.grabbable {
if hard_reset {
self.realign(&app.input_state.hmd); self.realign(&app.input_state.hmd);
} else {
//self.transform = snap_upright(self.transform, app.input_state.hmd.y_axis);
}
} }
self.dirty = true; self.dirty = true;
} }
@@ -168,7 +168,6 @@ impl OverlayState {
} }
let scale = self.transform.x_axis.length(); let scale = self.transform.x_axis.length();
self.saved_scale = Some(scale);
let col_z = (self.transform.translation - hmd.translation).normalize(); let col_z = (self.transform.translation - hmd.translation).normalize();
let col_y = up_dir; let col_y = up_dir;

View File

@@ -459,10 +459,9 @@ fn run_watch(data: &WatchAction, app: &mut AppState) {
app.tasks.enqueue(TaskType::Overlay( app.tasks.enqueue(TaskType::Overlay(
OverlaySelector::Name(WATCH_NAME.into()), OverlaySelector::Name(WATCH_NAME.into()),
Box::new(|app, o| { Box::new(|app, o| {
if o.saved_scale.is_none() { if o.saved_transform.is_none() {
o.saved_scale = Some(o.spawn_scale);
o.want_visible = false; o.want_visible = false;
o.saved_scale = Some(0.0); o.saved_transform = Some(o.transform);
Toast::new( Toast::new(
ToastTopic::System, ToastTopic::System,
"Watch hidden".into(), "Watch hidden".into(),
@@ -472,7 +471,7 @@ fn run_watch(data: &WatchAction, app: &mut AppState) {
.submit(app); .submit(app);
} else { } else {
o.want_visible = true; o.want_visible = true;
o.saved_scale = None; o.saved_transform = None;
Toast::new(ToastTopic::System, "Watch restored".into(), "".into()) Toast::new(ToastTopic::System, "Watch restored".into(), "".into())
.submit(app); .submit(app);
} }

View File

@@ -50,7 +50,7 @@ pub fn watch_fade<D>(app: &mut AppState, watch: &mut OverlayData<D>)
where where
D: Default, 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; watch.state.want_visible = false;
return; return;
} }