Skip to main content

rapier2d/utils/
pos_ops.rs

1//! SimdPose trait for pose (isometry) operations.
2
3use crate::math::SimdReal;
4use crate::math::{AngVector, Pose, Real, Rotation, Vector};
5use crate::utils::ScalarType;
6
7/// Trait for pose types (isometry) providing access to rotation and translation.
8pub trait PoseOps<N: ScalarType>: Copy {
9    /// Get the rotation component of this pose.
10    fn rotation(&self) -> N::Rotation;
11    /// Get the translation component of this pose as a vector.
12    fn translation(&self) -> N::Vector;
13    /// Set the translation component of this pose.
14    fn set_translation(&mut self, tra: N::Vector);
15    /// Prepend a translation to this pose.
16    fn prepend_translation(&self, translation: N::Vector) -> Self;
17    /// Append a translation to this pose.
18    fn append_translation(&self, translation: N::Vector) -> Self;
19    /// Prepend a rotation (as an axis-angle) to this pose.
20    fn prepend_rotation(&self, axisangle: N::AngVector) -> Self;
21    /// Append a rotation (as an axis-angle) to this pose.
22    fn append_rotation(&self, axisangle: N::AngVector) -> Self;
23}
24
25#[cfg(feature = "dim3")]
26impl PoseOps<SimdReal> for na::Isometry3<SimdReal> {
27    #[inline]
28    fn rotation(&self) -> na::UnitQuaternion<SimdReal> {
29        self.rotation
30    }
31    #[inline]
32    fn translation(&self) -> na::Vector3<SimdReal> {
33        self.translation.vector
34    }
35
36    #[inline]
37    fn set_translation(&mut self, tra: na::Vector3<SimdReal>) {
38        self.translation.vector = tra;
39    }
40
41    #[inline]
42    fn prepend_translation(&self, translation: na::Vector3<SimdReal>) -> Self {
43        self * na::Translation3::from(translation)
44    }
45
46    #[inline]
47    fn append_translation(&self, translation: na::Vector3<SimdReal>) -> Self {
48        na::Translation3::from(translation) * self
49    }
50
51    #[inline]
52    fn prepend_rotation(&self, rotation: na::Vector3<SimdReal>) -> Self {
53        self * na::UnitQuaternion::new(rotation)
54    }
55
56    #[inline]
57    fn append_rotation(&self, rotation: na::Vector3<SimdReal>) -> Self {
58        na::UnitQuaternion::new(rotation) * self
59    }
60}
61
62#[cfg(feature = "dim2")]
63impl PoseOps<SimdReal> for na::Isometry2<SimdReal> {
64    #[inline]
65    fn rotation(&self) -> na::UnitComplex<SimdReal> {
66        self.rotation
67    }
68    #[inline]
69    fn translation(&self) -> na::Vector2<SimdReal> {
70        self.translation.vector
71    }
72
73    #[inline]
74    fn set_translation(&mut self, tra: na::Vector2<SimdReal>) {
75        self.translation.vector = tra;
76    }
77
78    #[inline]
79    fn prepend_translation(&self, translation: na::Vector2<SimdReal>) -> Self {
80        self * na::Translation2::from(translation)
81    }
82
83    #[inline]
84    fn append_translation(&self, translation: na::Vector2<SimdReal>) -> Self {
85        na::Translation2::from(translation) * self
86    }
87
88    #[inline]
89    fn prepend_rotation(&self, rotation: SimdReal) -> Self {
90        self * na::UnitComplex::new(rotation)
91    }
92
93    #[inline]
94    fn append_rotation(&self, rotation: SimdReal) -> Self {
95        na::UnitComplex::new(rotation) * self
96    }
97}
98
99impl PoseOps<Real> for Pose {
100    #[inline]
101    fn rotation(&self) -> Rotation {
102        self.rotation
103    }
104    #[inline]
105    fn translation(&self) -> Vector {
106        self.translation
107    }
108
109    #[inline]
110    fn set_translation(&mut self, tra: Vector) {
111        self.translation = tra;
112    }
113
114    #[inline]
115    fn prepend_translation(&self, translation: Vector) -> Self {
116        (*self).prepend_translation(translation)
117    }
118
119    #[inline]
120    fn append_translation(&self, translation: Vector) -> Self {
121        (*self).append_translation(translation)
122    }
123
124    #[inline]
125    fn prepend_rotation(&self, rotation: AngVector) -> Self {
126        #[cfg(feature = "dim2")]
127        return *self * Rotation::from_angle(rotation);
128        #[cfg(feature = "dim3")]
129        return *self * Rotation::from_scaled_axis(rotation);
130    }
131
132    #[inline]
133    fn append_rotation(&self, rotation: AngVector) -> Self {
134        #[cfg(feature = "dim2")]
135        return Rotation::from_angle(rotation) * *self;
136        #[cfg(feature = "dim3")]
137        return Rotation::from_scaled_axis(rotation) * *self;
138    }
139}