mirror of https://github.com/wayvr-org/wayvr.git
dash-frontend: dedicated "Space drag" settings tab, deduplicate overlay shift code in xr&vr, account for gravity shift for static overlays
This commit is contained in:
parent
c7037f8941
commit
2f6131f8d0
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><!-- Icon from Material Symbols by Google - https://github.com/google/material-design-icons/blob/master/LICENSE --><path fill="currentColor" d="m12 22l-4.25-4.25l1.425-1.425L11 18.15V13H5.875L7.7 14.8l-1.45 1.45L2 12l4.225-4.225L7.65 9.2L5.85 11H11V5.85L9.175 7.675L7.75 6.25L12 2l4.25 4.25l-1.425 1.425L13 5.85V11h5.125L16.3 9.2l1.45-1.45L22 12l-4.25 4.25l-1.425-1.425L18.15 13H13v5.125l1.8-1.825l1.45 1.45z"/></svg>
|
||||||
|
After Width: | Height: | Size: 500 B |
|
|
@ -13,13 +13,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template name="SliderSetting">
|
<template name="SliderSetting">
|
||||||
<label text="${text}" translation="${translation}" />
|
<Slider id="${id}" width="200" height="24" min_value="${min}" max_value="${max}" step="${step}" value="${value}" tooltip="${tooltip}" />
|
||||||
<Slider id="${id}" width="250" height="24" min_value="${min}" max_value="${max}" step="${step}" value="${value}" tooltip="${tooltip}" />
|
<label text="${text}" weight="bold" translation="${translation}" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template name="RangeSetting">
|
<template name="RangeSetting">
|
||||||
<label text="${text}" translation="${translation}" />
|
<Slider id="${id}" width="200" height="24" min_value="${min}" max_value="${max}" step="${step}" value="${value}" value2="${value2}" tooltip="${tooltip}" />
|
||||||
<Slider id="${id}" width="250" height="24" min_value="${min}" max_value="${max}" step="${step}" value="${value}" value2="${value2}" tooltip="${tooltip}" />
|
<label text="${text}" weight="bold" translation="${translation}" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template name="SelectSetting">
|
<template name="SelectSetting">
|
||||||
|
|
@ -56,6 +56,7 @@
|
||||||
<Tab name="skybox" translation="APP_SETTINGS.SKYBOX" sprite_src_builtin="dashboard/globe.svg" />
|
<Tab name="skybox" translation="APP_SETTINGS.SKYBOX" sprite_src_builtin="dashboard/globe.svg" />
|
||||||
<Tab name="features" translation="APP_SETTINGS.FEATURES" sprite_src_builtin="dashboard/options.svg" />
|
<Tab name="features" translation="APP_SETTINGS.FEATURES" sprite_src_builtin="dashboard/options.svg" />
|
||||||
<Tab name="controls" translation="APP_SETTINGS.CONTROLS" sprite_src_builtin="dashboard/controller.svg" />
|
<Tab name="controls" translation="APP_SETTINGS.CONTROLS" sprite_src_builtin="dashboard/controller.svg" />
|
||||||
|
<Tab name="space_drag" translation="APP_SETTINGS.SPACE_DRAG" sprite_src_builtin="dashboard/drag.svg" />
|
||||||
<Tab name="misc" translation="APP_SETTINGS.MISC" sprite_src_builtin="dashboard/blocks.svg" />
|
<Tab name="misc" translation="APP_SETTINGS.MISC" sprite_src_builtin="dashboard/blocks.svg" />
|
||||||
<Tab name="autostart_apps" translation="APP_SETTINGS.AUTOSTART_APPS" sprite_src_builtin="dashboard/apps.svg" />
|
<Tab name="autostart_apps" translation="APP_SETTINGS.AUTOSTART_APPS" sprite_src_builtin="dashboard/apps.svg" />
|
||||||
<Tab name="troubleshooting" translation="APP_SETTINGS.TROUBLESHOOTING" sprite_src_builtin="dashboard/cpu.svg" />
|
<Tab name="troubleshooting" translation="APP_SETTINGS.TROUBLESHOOTING" sprite_src_builtin="dashboard/cpu.svg" />
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,7 @@
|
||||||
"SETS_ON_WATCH": "Sets on watch",
|
"SETS_ON_WATCH": "Sets on watch",
|
||||||
"SKYBOX": "Skybox",
|
"SKYBOX": "Skybox",
|
||||||
"SKYMAP_ALREADY_DOWNLOADED": "This skymap is already downloaded. Select desired action.",
|
"SKYMAP_ALREADY_DOWNLOADED": "This skymap is already downloaded. Select desired action.",
|
||||||
|
"SPACE_DRAG": "Space drag",
|
||||||
"SPACE_DRAG_FLING_STRENGTH": "Fling strength",
|
"SPACE_DRAG_FLING_STRENGTH": "Fling strength",
|
||||||
"SPACE_DRAG_DAMPING": "Damping",
|
"SPACE_DRAG_DAMPING": "Damping",
|
||||||
"SPACE_DRAG_GRAVITY": "Gravity",
|
"SPACE_DRAG_GRAVITY": "Gravity",
|
||||||
|
|
|
||||||
|
|
@ -39,12 +39,14 @@ mod tab_features;
|
||||||
mod tab_look_and_feel;
|
mod tab_look_and_feel;
|
||||||
mod tab_misc;
|
mod tab_misc;
|
||||||
mod tab_skybox;
|
mod tab_skybox;
|
||||||
|
mod tab_space_drag;
|
||||||
mod tab_troubleshooting;
|
mod tab_troubleshooting;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
enum TabNameEnum {
|
enum TabNameEnum {
|
||||||
LookAndFeel,
|
LookAndFeel,
|
||||||
Features,
|
Features,
|
||||||
|
SpaceDrag,
|
||||||
Controls,
|
Controls,
|
||||||
Misc,
|
Misc,
|
||||||
AutostartApps,
|
AutostartApps,
|
||||||
|
|
@ -58,6 +60,7 @@ impl TabNameEnum {
|
||||||
"look_and_feel" => Some(TabNameEnum::LookAndFeel),
|
"look_and_feel" => Some(TabNameEnum::LookAndFeel),
|
||||||
"features" => Some(TabNameEnum::Features),
|
"features" => Some(TabNameEnum::Features),
|
||||||
"controls" => Some(TabNameEnum::Controls),
|
"controls" => Some(TabNameEnum::Controls),
|
||||||
|
"space_drag" => Some(TabNameEnum::SpaceDrag),
|
||||||
"misc" => Some(TabNameEnum::Misc),
|
"misc" => Some(TabNameEnum::Misc),
|
||||||
"autostart_apps" => Some(TabNameEnum::AutostartApps),
|
"autostart_apps" => Some(TabNameEnum::AutostartApps),
|
||||||
"troubleshooting" => Some(TabNameEnum::Troubleshooting),
|
"troubleshooting" => Some(TabNameEnum::Troubleshooting),
|
||||||
|
|
@ -584,6 +587,9 @@ impl<T> TabSettings<T> {
|
||||||
TabNameEnum::Features => {
|
TabNameEnum::Features => {
|
||||||
self.current_tab = Some(Box::new(tab_features::State::mount(settings_mount_params)?));
|
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 => {
|
TabNameEnum::Controls => {
|
||||||
self.current_tab = Some(Box::new(tab_controls::State::mount(settings_mount_params)?));
|
self.current_tab = Some(Box::new(tab_controls::State::mount(settings_mount_params)?));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::tab::settings::{
|
use crate::tab::settings::{
|
||||||
SettingType, SettingsMountParams, SettingsTab,
|
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 {}
|
pub struct State {}
|
||||||
|
|
@ -13,18 +13,6 @@ impl State {
|
||||||
options_checkbox(par.mp, c, SettingType::NotificationsEnabled)?;
|
options_checkbox(par.mp, c, SettingType::NotificationsEnabled)?;
|
||||||
options_checkbox(par.mp, c, SettingType::NotificationsSoundEnabled)?;
|
options_checkbox(par.mp, c, SettingType::NotificationsSoundEnabled)?;
|
||||||
options_checkbox(par.mp, c, SettingType::KeyboardSoundEnabled)?;
|
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 {
|
if !par.feats.openxr || par.feats.monado {
|
||||||
// monado or openvr
|
// monado or openvr
|
||||||
options_checkbox(par.mp, c, SettingType::BlockGameInput)?;
|
options_checkbox(par.mp, c, SettingType::BlockGameInput)?;
|
||||||
|
|
|
||||||
|
|
@ -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<State> {
|
||||||
|
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 {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,7 +6,7 @@ use ovr_overlay::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::{input::InputState, task::PlayspaceTask},
|
backend::{input::InputState, playspace_common, task::PlayspaceTask},
|
||||||
state::AppState,
|
state::AppState,
|
||||||
windowing::manager::OverlayWindowManager,
|
windowing::manager::OverlayWindowManager,
|
||||||
};
|
};
|
||||||
|
|
@ -137,16 +137,7 @@ impl PlayspaceMover {
|
||||||
}
|
}
|
||||||
|
|
||||||
let overlay_offset = data.pose.inverse().transform_vector3a(relative_pos) * -1.0;
|
let overlay_offset = data.pose.inverse().transform_vector3a(relative_pos) * -1.0;
|
||||||
|
playspace_common::shift_overlays(overlays, overlay_offset);
|
||||||
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;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
data.pose.translation += relative_pos;
|
data.pose.translation += relative_pos;
|
||||||
data.hand_pose = new_hand;
|
data.hand_pose = new_hand;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use wgui::log::LogErr;
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::{
|
backend::{
|
||||||
input::InputState,
|
input::InputState,
|
||||||
playspace_common::{SpaceGravity, SpaceGravityUpdateParams},
|
playspace_common::{self, SpaceGravity, SpaceGravityUpdateParams},
|
||||||
task::PlayspaceTask,
|
task::PlayspaceTask,
|
||||||
},
|
},
|
||||||
state::AppState,
|
state::AppState,
|
||||||
|
|
@ -174,16 +174,7 @@ impl PlayspaceMover {
|
||||||
}
|
}
|
||||||
|
|
||||||
let overlay_offset = data.pose.inverse().transform_vector3a(relative_pos) * -1.0;
|
let overlay_offset = data.pose.inverse().transform_vector3a(relative_pos) * -1.0;
|
||||||
|
playspace_common::shift_overlays(overlays, overlay_offset);
|
||||||
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;
|
|
||||||
});
|
|
||||||
|
|
||||||
data.pose.translation += relative_pos;
|
data.pose.translation += relative_pos;
|
||||||
data.hand_pose = new_hand;
|
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,
|
dt: app.delta_time,
|
||||||
dragging: self.drag.is_some(),
|
dragging: self.drag.is_some(),
|
||||||
config: &app.session.config,
|
config: &app.session.config,
|
||||||
}) {
|
}) {
|
||||||
apply_offset(
|
apply_offset(
|
||||||
Affine3A::from_translation(playspace_pos.into()),
|
Affine3A::from_translation(res.playspace_pos.into()),
|
||||||
&mut monado.ipc,
|
&mut monado.ipc,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
playspace_common::shift_overlays(overlays, -res.playspace_pos_offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
use glam::Vec3A;
|
use glam::Vec3A;
|
||||||
use wlx_common::config::GeneralConfig;
|
use wlx_common::config::GeneralConfig;
|
||||||
|
|
||||||
|
use crate::windowing::manager::OverlayWindowManager;
|
||||||
|
|
||||||
pub struct SpaceGravityUpdateParams<'a> {
|
pub struct SpaceGravityUpdateParams<'a> {
|
||||||
pub dt: f32,
|
pub dt: f32,
|
||||||
pub dragging: bool,
|
pub dragging: bool,
|
||||||
|
|
@ -12,6 +14,26 @@ pub struct SpaceGravity {
|
||||||
space_pos: Vec3A,
|
space_pos: Vec3A,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn shift_overlays<OverlayData>(
|
||||||
|
overlays: &mut OverlayWindowManager<OverlayData>,
|
||||||
|
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 {
|
impl SpaceGravity {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -31,21 +53,29 @@ impl SpaceGravity {
|
||||||
self.space_pos = space_pos;
|
self.space_pos = space_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, par: SpaceGravityUpdateParams) -> Option<Vec3A> {
|
pub fn update(&mut self, par: SpaceGravityUpdateParams) -> Option<SpaceGravityUpdateResult> {
|
||||||
if !par.dragging {
|
if par.dragging {
|
||||||
self.velocity.y += par.config.space_drag_gravity * par.dt;
|
return None;
|
||||||
// terminal velocity
|
}
|
||||||
self.velocity.y = self.velocity.y.min(200.0);
|
|
||||||
|
|
||||||
self.velocity *= (par.config.space_drag_damping).powf(par.dt * 10.0);
|
let prev_pos = self.space_pos;
|
||||||
self.space_pos += self.velocity * par.dt;
|
|
||||||
|
|
||||||
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 {
|
// terminal velocity
|
||||||
// log::info!("velocity {}", self.velocity);
|
self.velocity.y = self.velocity.y.min(200.0);
|
||||||
return Some(self.space_pos);
|
|
||||||
}
|
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
|
None
|
||||||
|
|
|
||||||
|
|
@ -346,8 +346,8 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const BODY_COLOR: drawing::Color = drawing::Color::new(0.6, 0.65, 0.7, 0.2);
|
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, 1.0);
|
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: 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_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);
|
const HANDLE_COLOR: drawing::Color = drawing::Color::new(1.0, 1.0, 1.0, 1.0);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue