ncollide3d/utils/
isometry_ops.rs

1use crate::math::Vector;
2#[cfg(feature = "dim2")]
3use na::Isometry2;
4#[cfg(feature = "dim3")]
5use na::Isometry3;
6use na::{RealField, Unit};
7
8/// Extra operations with isometries.
9pub trait IsometryOps<N: RealField + Copy> {
10    /// Transform a vector by the absolute value of the homogeneous matrix
11    /// equivalent to `self`.
12    fn absolute_transform_vector(&self, v: &Vector<N>) -> Vector<N>;
13    /// Transform a unit vector by the inverse of `self`.
14    fn inverse_transform_unit_vector(&self, v: &Unit<Vector<N>>) -> Unit<Vector<N>>;
15    /// Interpolates between two isometries, using LERP for the translation part and SLERP for the rotation part.
16    fn lerp_slerp(&self, other: &Self, t: N) -> Self;
17}
18
19#[cfg(feature = "dim2")]
20impl<N: RealField + Copy> IsometryOps<N> for Isometry2<N> {
21    #[inline]
22    fn absolute_transform_vector(&self, v: &Vector<N>) -> Vector<N> {
23        self.rotation.to_rotation_matrix().into_inner().abs() * *v
24    }
25
26    #[inline]
27    fn inverse_transform_unit_vector(&self, v: &Unit<Vector<N>>) -> Unit<Vector<N>> {
28        let v = self.inverse_transform_vector(v.as_ref());
29        Unit::new_unchecked(v)
30    }
31
32    #[inline]
33    fn lerp_slerp(&self, other: &Self, t: N) -> Self {
34        let tr = self.translation.vector.lerp(&other.translation.vector, t);
35        let ang = self.rotation.angle() * (N::one() - t) + other.rotation.angle() * t;
36        Self::new(tr, ang)
37    }
38}
39
40#[cfg(feature = "dim3")]
41impl<N: RealField + Copy> IsometryOps<N> for Isometry3<N> {
42    #[inline]
43    fn absolute_transform_vector(&self, v: &Vector<N>) -> Vector<N> {
44        self.rotation.to_rotation_matrix().into_inner().abs() * *v
45    }
46
47    #[inline]
48    fn inverse_transform_unit_vector(&self, v: &Unit<Vector<N>>) -> Unit<Vector<N>> {
49        let v = self.inverse_transform_vector(v.as_ref());
50        Unit::new_unchecked(v)
51    }
52
53    #[inline]
54    fn lerp_slerp(&self, other: &Self, t: N) -> Self {
55        let tr = self.translation.vector.lerp(&other.translation.vector, t);
56        let rot = self.rotation.slerp(&other.rotation, t);
57        Self::from_parts(tr.into(), rot)
58    }
59}