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
use nalgebra::{convert, Point2, RealField, Unit, Vector2, Vector3}; /// First person view induced by displacement on screen. /// /// Implements [`Default`] and can be created with `First::default()`. /// /// All methods except [`Self::enabled()`] must be invoked on matching events fired by your 3D /// graphics library of choice. #[derive(Debug, Clone, Default)] pub struct First<N: RealField> { /// Caches captured yaw axis. ray: Option<Unit<Vector3<N>>>, } impl<N: RealField> First<N> { /// Captures current yaw axis when entering first person view. pub fn capture(&mut self, yaw_axis: Unit<Vector3<N>>) { self.ray = Some(yaw_axis); } /// Computes pitch and yaw from cursor/finger displacement vector in screen space. /// /// Carries cursor/finger displacements to arcs of the same length on great circles of an /// eye-centered trackball with radius of maximum of half the screen's width and height in /// compliance with [`crate::Orbit`] except that its trackball is target-centered. pub fn compute( &mut self, vec: &Vector2<N>, max: &Point2<N>, ) -> Option<(N, N, &Unit<Vector3<N>>)> { self.ray.as_ref().map(|ray| { let max = max.x.max(max.y) * convert(0.5); (vec.y / max, vec.x / max, ray) }) } /// Discards captured yaw axis when leaving first person view. pub fn discard(&mut self) { self.ray = None; } /// Whether a yaw axis has been captured. pub fn enabled(&self) -> bool { self.ray.is_some() } }