feat: improve screen alighment on show/hide
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<O>(
|
||||
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;
|
||||
|
||||
@@ -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<Vec3A>,
|
||||
pub saved_scale: Option<f32>,
|
||||
pub spawn_scale: f32, // aka width
|
||||
pub spawn_point: Vec3A,
|
||||
pub spawn_rotation: Quat,
|
||||
pub saved_transform: Option<Affine3A>,
|
||||
pub relative_to: RelativeTo,
|
||||
pub curvature: Option<f32>,
|
||||
pub primary_pointer: Option<usize>,
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ pub fn watch_fade<D>(app: &mut AppState, watch: &mut OverlayData<D>)
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user