mirror of https://github.com/wayvr-org/wayvr.git
feat: window snap angles
This commit is contained in:
parent
779baaf86c
commit
30d786eaa1
|
|
@ -192,7 +192,9 @@
|
||||||
"APPLY_CHANGES_RESTART": "WayVR neu starten, um die Änderungen zu übernehmen?",
|
"APPLY_CHANGES_RESTART": "WayVR neu starten, um die Änderungen zu übernehmen?",
|
||||||
"COLOR_PALETTE_HELP": "Klicken, um Farbpaletten zu durchsuchen.\nUm eigene zu erstellen, besuche die Webseite!",
|
"COLOR_PALETTE_HELP": "Klicken, um Farbpaletten zu durchsuchen.\nUm eigene zu erstellen, besuche die Webseite!",
|
||||||
"COLOR_PALETTE_CUSTOM_URL": "Füge dein eigenes benutzerdefiniertes Thema hinzu!",
|
"COLOR_PALETTE_CUSTOM_URL": "Füge dein eigenes benutzerdefiniertes Thema hinzu!",
|
||||||
"COLOR_PALETTE_CUSTOM_URL2": "Klicken Sie hier, um das Web-Handbuch zu öffnen."
|
"COLOR_PALETTE_CUSTOM_URL2": "Klicken Sie hier, um das Web-Handbuch zu öffnen.",
|
||||||
|
"SNAP_ANGLE_DEG": "Snap-Winkel für Fensterneigung und Rollwinkel",
|
||||||
|
"SNAP_ANGLE_DEG_HELP": "Gegriffene Fenster rasten in diesem Winkel auf der Nick- und Rollachse ein."
|
||||||
},
|
},
|
||||||
"HELLO": "Hallo!",
|
"HELLO": "Hallo!",
|
||||||
"AUDIO": {
|
"AUDIO": {
|
||||||
|
|
|
||||||
|
|
@ -174,6 +174,8 @@
|
||||||
"SCREEN_RENDER_DOWN_HELP": "Helps with aliasing on high-res screens",
|
"SCREEN_RENDER_DOWN_HELP": "Helps with aliasing on high-res screens",
|
||||||
"SCROLL_SPEED": "Scroll speed",
|
"SCROLL_SPEED": "Scroll speed",
|
||||||
"SELECT_VARIANT": "Select variant",
|
"SELECT_VARIANT": "Select variant",
|
||||||
|
"SNAP_ANGLE_DEG": "Window pitch & roll snap angle",
|
||||||
|
"SNAP_ANGLE_DEG_HELP": "Grabbed windows snap to this angle on pitch and roll axis.",
|
||||||
"ENABLE_WATCH": "Enable watch",
|
"ENABLE_WATCH": "Enable watch",
|
||||||
"SETS_ON_WATCH": "Sets on watch",
|
"SETS_ON_WATCH": "Sets on watch",
|
||||||
"SHOW_WELCOME_SCREEN": "Show welcome screen",
|
"SHOW_WELCOME_SCREEN": "Show welcome screen",
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,9 @@
|
||||||
"APPLY_CHANGES_RESTART": "¿Reiniciar WayVR para aplicar los cambios?",
|
"APPLY_CHANGES_RESTART": "¿Reiniciar WayVR para aplicar los cambios?",
|
||||||
"COLOR_PALETTE_HELP": "Haz clic para explorar paletas de colores.\nPara crear paletas personalizadas, ¡visita el sitio web!",
|
"COLOR_PALETTE_HELP": "Haz clic para explorar paletas de colores.\nPara crear paletas personalizadas, ¡visita el sitio web!",
|
||||||
"COLOR_PALETTE_CUSTOM_URL": "¡Añade tu propio tema personalizado!",
|
"COLOR_PALETTE_CUSTOM_URL": "¡Añade tu propio tema personalizado!",
|
||||||
"COLOR_PALETTE_CUSTOM_URL2": "Haz clic para abrir el manual web."
|
"COLOR_PALETTE_CUSTOM_URL2": "Haz clic para abrir el manual web.",
|
||||||
|
"SNAP_ANGLE_DEG": "Ángulo de ajuste de cabeceo y alabeo de la ventana",
|
||||||
|
"SNAP_ANGLE_DEG_HELP": "Las ventanas agarradas se ajustan a este ángulo en los ejes de cabeceo y balanceo."
|
||||||
},
|
},
|
||||||
"HELLO": "¡Hola!",
|
"HELLO": "¡Hola!",
|
||||||
"AUDIO": {
|
"AUDIO": {
|
||||||
|
|
|
||||||
|
|
@ -213,7 +213,9 @@
|
||||||
"APPLY_CHANGES_RESTART": "Riavviare WayVR per applicare le modifiche?",
|
"APPLY_CHANGES_RESTART": "Riavviare WayVR per applicare le modifiche?",
|
||||||
"COLOR_PALETTE_HELP": "Clicca per sfogliare le palette di colori.\nPer crearne di personalizzate, visita il sito web!",
|
"COLOR_PALETTE_HELP": "Clicca per sfogliare le palette di colori.\nPer crearne di personalizzate, visita il sito web!",
|
||||||
"COLOR_PALETTE_CUSTOM_URL": "Aggiungi il tuo tema personalizzato!",
|
"COLOR_PALETTE_CUSTOM_URL": "Aggiungi il tuo tema personalizzato!",
|
||||||
"COLOR_PALETTE_CUSTOM_URL2": "Clicca per aprire il manuale web."
|
"COLOR_PALETTE_CUSTOM_URL2": "Clicca per aprire il manuale web.",
|
||||||
|
"SNAP_ANGLE_DEG": "Angolo di scatto beccheggio e rollio finestra",
|
||||||
|
"SNAP_ANGLE_DEG_HELP": "Le finestre afferrate si allineano a questo angolo sugli assi di beccheggio e rollio."
|
||||||
},
|
},
|
||||||
"APPLICATION_LAUNCHER": "Lanciatore applicazioni",
|
"APPLICATION_LAUNCHER": "Lanciatore applicazioni",
|
||||||
"APPLICATION_STARTED": "Applicazione avviata",
|
"APPLICATION_STARTED": "Applicazione avviata",
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,9 @@
|
||||||
"APPLY_CHANGES_RESTART": "変更を適用するためにWayVRを再起動しますか?",
|
"APPLY_CHANGES_RESTART": "変更を適用するためにWayVRを再起動しますか?",
|
||||||
"COLOR_PALETTE_HELP": "クリックしてカラーパレットを選択してください。\nカスタムパレットの作成については、ウェブサイトを参照してください!",
|
"COLOR_PALETTE_HELP": "クリックしてカラーパレットを選択してください。\nカスタムパレットの作成については、ウェブサイトを参照してください!",
|
||||||
"COLOR_PALETTE_CUSTOM_URL": "カスタムテーマを追加しましょう!",
|
"COLOR_PALETTE_CUSTOM_URL": "カスタムテーマを追加しましょう!",
|
||||||
"COLOR_PALETTE_CUSTOM_URL2": "クリックしてウェブマニュアルを開く。"
|
"COLOR_PALETTE_CUSTOM_URL2": "クリックしてウェブマニュアルを開く。",
|
||||||
|
"SNAP_ANGLE_DEG": "ウィンドウのピッチ・ロールのスナップ角度",
|
||||||
|
"SNAP_ANGLE_DEG_HELP": "掴んでいるウィンドウが、ピッチ軸とロール軸でこの角度にスナップします。"
|
||||||
},
|
},
|
||||||
"HELLO": "こんにちは!",
|
"HELLO": "こんにちは!",
|
||||||
"AUDIO": {
|
"AUDIO": {
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,9 @@
|
||||||
"APPLY_CHANGES_RESTART": "Zrestartować WayVR, aby zastosować zmiany?",
|
"APPLY_CHANGES_RESTART": "Zrestartować WayVR, aby zastosować zmiany?",
|
||||||
"COLOR_PALETTE_HELP": "Kliknij, aby przeglądać palety kolorów.\nAby stworzyć własne, odwiedź stronę internetową!",
|
"COLOR_PALETTE_HELP": "Kliknij, aby przeglądać palety kolorów.\nAby stworzyć własne, odwiedź stronę internetową!",
|
||||||
"COLOR_PALETTE_CUSTOM_URL": "Dodaj własny motyw!",
|
"COLOR_PALETTE_CUSTOM_URL": "Dodaj własny motyw!",
|
||||||
"COLOR_PALETTE_CUSTOM_URL2": "Kliknij, aby otworzyć instrukcję internetową."
|
"COLOR_PALETTE_CUSTOM_URL2": "Kliknij, aby otworzyć instrukcję internetową.",
|
||||||
|
"SNAP_ANGLE_DEG": "Kąt przyciągania pochylenia i przechyłu okna",
|
||||||
|
"SNAP_ANGLE_DEG_HELP": "Chwycone okna przyciągają się do tego kąta na osi pochylenia i obrotu."
|
||||||
},
|
},
|
||||||
"APPLICATION_LAUNCHER": "Uruchamiacz aplikacji",
|
"APPLICATION_LAUNCHER": "Uruchamiacz aplikacji",
|
||||||
"APPLICATIONS": "Aplikacje",
|
"APPLICATIONS": "Aplikacje",
|
||||||
|
|
|
||||||
|
|
@ -213,7 +213,9 @@
|
||||||
"APPLY_CHANGES_RESTART": "重启 WayVR 以应用更改吗?",
|
"APPLY_CHANGES_RESTART": "重启 WayVR 以应用更改吗?",
|
||||||
"COLOR_PALETTE_HELP": "点击浏览配色方案。\n如需创建自定义配色,请参阅网站!",
|
"COLOR_PALETTE_HELP": "点击浏览配色方案。\n如需创建自定义配色,请参阅网站!",
|
||||||
"COLOR_PALETTE_CUSTOM_URL": "添加自定义主题!",
|
"COLOR_PALETTE_CUSTOM_URL": "添加自定义主题!",
|
||||||
"COLOR_PALETTE_CUSTOM_URL2": "点击打开网页版手册。"
|
"COLOR_PALETTE_CUSTOM_URL2": "点击打开网页版手册。",
|
||||||
|
"SNAP_ANGLE_DEG": "窗口俯仰与翻滚捕捉角度",
|
||||||
|
"SNAP_ANGLE_DEG_HELP": "抓取的窗口在俯仰轴和翻滚轴上将对齐到此角度。"
|
||||||
},
|
},
|
||||||
"APPLICATION_LAUNCHER": "应用启动器",
|
"APPLICATION_LAUNCHER": "应用启动器",
|
||||||
"APPLICATION_STARTED": "应用已启动",
|
"APPLICATION_STARTED": "应用已启动",
|
||||||
|
|
|
||||||
|
|
@ -320,6 +320,7 @@ pub(crate) enum SettingType {
|
||||||
PointerLerpFactor,
|
PointerLerpFactor,
|
||||||
ScreenRenderDown,
|
ScreenRenderDown,
|
||||||
ScrollSpeed,
|
ScrollSpeed,
|
||||||
|
SnapAngleDeg,
|
||||||
EnableWatch,
|
EnableWatch,
|
||||||
SetsOnWatch,
|
SetsOnWatch,
|
||||||
SpaceDragMultiplier,
|
SpaceDragMultiplier,
|
||||||
|
|
@ -389,6 +390,7 @@ impl SettingType {
|
||||||
Self::LongPressDuration => &mut config.long_press_duration,
|
Self::LongPressDuration => &mut config.long_press_duration,
|
||||||
Self::PointerLerpFactor => &mut config.pointer_lerp_factor,
|
Self::PointerLerpFactor => &mut config.pointer_lerp_factor,
|
||||||
Self::ScrollSpeed => &mut config.scroll_speed,
|
Self::ScrollSpeed => &mut config.scroll_speed,
|
||||||
|
Self::SnapAngleDeg => &mut config.snap_angle_deg,
|
||||||
Self::SpaceDragMultiplier => &mut config.space_drag_multiplier,
|
Self::SpaceDragMultiplier => &mut config.space_drag_multiplier,
|
||||||
Self::SpaceGravityDamping => &mut config.space_gravity_damping,
|
Self::SpaceGravityDamping => &mut config.space_gravity_damping,
|
||||||
Self::SpaceGravityFlingStrength => &mut config.space_gravity_fling_strength,
|
Self::SpaceGravityFlingStrength => &mut config.space_gravity_fling_strength,
|
||||||
|
|
@ -500,6 +502,7 @@ impl SettingType {
|
||||||
Self::ScrollSpeed => Ok("APP_SETTINGS.SCROLL_SPEED"),
|
Self::ScrollSpeed => Ok("APP_SETTINGS.SCROLL_SPEED"),
|
||||||
Self::EnableWatch => Ok("APP_SETTINGS.ENABLE_WATCH"),
|
Self::EnableWatch => Ok("APP_SETTINGS.ENABLE_WATCH"),
|
||||||
Self::SetsOnWatch => Ok("APP_SETTINGS.SETS_ON_WATCH"),
|
Self::SetsOnWatch => Ok("APP_SETTINGS.SETS_ON_WATCH"),
|
||||||
|
Self::SnapAngleDeg => Ok("APP_SETTINGS.SNAP_ANGLE_DEG"),
|
||||||
Self::SpaceDragMultiplier => Ok("APP_SETTINGS.SPACE_DRAG_MULTIPLIER"),
|
Self::SpaceDragMultiplier => Ok("APP_SETTINGS.SPACE_DRAG_MULTIPLIER"),
|
||||||
Self::SpaceDragUnlocked => Ok("APP_SETTINGS.SPACE_DRAG_UNLOCKED"),
|
Self::SpaceDragUnlocked => Ok("APP_SETTINGS.SPACE_DRAG_UNLOCKED"),
|
||||||
Self::SpaceGravityDamping => Ok("APP_SETTINGS.SPACE_GRAVITY_DAMPING"),
|
Self::SpaceGravityDamping => Ok("APP_SETTINGS.SPACE_GRAVITY_DAMPING"),
|
||||||
|
|
@ -536,6 +539,7 @@ impl SettingType {
|
||||||
Self::KeyboardMiddleClick => Some("APP_SETTINGS.KEYBOARD_MIDDLE_CLICK_HELP"),
|
Self::KeyboardMiddleClick => Some("APP_SETTINGS.KEYBOARD_MIDDLE_CLICK_HELP"),
|
||||||
Self::LeftHandedMouse => Some("APP_SETTINGS.LEFT_HANDED_MOUSE_HELP"),
|
Self::LeftHandedMouse => Some("APP_SETTINGS.LEFT_HANDED_MOUSE_HELP"),
|
||||||
Self::ScreenRenderDown => Some("APP_SETTINGS.SCREEN_RENDER_DOWN_HELP"),
|
Self::ScreenRenderDown => Some("APP_SETTINGS.SCREEN_RENDER_DOWN_HELP"),
|
||||||
|
Self::SnapAngleDeg => Some("APP_SETTINGS.SNAP_ANGLE_DEG_HELP"),
|
||||||
Self::SpaceGravityDamping => Some("APP_SETTINGS.SPACE_GRAVITY_DAMPING_HELP"),
|
Self::SpaceGravityDamping => Some("APP_SETTINGS.SPACE_GRAVITY_DAMPING_HELP"),
|
||||||
Self::SpaceGravityFlingStrength => Some("APP_SETTINGS.SPACE_GRAVITY_FLING_STRENGTH_HELP"),
|
Self::SpaceGravityFlingStrength => Some("APP_SETTINGS.SPACE_GRAVITY_FLING_STRENGTH_HELP"),
|
||||||
Self::SpaceGravityFloorHeight => Some("APP_SETTINGS.SPACE_GRAVITY_FLOOR_HEIGHT_HELP"),
|
Self::SpaceGravityFloorHeight => Some("APP_SETTINGS.SPACE_GRAVITY_FLOOR_HEIGHT_HELP"),
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,10 @@ use crate::util::popup_manager::PopupHolder;
|
||||||
use crate::{
|
use crate::{
|
||||||
frontend::FrontendTasks,
|
frontend::FrontendTasks,
|
||||||
tab::settings::{
|
tab::settings::{
|
||||||
SettingType, SettingsMountParams, SettingsTab,
|
|
||||||
macros::{options_category, options_checkbox, options_dropdown, options_slider_f32, options_slider_i32},
|
macros::{options_category, options_checkbox, options_dropdown, options_slider_f32, options_slider_i32},
|
||||||
|
SettingType, SettingsMountParams, SettingsTab,
|
||||||
},
|
},
|
||||||
views::{ViewUpdateParams, input_profiles},
|
views::{input_profiles, ViewUpdateParams},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|
@ -104,6 +104,7 @@ impl State {
|
||||||
options_checkbox(par.mp, c, SettingType::InvertScrollDirectionY)?;
|
options_checkbox(par.mp, c, SettingType::InvertScrollDirectionY)?;
|
||||||
options_slider_f32(par.mp, c, SettingType::ScrollSpeed, 0.1, 5.0, 0.1)?;
|
options_slider_f32(par.mp, c, SettingType::ScrollSpeed, 0.1, 5.0, 0.1)?;
|
||||||
options_slider_f32(par.mp, c, SettingType::LongPressDuration, 0.1, 2.0, 0.1)?;
|
options_slider_f32(par.mp, c, SettingType::LongPressDuration, 0.1, 2.0, 0.1)?;
|
||||||
|
options_slider_f32(par.mp, c, SettingType::SnapAngleDeg, 0., 45., 5.)?;
|
||||||
|
|
||||||
if par.feats.openxr {
|
if par.feats.openxr {
|
||||||
options_slider_f32(par.mp, c, SettingType::PointerLerpFactor, 0.1, 1.0, 0.1)?;
|
options_slider_f32(par.mp, c, SettingType::PointerLerpFactor, 0.1, 1.0, 0.1)?;
|
||||||
|
|
|
||||||
|
|
@ -888,7 +888,12 @@ where
|
||||||
app.anchor.translation =
|
app.anchor.translation =
|
||||||
pointer.pose.transform_point3a(grab_data.offset.translation);
|
pointer.pose.transform_point3a(grab_data.offset.translation);
|
||||||
let scale = scalar_scale(&app.anchor);
|
let scale = scalar_scale(&app.anchor);
|
||||||
realign(&mut app.anchor, &app.input_state.hmd, scale);
|
realign(
|
||||||
|
&mut app.anchor,
|
||||||
|
&app.input_state.hmd,
|
||||||
|
scale,
|
||||||
|
app.session.config.snap_angle_deg,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// single grab resize
|
// single grab resize
|
||||||
|
|
@ -912,7 +917,12 @@ where
|
||||||
let scale = scalar_scale(&overlay_state.transform);
|
let scale = scalar_scale(&overlay_state.transform);
|
||||||
overlay_state.transform.translation =
|
overlay_state.transform.translation =
|
||||||
pointer.pose.transform_point3a(grab_data.offset.translation);
|
pointer.pose.transform_point3a(grab_data.offset.translation);
|
||||||
realign(&mut overlay_state.transform, &app.input_state.hmd, scale);
|
realign(
|
||||||
|
&mut overlay_state.transform,
|
||||||
|
&app.input_state.hmd,
|
||||||
|
scale,
|
||||||
|
app.session.config.snap_angle_deg,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
overlay.config.pause_movement = true;
|
overlay.config.pause_movement = true;
|
||||||
overlay.config.dirty = true;
|
overlay.config.dirty = true;
|
||||||
|
|
|
||||||
|
|
@ -187,6 +187,7 @@ pub struct AutoSettings {
|
||||||
pub whisper_model: Arc<str>,
|
pub whisper_model: Arc<str>,
|
||||||
pub default_overlay_scale: f32,
|
pub default_overlay_scale: f32,
|
||||||
pub color_palette: Arc<str>,
|
pub color_palette: Arc<str>,
|
||||||
|
pub snap_angle_deg: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_settings_path() -> PathBuf {
|
fn get_settings_path() -> PathBuf {
|
||||||
|
|
@ -252,6 +253,7 @@ pub fn save_settings(config: &GeneralConfig) -> anyhow::Result<()> {
|
||||||
whisper_model: config.whisper_model.clone(),
|
whisper_model: config.whisper_model.clone(),
|
||||||
default_overlay_scale: config.default_overlay_scale,
|
default_overlay_scale: config.default_overlay_scale,
|
||||||
color_palette: config.color_palette.clone(),
|
color_palette: config.color_palette.clone(),
|
||||||
|
snap_angle_deg: config.snap_angle_deg,
|
||||||
};
|
};
|
||||||
|
|
||||||
let json = serde_json::to_string_pretty(&conf).unwrap(); // want panic
|
let json = serde_json::to_string_pretty(&conf).unwrap(); // want panic
|
||||||
|
|
|
||||||
|
|
@ -329,7 +329,7 @@ fn tutorial_spawn_effect(app: &mut AppState) -> anyhow::Result<()> {
|
||||||
let hmd = &app.input_state.hmd;
|
let hmd = &app.input_state.hmd;
|
||||||
let pos = hmd.translation + hmd.z_axis * -2.0;
|
let pos = hmd.translation + hmd.z_axis * -2.0;
|
||||||
let mut transform = Affine3A::from_rotation_translation(Quat::IDENTITY, pos.into());
|
let mut transform = Affine3A::from_rotation_translation(Quat::IDENTITY, pos.into());
|
||||||
realign(&mut transform, hmd, 1.0);
|
realign(&mut transform, hmd, 1.0, app.session.config.snap_angle_deg);
|
||||||
|
|
||||||
owc.active_state = Some(OverlayWindowState {
|
owc.active_state = Some(OverlayWindowState {
|
||||||
saved_transform: Some(Affine3A::from_translation(vec3(0., -0.1, -0.9))),
|
saved_transform: Some(Affine3A::from_translation(vec3(0., -0.1, -0.9))),
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use glam::{Affine3A, Mat3A, Quat, Vec3, Vec3A};
|
use glam::{Affine3A, EulerRot, Mat3A, Quat, Vec3, Vec3A};
|
||||||
use idmap_derive::IntegerId;
|
use idmap_derive::IntegerId;
|
||||||
use std::{f32::consts::PI, sync::Arc};
|
use std::{f32::consts::PI, sync::Arc};
|
||||||
use wlx_common::windowing::{OverlayWindowState, Positioning};
|
use wlx_common::windowing::{OverlayWindowState, Positioning};
|
||||||
|
|
@ -192,7 +192,12 @@ impl OverlayWindowConfig {
|
||||||
};
|
};
|
||||||
|
|
||||||
if align_to_hmd {
|
if align_to_hmd {
|
||||||
realign(&mut state.transform, &app.input_state.hmd, scale);
|
realign(
|
||||||
|
&mut state.transform,
|
||||||
|
&app.input_state.hmd,
|
||||||
|
scale,
|
||||||
|
app.session.config.snap_angle_deg,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
|
|
@ -250,13 +255,18 @@ impl OverlayWindowConfig {
|
||||||
|
|
||||||
if align_to_hmd || (state.grabbable && hard_reset) {
|
if align_to_hmd || (state.grabbable && hard_reset) {
|
||||||
let scale = scalar_scale(&cur_transform);
|
let scale = scalar_scale(&cur_transform);
|
||||||
realign(&mut state.transform, &app.input_state.hmd, scale);
|
realign(
|
||||||
|
&mut state.transform,
|
||||||
|
&app.input_state.hmd,
|
||||||
|
scale,
|
||||||
|
app.session.config.snap_angle_deg,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn realign(transform: &mut Affine3A, hmd: &Affine3A, scale: f32) {
|
pub fn realign(transform: &mut Affine3A, hmd: &Affine3A, scale: f32, snap_angle: f32) {
|
||||||
let to_hmd = hmd.translation - transform.translation;
|
let to_hmd = hmd.translation - transform.translation;
|
||||||
let up_dir: Vec3A;
|
let up_dir: Vec3A;
|
||||||
|
|
||||||
|
|
@ -289,8 +299,20 @@ pub fn realign(transform: &mut Affine3A, hmd: &Affine3A, scale: f32) {
|
||||||
let col_y = col_z.cross(col_x).normalize();
|
let col_y = col_z.cross(col_x).normalize();
|
||||||
let col_x = col_x.normalize();
|
let col_x = col_x.normalize();
|
||||||
|
|
||||||
let rot = Mat3A::from_quat(Quat::from_axis_angle(Vec3::Y, PI));
|
let flip = Mat3A::from_quat(Quat::from_axis_angle(Vec3::Y, PI));
|
||||||
transform.matrix3 = Mat3A::from_cols(col_x, col_y, col_z).mul_scalar(scale) * rot;
|
let mut rotation = Mat3A::from_cols(col_x, col_y, col_z) * flip;
|
||||||
|
|
||||||
|
if snap_angle > f32::EPSILON {
|
||||||
|
let snap_step = snap_angle.to_radians();
|
||||||
|
let (yaw, pitch, roll) = rotation.to_euler(EulerRot::YXZ);
|
||||||
|
|
||||||
|
let pitch = (pitch / snap_step).round() * snap_step;
|
||||||
|
let roll = (roll / snap_step).round() * snap_step;
|
||||||
|
|
||||||
|
rotation = Mat3A::from_euler(EulerRot::YXZ, yaw, pitch, roll);
|
||||||
|
}
|
||||||
|
|
||||||
|
transform.matrix3 = rotation.mul_scalar(scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scalar_scale(a: &Affine3A) -> f32 {
|
pub fn scalar_scale(a: &Affine3A) -> f32 {
|
||||||
|
|
|
||||||
|
|
@ -475,4 +475,7 @@ pub struct GeneralConfig {
|
||||||
|
|
||||||
#[serde(default = "def_default")]
|
#[serde(default = "def_default")]
|
||||||
pub color_palette: Arc<str>,
|
pub color_palette: Arc<str>,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub snap_angle_deg: f32,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue