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()))
|
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 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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user