diff --git a/dash-frontend/assets/dashboard/drag.svg b/dash-frontend/assets/dashboard/drag.svg
new file mode 100644
index 00000000..9710d6bd
--- /dev/null
+++ b/dash-frontend/assets/dashboard/drag.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/dash-frontend/assets/gui/tab/settings.xml b/dash-frontend/assets/gui/tab/settings.xml
index b6850851..8b7d33a8 100644
--- a/dash-frontend/assets/gui/tab/settings.xml
+++ b/dash-frontend/assets/gui/tab/settings.xml
@@ -13,13 +13,13 @@
-
-
+
+
-
-
+
+
@@ -56,6 +56,7 @@
+
diff --git a/dash-frontend/assets/lang/en.json b/dash-frontend/assets/lang/en.json
index 43085e09..e4f412d9 100644
--- a/dash-frontend/assets/lang/en.json
+++ b/dash-frontend/assets/lang/en.json
@@ -103,6 +103,7 @@
"SETS_ON_WATCH": "Sets on watch",
"SKYBOX": "Skybox",
"SKYMAP_ALREADY_DOWNLOADED": "This skymap is already downloaded. Select desired action.",
+ "SPACE_DRAG": "Space drag",
"SPACE_DRAG_FLING_STRENGTH": "Fling strength",
"SPACE_DRAG_DAMPING": "Damping",
"SPACE_DRAG_GRAVITY": "Gravity",
diff --git a/dash-frontend/src/tab/settings/mod.rs b/dash-frontend/src/tab/settings/mod.rs
index 4936ff23..b3725866 100644
--- a/dash-frontend/src/tab/settings/mod.rs
+++ b/dash-frontend/src/tab/settings/mod.rs
@@ -39,12 +39,14 @@ mod tab_features;
mod tab_look_and_feel;
mod tab_misc;
mod tab_skybox;
+mod tab_space_drag;
mod tab_troubleshooting;
#[derive(Clone)]
enum TabNameEnum {
LookAndFeel,
Features,
+ SpaceDrag,
Controls,
Misc,
AutostartApps,
@@ -58,6 +60,7 @@ impl TabNameEnum {
"look_and_feel" => Some(TabNameEnum::LookAndFeel),
"features" => Some(TabNameEnum::Features),
"controls" => Some(TabNameEnum::Controls),
+ "space_drag" => Some(TabNameEnum::SpaceDrag),
"misc" => Some(TabNameEnum::Misc),
"autostart_apps" => Some(TabNameEnum::AutostartApps),
"troubleshooting" => Some(TabNameEnum::Troubleshooting),
@@ -584,6 +587,9 @@ impl TabSettings {
TabNameEnum::Features => {
self.current_tab = Some(Box::new(tab_features::State::mount(settings_mount_params)?));
}
+ TabNameEnum::SpaceDrag => {
+ self.current_tab = Some(Box::new(tab_space_drag::State::mount(settings_mount_params)?));
+ }
TabNameEnum::Controls => {
self.current_tab = Some(Box::new(tab_controls::State::mount(settings_mount_params)?));
}
diff --git a/dash-frontend/src/tab/settings/tab_features.rs b/dash-frontend/src/tab/settings/tab_features.rs
index 042152e0..96d40fc3 100644
--- a/dash-frontend/src/tab/settings/tab_features.rs
+++ b/dash-frontend/src/tab/settings/tab_features.rs
@@ -1,6 +1,6 @@
use crate::tab::settings::{
SettingType, SettingsMountParams, SettingsTab,
- macros::{options_category, options_checkbox, options_range_f32, options_slider_f32},
+ macros::{options_category, options_checkbox, options_range_f32},
};
pub struct State {}
@@ -13,18 +13,6 @@ impl State {
options_checkbox(par.mp, c, SettingType::NotificationsEnabled)?;
options_checkbox(par.mp, c, SettingType::NotificationsSoundEnabled)?;
options_checkbox(par.mp, c, SettingType::KeyboardSoundEnabled)?;
- if !par.feats.openxr || par.feats.monado {
- // monado or openvr
- options_checkbox(par.mp, c, SettingType::SpaceDragUnlocked)?;
- options_slider_f32(par.mp, c, SettingType::SpaceDragMultiplier, -10.0, 10.0, 0.5)?;
- options_slider_f32(par.mp, c, SettingType::SpaceDragGravity, 0.0, 10.0, 0.5)?;
- options_slider_f32(par.mp, c, SettingType::SpaceDragDamping, 0.1, 1.0, 0.01)?;
- options_slider_f32(par.mp, c, SettingType::SpaceDragFlingStrength, 0.0, 3.0, 0.1)?;
- }
- if par.feats.monado {
- // openvr can only ever rotate yaw
- options_checkbox(par.mp, c, SettingType::SpaceRotateUnlocked)?;
- }
if !par.feats.openxr || par.feats.monado {
// monado or openvr
options_checkbox(par.mp, c, SettingType::BlockGameInput)?;
diff --git a/dash-frontend/src/tab/settings/tab_space_drag.rs b/dash-frontend/src/tab/settings/tab_space_drag.rs
new file mode 100644
index 00000000..b507e3dd
--- /dev/null
+++ b/dash-frontend/src/tab/settings/tab_space_drag.rs
@@ -0,0 +1,27 @@
+use crate::tab::settings::{
+ SettingType, SettingsMountParams, SettingsTab,
+ macros::{options_category, options_checkbox, options_slider_f32},
+};
+
+pub struct State {}
+
+impl SettingsTab for State {}
+
+impl State {
+ pub fn mount(par: SettingsMountParams) -> anyhow::Result {
+ let c = options_category(par.mp, par.id_parent, "APP_SETTINGS.SPACE_DRAG", "dashboard/drag.svg")?;
+ if !par.feats.openxr || par.feats.monado {
+ // monado or openvr
+ options_checkbox(par.mp, c, SettingType::SpaceDragUnlocked)?;
+ options_slider_f32(par.mp, c, SettingType::SpaceDragMultiplier, -10.0, 10.0, 0.5)?;
+ options_slider_f32(par.mp, c, SettingType::SpaceDragGravity, 0.0, 10.0, 0.5)?;
+ options_slider_f32(par.mp, c, SettingType::SpaceDragDamping, 0.1, 1.0, 0.01)?;
+ options_slider_f32(par.mp, c, SettingType::SpaceDragFlingStrength, 0.0, 3.0, 0.1)?;
+ }
+ if par.feats.monado {
+ // openvr can only ever rotate yaw
+ options_checkbox(par.mp, c, SettingType::SpaceRotateUnlocked)?;
+ }
+ Ok(State {})
+ }
+}
diff --git a/wayvr/src/backend/openvr/playspace.rs b/wayvr/src/backend/openvr/playspace.rs
index e73b1ef2..670dfd5d 100644
--- a/wayvr/src/backend/openvr/playspace.rs
+++ b/wayvr/src/backend/openvr/playspace.rs
@@ -6,7 +6,7 @@ use ovr_overlay::{
};
use crate::{
- backend::{input::InputState, task::PlayspaceTask},
+ backend::{input::InputState, playspace_common, task::PlayspaceTask},
state::AppState,
windowing::manager::OverlayWindowManager,
};
@@ -137,16 +137,7 @@ impl PlayspaceMover {
}
let overlay_offset = data.pose.inverse().transform_vector3a(relative_pos) * -1.0;
-
- overlays.values_mut().for_each(|overlay| {
- let Some(state) = overlay.config.active_state.as_mut() else {
- return;
- };
- if state.positioning.moves_with_space() {
- state.transform.translation += overlay_offset;
- overlay.config.dirty = true;
- }
- });
+ playspace_common::shift_overlays(overlays, overlay_offset);
data.pose.translation += relative_pos;
data.hand_pose = new_hand;
diff --git a/wayvr/src/backend/openxr/playspace.rs b/wayvr/src/backend/openxr/playspace.rs
index 3b75b214..ce3f5f1e 100644
--- a/wayvr/src/backend/openxr/playspace.rs
+++ b/wayvr/src/backend/openxr/playspace.rs
@@ -5,7 +5,7 @@ use wgui::log::LogErr;
use crate::{
backend::{
input::InputState,
- playspace_common::{SpaceGravity, SpaceGravityUpdateParams},
+ playspace_common::{self, SpaceGravity, SpaceGravityUpdateParams},
task::PlayspaceTask,
},
state::AppState,
@@ -174,16 +174,7 @@ impl PlayspaceMover {
}
let overlay_offset = data.pose.inverse().transform_vector3a(relative_pos) * -1.0;
-
- overlays.values_mut().for_each(|overlay| {
- let Some(state) = overlay.config.active_state.as_mut() else {
- return;
- };
- if state.positioning.moves_with_space() {
- state.transform.translation += overlay_offset;
- }
- overlay.config.dirty = true;
- });
+ playspace_common::shift_overlays(overlays, overlay_offset);
data.pose.translation += relative_pos;
data.hand_pose = new_hand;
@@ -220,15 +211,17 @@ impl PlayspaceMover {
}
}
- if let Some(playspace_pos) = self.gravity.update(SpaceGravityUpdateParams {
+ if let Some(res) = self.gravity.update(SpaceGravityUpdateParams {
dt: app.delta_time,
dragging: self.drag.is_some(),
config: &app.session.config,
}) {
apply_offset(
- Affine3A::from_translation(playspace_pos.into()),
+ Affine3A::from_translation(res.playspace_pos.into()),
&mut monado.ipc,
);
+
+ playspace_common::shift_overlays(overlays, -res.playspace_pos_offset);
}
}
diff --git a/wayvr/src/backend/playspace_common.rs b/wayvr/src/backend/playspace_common.rs
index 60b7d80e..18d134c0 100644
--- a/wayvr/src/backend/playspace_common.rs
+++ b/wayvr/src/backend/playspace_common.rs
@@ -1,6 +1,8 @@
use glam::Vec3A;
use wlx_common::config::GeneralConfig;
+use crate::windowing::manager::OverlayWindowManager;
+
pub struct SpaceGravityUpdateParams<'a> {
pub dt: f32,
pub dragging: bool,
@@ -12,6 +14,26 @@ pub struct SpaceGravity {
space_pos: Vec3A,
}
+pub fn shift_overlays(
+ overlays: &mut OverlayWindowManager,
+ overlay_offset: Vec3A,
+) {
+ overlays.values_mut().for_each(|overlay| {
+ let Some(state) = overlay.config.active_state.as_mut() else {
+ return;
+ };
+ if state.positioning.moves_with_space() {
+ state.transform.translation += overlay_offset;
+ }
+ overlay.config.dirty = true;
+ });
+}
+
+pub struct SpaceGravityUpdateResult {
+ pub playspace_pos: Vec3A,
+ pub playspace_pos_offset: Vec3A, // position difference compared to previous update() call
+}
+
impl SpaceGravity {
pub fn new() -> Self {
Self {
@@ -31,21 +53,29 @@ impl SpaceGravity {
self.space_pos = space_pos;
}
- pub fn update(&mut self, par: SpaceGravityUpdateParams) -> Option {
- if !par.dragging {
- self.velocity.y += par.config.space_drag_gravity * par.dt;
- // terminal velocity
- self.velocity.y = self.velocity.y.min(200.0);
+ pub fn update(&mut self, par: SpaceGravityUpdateParams) -> Option {
+ if par.dragging {
+ return None;
+ }
- self.velocity *= (par.config.space_drag_damping).powf(par.dt * 10.0);
- self.space_pos += self.velocity * par.dt;
+ let prev_pos = self.space_pos;
- self.space_pos.y = self.space_pos.y.min(0.0);
+ self.velocity.y += par.config.space_drag_gravity * par.dt;
- if self.velocity.length_squared() > 0.00003 {
- // log::info!("velocity {}", self.velocity);
- return Some(self.space_pos);
- }
+ // terminal velocity
+ self.velocity.y = self.velocity.y.min(200.0);
+
+ self.velocity *= (par.config.space_drag_damping).powf(par.dt * 10.0);
+ self.space_pos += self.velocity * par.dt;
+
+ self.space_pos.y = self.space_pos.y.min(0.0);
+
+ if self.velocity.length_squared() > 0.00003 {
+ // Space position changed
+ return Some(SpaceGravityUpdateResult {
+ playspace_pos: self.space_pos,
+ playspace_pos_offset: self.space_pos - prev_pos,
+ });
}
None
diff --git a/wgui/src/components/slider.rs b/wgui/src/components/slider.rs
index f51f5021..56a8ae9b 100644
--- a/wgui/src/components/slider.rs
+++ b/wgui/src/components/slider.rs
@@ -346,8 +346,8 @@ impl State {
}
}
-const BODY_COLOR: drawing::Color = drawing::Color::new(0.6, 0.65, 0.7, 0.2);
-const BODY_BORDER_COLOR: drawing::Color = drawing::Color::new(0.4, 0.45, 0.5, 1.0);
+const BODY_COLOR: drawing::Color = drawing::Color::new(0.6, 0.65, 0.7, 0.1);
+const BODY_BORDER_COLOR: drawing::Color = drawing::Color::new(0.4, 0.45, 0.5, 0.6);
const HANDLE_BORDER_COLOR: drawing::Color = drawing::Color::new(0.85, 0.85, 0.85, 1.0);
const HANDLE_BORDER_COLOR_HOVERED: drawing::Color = drawing::Color::new(0.0, 0.0, 0.0, 1.0);
const HANDLE_COLOR: drawing::Color = drawing::Color::new(1.0, 1.0, 1.0, 1.0);