bevy_math/cubic_splines/
curve_impls.rs

1use super::{CubicSegment, RationalSegment};
2use crate::common_traits::{VectorSpace, WithDerivative, WithTwoDerivatives};
3use crate::curve::{
4    derivatives::{SampleDerivative, SampleTwoDerivatives},
5    Curve, Interval,
6};
7
8#[cfg(feature = "alloc")]
9use super::{CubicCurve, RationalCurve};
10
11// -- CubicSegment
12
13impl<P: VectorSpace> Curve<P> for CubicSegment<P> {
14    #[inline]
15    fn domain(&self) -> Interval {
16        Interval::UNIT
17    }
18
19    #[inline]
20    fn sample_unchecked(&self, t: f32) -> P {
21        self.position(t)
22    }
23}
24
25impl<P: VectorSpace> SampleDerivative<P> for CubicSegment<P> {
26    #[inline]
27    fn sample_with_derivative_unchecked(&self, t: f32) -> WithDerivative<P> {
28        WithDerivative {
29            value: self.position(t),
30            derivative: self.velocity(t),
31        }
32    }
33}
34
35impl<P: VectorSpace> SampleTwoDerivatives<P> for CubicSegment<P> {
36    #[inline]
37    fn sample_with_two_derivatives_unchecked(&self, t: f32) -> WithTwoDerivatives<P> {
38        WithTwoDerivatives {
39            value: self.position(t),
40            derivative: self.velocity(t),
41            second_derivative: self.acceleration(t),
42        }
43    }
44}
45
46// -- CubicCurve
47
48#[cfg(feature = "alloc")]
49impl<P: VectorSpace> Curve<P> for CubicCurve<P> {
50    #[inline]
51    fn domain(&self) -> Interval {
52        // The non-emptiness invariant guarantees that this succeeds.
53        Interval::new(0.0, self.segments.len() as f32)
54            .expect("CubicCurve is invalid because it has no segments")
55    }
56
57    #[inline]
58    fn sample_unchecked(&self, t: f32) -> P {
59        self.position(t)
60    }
61}
62
63#[cfg(feature = "alloc")]
64impl<P: VectorSpace> SampleDerivative<P> for CubicCurve<P> {
65    #[inline]
66    fn sample_with_derivative_unchecked(&self, t: f32) -> WithDerivative<P> {
67        WithDerivative {
68            value: self.position(t),
69            derivative: self.velocity(t),
70        }
71    }
72}
73
74#[cfg(feature = "alloc")]
75impl<P: VectorSpace> SampleTwoDerivatives<P> for CubicCurve<P> {
76    #[inline]
77    fn sample_with_two_derivatives_unchecked(&self, t: f32) -> WithTwoDerivatives<P> {
78        WithTwoDerivatives {
79            value: self.position(t),
80            derivative: self.velocity(t),
81            second_derivative: self.acceleration(t),
82        }
83    }
84}
85
86// -- RationalSegment
87
88impl<P: VectorSpace> Curve<P> for RationalSegment<P> {
89    #[inline]
90    fn domain(&self) -> Interval {
91        Interval::UNIT
92    }
93
94    #[inline]
95    fn sample_unchecked(&self, t: f32) -> P {
96        self.position(t)
97    }
98}
99
100impl<P: VectorSpace> SampleDerivative<P> for RationalSegment<P> {
101    #[inline]
102    fn sample_with_derivative_unchecked(&self, t: f32) -> WithDerivative<P> {
103        WithDerivative {
104            value: self.position(t),
105            derivative: self.velocity(t),
106        }
107    }
108}
109
110impl<P: VectorSpace> SampleTwoDerivatives<P> for RationalSegment<P> {
111    #[inline]
112    fn sample_with_two_derivatives_unchecked(&self, t: f32) -> WithTwoDerivatives<P> {
113        WithTwoDerivatives {
114            value: self.position(t),
115            derivative: self.velocity(t),
116            second_derivative: self.acceleration(t),
117        }
118    }
119}
120
121// -- RationalCurve
122
123#[cfg(feature = "alloc")]
124impl<P: VectorSpace> Curve<P> for RationalCurve<P> {
125    #[inline]
126    fn domain(&self) -> Interval {
127        // The non-emptiness invariant guarantees the success of this.
128        Interval::new(0.0, self.length())
129            .expect("RationalCurve is invalid because it has zero length")
130    }
131
132    #[inline]
133    fn sample_unchecked(&self, t: f32) -> P {
134        self.position(t)
135    }
136}
137
138#[cfg(feature = "alloc")]
139impl<P: VectorSpace> SampleDerivative<P> for RationalCurve<P> {
140    #[inline]
141    fn sample_with_derivative_unchecked(&self, t: f32) -> WithDerivative<P> {
142        WithDerivative {
143            value: self.position(t),
144            derivative: self.velocity(t),
145        }
146    }
147}
148
149#[cfg(feature = "alloc")]
150impl<P: VectorSpace> SampleTwoDerivatives<P> for RationalCurve<P> {
151    #[inline]
152    fn sample_with_two_derivatives_unchecked(&self, t: f32) -> WithTwoDerivatives<P> {
153        WithTwoDerivatives {
154            value: self.position(t),
155            derivative: self.velocity(t),
156            second_derivative: self.acceleration(t),
157        }
158    }
159}