persist sets between sessions
This commit is contained in:
@@ -28,6 +28,7 @@ use crate::{
|
|||||||
task::{SystemTask, TaskType},
|
task::{SystemTask, TaskType},
|
||||||
BackendError,
|
BackendError,
|
||||||
},
|
},
|
||||||
|
config::save_state,
|
||||||
graphics::{init_openvr_graphics, CommandBuffers},
|
graphics::{init_openvr_graphics, CommandBuffers},
|
||||||
overlays::{
|
overlays::{
|
||||||
toast::{Toast, ToastTopic},
|
toast::{Toast, ToastTopic},
|
||||||
@@ -368,8 +369,11 @@ pub fn openvr_run(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// chaperone
|
// chaperone
|
||||||
|
} // main_loop
|
||||||
|
|
||||||
// close font handles?
|
overlays.persist_layout(&mut app);
|
||||||
|
if let Err(e) = save_state(&app.session.config) {
|
||||||
|
log::error!("Could not save state: {e:?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
log::warn!("OpenVR shutdown");
|
log::warn!("OpenVR shutdown");
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ use crate::{
|
|||||||
task::{SystemTask, TaskType},
|
task::{SystemTask, TaskType},
|
||||||
BackendError,
|
BackendError,
|
||||||
},
|
},
|
||||||
|
config::save_state,
|
||||||
graphics::{init_openxr_graphics, CommandBuffers},
|
graphics::{init_openxr_graphics, CommandBuffers},
|
||||||
overlays::{
|
overlays::{
|
||||||
toast::{Toast, ToastTopic},
|
toast::{Toast, ToastTopic},
|
||||||
@@ -561,6 +562,11 @@ pub fn openxr_run(
|
|||||||
//FIXME: Temporary workaround for Monado bug
|
//FIXME: Temporary workaround for Monado bug
|
||||||
let watch = overlays.mut_by_id(watch_id).unwrap(); // want panic
|
let watch = overlays.mut_by_id(watch_id).unwrap(); // want panic
|
||||||
watch.config.active_state.as_mut().unwrap().transform = watch_transform;
|
watch.config.active_state.as_mut().unwrap().transform = watch_transform;
|
||||||
|
} // main_loop
|
||||||
|
|
||||||
|
overlays.persist_layout(&mut app);
|
||||||
|
if let Err(e) = save_state(&app.session.config) {
|
||||||
|
log::error!("Could not save state: {e:?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use std::sync::Arc;
|
|||||||
use crate::config_io;
|
use crate::config_io;
|
||||||
use crate::overlays::toast::{DisplayMethod, ToastTopic};
|
use crate::overlays::toast::{DisplayMethod, ToastTopic};
|
||||||
use crate::state::LeftRight;
|
use crate::state::LeftRight;
|
||||||
|
use crate::windowing::set::SerializedWindowSet;
|
||||||
use chrono::Offset;
|
use chrono::Offset;
|
||||||
use config::{Config, File};
|
use config::{Config, File};
|
||||||
use glam::{vec3, Affine3A, Quat, Vec3};
|
use glam::{vec3, Affine3A, Quat, Vec3};
|
||||||
@@ -126,6 +127,14 @@ const fn def_empty_vec_string() -> Vec<String> {
|
|||||||
Vec::new()
|
Vec::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fn def_sets() -> Vec<SerializedWindowSet> {
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn def_zero_u32() -> u32 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
fn def_timezones() -> Vec<String> {
|
fn def_timezones() -> Vec<String> {
|
||||||
const EMEA: i32 = -60 * 60; // UTC-1
|
const EMEA: i32 = -60 * 60; // UTC-1
|
||||||
const APAC: i32 = 5 * 60 * 60; // UTC+5
|
const APAC: i32 = 5 * 60 * 60; // UTC+5
|
||||||
@@ -309,6 +318,12 @@ pub struct GeneralConfig {
|
|||||||
|
|
||||||
#[serde(default = "def_false")]
|
#[serde(default = "def_false")]
|
||||||
pub clock_12h: bool,
|
pub clock_12h: bool,
|
||||||
|
|
||||||
|
#[serde(default = "def_sets")]
|
||||||
|
pub sets: Vec<SerializedWindowSet>,
|
||||||
|
|
||||||
|
#[serde(default = "def_zero_u32")]
|
||||||
|
pub last_set: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GeneralConfig {
|
impl GeneralConfig {
|
||||||
@@ -480,9 +495,8 @@ pub fn save_settings(config: &GeneralConfig) -> anyhow::Result<()> {
|
|||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct AutoState {
|
pub struct AutoState {
|
||||||
pub show_screens: AStrSet,
|
pub sets: Vec<SerializedWindowSet>,
|
||||||
pub curve_values: AStrMap<f32>,
|
pub last_set: u32,
|
||||||
pub transform_values: AStrMap<Affine3A>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_state_path() -> PathBuf {
|
fn get_state_path() -> PathBuf {
|
||||||
@@ -491,15 +505,15 @@ fn get_state_path() -> PathBuf {
|
|||||||
.join("zz-saved-state.json5")
|
.join("zz-saved-state.json5")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save_layout(config: &GeneralConfig) -> anyhow::Result<()> {
|
pub fn save_state(config: &GeneralConfig) -> anyhow::Result<()> {
|
||||||
let conf = AutoState {
|
let conf = AutoState {
|
||||||
show_screens: config.show_screens.clone(),
|
sets: config.sets.clone(),
|
||||||
curve_values: config.curve_values.clone(),
|
last_set: config.last_set.clone(),
|
||||||
transform_values: config.transform_values.clone(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let json = serde_json::to_string_pretty(&conf).unwrap(); // want panic
|
let json = serde_json::to_string_pretty(&conf).unwrap(); // want panic
|
||||||
std::fs::write(get_state_path(), json)?;
|
std::fs::write(get_state_path(), json)?;
|
||||||
|
|
||||||
|
log::info!("State was saved successfully.");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ use crate::{
|
|||||||
},
|
},
|
||||||
config::load_config_with_conf_d,
|
config::load_config_with_conf_d,
|
||||||
config_io,
|
config_io,
|
||||||
overlays::wayvr::{WayVRData, executable_exists_in_path},
|
overlays::wayvr::{executable_exists_in_path, WayVRData},
|
||||||
|
state::LeftRight,
|
||||||
windowing::window::Positioning,
|
windowing::window::Positioning,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -36,8 +37,14 @@ impl AttachTo {
|
|||||||
pub const fn get_positioning(&self) -> Positioning {
|
pub const fn get_positioning(&self) -> Positioning {
|
||||||
match self {
|
match self {
|
||||||
Self::None => Positioning::Floating,
|
Self::None => Positioning::Floating,
|
||||||
Self::HandLeft => Positioning::FollowHand { hand: 0, lerp: 1.0 },
|
Self::HandLeft => Positioning::FollowHand {
|
||||||
Self::HandRight => Positioning::FollowHand { hand: 1, lerp: 1.0 },
|
hand: LeftRight::Left,
|
||||||
|
lerp: 1.0,
|
||||||
|
},
|
||||||
|
Self::HandRight => Positioning::FollowHand {
|
||||||
|
hand: LeftRight::Right,
|
||||||
|
lerp: 1.0,
|
||||||
|
},
|
||||||
Self::Stage => Positioning::Static,
|
Self::Stage => Positioning::Static,
|
||||||
Self::Head => Positioning::FollowHead { lerp: 1.0 },
|
Self::Head => Positioning::FollowHead { lerp: 1.0 },
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,11 +147,17 @@ fn new_toast(toast: Toast, app: &mut AppState) -> Option<OverlayWindowConfig> {
|
|||||||
let mut watch_pos = app.session.config.watch_pos + vec3(-0.005, -0.05, 0.02);
|
let mut watch_pos = app.session.config.watch_pos + vec3(-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 => Positioning::FollowHand { hand: 0, lerp: 1.0 },
|
LeftRight::Left => Positioning::FollowHand {
|
||||||
|
hand: LeftRight::Left,
|
||||||
|
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);
|
||||||
Positioning::FollowHand { hand: 1, lerp: 1.0 }
|
Positioning::FollowHand {
|
||||||
|
hand: LeftRight::Right,
|
||||||
|
lerp: 1.0,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
(watch_pos, watch_rot, relative_to)
|
(watch_pos, watch_rot, relative_to)
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ pub fn create_watch(app: &mut AppState, num_sets: usize) -> anyhow::Result<Overl
|
|||||||
.push(GuiTimer::new(Duration::from_millis(100), 0));
|
.push(GuiTimer::new(Duration::from_millis(100), 0));
|
||||||
|
|
||||||
let positioning = Positioning::FollowHand {
|
let positioning = Positioning::FollowHand {
|
||||||
hand: app.session.config.watch_hand as _,
|
hand: app.session.config.watch_hand,
|
||||||
lerp: 1.0,
|
lerp: 1.0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use glam::Affine3A;
|
use glam::Affine3A;
|
||||||
use idmap::IdMap;
|
use idmap::IdMap;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use smallvec::{SmallVec, smallvec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use wgui::{
|
use wgui::{
|
||||||
font_config::WguiFontConfig, gfx::WGfx, globals::WguiGlobals,
|
font_config::WguiFontConfig, gfx::WGfx, globals::WguiGlobals,
|
||||||
@@ -189,7 +189,7 @@ pub struct ScreenMeta {
|
|||||||
pub native_handle: u32,
|
pub native_handle: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Copy, Default)]
|
#[derive(Debug, Serialize, Deserialize, Clone, Copy, Default)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum LeftRight {
|
pub enum LeftRight {
|
||||||
#[default]
|
#[default]
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use glam::{Affine3A, Vec3, Vec3A};
|
use glam::{Affine3A, Vec3, Vec3A};
|
||||||
use slotmap::{HopSlotMap, Key};
|
use slotmap::{HopSlotMap, Key, SecondaryMap};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
overlays::{
|
overlays::{
|
||||||
@@ -8,7 +10,10 @@ use crate::{
|
|||||||
},
|
},
|
||||||
state::AppState,
|
state::AppState,
|
||||||
windowing::{
|
windowing::{
|
||||||
set::OverlayWindowSet, snap_upright, window::OverlayWindowData, OverlayID, OverlaySelector,
|
set::{OverlayWindowSet, SerializedWindowSet},
|
||||||
|
snap_upright,
|
||||||
|
window::OverlayWindowData,
|
||||||
|
OverlayID, OverlaySelector,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -43,7 +48,9 @@ where
|
|||||||
if headless {
|
if headless {
|
||||||
log::info!("Running in headless mode; keyboard will be en-US");
|
log::info!("Running in headless mode; keyboard will be en-US");
|
||||||
} else {
|
} else {
|
||||||
// create one work set for each screen.
|
// create one window set for each screen.
|
||||||
|
// this is the default and would be overwritten by
|
||||||
|
// OverlayWindowManager::restore_layout down below
|
||||||
match create_screens(app) {
|
match create_screens(app) {
|
||||||
Ok((data, keymap)) => {
|
Ok((data, keymap)) => {
|
||||||
let last_idx = data.screens.len() - 1;
|
let last_idx = data.screens.len() - 1;
|
||||||
@@ -68,6 +75,7 @@ where
|
|||||||
keyboard.config.show_on_spawn = true;
|
keyboard.config.show_on_spawn = true;
|
||||||
let keyboard_id = me.add(keyboard, app);
|
let keyboard_id = me.add(keyboard, app);
|
||||||
|
|
||||||
|
// is this needed?
|
||||||
me.switch_to_set(app, None);
|
me.switch_to_set(app, None);
|
||||||
|
|
||||||
// copy keyboard to all sets
|
// copy keyboard to all sets
|
||||||
@@ -87,13 +95,79 @@ where
|
|||||||
let watch = OverlayWindowData::from_config(create_watch(app, me.sets.len())?);
|
let watch = OverlayWindowData::from_config(create_watch(app, me.sets.len())?);
|
||||||
me.watch_id = me.add(watch, app);
|
me.watch_id = me.add(watch, app);
|
||||||
|
|
||||||
me.switch_to_set(app, None);
|
// overwrite default layout with saved layout, if exists
|
||||||
|
me.restore_layout(app);
|
||||||
|
|
||||||
Ok(me)
|
Ok(me)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> OverlayWindowManager<T> {
|
impl<T> OverlayWindowManager<T> {
|
||||||
|
pub fn persist_layout(&mut self, app: &mut AppState) {
|
||||||
|
app.session.config.sets.clear();
|
||||||
|
app.session.config.sets.reserve(self.sets.len());
|
||||||
|
app.session.config.last_set = self.restore_set as _;
|
||||||
|
|
||||||
|
let mut restore_after = false;
|
||||||
|
// only safe to save when current_set is None
|
||||||
|
if self.current_set.is_some() {
|
||||||
|
self.switch_to_set(app, None);
|
||||||
|
restore_after = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for set in self.sets.iter() {
|
||||||
|
let overlays: HashMap<_, _> = set
|
||||||
|
.overlays
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(k, v)| {
|
||||||
|
let Some(n) = self.overlays.get(k).map(|o| o.config.name.clone()) else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
Some((n, v.clone()))
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let serialized = SerializedWindowSet {
|
||||||
|
name: set.name.clone(),
|
||||||
|
overlays,
|
||||||
|
};
|
||||||
|
app.session.config.sets.push(serialized);
|
||||||
|
}
|
||||||
|
|
||||||
|
if restore_after {
|
||||||
|
self.switch_to_set(app, Some(self.restore_set));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn restore_layout(&mut self, app: &mut AppState) {
|
||||||
|
if app.session.config.sets.is_empty() {
|
||||||
|
// keep defaults
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// only safe to load when current_set is None
|
||||||
|
if self.current_set.is_some() {
|
||||||
|
self.switch_to_set(app, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.sets.clear();
|
||||||
|
self.sets.reserve(app.session.config.sets.len());
|
||||||
|
|
||||||
|
for s in app.session.config.sets.iter() {
|
||||||
|
let overlays: SecondaryMap<_, _> = s
|
||||||
|
.overlays
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(name, v)| self.lookup(&name).map(|id| (id, v.clone())))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
self.sets.push(OverlayWindowSet {
|
||||||
|
name: s.name.clone(),
|
||||||
|
overlays,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
self.restore_set = (app.session.config.last_set as usize).min(self.sets.len() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn mut_by_selector(
|
pub fn mut_by_selector(
|
||||||
&mut self,
|
&mut self,
|
||||||
selector: &OverlaySelector,
|
selector: &OverlaySelector,
|
||||||
@@ -151,7 +225,6 @@ impl<T> OverlayWindowManager<T> {
|
|||||||
if overlay.config.show_on_spawn {
|
if overlay.config.show_on_spawn {
|
||||||
overlay.config.activate(app);
|
overlay.config.activate(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.overlays.insert(overlay)
|
self.overlays.insert(overlay)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,7 +261,7 @@ impl<T> OverlayWindowManager<T> {
|
|||||||
|
|
||||||
if let Some(new_set) = new_set {
|
if let Some(new_set) = new_set {
|
||||||
if new_set >= self.sets.len() {
|
if new_set >= self.sets.len() {
|
||||||
log::warn!("switch_to_set: new_set is out of range ({new_set:?})");
|
log::error!("switch_to_set: new_set is out of range ({new_set:?})");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
pub mod backend;
|
pub mod backend;
|
||||||
pub mod manager;
|
pub mod manager;
|
||||||
mod set;
|
pub mod set;
|
||||||
pub mod window;
|
pub mod window;
|
||||||
|
|
||||||
new_key_type! {
|
new_key_type! {
|
||||||
|
|||||||
@@ -1,8 +1,18 @@
|
|||||||
|
use std::{collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use slotmap::SecondaryMap;
|
use slotmap::SecondaryMap;
|
||||||
|
|
||||||
use crate::windowing::{window::OverlayWindowState, OverlayID};
|
use crate::windowing::{window::OverlayWindowState, OverlayID};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct OverlayWindowSet {
|
pub struct OverlayWindowSet {
|
||||||
|
pub(super) name: Arc<str>,
|
||||||
pub(super) overlays: SecondaryMap<OverlayID, OverlayWindowState>,
|
pub(super) overlays: SecondaryMap<OverlayID, OverlayWindowState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
|
pub struct SerializedWindowSet {
|
||||||
|
pub name: Arc<str>,
|
||||||
|
pub overlays: HashMap<Arc<str>, OverlayWindowState>,
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
use glam::{Affine3A, Mat3A, Quat, Vec3, Vec3A};
|
use glam::{Affine3A, Mat3A, Quat, Vec3, Vec3A};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{f32::consts::PI, sync::Arc};
|
use std::{f32::consts::PI, sync::Arc};
|
||||||
use vulkano::image::view::ImageView;
|
use vulkano::image::view::ImageView;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
graphics::CommandBuffers,
|
graphics::CommandBuffers,
|
||||||
state::AppState,
|
state::{AppState, LeftRight},
|
||||||
subsystem::input::KeyboardFocus,
|
subsystem::input::KeyboardFocus,
|
||||||
windowing::{
|
windowing::{
|
||||||
backend::{FrameMeta, OverlayBackend, ShouldRender},
|
backend::{FrameMeta, OverlayBackend, ShouldRender},
|
||||||
@@ -12,7 +13,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default)]
|
#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize)]
|
||||||
pub enum Positioning {
|
pub enum Positioning {
|
||||||
/// Stays in place, recenters relative to HMD
|
/// Stays in place, recenters relative to HMD
|
||||||
#[default]
|
#[default]
|
||||||
@@ -26,19 +27,14 @@ pub enum Positioning {
|
|||||||
/// Normally follows HMD, but paused due to interaction
|
/// Normally follows HMD, but paused due to interaction
|
||||||
FollowHeadPaused { lerp: f32 },
|
FollowHeadPaused { lerp: f32 },
|
||||||
/// Following hand
|
/// Following hand
|
||||||
FollowHand { hand: usize, lerp: f32 },
|
FollowHand { hand: LeftRight, lerp: f32 },
|
||||||
/// Normally follows hand, but paused due to interaction
|
/// Normally follows hand, but paused due to interaction
|
||||||
FollowHandPaused { hand: usize, lerp: f32 },
|
FollowHandPaused { hand: LeftRight, lerp: f32 },
|
||||||
/// Follow another overlay
|
|
||||||
FollowOverlay { id: usize },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Positioning {
|
impl Positioning {
|
||||||
pub const fn moves_with_space(&self) -> bool {
|
pub const fn moves_with_space(&self) -> bool {
|
||||||
matches!(
|
matches!(self, Self::Floating | Self::Anchored | Self::Static)
|
||||||
self,
|
|
||||||
Self::Floating | Self::Anchored | Self::Static
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,9 +150,10 @@ impl OverlayWindowConfig {
|
|||||||
|
|
||||||
let (target_transform, lerp) = match state.positioning {
|
let (target_transform, lerp) = match state.positioning {
|
||||||
Positioning::FollowHead { lerp } => (app.input_state.hmd * cur_transform, lerp),
|
Positioning::FollowHead { lerp } => (app.input_state.hmd * cur_transform, lerp),
|
||||||
Positioning::FollowHand { hand, lerp } => {
|
Positioning::FollowHand { hand, lerp } => (
|
||||||
(app.input_state.pointers[hand].pose * cur_transform, lerp)
|
app.input_state.pointers[hand as usize].pose * cur_transform,
|
||||||
}
|
lerp,
|
||||||
|
),
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -196,10 +193,10 @@ impl OverlayWindowConfig {
|
|||||||
app.input_state.hmd
|
app.input_state.hmd
|
||||||
}
|
}
|
||||||
Positioning::FollowHand { hand, .. } | Positioning::FollowHandPaused { hand, .. } => {
|
Positioning::FollowHand { hand, .. } | Positioning::FollowHandPaused { hand, .. } => {
|
||||||
app.input_state.pointers[hand].pose
|
app.input_state.pointers[hand as usize].pose
|
||||||
}
|
}
|
||||||
Positioning::Anchored => snap_upright(app.anchor, Vec3A::Y),
|
Positioning::Anchored => snap_upright(app.anchor, Vec3A::Y),
|
||||||
Positioning::FollowOverlay { .. } | Positioning::Static => return false,
|
Positioning::Static => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.saved_transform = Some(parent_transform.inverse() * state.transform);
|
self.saved_transform = Some(parent_transform.inverse() * state.transform);
|
||||||
@@ -219,10 +216,10 @@ impl OverlayWindowConfig {
|
|||||||
| Positioning::FollowHead { .. }
|
| Positioning::FollowHead { .. }
|
||||||
| Positioning::FollowHeadPaused { .. } => app.input_state.hmd,
|
| Positioning::FollowHeadPaused { .. } => app.input_state.hmd,
|
||||||
Positioning::FollowHand { hand, .. } | Positioning::FollowHandPaused { hand, .. } => {
|
Positioning::FollowHand { hand, .. } | Positioning::FollowHandPaused { hand, .. } => {
|
||||||
app.input_state.pointers[hand].pose
|
app.input_state.pointers[hand as usize].pose
|
||||||
}
|
}
|
||||||
Positioning::Anchored => app.anchor,
|
Positioning::Anchored => app.anchor,
|
||||||
Positioning::FollowOverlay { .. } | Positioning::Static => return,
|
Positioning::Static => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
if hard_reset {
|
if hard_reset {
|
||||||
@@ -284,7 +281,7 @@ impl OverlayWindowConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Contains the window state for a given set
|
// Contains the window state for a given set
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
pub struct OverlayWindowState {
|
pub struct OverlayWindowState {
|
||||||
pub transform: Affine3A,
|
pub transform: Affine3A,
|
||||||
pub alpha: f32,
|
pub alpha: f32,
|
||||||
|
|||||||
Reference in New Issue
Block a user