Skip to content

Commit 7100331

Browse files
committed
Let m toggle between map_esdf and map_wasd.
1 parent 222e912 commit 7100331

File tree

4 files changed

+88
-2
lines changed

4 files changed

+88
-2
lines changed

src/controller.rs

+17
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,23 @@ pub struct TrackballController {
3737
first_count: usize,
3838
}
3939

40+
impl TrackballController {
41+
/// Trackball controller using [`TrackballInput::map_esdf`].
42+
#[must_use]
43+
pub fn map_esdf() -> Self {
44+
let mut controller = Self::default();
45+
controller.input.map_esdf();
46+
controller
47+
}
48+
/// Trackball controller using [`TrackballInput::map_wasd`].
49+
#[must_use]
50+
pub fn map_wasd() -> Self {
51+
let mut controller = Self::default();
52+
controller.input.map_wasd();
53+
controller
54+
}
55+
}
56+
4057
#[allow(clippy::needless_pass_by_value)]
4158
#[allow(clippy::too_many_arguments)]
4259
pub fn trackball_controller(

src/controller/input.rs

+49
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ pub struct TrackballInput {
1919
/// the focus operation in favor of the orbit operation.
2020
pub focus: bool,
2121

22+
/// Key used to toggle `esdf`/`wasd` mapping. Default is [`KeyCode::M`].
23+
pub gamer_key: Option<KeyCode>,
2224
/// Key used to toggle projection mode. Default is [`KeyCode::P`].
2325
pub ortho_key: Option<KeyCode>,
2426

@@ -74,6 +76,51 @@ pub struct TrackballInput {
7476
pub scale_out_key: Option<KeyCode>,
7577
}
7678

79+
impl TrackballInput {
80+
/// Maps `esdf`/`gv` to slide operations.
81+
///
82+
/// Key | Operation
83+
/// --- | ---------------------------
84+
/// `e` | Slides up.
85+
/// `s` | Slides left.
86+
/// `d` | Slides down.
87+
/// `f` | Slides right.
88+
/// `g` | Slides far (in/forward).
89+
/// `v` | Slides near (out/backward).
90+
///
91+
/// This mapping is symmetric to the `ijkl`/`hn` orbit mapping but less intuitive to gamers
92+
/// compared with [`Self::map_wasd`].
93+
pub fn map_esdf(&mut self) {
94+
self.slide_up_key = Some(KeyCode::E);
95+
self.slide_down_key = Some(KeyCode::D);
96+
self.slide_left_key = Some(KeyCode::S);
97+
self.slide_right_key = Some(KeyCode::F);
98+
self.slide_far_key = Some(KeyCode::G);
99+
self.slide_near_key = Some(KeyCode::V);
100+
}
101+
/// Maps `wasd`/`Space`/`ControlLeft` to slide operations.
102+
///
103+
/// Key | Operation
104+
/// ------------- | ---------------------------
105+
/// `w` | Slides far (in/forward).
106+
/// `a` | Slides left.
107+
/// `s` | Slides near (out/backward).
108+
/// `d` | Slides right.
109+
/// `Space` | Slides up (jump).
110+
/// `ControlLeft` | Slides down (crouch).
111+
///
112+
/// This mapping isn't symmetric to the `ijkl`/`hn` orbit mapping but more intuitive to gamers
113+
/// compared with [`Self::map_esdf`].
114+
pub fn map_wasd(&mut self) {
115+
self.slide_up_key = Some(KeyCode::Space);
116+
self.slide_down_key = Some(KeyCode::ControlLeft);
117+
self.slide_left_key = Some(KeyCode::A);
118+
self.slide_right_key = Some(KeyCode::D);
119+
self.slide_far_key = Some(KeyCode::W);
120+
self.slide_near_key = Some(KeyCode::S);
121+
}
122+
}
123+
77124
impl Default for TrackballInput {
78125
fn default() -> Self {
79126
Self {
@@ -82,6 +129,8 @@ impl Default for TrackballInput {
82129

83130
focus: true,
84131

132+
gamer_key: Some(KeyCode::M),
133+
85134
ortho_key: Some(KeyCode::P),
86135

87136
reset_key: Some(KeyCode::Return),

src/controller/key.rs

+8
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use trackball::nalgebra::{Point3, Unit, UnitQuaternion};
44
use crate::{TrackballCamera, TrackballController, TrackballEvent};
55

66
#[allow(clippy::too_many_arguments)]
7+
#[allow(clippy::too_many_lines)]
78
pub fn key(
89
group: Entity,
910
trackball_events: &mut EventWriter<TrackballEvent>,
@@ -29,6 +30,13 @@ pub fn key(
2930
if just_pressed(controller.input.ortho_key) {
3031
trackball_events.send(TrackballEvent::ortho(group, None));
3132
}
33+
if just_pressed(controller.input.gamer_key) {
34+
if controller.input.slide_far_key == Some(KeyCode::W) {
35+
controller.input.map_esdf();
36+
} else {
37+
controller.input.map_wasd();
38+
}
39+
}
3240
for (key, vec) in [
3341
(controller.input.slide_far_key, Vec3::NEG_Z),
3442
(controller.input.slide_near_key, Vec3::Z),

src/lib.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@
55
//! [WebAssembly]: https://en.wikipedia.org/wiki/WebAssembly
66
//! [WebGL]: https://en.wikipedia.org/wiki/WebGL
77
//!
8+
//! # Camera Modes
9+
//!
10+
//! Supports multiple camera modes:
11+
//!
12+
//! * Trackball mode rotates camera around target.
13+
//! * First-Person mode rotates target around camera.
14+
//! * Spectator mode translates target and camera.
15+
//!
816
//! # Coherence Features
917
//!
1018
//! This is an alternative trackball technique using exponential map and parallel transport to
@@ -22,7 +30,7 @@
2230
//! * Coherent and intuitive orbiting via the exponential map, see the underlying [`trackball`]
2331
//! crate which follows the recipe given in the paper of Stantchev, G.. “Virtual Trackball
2432
//! Modeling and the Exponential Map.”. [S2CID] [44199608]. See the [`exponential_map`] example.
25-
//! * Coherent first person view aka free look or mouse look with the world trackball centered at
33+
//! * Coherent first-person mode aka free look or mouse look with the world trackball centered at
2634
//! eye instead of target.
2735
//! * Coherent scaling by translating mouse wheel device units, see [`TrackballWheelUnit`]. Scales
2836
//! eye distance from current cursor position or centroid of finger positions projected onto
@@ -76,14 +84,18 @@
7684
//! ----------------------- | ----------------------- | -------- | ---------------------------------
7785
//! Left Press + Drag | One + Drag | `ijkl` | Orbits around target.
7886
//! ↳ at trackball's border | Two + Roll | `uo` | Rolls about view direction.
79-
//! Middle Press + Drag | Any + Drag + Left Shift | `↑←↓→` | First person view.
87+
//! Middle Press + Drag | Any + Drag + Left Shift | `↑←↓→` | First-person mode.
8088
//! Right Press + Drag | Two + Drag | `esdf` | Slides trackball on focus plane.
8189
//! &nbsp; | &nbsp; | `gv` | Slides trackball in/out.
8290
//! Scroll In/Out | Two + Pinch Out/In | `hn` | Scales distance zooming in/out.
8391
//! Left Press + Release | Any + Release | &nbsp; | Slides to cursor/finger position.
92+
//! &nbsp; | &nbsp; | `m` | Toggle `esdf`/`wasd` mapping.
8493
//! &nbsp; | &nbsp; | `p` | Toggle orthographic/perspective.
8594
//! &nbsp; | &nbsp; | `Return` | Reset camera transform.
8695
//!
96+
//! Alternatively, [`TrackballInput::map_wasd`] maps `wasd`/`Space`/`ControlLeft` to slide
97+
//! operations where `wd` slides in/out and `Space`/`ControlLeft` slides up/down (jump/crouch).
98+
//!
8799
//! # Usage
88100
//!
89101
//! Add the [`TrackballPlugin`] followed by spawning a [`TrackballController`] together with a

0 commit comments

Comments
 (0)