feat: anchor point for working set
This commit is contained in:
@@ -5,10 +5,11 @@ use std::{
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
#[cfg(feature = "openxr")]
|
||||
use openxr as xr;
|
||||
|
||||
use glam::{Affine3A, Vec2, Vec3A, Vec3Swizzles};
|
||||
use glam::{Affine3A, Vec2, Vec3, Vec3A, Vec3Swizzles};
|
||||
use idmap::IdMap;
|
||||
use serde::Deserialize;
|
||||
use thiserror::Error;
|
||||
@@ -16,6 +17,7 @@ use thiserror::Error;
|
||||
use crate::{
|
||||
config::{AStrMapExt, AStrSetExt},
|
||||
overlays::{
|
||||
anchor::create_anchor,
|
||||
keyboard::{create_keyboard, KEYBOARD_NAME},
|
||||
screen::WlxClientAlias,
|
||||
watch::{create_watch, WATCH_NAME},
|
||||
@@ -102,6 +104,9 @@ where
|
||||
app.screens.push(meta);
|
||||
}
|
||||
|
||||
let anchor = create_anchor(app)?;
|
||||
overlays.insert(anchor.state.id, anchor);
|
||||
|
||||
let mut watch = create_watch::<T>(app)?;
|
||||
watch.state.want_visible = true;
|
||||
overlays.insert(watch.state.id, watch);
|
||||
@@ -314,6 +319,13 @@ where
|
||||
.values()
|
||||
.any(|o| o.state.show_hide && o.state.want_visible);
|
||||
|
||||
if !any_shown {
|
||||
static ANCHOR_LOCAL: Lazy<Affine3A> =
|
||||
Lazy::new(|| Affine3A::from_translation(Vec3::NEG_Z));
|
||||
let hmd = snap_upright(app.input_state.hmd, Vec3A::Y);
|
||||
app.anchor = hmd * *ANCHOR_LOCAL;
|
||||
}
|
||||
|
||||
self.overlays.values_mut().for_each(|o| {
|
||||
if o.state.show_hide {
|
||||
o.state.want_visible = !any_shown;
|
||||
@@ -332,7 +344,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize)]
|
||||
#[derive(Clone, Deserialize, Debug)]
|
||||
#[serde(untagged)]
|
||||
pub enum OverlaySelector {
|
||||
Id(usize),
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
use std::{collections::VecDeque, time::Instant};
|
||||
|
||||
use glam::{Affine3A, Vec2, Vec3A};
|
||||
use glam::{Affine3A, Vec2, Vec3, Vec3A};
|
||||
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
|
||||
use crate::backend::common::snap_upright;
|
||||
use crate::backend::common::{snap_upright, OverlaySelector, TaskType};
|
||||
use crate::config::{save_state, AStrMapExt, GeneralConfig};
|
||||
use crate::overlays::anchor::ANCHOR_NAME;
|
||||
use crate::state::AppState;
|
||||
|
||||
use super::common::TaskContainer;
|
||||
use super::{
|
||||
common::{raycast_cylinder, raycast_plane, OverlayContainer},
|
||||
overlay::OverlayData,
|
||||
@@ -244,6 +246,7 @@ pub struct GrabData {
|
||||
pub offset: Vec3A,
|
||||
pub grabbed_id: usize,
|
||||
pub old_curvature: Option<f32>,
|
||||
pub grab_all: bool,
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
@@ -286,7 +289,13 @@ where
|
||||
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,
|
||||
&app.anchor,
|
||||
&mut app.tasks,
|
||||
&mut app.session.config,
|
||||
);
|
||||
} else {
|
||||
log::warn!("Grabbed overlay {} does not exist", grab_data.grabbed_id);
|
||||
pointer.interaction.grabbed = None;
|
||||
@@ -348,7 +357,7 @@ where
|
||||
log::trace!("Hit: {} {:?}", hovered.state.name, hit);
|
||||
|
||||
if pointer.now.grab && !pointer.before.grab && hovered.state.grabbable {
|
||||
pointer.start_grab(hovered);
|
||||
pointer.start_grab(hovered, &mut app.tasks);
|
||||
return (
|
||||
hit.dist,
|
||||
Some(Haptics {
|
||||
@@ -455,7 +464,7 @@ impl Pointer {
|
||||
None
|
||||
}
|
||||
|
||||
fn start_grab<O>(&mut self, overlay: &mut OverlayData<O>)
|
||||
fn start_grab<O>(&mut self, overlay: &mut OverlayData<O>, tasks: &mut TaskContainer)
|
||||
where
|
||||
O: Default,
|
||||
{
|
||||
@@ -468,7 +477,21 @@ impl Pointer {
|
||||
offset,
|
||||
grabbed_id: overlay.state.id,
|
||||
old_curvature: overlay.state.curvature,
|
||||
grab_all: matches!(self.interaction.mode, PointerMode::Right),
|
||||
});
|
||||
tasks.enqueue(TaskType::Overlay(
|
||||
OverlaySelector::Name(ANCHOR_NAME.clone()),
|
||||
Box::new(|app, o| {
|
||||
o.transform = app.anchor
|
||||
* Affine3A::from_scale_rotation_translation(
|
||||
Vec3::ONE * o.spawn_scale,
|
||||
o.spawn_rotation,
|
||||
o.spawn_point.into(),
|
||||
);
|
||||
o.dirty = true;
|
||||
o.want_visible = true;
|
||||
}),
|
||||
));
|
||||
log::info!("Hand {}: grabbed {}", self.idx, overlay.state.name);
|
||||
}
|
||||
|
||||
@@ -476,6 +499,8 @@ impl Pointer {
|
||||
&mut self,
|
||||
overlay: &mut OverlayData<O>,
|
||||
hmd: &Affine3A,
|
||||
anchor: &Affine3A,
|
||||
tasks: &mut TaskContainer,
|
||||
config: &mut GeneralConfig,
|
||||
) where
|
||||
O: Default,
|
||||
@@ -509,7 +534,7 @@ impl Pointer {
|
||||
}
|
||||
} else {
|
||||
overlay.state.saved_transform =
|
||||
Some(snap_upright(*hmd, Vec3A::Y).inverse() * overlay.state.transform);
|
||||
Some(snap_upright(*anchor, Vec3A::Y).inverse() * overlay.state.transform);
|
||||
|
||||
if let Some(grab_data) = self.interaction.grabbed.as_ref() {
|
||||
let mut state_dirty = false;
|
||||
@@ -531,6 +556,12 @@ impl Pointer {
|
||||
}
|
||||
|
||||
self.interaction.grabbed = None;
|
||||
tasks.enqueue(TaskType::Overlay(
|
||||
OverlaySelector::Name(ANCHOR_NAME.clone()),
|
||||
Box::new(|_app, o| {
|
||||
o.want_visible = false;
|
||||
}),
|
||||
));
|
||||
log::info!("Hand {}: dropped {}", self.idx, overlay.state.name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,6 +213,8 @@ pub fn openvr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
|
||||
TaskType::Overlay(sel, f) => {
|
||||
if let Some(o) = overlays.mut_by_selector(&sel) {
|
||||
f(&mut state, &mut o.state);
|
||||
} else {
|
||||
log::warn!("Overlay not found for task: {:?}", sel);
|
||||
}
|
||||
}
|
||||
TaskType::CreateOverlay(sel, f) => {
|
||||
|
||||
@@ -11,7 +11,7 @@ use vulkano::{Handle, VulkanObject};
|
||||
use crate::{
|
||||
backend::overlay::{OverlayData, RelativeTo},
|
||||
graphics::WlxGraphics,
|
||||
overlays::watch::WATCH_NAME,
|
||||
overlays::{anchor::ANCHOR_NAME, watch::WATCH_NAME},
|
||||
state::AppState,
|
||||
};
|
||||
|
||||
@@ -50,6 +50,10 @@ impl OverlayData<OpenVrOverlayData> {
|
||||
self.data.sort_order = 68;
|
||||
}
|
||||
|
||||
if *self.state.name == *ANCHOR_NAME.as_ref() {
|
||||
self.data.sort_order = 67;
|
||||
}
|
||||
|
||||
self.data.handle = Some(handle);
|
||||
self.data.color = Vec4::ONE;
|
||||
|
||||
@@ -260,7 +264,7 @@ impl OverlayData<OpenVrOverlayData> {
|
||||
m_pQueue: graphics.queue.handle().as_raw() as *mut _,
|
||||
m_nQueueFamilyIndex: graphics.queue.queue_family_index(),
|
||||
};
|
||||
log::debug!(
|
||||
log::trace!(
|
||||
"{}: UploadTex {:?}, {}x{}, {:?}",
|
||||
self.state.name,
|
||||
format,
|
||||
|
||||
@@ -334,6 +334,8 @@ pub fn openxr_run(running: Arc<AtomicBool>) -> Result<(), BackendError> {
|
||||
TaskType::Overlay(sel, f) => {
|
||||
if let Some(o) = overlays.mut_by_selector(&sel) {
|
||||
f(&mut app_state, &mut o.state);
|
||||
} else {
|
||||
log::warn!("Overlay not found for task: {:?}", sel);
|
||||
}
|
||||
}
|
||||
TaskType::CreateOverlay(sel, f) => {
|
||||
|
||||
@@ -12,10 +12,7 @@ use vulkano::image::view::ImageView;
|
||||
|
||||
use crate::state::AppState;
|
||||
|
||||
use super::{
|
||||
common::snap_upright,
|
||||
input::{DummyInteractionHandler, Haptics, InteractionHandler, PointerHit},
|
||||
};
|
||||
use super::input::{DummyInteractionHandler, Haptics, InteractionHandler, PointerHit};
|
||||
|
||||
static AUTO_INCREMENT: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
@@ -127,15 +124,10 @@ impl OverlayState {
|
||||
self.saved_transform = None;
|
||||
}
|
||||
|
||||
let hmd = snap_upright(app.input_state.hmd, Vec3A::Y);
|
||||
self.transform = hmd * self.get_transform();
|
||||
self.transform = app.anchor * self.get_transform();
|
||||
|
||||
if self.grabbable {
|
||||
if hard_reset {
|
||||
self.realign(&app.input_state.hmd);
|
||||
} else {
|
||||
//self.transform = snap_upright(self.transform, app.input_state.hmd.y_axis);
|
||||
}
|
||||
if self.grabbable && hard_reset {
|
||||
self.realign(&app.input_state.hmd);
|
||||
}
|
||||
self.dirty = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user