1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
//! Coherent virtual trackball controller/camera plugin for Bevy
//!
//! Run interactive [examples] in your browser using [WebAssembly] and [WebGL].
//!
//! [WebAssembly]: https://en.wikipedia.org/wiki/WebAssembly
//! [WebGL]: https://en.wikipedia.org/wiki/WebGL
//!
//! **NOTE**: Not all features are enabled by default, see [Optional Features](#optional-features).
//! On Linux the `bevy/wayland` or `bevy/x11` feature gate must be enabled for a successful build.
//!
//! # Camera Modes
//!
//! Supports multiple camera modes:
//!
//! * Trackball mode rotates camera around target.
//! * First-person mode rotates target around camera.
//! * Spectator mode translates target and camera.
//!
//! # Coherence Features
//!
//! This is an alternative trackball technique using exponential map and parallel transport to
//! preserve distances and angles for inducing coherent and intuitive trackball rotations. For
//! instance, displacements on straight radial lines through the screen's center are carried to arcs
//! of the same length on great circles of the trackball (e.g., dragging the mouse along an eights
//! of the trackball's circumference rolls the camera by 360/8=45 degrees, dragging the mouse from
//! the screen's center to its further edge *linearly* rotates the camera by 1 [radian], where the
//! trackball's diameter is the maximum of the screen's width and height). This is in contrast to
//! state-of-the-art techniques using orthogonal projection which distorts radial distances further
//! away from the screen's center (e.g., the rotation accelerates towards the edge).[^1]
//!
//! [^1]: G. Stantchev, “Virtual Trackball Modeling and the Exponential Map”, [S2CID 44199608 (2004)
//! ](https://api.semanticscholar.org/CorpusID:44199608), [Archived PDF
//! ](https://web.archive.org/web/2/http://www.math.umd.edu:80/~gogo/Papers/trackballExp.pdf)
//!
//! [radian]: https://en.wikipedia.org/wiki/Radian
//!
//! * Coherent and intuitive orbiting via the exponential map, see the underlying [`trackball`]
//! crate and the [`exponential_map`] example.
//! * Coherent first-person mode aka free look or mouse look with the world trackball centered at
//! eye instead of target.
//! * Coherent scaling by translating mouse wheel device units, see [`TrackballWheelUnit`]. Scales
//! eye distance from current cursor position or centroid of finger positions projected onto
//! focus plane.
//! * Coherent linear/angular [`TrackballVelocity`] for sliding/orbiting or free look by
//! time-based input (e.g., pressed key). By default, the linear velocity is deduced from the
//! angular velocity (where target and eye positions define the world radius) which in turn is
//! defined in units of vertical field of view per seconds and hence independent of the world
//! unit scale.
//!
//! # Additional Features
//!
//! * Time-free multi-touch gesture recognition for orbit, scale, slide, and focus (i.e., slide to
//! cursor/finger position) operations.
//! * Smoothing of movement implemented as fps-agnostic exponential ease-out.
//! * Gimbal lock-free using quaternion instead of Euler angles.
//! * Gliding clamp (experimental): The movement of a camera can be restricted to user-defined
//! boundary conditions (e.g., to not orbit below the ground plane). When the movement is not
//! orthogonal to a boundary plane, it is changed such that the camera glides along the boundary
//! plane. Currently, only implemented for orbit and slide operations, see the [`gliding_clamp`]
//! example.
//! * Camera constellation: A camera is decoupled from its input controller and instead multiple
//! cameras can be sensitive to zero or multiple selected controllers (e.g., a minimap
//! controlled by the same controller of the main viewport).
//! * Constellation clamp: Cameras sensitive to the same controller are referred to as a group
//! and can be configured to clamp the movement for the whole group whenever a group member
//! crosses a boundary condition (e.g., rigid and loose constellation clamp), see the
//! [`constellation_clamp`] example.
//! * Viewport stealing: This allows UI system (e.g., egui behind `bevy_egui` feature gate) to
//! steal the viewport and hence capture the input instead, see the [`egui`] example.
//! * Scale-preserving transitioning between orthographic and perspective projection mode.
//! * Converting between scaling modes (i.e., fixed vertical or horizontal field of view or fixed
//! unit per pixels). This defines whether the scene scales or the corresponding vertical or
//! horizontal field of view adjusts whenever the height or width of the viewport is resized,
//! see the [`scaling_modes`] example.
//! * Object inspection mode scaling clip plane distances by measuring from target instead of eye.
//! This benefits the precision of the depth map. Applicable, whenever the extend of the object
//! to inspect is known and hence the near clip plane can safely be placed just in front of it.
//! * `f64`-ready for large worlds (e.g., solar system scale) whenever Bevy is, see issue [#1680].
//!
//! [#1680]: https://github.com/bevyengine/bevy/issues/1680
//!
//! # Optional Features
//!
//! Following features are disabled unless their corresponding feature gate is enabled:
//!
//! * `bevy_egui` for automatic viewport stealing whenever `egui` wants focus.
//! * `serialize` for `serde` support of various structures of this crate and its dependencies.
//! * `c11-orbit` for testing the behaviorally identical C implementation of the exponential map.
//!
//! # Roadmap
//!
//! * Implement gliding clamp for first-person mode and scale operation, see
//! [issue](https://github.com/qu1x/bevy_trackball/issues/5).
//! * Support more camera modes out of the box by adding dedicated controllers for each mode, see
//! [issue](https://github.com/qu1x/bevy_trackball/issues/3).
//! * Support gamepad inputs, see [issue](https://github.com/qu1x/bevy_trackball/issues/4).
//!
//! # Input Mappings
//!
//! Following mappings are the defaults which can be customized, see [`TrackballInput`].
//!
//! Mouse (Buttons) | Touch (Fingers) | Keyboard | Operation
//! ----------------------- | ----------------------- | -------- | ---------------------------------
//! Left Press + Drag | One + Drag | `ijkl` | Orbits around target.
//! ↳ at trackball's border | Two + Roll | `uo` | Rolls about view direction.
//! Middle Press + Drag | Any + Drag + Left Shift | `↑←↓→` | First-person mode.
//! Right Press + Drag | Two + Drag | `esdf` | Slides trackball on focus plane.
//! | | `gv` | Slides trackball in/out.
//! Scroll In/Out | Two + Pinch Out/In | `hn` | Scales distance zooming in/out.
//! Left Press + Release | Any + Release | | Slides to cursor/finger position.
//! | | `m` | Toggle `esdf`/`wasd` mapping.
//! | | `p` | Toggle orthographic/perspective.
//! | | `Enter` | Reset camera transform.
//!
//! Alternatively, [`TrackballInput::map_wasd`] maps `wasd`/`Space`/`ControlLeft` to slide
//! operations where `ws` slides in/out and `Space`/`ControlLeft` slides up/down (jump/crouch).
//!
//! # Usage
//!
//! Add the [`TrackballPlugin`] followed by spawning a [`TrackballController`] together with a
//! [`TrackballCamera`] and a `Camera3dBundle` or try the interactive [examples].
//!
//! ```no_run
//! use bevy::prelude::*;
//! use bevy_trackball::prelude::*;
//!
//! // Add the trackball plugin.
//! fn main() {
//! App::new()
//! .add_plugins(DefaultPlugins)
//! .add_plugins(TrackballPlugin)
//! .add_systems(Startup, setup)
//! .run();
//! }
//!
//! // Add a trackball controller and trackball camera to a camera 3D bundle.
//! fn setup(mut commands: Commands) {
//! let [target, eye, up] = [Vec3::ZERO, Vec3::Z * 10.0, Vec3::Y];
//! commands.spawn((
//! TrackballController::default(),
//! TrackballCamera::look_at(target, eye, up),
//! Camera3d::default(),
//! ));
//!
//! // Set up your scene...
//! }
//! ```
//!
//! [examples]: https://qu1x.dev/bevy_trackball
//! [`exponential_map`]: https://qu1x.dev/bevy_trackball/exponential_map.html
//! [`gliding_clamp`]: https://qu1x.dev/bevy_trackball/gliding_clamp.html
//! [`constellation_clamp`]: https://qu1x.dev/bevy_trackball/constellation_clamp.html
//! [`egui`]: https://qu1x.dev/bevy_trackball/egui.html
//! [`scaling_modes`]: https://github.com/qu1x/bevy_trackball/blob/main/examples/scaling_modes.rs
use *;
pub use TrackballCamera;
use trackball_camera;
use trackball_constellation;
use trackball_controller;
pub use ;
pub use trackball;
use ;
/// Prelude to get started quickly.
/// Plugin adding and configuring systems and their resources.
///
/// Halts [`TrackballSystemSet::Controller`] for supported UI systems (i.e., `bevy_egui` feature
/// gate) whenever they request focus by marking the active viewport as stolen.
///
/// See [`TrackballViewport::set_stolen`] in order to steal the viewport and hence exclusively
/// consume its input events for UI systems that are not yet supported behind feature gate.
;
/// Event sent from [`TrackballController`] component to group of [`TrackballCamera`] components.
/// Setup of [`TrackballCamera`] as part of [`TrackballMessage`].
/// System sets configured by [`TrackballPlugin`].