trackball/
lib.rs

1//! Virtual Trackball Orbiting via the Exponential Map
2//!
3//! This is an alternative trackball technique using exponential map and parallel transport to
4//! preserve distances and angles for inducing coherent and intuitive trackball rotations. For
5//! instance, displacements on straight radial lines through the screen's center are carried to arcs
6//! of the same length on great circles of the trackball. This is in contrast to state-of-the-art
7//! techniques using orthogonal projection which distorts radial distances further away from the
8//! screen's center. This implementation strictly follows the recipe given in the paper of
9//! Stantchev, G.. “Virtual Trackball Modeling and the Exponential Map.” . [S2CID] [44199608].
10//!
11//! [S2CID]: https://en.wikipedia.org/wiki/S2CID_(identifier)
12//! [44199608]: https://api.semanticscholar.org/CorpusID:44199608
13//!
14//! # Features
15//!
16//!   * Common trackball operations split into several operation handlers.
17//!   * Coherent and intuitive orbiting via the exponential map, see [`Orbit`] operation handler.
18//!   * Identical C11 implementation for [`Orbit`] operation handler behind `cc` feature gate.
19//!   * Coherent [`First`] person view aka free look or mouse look wrt [`Orbit`] operation handler.
20//!   * Observer [`Frame`] with [`Frame::slide()`], [`Frame::orbit()`], [`Frame::scale()`]
21//!     operations in world space and their local complements in camera space and with orbit and
22//!     slide operations around arbitrary points in either world or camera space.
23//!   * Gliding [`Clamp`] operation handler trait ensuring boundary conditions of observer
24//!     [`Frame`]. When [`Delta`] between initial and final [`Frame`] is not orthogonal to a
25//!     boundary [`Plane`], [`Delta`] is changed in such a way that the clamped movement glides
26//!     along the plane.
27//!   * [`Bound`] implementing [`Clamp`] providing customizable orthogonal boundary conditions.
28//!   * Object inspection mode scaling clip plane distances by measuring from target instead of eye.
29//!   * Scale-preserving transitioning between orthographic and perspective projection mode.
30//!   * Converting between [`Fixed`] quantities wrt to field of view, see [`Scope::set_fov()`].
31//!   * Time-free [`Touch`] gesture recognition for slide, orbit, scale, and focus operations.
32//!
33//! # Example
34//!
35//! A trackball camera mode implementation can be as easy as this by delegating events of your 3D
36//! graphics library of choice to the [`Orbit`] operation handler along with other handlers.
37//!
38//! ```
39//! use trackball::{
40//! 	nalgebra::{Point2, Vector3},
41//! 	Frame, Image, Orbit,
42//! };
43//!
44//! /// Trackball camera mode.
45//! pub struct Trackball {
46//! 	// Frame wrt camera eye and target.
47//! 	frame: Frame<f32>,
48//! 	// Image as projection of `Scope` wrt `Frame`.
49//! 	image: Image<f32>,
50//! 	// Orbit induced by displacement on screen.
51//! 	orbit: Orbit<f32>,
52//! }
53//!
54//! impl Trackball {
55//! 	// Usually, a cursor position event with left mouse button being pressed.
56//! 	fn handle_left_button_displacement(&mut self, pos: &Point2<f32>) {
57//! 		// Maximum position as screen's width and height.
58//! 		let max = self.image.max();
59//! 		// Induced rotation in camera space.
60//! 		let rot = self.orbit.compute(&pos, max).unwrap_or_default();
61//! 		// Apply induced rotation to local observer frame.
62//! 		self.frame.local_orbit(&rot);
63//! 	}
64//! 	// Event when left mouse button is released again.
65//! 	fn handle_left_button_release(&mut self) {
66//! 		// Can also or instead be invoked on `Self::handle_left_button_press()`.
67//! 		self.orbit.discard();
68//! 	}
69//! }
70//! ```
71
72#![cfg_attr(any(feature = "rkyv", feature = "cc"), deny(unsafe_code))]
73#![cfg_attr(not(any(feature = "rkyv", feature = "cc")), forbid(unsafe_code))]
74#![cfg_attr(docsrs, feature(doc_auto_cfg))]
75#![no_std]
76
77pub use approx;
78pub use nalgebra;
79
80mod bound;
81mod clamp;
82mod delta;
83mod first;
84mod fixed;
85mod frame;
86mod image;
87mod orbit;
88mod plane;
89mod scale;
90mod scope;
91mod slide;
92mod touch;
93
94pub use bound::*;
95pub use clamp::*;
96pub use delta::*;
97pub use first::*;
98pub use fixed::*;
99pub use frame::*;
100pub use image::*;
101pub use orbit::*;
102pub use plane::*;
103pub use scale::*;
104pub use scope::*;
105pub use slide::*;
106pub use touch::*;