1use libm::round;
2
3use crate::{
4 BBOX, BBox, BBox3D, GetXY, GetZ, JSONProperties, JSONValue, MValue, Point, Point3D,
5 PointOrPoint3D, PrimitiveValue, STPoint, Value, ValuePrimitive, ValuePrimitiveType, ValueType,
6 VectorPoint,
7};
8
9pub trait Interpolate {
11 fn interpolate(&self, other: &Self, t: f64) -> Self;
13}
14
15impl Interpolate for () {
18 fn interpolate(&self, _: &Self, _: f64) -> Self {}
19}
20macro_rules! impl_interpolate {
21 ($($t:ty),* $(,)?) => {
23 $(
24 impl Interpolate for $t {
25 fn interpolate(&self, other: &Self, t: f64) -> Self {
26 ((*self as f64) + ((*other as f64) - (*self as f64)) * t) as $t
27 }
28 }
29 )*
30 };
31
32 (round: $($t:ty),* $(,)?) => {
34 $(
35 impl Interpolate for $t {
36 fn interpolate(&self, other: &Self, t: f64) -> Self {
37 round((*self as f64) + ((*other as f64) - (*self as f64)) * t) as $t
38 }
39 }
40 )*
41 };
42}
43impl_interpolate!(f32);
44impl_interpolate!(round: usize, u8, u16, u32, u64, isize, i8, i16, i32, i64);
45impl Interpolate for f64 {
46 fn interpolate(&self, other: &Self, t: f64) -> Self {
47 self + (other - self) * t
48 }
49}
50impl<M: Interpolate> Interpolate for Option<M> {
51 fn interpolate(&self, other: &Self, t: f64) -> Self {
52 match (self, other) {
53 (Some(a), Some(b)) => Some(a.interpolate(b, t)),
54 _ => None,
55 }
56 }
57}
58
59impl Interpolate for Point {
62 fn interpolate(&self, other: &Self, t: f64) -> Self {
63 Point(self.x().interpolate(&other.x(), t), self.y().interpolate(&other.y(), t))
64 }
65}
66impl Interpolate for Point3D {
67 fn interpolate(&self, other: &Self, t: f64) -> Self {
68 Point3D(
69 self.0.interpolate(&other.0, t),
70 self.1.interpolate(&other.1, t),
71 self.2.interpolate(&other.2, t),
72 )
73 }
74}
75impl Interpolate for PointOrPoint3D {
76 fn interpolate(&self, other: &Self, t: f64) -> Self {
77 PointOrPoint3D(
78 self.x().interpolate(&other.x(), t),
79 self.y().interpolate(&other.y(), t),
80 self.z().interpolate(&other.z(), t),
81 )
82 }
83}
84impl<M: Interpolate> Interpolate for STPoint<M> {
85 fn interpolate(&self, other: &Self, t: f64) -> Self {
86 Self {
87 face: self.face,
88 s: self.s.interpolate(&other.s, t),
89 t: self.t.interpolate(&other.t, t),
90 z: self.z.interpolate(&other.z, t),
91 m: self.m.interpolate(&other.m, t),
92 }
93 }
94}
95impl<M: Interpolate + Clone> Interpolate for VectorPoint<M> {
96 fn interpolate(&self, other: &Self, t: f64) -> Self {
97 VectorPoint {
98 x: self.x.interpolate(&other.x, t),
99 y: self.y.interpolate(&other.y, t),
100 z: self.z.interpolate(&other.z, t),
101 m: self.m.interpolate(&other.m, t),
102 t: self.t.interpolate(&other.t, t),
103 }
104 }
105}
106
107impl Interpolate for Value {
110 fn interpolate(&self, other: &Self, t: f64) -> Self {
111 let mut res = MValue::new();
112
113 for (a, b) in self.iter().zip(other.iter()) {
115 res.insert(a.0.clone(), a.1.interpolate(b.1, t));
116 }
117 for (k, v) in self.iter() {
119 if !res.contains_key(k) {
120 res.insert(k.clone(), v.clone());
121 }
122 }
123 for (k, v) in other.iter() {
125 if !res.contains_key(k) {
126 res.insert(k.clone(), v.clone());
127 }
128 }
129
130 res
131 }
132}
133impl Interpolate for ValueType {
134 fn interpolate(&self, other: &Self, t: f64) -> Self {
135 match (self, other) {
136 (ValueType::Primitive(a), ValueType::Primitive(b)) => {
137 ValueType::Primitive(a.interpolate(b, t))
138 }
139 (ValueType::Array(a), ValueType::Array(b)) => {
140 ValueType::Array(a.iter().zip(b.iter()).map(|(a, b)| a.interpolate(b, t)).collect())
141 }
142 (ValueType::Nested(a), ValueType::Nested(b)) => ValueType::Nested(a.interpolate(b, t)),
143 _ => ValueType::Primitive(PrimitiveValue::Null),
144 }
145 }
146}
147impl Interpolate for ValuePrimitiveType {
148 fn interpolate(&self, other: &Self, t: f64) -> Self {
149 match (self, other) {
150 (ValuePrimitiveType::Primitive(a), ValuePrimitiveType::Primitive(b)) => {
151 ValuePrimitiveType::Primitive(a.interpolate(b, t))
152 }
153 (ValuePrimitiveType::NestedPrimitive(a), ValuePrimitiveType::NestedPrimitive(b)) => {
154 ValuePrimitiveType::NestedPrimitive(a.interpolate(b, t))
155 }
156 _ => ValuePrimitiveType::Primitive(PrimitiveValue::Null),
157 }
158 }
159}
160impl Interpolate for ValuePrimitive {
161 fn interpolate(&self, other: &Self, t: f64) -> Self {
162 let mut res = ValuePrimitive::new();
163
164 for (a, b) in self.iter().zip(other.iter()) {
166 res.insert(a.0.clone(), a.1.interpolate(b.1, t));
167 }
168 for (k, v) in self.iter() {
170 if !res.contains_key(k) {
171 res.insert(k.clone(), v.clone());
172 }
173 }
174 for (k, v) in other.iter() {
176 if !res.contains_key(k) {
177 res.insert(k.clone(), v.clone());
178 }
179 }
180
181 res
182 }
183}
184impl Interpolate for PrimitiveValue {
185 fn interpolate(&self, other: &Self, t: f64) -> Self {
186 match (self, other) {
187 (PrimitiveValue::U64(a), PrimitiveValue::U64(b)) => {
188 PrimitiveValue::U64(a.interpolate(b, t))
189 }
190 (PrimitiveValue::I64(a), PrimitiveValue::I64(b)) => {
191 PrimitiveValue::I64(a.interpolate(b, t))
192 }
193 (PrimitiveValue::F32(a), PrimitiveValue::F32(b)) => {
194 PrimitiveValue::F32(a.interpolate(b, t))
195 }
196 (PrimitiveValue::F64(a), PrimitiveValue::F64(b)) => {
197 PrimitiveValue::F64(a.interpolate(b, t))
198 }
199 (PrimitiveValue::String(a), PrimitiveValue::String(b)) => {
200 PrimitiveValue::String(if t <= 0.5 { a.clone() } else { b.clone() })
201 }
202 (PrimitiveValue::Bool(a), PrimitiveValue::Bool(b)) => {
203 PrimitiveValue::Bool(if t <= 0.5 { *a } else { *b })
204 }
205 _ => self.clone(),
206 }
207 }
208}
209
210impl Interpolate for JSONProperties {
213 fn interpolate(&self, other: &Self, t: f64) -> Self {
214 let mut res = JSONProperties::new();
215
216 for (a, b) in self.iter().zip(other.iter()) {
218 res.insert(a.0.clone(), a.1.interpolate(b.1, t));
219 }
220 for (k, v) in self.iter() {
222 if !res.contains_key(k) {
223 res.insert(k.clone(), v.clone());
224 }
225 }
226 for (k, v) in other.iter() {
228 if !res.contains_key(k) {
229 res.insert(k.clone(), v.clone());
230 }
231 }
232
233 res
234 }
235}
236impl Interpolate for JSONValue {
237 fn interpolate(&self, other: &Self, t: f64) -> Self {
238 match (self, other) {
239 (JSONValue::Primitive(a), JSONValue::Primitive(b)) => {
240 JSONValue::Primitive(a.interpolate(b, t))
241 }
242 (JSONValue::Array(a), JSONValue::Array(b)) => {
243 JSONValue::Array(a.iter().zip(b.iter()).map(|(a, b)| a.interpolate(b, t)).collect())
244 }
245 (JSONValue::Object(a), JSONValue::Object(b)) => JSONValue::Object(a.interpolate(b, t)),
246 _ => JSONValue::Primitive(PrimitiveValue::Null),
247 }
248 }
249}
250
251impl<T: Interpolate> Interpolate for BBox<T> {
254 fn interpolate(&self, other: &Self, t: f64) -> Self {
255 BBox {
256 left: self.left.interpolate(&other.left, t),
257 bottom: self.bottom.interpolate(&other.bottom, t),
258 right: self.right.interpolate(&other.right, t),
259 top: self.top.interpolate(&other.top, t),
260 }
261 }
262}
263impl<T: Interpolate> Interpolate for BBox3D<T> {
264 fn interpolate(&self, other: &Self, t: f64) -> Self {
265 BBox3D {
266 left: self.left.interpolate(&other.left, t),
267 bottom: self.bottom.interpolate(&other.bottom, t),
268 right: self.right.interpolate(&other.right, t),
269 top: self.top.interpolate(&other.top, t),
270 near: self.near.interpolate(&other.near, t),
271 far: self.far.interpolate(&other.far, t),
272 }
273 }
274}
275impl Interpolate for BBOX {
276 fn interpolate(&self, other: &Self, t: f64) -> Self {
277 match (self, other) {
278 (BBOX::BBox(a), BBOX::BBox(b)) => a.interpolate(b, t).into(),
279 (BBOX::BBox3D(a), BBOX::BBox3D(b)) => a.interpolate(b, t).into(),
280 (BBOX::BBox(_), BBOX::BBox3D(_)) => *self,
282 (BBOX::BBox3D(_), BBOX::BBox(_)) => *self,
283 }
284 }
285}