1pub trait Tweenable: Copy + Send + Sync + 'static {
22 fn lerp(self, other: Self, t: f32) -> Self;
28}
29
30impl Tweenable for f32 {
33 #[inline(always)]
34 fn lerp(self, other: Self, t: f32) -> Self {
35 self + (other - self) * t
36 }
37}
38
39impl Tweenable for f64 {
40 #[inline(always)]
41 fn lerp(self, other: Self, t: f32) -> Self {
42 self + (other - self) * t as f64
43 }
44}
45
46impl Tweenable for i32 {
47 #[inline(always)]
48 fn lerp(self, other: Self, t: f32) -> Self {
49 (self as f32 + (other - self) as f32 * t).round() as i32
50 }
51}
52
53impl Tweenable for u32 {
54 #[inline(always)]
55 fn lerp(self, other: Self, t: f32) -> Self {
56 (self as f32 + (other as f32 - self as f32) * t).round() as u32
57 }
58}
59
60impl Tweenable for [f32; 2] {
63 #[inline(always)]
64 fn lerp(self, other: Self, t: f32) -> Self {
65 [
66 self[0] + (other[0] - self[0]) * t,
67 self[1] + (other[1] - self[1]) * t,
68 ]
69 }
70}
71
72impl Tweenable for [f32; 3] {
73 #[inline(always)]
74 fn lerp(self, other: Self, t: f32) -> Self {
75 [
76 self[0] + (other[0] - self[0]) * t,
77 self[1] + (other[1] - self[1]) * t,
78 self[2] + (other[2] - self[2]) * t,
79 ]
80 }
81}
82
83impl Tweenable for [f32; 4] {
84 #[inline(always)]
85 fn lerp(self, other: Self, t: f32) -> Self {
86 [
87 self[0] + (other[0] - self[0]) * t,
88 self[1] + (other[1] - self[1]) * t,
89 self[2] + (other[2] - self[2]) * t,
90 self[3] + (other[3] - self[3]) * t,
91 ]
92 }
93}
94
95impl Tweenable for [f64; 2] {
96 #[inline(always)]
97 fn lerp(self, other: Self, t: f32) -> Self {
98 let t = t as f64;
99
100 [
101 self[0] + (other[0] - self[0]) * t,
102 self[1] + (other[1] - self[1]) * t,
103 ]
104 }
105}
106
107impl Tweenable for [f64; 3] {
108 #[inline(always)]
109 fn lerp(self, other: Self, t: f32) -> Self {
110 let t = t as f64;
111
112 [
113 self[0] + (other[0] - self[0]) * t,
114 self[1] + (other[1] - self[1]) * t,
115 self[2] + (other[2] - self[2]) * t,
116 ]
117 }
118}
119
120impl Tweenable for [f64; 4] {
121 #[inline(always)]
122 fn lerp(self, other: Self, t: f32) -> Self {
123 let t = t as f64;
124
125 [
126 self[0] + (other[0] - self[0]) * t,
127 self[1] + (other[1] - self[1]) * t,
128 self[2] + (other[2] - self[2]) * t,
129 self[3] + (other[3] - self[3]) * t,
130 ]
131 }
132}
133
134impl Tweenable for (f32, f32) {
137 #[inline(always)]
138 fn lerp(self, other: Self, t: f32) -> Self {
139 (
140 self.0 + (other.0 - self.0) * t,
141 self.1 + (other.1 - self.1) * t,
142 )
143 }
144}
145
146impl Tweenable for (f32, f32, f32) {
147 #[inline(always)]
148 fn lerp(self, other: Self, t: f32) -> Self {
149 (
150 self.0 + (other.0 - self.0) * t,
151 self.1 + (other.1 - self.1) * t,
152 self.2 + (other.2 - self.2) * t,
153 )
154 }
155}
156
157impl Tweenable for (f32, f32, f32, f32) {
158 #[inline(always)]
159 fn lerp(self, other: Self, t: f32) -> Self {
160 (
161 self.0 + (other.0 - self.0) * t,
162 self.1 + (other.1 - self.1) * t,
163 self.2 + (other.2 - self.2) * t,
164 self.3 + (other.3 - self.3) * t,
165 )
166 }
167}
168
169#[cfg(test)]
170mod tests {
171 use super::*;
172
173 #[test]
174 fn test_f32_lerp() {
175 assert_eq!(0.0_f32.lerp(100.0, 0.0), 0.0);
176 assert_eq!(0.0_f32.lerp(100.0, 0.5), 50.0);
177 assert_eq!(0.0_f32.lerp(100.0, 1.0), 100.0);
178 }
179
180 #[test]
181 fn test_array_lerp() {
182 let a = [0.0_f32, 0.0, 0.0];
183 let b = [100.0_f32, 200.0, 300.0];
184 let mid = a.lerp(b, 0.5);
185
186 assert_eq!(mid, [50.0, 100.0, 150.0]);
187 }
188
189 #[test]
190 fn test_extrapolation() {
191 assert_eq!(0.0_f32.lerp(100.0, 1.5), 150.0);
193 assert_eq!(0.0_f32.lerp(100.0, -0.5), -50.0);
195 }
196}