relative positioning rework
This commit is contained in:
@@ -6,8 +6,9 @@ use glam::{Affine3A, Vec2, Vec3, Vec3A, Vec3Swizzles};
|
|||||||
|
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
|
|
||||||
use crate::backend::common::{snap_upright, OverlaySelector};
|
use crate::backend::common::OverlaySelector;
|
||||||
use crate::config::{AStrMapExt, GeneralConfig};
|
use crate::backend::overlay::Positioning;
|
||||||
|
use crate::config::AStrMapExt;
|
||||||
use crate::overlays::anchor::ANCHOR_NAME;
|
use crate::overlays::anchor::ANCHOR_NAME;
|
||||||
use crate::state::{AppSession, AppState, KeyboardFocus};
|
use crate::state::{AppSession, AppState, KeyboardFocus};
|
||||||
|
|
||||||
@@ -334,17 +335,10 @@ fn interact_hand<O>(
|
|||||||
where
|
where
|
||||||
O: Default,
|
O: Default,
|
||||||
{
|
{
|
||||||
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(
|
Pointer::handle_grabbed(idx, grabbed, app);
|
||||||
grabbed,
|
|
||||||
&hmd,
|
|
||||||
&app.anchor,
|
|
||||||
&mut app.tasks,
|
|
||||||
&mut app.session.config,
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
log::warn!("Grabbed overlay {} does not exist", grab_data.grabbed_id.0);
|
log::warn!("Grabbed overlay {} does not exist", grab_data.grabbed_id.0);
|
||||||
pointer.interaction.grabbed = None;
|
pointer.interaction.grabbed = None;
|
||||||
@@ -537,6 +531,13 @@ impl Pointer {
|
|||||||
old_curvature: overlay.state.curvature,
|
old_curvature: overlay.state.curvature,
|
||||||
grab_all: matches!(self.interaction.mode, PointerMode::Right),
|
grab_all: matches!(self.interaction.mode, PointerMode::Right),
|
||||||
});
|
});
|
||||||
|
overlay.state.positioning = match overlay.state.positioning {
|
||||||
|
Positioning::FollowHand { hand, lerp } => Positioning::FollowHandPaused { hand, lerp },
|
||||||
|
Positioning::FollowHead { lerp } => Positioning::FollowHeadPaused { lerp },
|
||||||
|
x => x,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Show anchor
|
||||||
tasks.enqueue(TaskType::Overlay(
|
tasks.enqueue(TaskType::Overlay(
|
||||||
OverlaySelector::Name(ANCHOR_NAME.clone()),
|
OverlaySelector::Name(ANCHOR_NAME.clone()),
|
||||||
Box::new(|app, o| {
|
Box::new(|app, o| {
|
||||||
@@ -553,25 +554,20 @@ impl Pointer {
|
|||||||
log::info!("Hand {}: grabbed {}", self.idx, overlay.state.name);
|
log::info!("Hand {}: grabbed {}", self.idx, overlay.state.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_grabbed<O>(
|
fn handle_grabbed<O>(idx: usize, overlay: &mut OverlayData<O>, app: &mut AppState)
|
||||||
&mut self,
|
where
|
||||||
overlay: &mut OverlayData<O>,
|
|
||||||
hmd: &Affine3A,
|
|
||||||
anchor: &Affine3A,
|
|
||||||
tasks: &mut TaskContainer,
|
|
||||||
config: &mut GeneralConfig,
|
|
||||||
) where
|
|
||||||
O: Default,
|
O: Default,
|
||||||
{
|
{
|
||||||
if self.now.grab {
|
let mut pointer = &mut app.input_state.pointers[idx];
|
||||||
if let Some(grab_data) = self.interaction.grabbed.as_mut() {
|
if pointer.now.grab {
|
||||||
if self.now.click {
|
if let Some(grab_data) = pointer.interaction.grabbed.as_mut() {
|
||||||
self.interaction.mode = PointerMode::Special;
|
if pointer.now.click {
|
||||||
|
pointer.interaction.mode = PointerMode::Special;
|
||||||
let cur_scale = overlay.state.transform.x_axis.length();
|
let cur_scale = overlay.state.transform.x_axis.length();
|
||||||
if cur_scale < 0.1 && self.now.scroll_y > 0.0 {
|
if cur_scale < 0.1 && pointer.now.scroll_y > 0.0 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if cur_scale > 20. && self.now.scroll_y < 0.0 {
|
if cur_scale > 20. && pointer.now.scroll_y < 0.0 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -579,46 +575,62 @@ impl Pointer {
|
|||||||
.state
|
.state
|
||||||
.transform
|
.transform
|
||||||
.matrix3
|
.matrix3
|
||||||
.mul_scalar(0.025f32.mul_add(-self.now.scroll_y, 1.0));
|
.mul_scalar(0.025f32.mul_add(-pointer.now.scroll_y, 1.0));
|
||||||
} else if config.allow_sliding && self.now.scroll_y.is_finite() {
|
} else if app.session.config.allow_sliding && pointer.now.scroll_y.is_finite() {
|
||||||
grab_data.offset.z -= self.now.scroll_y * 0.05;
|
grab_data.offset.z -= pointer.now.scroll_y * 0.05;
|
||||||
}
|
}
|
||||||
overlay.state.transform.translation = self.pose.transform_point3a(grab_data.offset);
|
overlay.state.transform.translation =
|
||||||
overlay.state.realign(hmd);
|
pointer.pose.transform_point3a(grab_data.offset);
|
||||||
|
overlay.state.realign(&app.input_state.hmd);
|
||||||
overlay.state.dirty = true;
|
overlay.state.dirty = true;
|
||||||
} else {
|
} else {
|
||||||
log::error!("Grabbed overlay {} does not exist", overlay.state.id.0);
|
log::error!("Grabbed overlay {} does not exist", overlay.state.id.0);
|
||||||
self.interaction.grabbed = None;
|
pointer.interaction.grabbed = None;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if overlay.state.anchored {
|
overlay.state.positioning = match overlay.state.positioning {
|
||||||
overlay.state.saved_transform =
|
Positioning::FollowHandPaused { hand, lerp } => {
|
||||||
Some(snap_upright(*anchor, Vec3A::Y).inverse() * overlay.state.transform);
|
Positioning::FollowHand { hand, lerp }
|
||||||
|
}
|
||||||
|
Positioning::FollowHeadPaused { lerp } => Positioning::FollowHead { lerp },
|
||||||
|
x => x,
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(grab_data) = self.interaction.grabbed.as_ref() {
|
let save_success = overlay.state.save_transform(app);
|
||||||
|
|
||||||
|
// re-borrow
|
||||||
|
pointer = &mut app.input_state.pointers[idx];
|
||||||
|
|
||||||
|
if save_success {
|
||||||
|
if let Some(grab_data) = pointer.interaction.grabbed.as_ref() {
|
||||||
if overlay.state.curvature != grab_data.old_curvature {
|
if overlay.state.curvature != grab_data.old_curvature {
|
||||||
if let Some(val) = overlay.state.curvature {
|
if let Some(val) = overlay.state.curvature {
|
||||||
config.curve_values.arc_set(overlay.state.name.clone(), val);
|
app.session
|
||||||
|
.config
|
||||||
|
.curve_values
|
||||||
|
.arc_set(overlay.state.name.clone(), val);
|
||||||
} else {
|
} else {
|
||||||
let ref_name = overlay.state.name.as_ref();
|
let ref_name = overlay.state.name.as_ref();
|
||||||
config.curve_values.arc_rm(ref_name);
|
app.session.config.curve_values.arc_rm(ref_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
config.transform_values.arc_set(
|
app.session.config.transform_values.arc_set(
|
||||||
overlay.state.name.clone(),
|
overlay.state.name.clone(),
|
||||||
overlay.state.saved_transform.unwrap(), // safe
|
overlay.state.saved_transform.unwrap(), // safe
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.interaction.grabbed = None;
|
pointer.interaction.grabbed = None;
|
||||||
tasks.enqueue(TaskType::Overlay(
|
|
||||||
|
// Hide anchor
|
||||||
|
app.tasks.enqueue(TaskType::Overlay(
|
||||||
OverlaySelector::Name(ANCHOR_NAME.clone()),
|
OverlaySelector::Name(ANCHOR_NAME.clone()),
|
||||||
Box::new(|_app, o| {
|
Box::new(|_app, o| {
|
||||||
o.want_visible = false;
|
o.want_visible = false;
|
||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
log::info!("Hand {}: dropped {}", self.idx, overlay.state.name);
|
log::info!("Hand {}: dropped {}", idx, overlay.state.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,10 @@ use crate::{
|
|||||||
state::{AppState, KeyboardFocus},
|
state::{AppState, KeyboardFocus},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::input::{DummyInteractionHandler, Haptics, InteractionHandler, PointerHit};
|
use super::{
|
||||||
|
common::snap_upright,
|
||||||
|
input::{DummyInteractionHandler, Haptics, InteractionHandler, PointerHit},
|
||||||
|
};
|
||||||
|
|
||||||
static OVERLAY_AUTO_INCREMENT: AtomicUsize = AtomicUsize::new(0);
|
static OVERLAY_AUTO_INCREMENT: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
@@ -44,7 +47,6 @@ pub struct OverlayState {
|
|||||||
pub grabbable: bool,
|
pub grabbable: bool,
|
||||||
pub interactable: bool,
|
pub interactable: bool,
|
||||||
pub recenter: bool,
|
pub recenter: bool,
|
||||||
pub anchored: bool,
|
|
||||||
pub keyboard_focus: Option<KeyboardFocus>,
|
pub keyboard_focus: Option<KeyboardFocus>,
|
||||||
pub dirty: bool,
|
pub dirty: bool,
|
||||||
pub alpha: f32,
|
pub alpha: f32,
|
||||||
@@ -54,7 +56,7 @@ pub struct OverlayState {
|
|||||||
pub spawn_point: Vec3A,
|
pub spawn_point: Vec3A,
|
||||||
pub spawn_rotation: Quat,
|
pub spawn_rotation: Quat,
|
||||||
pub saved_transform: Option<Affine3A>,
|
pub saved_transform: Option<Affine3A>,
|
||||||
pub relative_to: RelativeTo,
|
pub positioning: Positioning,
|
||||||
pub curvature: Option<f32>,
|
pub curvature: Option<f32>,
|
||||||
pub interaction_transform: Affine2,
|
pub interaction_transform: Affine2,
|
||||||
pub birthframe: usize,
|
pub birthframe: usize,
|
||||||
@@ -70,12 +72,11 @@ impl Default for OverlayState {
|
|||||||
grabbable: false,
|
grabbable: false,
|
||||||
recenter: false,
|
recenter: false,
|
||||||
interactable: false,
|
interactable: false,
|
||||||
anchored: false,
|
|
||||||
keyboard_focus: None,
|
keyboard_focus: None,
|
||||||
dirty: true,
|
dirty: true,
|
||||||
alpha: 1.0,
|
alpha: 1.0,
|
||||||
z_order: Z_ORDER_DEFAULT,
|
z_order: Z_ORDER_DEFAULT,
|
||||||
relative_to: RelativeTo::None,
|
positioning: Positioning::Floating,
|
||||||
curvature: None,
|
curvature: None,
|
||||||
spawn_scale: 1.0,
|
spawn_scale: 1.0,
|
||||||
spawn_point: Vec3A::NEG_Z,
|
spawn_point: Vec3A::NEG_Z,
|
||||||
@@ -113,23 +114,6 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl OverlayState {
|
impl OverlayState {
|
||||||
pub const fn parent_transform(&self, app: &AppState) -> Option<Affine3A> {
|
|
||||||
match self.relative_to {
|
|
||||||
RelativeTo::Head => Some(app.input_state.hmd),
|
|
||||||
RelativeTo::Hand(idx) => Some(app.input_state.pointers[idx].pose),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const fn get_anchor(&self, app: &AppState) -> Affine3A {
|
|
||||||
if self.anchored {
|
|
||||||
app.anchor
|
|
||||||
} else {
|
|
||||||
// fake anchor that's always in front of HMD
|
|
||||||
app.input_state.hmd
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_transform(&self) -> Affine3A {
|
fn get_transform(&self) -> Affine3A {
|
||||||
self.saved_transform.unwrap_or_else(|| {
|
self.saved_transform.unwrap_or_else(|| {
|
||||||
Affine3A::from_scale_rotation_translation(
|
Affine3A::from_scale_rotation_translation(
|
||||||
@@ -141,21 +125,57 @@ impl OverlayState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
let (target_transform, lerp) = match self.positioning {
|
||||||
self.transform = parent * self.get_transform();
|
Positioning::FollowHead { lerp } => (app.input_state.hmd * self.get_transform(), lerp),
|
||||||
self.dirty = true;
|
Positioning::FollowHand { hand, lerp } => (
|
||||||
}
|
app.input_state.pointers[hand].pose * self.get_transform(),
|
||||||
|
lerp,
|
||||||
|
),
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.transform = match lerp {
|
||||||
|
1.0 => target_transform,
|
||||||
|
lerp => {
|
||||||
|
let scale = target_transform.matrix3.x_axis.length();
|
||||||
|
|
||||||
|
let rot_from = Quat::from_mat3a(&self.transform.matrix3.div_scalar(scale));
|
||||||
|
let rot_to = Quat::from_mat3a(&target_transform.matrix3.div_scalar(scale));
|
||||||
|
|
||||||
|
let rotation = rot_from.slerp(rot_to, lerp);
|
||||||
|
let translation = self
|
||||||
|
.transform
|
||||||
|
.translation
|
||||||
|
.slerp(target_transform.translation, lerp);
|
||||||
|
|
||||||
|
Affine3A::from_scale_rotation_translation(
|
||||||
|
Vec3::ONE * scale,
|
||||||
|
rotation,
|
||||||
|
translation.into(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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) {
|
||||||
|
let parent_transform = match self.positioning {
|
||||||
|
Positioning::Floating
|
||||||
|
| Positioning::FollowHead { .. }
|
||||||
|
| Positioning::FollowHeadPaused { .. } => app.input_state.hmd,
|
||||||
|
Positioning::FollowHand { hand, .. } | Positioning::FollowHandPaused { hand, .. } => {
|
||||||
|
app.input_state.pointers[hand].pose
|
||||||
|
}
|
||||||
|
Positioning::Anchored => app.anchor,
|
||||||
|
Positioning::Static => return,
|
||||||
|
};
|
||||||
|
|
||||||
if hard_reset {
|
if hard_reset {
|
||||||
self.saved_transform = None;
|
self.saved_transform = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.transform = self
|
self.transform = parent_transform * self.get_transform();
|
||||||
.parent_transform(app)
|
|
||||||
.unwrap_or_else(|| self.get_anchor(app))
|
|
||||||
* self.get_transform();
|
|
||||||
|
|
||||||
if self.grabbable && hard_reset {
|
if self.grabbable && hard_reset {
|
||||||
self.realign(&app.input_state.hmd);
|
self.realign(&app.input_state.hmd);
|
||||||
@@ -163,6 +183,24 @@ impl OverlayState {
|
|||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn save_transform(&mut self, app: &mut AppState) -> bool {
|
||||||
|
let parent_transform = match self.positioning {
|
||||||
|
Positioning::Floating => snap_upright(app.input_state.hmd, Vec3A::Y),
|
||||||
|
Positioning::FollowHead { .. } | Positioning::FollowHeadPaused { .. } => {
|
||||||
|
app.input_state.hmd
|
||||||
|
}
|
||||||
|
Positioning::FollowHand { hand, .. } | Positioning::FollowHandPaused { hand, .. } => {
|
||||||
|
app.input_state.pointers[hand].pose
|
||||||
|
}
|
||||||
|
Positioning::Anchored => snap_upright(app.anchor, Vec3A::Y),
|
||||||
|
Positioning::Static => return false,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.saved_transform = Some(parent_transform.inverse() * self.transform);
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
pub fn realign(&mut self, hmd: &Affine3A) {
|
pub fn realign(&mut self, hmd: &Affine3A) {
|
||||||
let to_hmd = hmd.translation - self.transform.translation;
|
let to_hmd = hmd.translation - self.transform.translation;
|
||||||
let up_dir: Vec3A;
|
let up_dir: Vec3A;
|
||||||
@@ -218,7 +256,10 @@ where
|
|||||||
.copied();
|
.copied();
|
||||||
}
|
}
|
||||||
|
|
||||||
if matches!(self.state.relative_to, RelativeTo::None) {
|
if matches!(
|
||||||
|
self.state.positioning,
|
||||||
|
Positioning::Floating | Positioning::Anchored
|
||||||
|
) {
|
||||||
let hard_reset;
|
let hard_reset;
|
||||||
if let Some(transform) = app
|
if let Some(transform) = app
|
||||||
.session
|
.session
|
||||||
@@ -321,16 +362,22 @@ impl OverlayRenderer for FallbackRenderer {
|
|||||||
// Boilerplate and dummies
|
// Boilerplate and dummies
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default)]
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
pub enum RelativeTo {
|
pub enum Positioning {
|
||||||
/// Stays in place unless rencentered
|
/// Stays in place unless recentered, recenters relative to HMD
|
||||||
#[default]
|
#[default]
|
||||||
None,
|
Floating,
|
||||||
/// Stays in position relative to HMD
|
/// Stays in place unless recentered, recenters relative to anchor
|
||||||
Head,
|
Anchored,
|
||||||
/// Stays in position relative to hand
|
/// Following HMD
|
||||||
Hand(usize),
|
FollowHead { lerp: f32 },
|
||||||
|
/// Normally follows HMD, but paused due to interaction
|
||||||
|
FollowHeadPaused { lerp: f32 },
|
||||||
|
/// Following hand
|
||||||
|
FollowHand { hand: usize, lerp: f32 },
|
||||||
|
/// Normally follows hand, but paused due to interaction
|
||||||
|
FollowHandPaused { hand: usize, lerp: f32 },
|
||||||
/// Stays in place, no recentering
|
/// Stays in place, no recentering
|
||||||
Stage,
|
Static,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SplitOverlayBackend {
|
pub struct SplitOverlayBackend {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::{
|
backend::{
|
||||||
overlay::RelativeTo,
|
overlay::Positioning,
|
||||||
task::{TaskContainer, TaskType},
|
task::{TaskContainer, TaskType},
|
||||||
wayvr,
|
wayvr,
|
||||||
},
|
},
|
||||||
@@ -33,13 +33,14 @@ pub enum AttachTo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AttachTo {
|
impl AttachTo {
|
||||||
pub const fn get_relative_to(&self) -> RelativeTo {
|
// TODO: adjustable lerp factor
|
||||||
|
pub const fn get_positioning(&self) -> Positioning {
|
||||||
match self {
|
match self {
|
||||||
Self::None => RelativeTo::None,
|
Self::None => Positioning::Floating,
|
||||||
Self::HandLeft => RelativeTo::Hand(0),
|
Self::HandLeft => Positioning::FollowHand { hand: 0, lerp: 1.0 },
|
||||||
Self::HandRight => RelativeTo::Hand(1),
|
Self::HandRight => Positioning::FollowHand { hand: 1, lerp: 1.0 },
|
||||||
Self::Stage => RelativeTo::Stage,
|
Self::Stage => Positioning::Static,
|
||||||
Self::Head => RelativeTo::Head,
|
Self::Head => Positioning::FollowHead { lerp: 1.0 },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use crate::{
|
|||||||
backend::{
|
backend::{
|
||||||
common::OverlaySelector,
|
common::OverlaySelector,
|
||||||
input::PointerMode,
|
input::PointerMode,
|
||||||
overlay::RelativeTo,
|
overlay::Positioning,
|
||||||
task::{ColorChannel, SystemTask, TaskType},
|
task::{ColorChannel, SystemTask, TaskType},
|
||||||
},
|
},
|
||||||
config::{save_layout, save_settings, AStrSetExt},
|
config::{save_layout, save_settings, AStrSetExt},
|
||||||
@@ -626,15 +626,15 @@ 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 matches!(o.relative_to, RelativeTo::Hand(0)) {
|
if matches!(o.positioning, Positioning::FollowHand { hand: 0, .. }) {
|
||||||
o.relative_to = RelativeTo::Hand(1);
|
o.positioning = Positioning::FollowHand { hand: 1, lerp: 1.0 };
|
||||||
o.spawn_rotation = app.session.config.watch_rot
|
o.spawn_rotation = app.session.config.watch_rot
|
||||||
* Quat::from_rotation_x(PI)
|
* Quat::from_rotation_x(PI)
|
||||||
* Quat::from_rotation_z(PI);
|
* Quat::from_rotation_z(PI);
|
||||||
o.spawn_point = app.session.config.watch_pos;
|
o.spawn_point = app.session.config.watch_pos;
|
||||||
o.spawn_point.x *= -1.;
|
o.spawn_point.x *= -1.;
|
||||||
} else {
|
} else {
|
||||||
o.relative_to = RelativeTo::Hand(0);
|
o.positioning = Positioning::FollowHand { hand: 0, lerp: 1.0 };
|
||||||
o.spawn_rotation = app.session.config.watch_rot;
|
o.spawn_rotation = app.session.config.watch_rot;
|
||||||
o.spawn_point = app.session.config.watch_pos;
|
o.spawn_point = app.session.config.watch_pos;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use glam::Vec3A;
|
use glam::Vec3A;
|
||||||
use std::sync::{Arc, LazyLock};
|
use std::sync::{Arc, LazyLock};
|
||||||
|
|
||||||
use crate::backend::overlay::{OverlayData, OverlayState, RelativeTo, Z_ORDER_ANCHOR};
|
use crate::backend::overlay::{OverlayData, OverlayState, Positioning, Z_ORDER_ANCHOR};
|
||||||
use crate::config::{load_known_yaml, ConfigType};
|
use crate::config::{load_known_yaml, ConfigType};
|
||||||
use crate::gui::modular::{modular_canvas, ModularUiConfig};
|
use crate::gui::modular::{modular_canvas, ModularUiConfig};
|
||||||
use crate::state::AppState;
|
use crate::state::AppState;
|
||||||
@@ -23,7 +23,7 @@ where
|
|||||||
z_order: Z_ORDER_ANCHOR,
|
z_order: Z_ORDER_ANCHOR,
|
||||||
spawn_scale: config.width,
|
spawn_scale: config.width,
|
||||||
spawn_point: Vec3A::NEG_Z * 0.5,
|
spawn_point: Vec3A::NEG_Z * 0.5,
|
||||||
relative_to: RelativeTo::Stage,
|
positioning: Positioning::Static,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
backend: Box::new(modular_canvas(config.size, &config.elements, state)?),
|
backend: Box::new(modular_canvas(config.size, &config.elements, state)?),
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ use crate::{
|
|||||||
backend::{
|
backend::{
|
||||||
input::{InteractionHandler, PointerMode},
|
input::{InteractionHandler, PointerMode},
|
||||||
overlay::{
|
overlay::{
|
||||||
FrameMeta, OverlayBackend, OverlayData, OverlayRenderer, OverlayState, ShouldRender,
|
FrameMeta, OverlayBackend, OverlayData, OverlayRenderer, OverlayState, Positioning,
|
||||||
|
ShouldRender,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
config::{self, ConfigType},
|
config::{self, ConfigType},
|
||||||
@@ -222,7 +223,7 @@ where
|
|||||||
name: KEYBOARD_NAME.into(),
|
name: KEYBOARD_NAME.into(),
|
||||||
grabbable: true,
|
grabbable: true,
|
||||||
recenter: true,
|
recenter: true,
|
||||||
anchored: true,
|
positioning: Positioning::Anchored,
|
||||||
interactable: true,
|
interactable: true,
|
||||||
spawn_scale: width,
|
spawn_scale: width,
|
||||||
spawn_point: vec3a(0., -0.5, 0.),
|
spawn_point: vec3a(0., -0.5, 0.),
|
||||||
|
|||||||
@@ -50,7 +50,10 @@ use glam::{vec2, vec3a, Affine2, Affine3A, Quat, Vec2, Vec3};
|
|||||||
use crate::{
|
use crate::{
|
||||||
backend::{
|
backend::{
|
||||||
input::{Haptics, InteractionHandler, PointerHit, PointerMode},
|
input::{Haptics, InteractionHandler, PointerHit, PointerMode},
|
||||||
overlay::{FrameMeta, OverlayRenderer, OverlayState, ShouldRender, SplitOverlayBackend},
|
overlay::{
|
||||||
|
FrameMeta, OverlayRenderer, OverlayState, Positioning, ShouldRender,
|
||||||
|
SplitOverlayBackend,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
config::{def_pw_tokens, GeneralConfig, PwTokenMap},
|
config::{def_pw_tokens, GeneralConfig, PwTokenMap},
|
||||||
graphics::{fourcc_to_vk, CommandBuffers, WlxGraphics, WlxPipeline, WlxUploadsBuffer},
|
graphics::{fourcc_to_vk, CommandBuffers, WlxGraphics, WlxPipeline, WlxUploadsBuffer},
|
||||||
@@ -718,7 +721,7 @@ fn create_screen_state(
|
|||||||
keyboard_focus: Some(KeyboardFocus::PhysicalScreen),
|
keyboard_focus: Some(KeyboardFocus::PhysicalScreen),
|
||||||
grabbable: true,
|
grabbable: true,
|
||||||
recenter: true,
|
recenter: true,
|
||||||
anchored: true,
|
positioning: Positioning::Anchored,
|
||||||
interactable: true,
|
interactable: true,
|
||||||
spawn_scale: 1.5 * session.config.desktop_view_scale,
|
spawn_scale: 1.5 * session.config.desktop_view_scale,
|
||||||
spawn_point: vec3a(0., 0.5, 0.),
|
spawn_point: vec3a(0., 0.5, 0.),
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use crate::{
|
use crate::{
|
||||||
backend::{
|
backend::{
|
||||||
common::OverlaySelector,
|
common::OverlaySelector,
|
||||||
overlay::{OverlayBackend, OverlayState, RelativeTo, Z_ORDER_TOAST},
|
overlay::{OverlayBackend, OverlayState, Positioning, Z_ORDER_TOAST},
|
||||||
task::TaskType,
|
task::TaskType,
|
||||||
},
|
},
|
||||||
gui::{canvas::builder::CanvasBuilder, color_parse},
|
gui::{canvas::builder::CanvasBuilder, color_parse},
|
||||||
@@ -125,18 +125,22 @@ fn new_toast(toast: Toast, app: &mut AppState) -> Option<(OverlayState, Box<dyn
|
|||||||
.copied()
|
.copied()
|
||||||
.unwrap_or(DisplayMethod::Hide);
|
.unwrap_or(DisplayMethod::Hide);
|
||||||
|
|
||||||
let (spawn_point, spawn_rotation, relative_to) = match current_method {
|
let (spawn_point, spawn_rotation, positioning) = match current_method {
|
||||||
DisplayMethod::Hide => return None,
|
DisplayMethod::Hide => return None,
|
||||||
DisplayMethod::Center => (vec3a(0., -0.2, -0.5), Quat::IDENTITY, RelativeTo::Head),
|
DisplayMethod::Center => (
|
||||||
|
vec3a(0., -0.2, -0.5),
|
||||||
|
Quat::IDENTITY,
|
||||||
|
Positioning::FollowHead { lerp: 0.1 },
|
||||||
|
),
|
||||||
DisplayMethod::Watch => {
|
DisplayMethod::Watch => {
|
||||||
let mut watch_pos = app.session.config.watch_pos + vec3a(-0.005, -0.05, 0.02);
|
let mut watch_pos = app.session.config.watch_pos + vec3a(-0.005, -0.05, 0.02);
|
||||||
let mut watch_rot = app.session.config.watch_rot;
|
let mut watch_rot = app.session.config.watch_rot;
|
||||||
let relative_to = match app.session.config.watch_hand {
|
let relative_to = match app.session.config.watch_hand {
|
||||||
LeftRight::Left => RelativeTo::Hand(0),
|
LeftRight::Left => Positioning::FollowHand { hand: 0, lerp: 1.0 },
|
||||||
LeftRight::Right => {
|
LeftRight::Right => {
|
||||||
watch_pos.x = -watch_pos.x;
|
watch_pos.x = -watch_pos.x;
|
||||||
watch_rot = watch_rot * Quat::from_rotation_x(PI) * Quat::from_rotation_z(PI);
|
watch_rot = watch_rot * Quat::from_rotation_x(PI) * Quat::from_rotation_z(PI);
|
||||||
RelativeTo::Hand(1)
|
Positioning::FollowHand { hand: 1, lerp: 1.0 }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
(watch_pos, watch_rot, relative_to)
|
(watch_pos, watch_rot, relative_to)
|
||||||
@@ -202,7 +206,7 @@ fn new_toast(toast: Toast, app: &mut AppState) -> Option<(OverlayState, Box<dyn
|
|||||||
spawn_rotation,
|
spawn_rotation,
|
||||||
spawn_point,
|
spawn_point,
|
||||||
z_order: Z_ORDER_TOAST,
|
z_order: Z_ORDER_TOAST,
|
||||||
relative_to,
|
positioning,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let backend = Box::new(canvas.build());
|
let backend = Box::new(canvas.build());
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use glam::Vec3A;
|
use glam::Vec3A;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::overlay::{ui_transform, OverlayData, OverlayState, RelativeTo, Z_ORDER_WATCH},
|
backend::overlay::{ui_transform, OverlayData, OverlayState, Positioning, Z_ORDER_WATCH},
|
||||||
config::{load_known_yaml, ConfigType},
|
config::{load_known_yaml, ConfigType},
|
||||||
gui::{
|
gui::{
|
||||||
canvas::Canvas,
|
canvas::Canvas,
|
||||||
@@ -18,7 +18,10 @@ where
|
|||||||
{
|
{
|
||||||
let config = load_known_yaml::<ModularUiConfig>(ConfigType::Watch);
|
let config = load_known_yaml::<ModularUiConfig>(ConfigType::Watch);
|
||||||
|
|
||||||
let relative_to = RelativeTo::Hand(state.session.config.watch_hand as usize);
|
let positioning = Positioning::FollowHand {
|
||||||
|
hand: state.session.config.watch_hand as _,
|
||||||
|
lerp: 1.0,
|
||||||
|
};
|
||||||
|
|
||||||
Ok(OverlayData {
|
Ok(OverlayData {
|
||||||
state: OverlayState {
|
state: OverlayState {
|
||||||
@@ -30,7 +33,7 @@ where
|
|||||||
spawn_point: state.session.config.watch_pos,
|
spawn_point: state.session.config.watch_pos,
|
||||||
spawn_rotation: state.session.config.watch_rot,
|
spawn_rotation: state.session.config.watch_rot,
|
||||||
interaction_transform: ui_transform(config.size),
|
interaction_transform: ui_transform(config.size),
|
||||||
relative_to,
|
positioning,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
backend: Box::new(create_watch_canvas(Some(config), state)?),
|
backend: Box::new(create_watch_canvas(Some(config), state)?),
|
||||||
|
|||||||
@@ -402,7 +402,7 @@ where
|
|||||||
.insert(disp_handle, overlay.state.id);
|
.insert(disp_handle, overlay.state.id);
|
||||||
|
|
||||||
if let Some(attach_to) = &conf_display.attach_to {
|
if let Some(attach_to) = &conf_display.attach_to {
|
||||||
overlay.state.relative_to = attach_to.get_relative_to();
|
overlay.state.positioning = attach_to.get_positioning();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(rot) = &conf_display.rotation {
|
if let Some(rot) = &conf_display.rotation {
|
||||||
|
|||||||
Reference in New Issue
Block a user