ncollide3d/interpolation/
rigid_motion.rs1use na::RealField;
2
3use crate::math::{Isometry, Point, Translation, Vector};
4
5pub trait RigidMotion<N: RealField + Copy> {
11 fn position_at_time(&self, t: N) -> Isometry<N>;
13}
14
15impl<N: RealField + Copy> RigidMotion<N> for Isometry<N> {
16 fn position_at_time(&self, _: N) -> Isometry<N> {
17 *self
18 }
19}
20
21pub struct InterpolatedRigidMotion<N: RealField + Copy> {
23 pub start: Isometry<N>,
25 pub end: Isometry<N>,
27}
28
29impl<N: RealField + Copy> InterpolatedRigidMotion<N> {
30 pub fn new(start: Isometry<N>, end: Isometry<N>) -> Self {
35 InterpolatedRigidMotion { start, end }
36 }
37}
38
39impl<N: RealField + Copy> RigidMotion<N> for InterpolatedRigidMotion<N> {
40 fn position_at_time(&self, t: N) -> Isometry<N> {
41 self.start.lerp_slerp(&self.end, t)
42 }
43}
44
45pub struct ConstantLinearVelocityRigidMotion<N: RealField + Copy> {
47 pub t0: N,
49 pub start: Isometry<N>,
51 pub velocity: Vector<N>,
53}
54
55impl<N: RealField + Copy> ConstantLinearVelocityRigidMotion<N> {
56 pub fn new(t0: N, start: Isometry<N>, velocity: Vector<N>) -> Self {
58 ConstantLinearVelocityRigidMotion {
59 t0,
60 start,
61 velocity,
62 }
63 }
64}
65
66impl<N: RealField + Copy> RigidMotion<N> for ConstantLinearVelocityRigidMotion<N> {
67 fn position_at_time(&self, t: N) -> Isometry<N> {
68 Isometry::from_parts(
69 (self.start.translation.vector + self.velocity * (t - self.t0)).into(),
70 self.start.rotation,
71 )
72 }
73}
74
75#[derive(Debug)]
77pub struct ConstantVelocityRigidMotion<N: RealField + Copy> {
78 pub t0: N,
80 pub start: Isometry<N>,
82 pub local_center: Point<N>,
84 pub linvel: Vector<N>,
86 #[cfg(feature = "dim2")]
88 pub angvel: N,
89 #[cfg(feature = "dim3")]
91 pub angvel: Vector<N>,
92}
93
94impl<N: RealField + Copy> ConstantVelocityRigidMotion<N> {
95 #[cfg(feature = "dim2")]
97 pub fn new(
98 t0: N,
99 start: Isometry<N>,
100 local_center: Point<N>,
101 linvel: Vector<N>,
102 angvel: N,
103 ) -> Self {
104 ConstantVelocityRigidMotion {
105 t0,
106 start,
107 local_center,
108 linvel,
109 angvel,
110 }
111 }
112
113 #[cfg(feature = "dim3")]
115 pub fn new(
116 t0: N,
117 start: Isometry<N>,
118 local_center: Point<N>,
119 linvel: Vector<N>,
120 angvel: Vector<N>,
121 ) -> Self {
122 ConstantVelocityRigidMotion {
123 t0,
124 start,
125 local_center,
126 linvel,
127 angvel,
128 }
129 }
130}
131
132impl<N: RealField + Copy> RigidMotion<N> for ConstantVelocityRigidMotion<N> {
133 fn position_at_time(&self, t: N) -> Isometry<N> {
134 let scaled_linvel = self.linvel * (t - self.t0);
135 let scaled_angvel = self.angvel * (t - self.t0);
136
137 let center = self.start.rotation * self.local_center.coords;
138 let lhs = self.start.translation * Translation::from(center);
139 let rhs = Translation::from(-center) * self.start.rotation;
140
141 lhs * Isometry::new(scaled_linvel, scaled_angvel) * rhs
142 }
143}
144
145pub trait RigidMotionComposition<N: RealField + Copy>: RigidMotion<N> {
151 fn prepend_translation(&self, translation: Vector<N>) -> PrependTranslation<N, Self> {
153 PrependTranslation {
154 motion: self,
155 translation,
156 }
157 }
158
159 fn prepend_transformation(
161 &self,
162 transformation: Isometry<N>,
163 ) -> PrependTransformation<N, Self> {
164 PrependTransformation {
165 motion: self,
166 transformation,
167 }
168 }
169}
170
171impl<N: RealField + Copy, M: ?Sized + RigidMotion<N>> RigidMotionComposition<N> for M {}
172
173pub struct PrependTranslation<'a, N: RealField + Copy, M: ?Sized> {
175 motion: &'a M,
176 translation: Vector<N>,
177}
178
179impl<'a, N: RealField + Copy, M: ?Sized + RigidMotion<N>> RigidMotion<N>
180 for PrependTranslation<'a, N, M>
181{
182 fn position_at_time(&self, t: N) -> Isometry<N> {
183 let m = self.motion.position_at_time(t);
184 m * Translation::from(self.translation)
185 }
186}
187
188pub struct PrependTransformation<'a, N: RealField + Copy, M: ?Sized> {
190 motion: &'a M,
191 transformation: Isometry<N>,
192}
193
194impl<'a, N: RealField + Copy, M: ?Sized + RigidMotion<N>> RigidMotion<N>
195 for PrependTransformation<'a, N, M>
196{
197 fn position_at_time(&self, t: N) -> Isometry<N> {
198 let m = self.motion.position_at_time(t);
199 m * self.transformation
200 }
201}