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
//! Virtual Trackball Orbiting via the Exponential Map
//!
//! 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. This is in contrast to state-of-the-art
//! techniques using orthogonal projection which distorts radial distances further away from the
//! screen's center. This implementation strictly follows the recipe given in the paper of
//! Stantchev, G.. “Virtual Trackball Modeling and the Exponential Map.” . [S2CID] [44199608].
//!
//! [S2CID]: https://en.wikipedia.org/wiki/S2CID_(identifier)
//! [44199608]: https://api.semanticscholar.org/CorpusID:44199608
//!
//! # Present Features
//!
//!   * Common trackball operations split into several operation handlers.
//!   * Coherent and intuitive orbiting via the exponential map, see [`Orbit`] operation handler.
//!   * Identical C11 implementation for [`Orbit`] operation handler behind `cc` feature gate.
//!   * Observer frame with [`Frame::slide()`], [`Frame::orbit()`], [`Frame::scale()`] operations in
//!     world space and their local complements in camera space.
//!   * Object inspection mode scaling clip plane distances by measuring from target instead of eye.
//!   * Scale-preserving transitioning between orthographic and perspective projection mode.
//!   * Time-free touch gesture recognition for slide, orbit, scale, and focus operations.
//!
//! # Future Features
//!
//!   * Add `Clamp` operation handler ensuring user boundary conditions of [`Frame`] and [`Scene`].
//!   * Compute bounding box of scene graph and track total slide to prevent clip plane collisions.
//!
//! # Example
//!
//! A trackball camera mode implementation can be as easy as this by delegating events of your 3D
//! graphics library of choice to the [`Orbit`] operation handler along with other handlers.
//!
//! ```
//! use nalgebra::{Point2, UnitQuaternion, Vector3};
//! use std::f32::consts::PI;
//! use trackball::{Frame, Image, Orbit};
//!
//! /// Trackball camera mode.
//! pub struct Trackball {
//! 	// Frame wrt camera eye and target.
//! 	frame: Frame<f32>,
//! 	// Image as projection of `Scene` wrt `Frame`.
//! 	image: Image<f32>,
//! 	// Orbit induced by displacement on screen.
//! 	orbit: Orbit<f32>,
//! }
//!
//! impl Trackball {
//! 	// Usually, a cursor position event with left mouse button being pressed.
//! 	fn handle_left_button_displacement(&mut self, pos: &Point2<f32>) {
//! 		// Maximum position as screen's width and height.
//! 		let max = self.image.max();
//! 		// Induced rotation in camera space.
//! 		let rot = self.orbit.compute(&pos, max).unwrap_or_default();
//! 		// Apply induced rotation to local observer frame.
//! 		self.frame.local_orbit(&rot);
//! 	}
//! 	// Event when left mouse button is released again.
//! 	fn handle_left_button_release(&mut self) {
//! 		// Can also or instead be invoked on `Self::handle_left_button_press()`.
//! 		self.orbit.discard();
//! 	}
//! }
//! ```

#![forbid(missing_docs)]

mod frame;
mod image;
mod orbit;
mod scale;
mod scene;
mod slide;
mod touch;

pub use frame::*;
pub use image::*;
pub use orbit::*;
pub use scale::*;
pub use scene::*;
pub use slide::*;
pub use touch::*;