1use crate::{
2 macros::{impl_animated_data_insert, impl_data_type_ops, impl_sample_for_animated_data},
3 time_data_map::TimeDataMapControl,
4 *,
5};
6use anyhow::Result;
7use core::num::NonZeroU16;
8use enum_dispatch::enum_dispatch;
9use smallvec::SmallVec;
10use std::hash::Hasher;
11
12#[enum_dispatch(AnimatedDataOps)]
18#[derive(Debug, Clone, PartialEq, Eq)]
19#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
20#[cfg_attr(feature = "facet", derive(Facet))]
21#[cfg_attr(feature = "facet", facet(opaque))]
22#[cfg_attr(feature = "facet", repr(u8))]
23pub enum AnimatedData {
24 Boolean(TimeDataMap<Boolean>),
26 Integer(TimeDataMap<Integer>),
28 Real(TimeDataMap<Real>),
30 String(TimeDataMap<String>),
32 Color(TimeDataMap<Color>),
34 #[cfg(feature = "vector2")]
36 Vector2(TimeDataMap<Vector2>),
37 #[cfg(feature = "vector3")]
39 Vector3(TimeDataMap<Vector3>),
40 #[cfg(feature = "matrix3")]
42 Matrix3(TimeDataMap<Matrix3>),
43 #[cfg(feature = "normal3")]
45 Normal3(TimeDataMap<Normal3>),
46 #[cfg(feature = "point3")]
48 Point3(TimeDataMap<Point3>),
49 #[cfg(feature = "matrix4")]
51 Matrix4(TimeDataMap<Matrix4>),
52 BooleanVec(TimeDataMap<BooleanVec>),
54 IntegerVec(TimeDataMap<IntegerVec>),
56 RealVec(TimeDataMap<RealVec>),
58 ColorVec(TimeDataMap<ColorVec>),
60 StringVec(TimeDataMap<StringVec>),
62 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
64 Vector2Vec(TimeDataMap<Vector2Vec>),
65 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
67 Vector3Vec(TimeDataMap<Vector3Vec>),
68 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
70 Matrix3Vec(TimeDataMap<Matrix3Vec>),
71 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
73 Normal3Vec(TimeDataMap<Normal3Vec>),
74 #[cfg(all(feature = "point3", feature = "vec_variants"))]
76 Point3Vec(TimeDataMap<Point3Vec>),
77 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
79 Matrix4Vec(TimeDataMap<Matrix4Vec>),
80}
81
82#[enum_dispatch]
84pub trait AnimatedDataOps {
85 fn len(&self) -> usize;
87 fn is_empty(&self) -> bool;
89 fn is_animated(&self) -> bool;
91}
92
93impl<T> AnimatedDataOps for TimeDataMap<T> {
94 fn len(&self) -> usize {
95 self.values.len()
96 }
97
98 fn is_empty(&self) -> bool {
99 self.values.is_empty()
100 }
101
102 fn is_animated(&self) -> bool {
103 self.values.len() > 1
104 }
105}
106
107impl_data_type_ops!(AnimatedData);
108
109impl AnimatedData {
110 pub fn times(&self) -> SmallVec<[Time; 10]> {
112 match self {
113 AnimatedData::Boolean(map) => map.iter().map(|(t, _)| *t).collect(),
114 AnimatedData::Integer(map) => map.iter().map(|(t, _)| *t).collect(),
115 AnimatedData::Real(map) => map.iter().map(|(t, _)| *t).collect(),
116 AnimatedData::String(map) => map.iter().map(|(t, _)| *t).collect(),
117 AnimatedData::Color(map) => map.iter().map(|(t, _)| *t).collect(),
118 #[cfg(feature = "vector2")]
119 AnimatedData::Vector2(map) => map.iter().map(|(t, _)| *t).collect(),
120 #[cfg(feature = "vector3")]
121 AnimatedData::Vector3(map) => map.iter().map(|(t, _)| *t).collect(),
122 #[cfg(feature = "matrix3")]
123 AnimatedData::Matrix3(map) => map.iter().map(|(t, _)| *t).collect(),
124 #[cfg(feature = "normal3")]
125 AnimatedData::Normal3(map) => map.iter().map(|(t, _)| *t).collect(),
126 #[cfg(feature = "point3")]
127 AnimatedData::Point3(map) => map.iter().map(|(t, _)| *t).collect(),
128 #[cfg(feature = "matrix4")]
129 AnimatedData::Matrix4(map) => map.iter().map(|(t, _)| *t).collect(),
130 AnimatedData::BooleanVec(map) => map.iter().map(|(t, _)| *t).collect(),
131 AnimatedData::IntegerVec(map) => map.iter().map(|(t, _)| *t).collect(),
132 AnimatedData::RealVec(map) => map.iter().map(|(t, _)| *t).collect(),
133 AnimatedData::ColorVec(map) => map.iter().map(|(t, _)| *t).collect(),
134 AnimatedData::StringVec(map) => map.iter().map(|(t, _)| *t).collect(),
135 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
136 AnimatedData::Vector2Vec(map) => map.iter().map(|(t, _)| *t).collect(),
137 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
138 AnimatedData::Vector3Vec(map) => map.iter().map(|(t, _)| *t).collect(),
139 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
140 AnimatedData::Matrix3Vec(map) => map.iter().map(|(t, _)| *t).collect(),
141 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
142 AnimatedData::Normal3Vec(map) => map.iter().map(|(t, _)| *t).collect(),
143 #[cfg(all(feature = "point3", feature = "vec_variants"))]
144 AnimatedData::Point3Vec(map) => map.iter().map(|(t, _)| *t).collect(),
145 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
146 AnimatedData::Matrix4Vec(map) => map.iter().map(|(t, _)| *t).collect(),
147 }
148 }
149}
150
151impl From<(Time, Value)> for AnimatedData {
152 fn from((time, value): (Time, Value)) -> Self {
153 match value {
154 Value::Uniform(data) => AnimatedData::from((time, data)),
155 Value::Animated(animated_data) => {
156 animated_data
161 }
162 }
163 }
164}
165
166impl From<(Time, Data)> for AnimatedData {
167 fn from((time, data): (Time, Data)) -> Self {
168 match data {
169 Data::Boolean(v) => AnimatedData::Boolean(TimeDataMap::from((time, v))),
170 Data::Integer(v) => AnimatedData::Integer(TimeDataMap::from((time, v))),
171 Data::Real(v) => AnimatedData::Real(TimeDataMap::from((time, v))),
172 Data::String(v) => AnimatedData::String(TimeDataMap::from((time, v))),
173 Data::Color(v) => AnimatedData::Color(TimeDataMap::from((time, v))),
174 #[cfg(feature = "vector2")]
175 Data::Vector2(v) => AnimatedData::Vector2(TimeDataMap::from((time, v))),
176 #[cfg(feature = "vector3")]
177 Data::Vector3(v) => AnimatedData::Vector3(TimeDataMap::from((time, v))),
178 #[cfg(feature = "matrix3")]
179 Data::Matrix3(v) => AnimatedData::Matrix3(TimeDataMap::from((time, v))),
180 #[cfg(feature = "normal3")]
181 Data::Normal3(v) => AnimatedData::Normal3(TimeDataMap::from((time, v))),
182 #[cfg(feature = "point3")]
183 Data::Point3(v) => AnimatedData::Point3(TimeDataMap::from((time, v))),
184 #[cfg(feature = "matrix4")]
185 Data::Matrix4(v) => AnimatedData::Matrix4(TimeDataMap::from((time, v))),
186 Data::BooleanVec(v) => AnimatedData::BooleanVec(TimeDataMap::from((time, v))),
187 Data::IntegerVec(v) => AnimatedData::IntegerVec(TimeDataMap::from((time, v))),
188 Data::RealVec(v) => AnimatedData::RealVec(TimeDataMap::from((time, v))),
189 Data::ColorVec(v) => AnimatedData::ColorVec(TimeDataMap::from((time, v))),
190 Data::StringVec(v) => AnimatedData::StringVec(TimeDataMap::from((time, v))),
191 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
192 Data::Vector2Vec(v) => AnimatedData::Vector2Vec(TimeDataMap::from((time, v))),
193 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
194 Data::Vector3Vec(v) => AnimatedData::Vector3Vec(TimeDataMap::from((time, v))),
195 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
196 Data::Matrix3Vec(v) => AnimatedData::Matrix3Vec(TimeDataMap::from((time, v))),
197 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
198 Data::Normal3Vec(v) => AnimatedData::Normal3Vec(TimeDataMap::from((time, v))),
199 #[cfg(all(feature = "point3", feature = "vec_variants"))]
200 Data::Point3Vec(v) => AnimatedData::Point3Vec(TimeDataMap::from((time, v))),
201 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
202 Data::Matrix4Vec(v) => AnimatedData::Matrix4Vec(TimeDataMap::from((time, v))),
203 }
204 }
205}
206
207impl_animated_data_insert!(
208 insert_boolean, Boolean, Boolean;
209 insert_integer, Integer, Integer;
210 insert_real, Real, Real;
211 insert_string, String, String;
212 insert_color, Color, Color;
213);
214
215#[cfg(feature = "vector2")]
216impl_animated_data_insert!(
217 insert_vector2, Vector2, Vector2;
218);
219
220#[cfg(feature = "vector3")]
221impl_animated_data_insert!(
222 insert_vector3, Vector3, Vector3;
223);
224
225#[cfg(feature = "matrix3")]
226impl_animated_data_insert!(
227 insert_matrix3, Matrix3, Matrix3;
228);
229
230#[cfg(feature = "normal3")]
231impl_animated_data_insert!(
232 insert_normal3, Normal3, Normal3;
233);
234
235#[cfg(feature = "point3")]
236impl_animated_data_insert!(
237 insert_point3, Point3, Point3;
238);
239
240#[cfg(feature = "matrix4")]
241impl_animated_data_insert!(
242 insert_matrix4, Matrix4, Matrix4;
243);
244
245impl AnimatedData {
246 #[named]
249 pub fn try_insert(&mut self, time: Time, value: Data) -> Result<()> {
250 match (self, value) {
251 (AnimatedData::Boolean(map), Data::Boolean(v)) => {
252 map.insert(time, v);
253 Ok(())
254 }
255 (AnimatedData::Integer(map), Data::Integer(v)) => {
256 map.insert(time, v);
257 Ok(())
258 }
259 (AnimatedData::Real(map), Data::Real(v)) => {
260 map.insert(time, v);
261 Ok(())
262 }
263 (AnimatedData::String(map), Data::String(v)) => {
264 map.insert(time, v);
265 Ok(())
266 }
267 (AnimatedData::Color(map), Data::Color(v)) => {
268 map.insert(time, v);
269 Ok(())
270 }
271 #[cfg(feature = "vector2")]
272 (AnimatedData::Vector2(map), Data::Vector2(v)) => {
273 map.insert(time, v);
274 Ok(())
275 }
276 #[cfg(feature = "vector3")]
277 (AnimatedData::Vector3(map), Data::Vector3(v)) => {
278 map.insert(time, v);
279 Ok(())
280 }
281 #[cfg(feature = "matrix3")]
282 (AnimatedData::Matrix3(map), Data::Matrix3(v)) => {
283 map.insert(time, v);
284 Ok(())
285 }
286 #[cfg(feature = "normal3")]
287 (AnimatedData::Normal3(map), Data::Normal3(v)) => {
288 map.insert(time, v);
289 Ok(())
290 }
291 #[cfg(feature = "point3")]
292 (AnimatedData::Point3(map), Data::Point3(v)) => {
293 map.insert(time, v);
294 Ok(())
295 }
296 #[cfg(feature = "matrix4")]
297 (AnimatedData::Matrix4(map), Data::Matrix4(v)) => {
298 map.insert(time, v);
299 Ok(())
300 }
301 (AnimatedData::BooleanVec(map), Data::BooleanVec(v)) => {
302 map.insert(time, v);
303 Ok(())
304 }
305 (AnimatedData::IntegerVec(map), Data::IntegerVec(v)) => {
306 map.insert(time, v);
307 Ok(())
308 }
309 (AnimatedData::RealVec(map), Data::RealVec(v)) => {
310 map.insert(time, v);
311 Ok(())
312 }
313 (AnimatedData::ColorVec(map), Data::ColorVec(v)) => {
314 map.insert(time, v);
315 Ok(())
316 }
317 (AnimatedData::StringVec(map), Data::StringVec(v)) => {
318 map.insert(time, v);
319 Ok(())
320 }
321 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
322 (AnimatedData::Vector2Vec(map), Data::Vector2Vec(v)) => {
323 map.insert(time, v);
324 Ok(())
325 }
326 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
327 (AnimatedData::Vector3Vec(map), Data::Vector3Vec(v)) => {
328 map.insert(time, v);
329 Ok(())
330 }
331 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
332 (AnimatedData::Matrix3Vec(map), Data::Matrix3Vec(v)) => {
333 map.insert(time, v);
334 Ok(())
335 }
336 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
337 (AnimatedData::Normal3Vec(map), Data::Normal3Vec(v)) => {
338 map.insert(time, v);
339 Ok(())
340 }
341 #[cfg(all(feature = "point3", feature = "vec_variants"))]
342 (AnimatedData::Point3Vec(map), Data::Point3Vec(v)) => {
343 map.insert(time, v);
344 Ok(())
345 }
346 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
347 (AnimatedData::Matrix4Vec(map), Data::Matrix4Vec(v)) => {
348 map.insert(time, v);
349 Ok(())
350 }
351 (s, v) => Err(anyhow!(
352 "{}: type mismatch: {:?} variant does not match {:?} type",
353 function_name!(),
354 s.data_type(),
355 v.data_type()
356 )),
357 }
358 }
359
360 pub fn remove_at(&mut self, time: &Time) -> Option<Data> {
364 match self {
365 AnimatedData::Boolean(map) => map.remove(time).map(Data::Boolean),
366 AnimatedData::Integer(map) => map.remove(time).map(Data::Integer),
367 AnimatedData::Real(map) => map.remove(time).map(Data::Real),
368 AnimatedData::String(map) => map.remove(time).map(Data::String),
369 AnimatedData::Color(map) => map.remove(time).map(Data::Color),
370 #[cfg(feature = "vector2")]
371 AnimatedData::Vector2(map) => map.remove(time).map(Data::Vector2),
372 #[cfg(feature = "vector3")]
373 AnimatedData::Vector3(map) => map.remove(time).map(Data::Vector3),
374 #[cfg(feature = "matrix3")]
375 AnimatedData::Matrix3(map) => map.remove(time).map(Data::Matrix3),
376 #[cfg(feature = "normal3")]
377 AnimatedData::Normal3(map) => map.remove(time).map(Data::Normal3),
378 #[cfg(feature = "point3")]
379 AnimatedData::Point3(map) => map.remove(time).map(Data::Point3),
380 #[cfg(feature = "matrix4")]
381 AnimatedData::Matrix4(map) => map.remove(time).map(Data::Matrix4),
382 AnimatedData::BooleanVec(map) => map.remove(time).map(Data::BooleanVec),
383 AnimatedData::IntegerVec(map) => map.remove(time).map(Data::IntegerVec),
384 AnimatedData::RealVec(map) => map.remove(time).map(Data::RealVec),
385 AnimatedData::ColorVec(map) => map.remove(time).map(Data::ColorVec),
386 AnimatedData::StringVec(map) => map.remove(time).map(Data::StringVec),
387 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
388 AnimatedData::Vector2Vec(map) => map.remove(time).map(Data::Vector2Vec),
389 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
390 AnimatedData::Vector3Vec(map) => map.remove(time).map(Data::Vector3Vec),
391 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
392 AnimatedData::Matrix3Vec(map) => map.remove(time).map(Data::Matrix3Vec),
393 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
394 AnimatedData::Normal3Vec(map) => map.remove(time).map(Data::Normal3Vec),
395 #[cfg(all(feature = "point3", feature = "vec_variants"))]
396 AnimatedData::Point3Vec(map) => map.remove(time).map(Data::Point3Vec),
397 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
398 AnimatedData::Matrix4Vec(map) => map.remove(time).map(Data::Matrix4Vec),
399 }
400 }
401
402 pub fn sample_at(&self, time: Time) -> Option<Data> {
403 match self {
404 AnimatedData::Boolean(map) => map.get(&time).map(|v| Data::Boolean(v.clone())),
405 AnimatedData::Integer(map) => map.get(&time).map(|v| Data::Integer(v.clone())),
406 AnimatedData::Real(map) => map.get(&time).map(|v| Data::Real(v.clone())),
407 AnimatedData::String(map) => map.get(&time).map(|v| Data::String(v.clone())),
408 AnimatedData::Color(map) => map.get(&time).map(|v| Data::Color(v.clone())),
409 #[cfg(feature = "vector2")]
410 AnimatedData::Vector2(map) => map.get(&time).map(|v| Data::Vector2(v.clone())),
411 #[cfg(feature = "vector3")]
412 AnimatedData::Vector3(map) => map.get(&time).map(|v| Data::Vector3(v.clone())),
413 #[cfg(feature = "matrix3")]
414 AnimatedData::Matrix3(map) => map.get(&time).map(|v| Data::Matrix3(v.clone())),
415 #[cfg(feature = "normal3")]
416 AnimatedData::Normal3(map) => map.get(&time).map(|v| Data::Normal3(v.clone())),
417 #[cfg(feature = "point3")]
418 AnimatedData::Point3(map) => map.get(&time).map(|v| Data::Point3(v.clone())),
419 #[cfg(feature = "matrix4")]
420 AnimatedData::Matrix4(map) => map.get(&time).map(|v| Data::Matrix4(v.clone())),
421 AnimatedData::BooleanVec(map) => map.get(&time).map(|v| Data::BooleanVec(v.clone())),
422 AnimatedData::IntegerVec(map) => map.get(&time).map(|v| Data::IntegerVec(v.clone())),
423 AnimatedData::RealVec(map) => map.get(&time).map(|v| Data::RealVec(v.clone())),
424 AnimatedData::ColorVec(map) => map.get(&time).map(|v| Data::ColorVec(v.clone())),
425 AnimatedData::StringVec(map) => map.get(&time).map(|v| Data::StringVec(v.clone())),
426 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
427 AnimatedData::Vector2Vec(map) => map.get(&time).map(|v| Data::Vector2Vec(v.clone())),
428 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
429 AnimatedData::Vector3Vec(map) => map.get(&time).map(|v| Data::Vector3Vec(v.clone())),
430 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
431 AnimatedData::Matrix3Vec(map) => map.get(&time).map(|v| Data::Matrix3Vec(v.clone())),
432 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
433 AnimatedData::Normal3Vec(map) => map.get(&time).map(|v| Data::Normal3Vec(v.clone())),
434 #[cfg(all(feature = "point3", feature = "vec_variants"))]
435 AnimatedData::Point3Vec(map) => map.get(&time).map(|v| Data::Point3Vec(v.clone())),
436 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
437 AnimatedData::Matrix4Vec(map) => map.get(&time).map(|v| Data::Matrix4Vec(v.clone())),
438 }
439 }
440
441 pub fn interpolate(&self, time: Time) -> Data {
442 match self {
443 AnimatedData::Boolean(map) => Data::Boolean(map.closest_sample(time).clone()),
444 AnimatedData::Integer(map) => {
445 if TimeDataMapControl::is_animated(map) {
446 Data::Integer(map.interpolate(time))
447 } else {
448 Data::Integer(map.iter().next().unwrap().1.clone())
449 }
450 }
451 AnimatedData::Real(map) => {
452 if TimeDataMapControl::is_animated(map) {
453 Data::Real(map.interpolate(time))
454 } else {
455 Data::Real(map.iter().next().unwrap().1.clone())
456 }
457 }
458 AnimatedData::String(map) => Data::String(map.closest_sample(time).clone()),
459 AnimatedData::Color(map) => {
460 if TimeDataMapControl::is_animated(map) {
461 Data::Color(map.interpolate(time))
462 } else {
463 Data::Color(map.iter().next().unwrap().1.clone())
464 }
465 }
466 #[cfg(feature = "vector2")]
467 AnimatedData::Vector2(map) => {
468 if TimeDataMapControl::is_animated(map) {
469 Data::Vector2(map.interpolate(time))
470 } else {
471 Data::Vector2(map.iter().next().unwrap().1.clone())
472 }
473 }
474 #[cfg(feature = "vector3")]
475 AnimatedData::Vector3(map) => {
476 if TimeDataMapControl::is_animated(map) {
477 Data::Vector3(map.interpolate(time))
478 } else {
479 Data::Vector3(map.iter().next().unwrap().1.clone())
480 }
481 }
482 #[cfg(feature = "matrix3")]
483 AnimatedData::Matrix3(map) => {
484 if TimeDataMapControl::is_animated(map) {
485 Data::Matrix3(map.interpolate(time))
486 } else {
487 Data::Matrix3(map.iter().next().unwrap().1.clone())
488 }
489 }
490 #[cfg(feature = "normal3")]
491 AnimatedData::Normal3(map) => {
492 if TimeDataMapControl::is_animated(map) {
493 Data::Normal3(map.interpolate(time))
494 } else {
495 Data::Normal3(map.iter().next().unwrap().1.clone())
496 }
497 }
498 #[cfg(feature = "point3")]
499 AnimatedData::Point3(map) => {
500 if TimeDataMapControl::is_animated(map) {
501 Data::Point3(map.interpolate(time))
502 } else {
503 Data::Point3(map.iter().next().unwrap().1.clone())
504 }
505 }
506 #[cfg(feature = "matrix4")]
507 AnimatedData::Matrix4(map) => {
508 if TimeDataMapControl::is_animated(map) {
509 Data::Matrix4(map.interpolate(time))
510 } else {
511 Data::Matrix4(map.iter().next().unwrap().1.clone())
512 }
513 }
514 AnimatedData::BooleanVec(map) => Data::BooleanVec(map.closest_sample(time).clone()),
515 AnimatedData::IntegerVec(map) => {
516 if TimeDataMapControl::is_animated(map) {
517 Data::IntegerVec(map.interpolate(time))
518 } else {
519 Data::IntegerVec(map.iter().next().unwrap().1.clone())
520 }
521 }
522 AnimatedData::RealVec(map) => {
523 if TimeDataMapControl::is_animated(map) {
524 Data::RealVec(map.interpolate(time))
525 } else {
526 Data::RealVec(map.iter().next().unwrap().1.clone())
527 }
528 }
529 AnimatedData::ColorVec(map) => {
530 if TimeDataMapControl::is_animated(map) {
531 Data::ColorVec(map.interpolate(time))
532 } else {
533 Data::ColorVec(map.iter().next().unwrap().1.clone())
534 }
535 }
536 AnimatedData::StringVec(map) => Data::StringVec(map.closest_sample(time).clone()),
537 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
538 AnimatedData::Vector2Vec(map) => {
539 if TimeDataMapControl::is_animated(map) {
540 Data::Vector2Vec(map.interpolate(time))
541 } else {
542 Data::Vector2Vec(map.iter().next().unwrap().1.clone())
543 }
544 }
545 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
546 AnimatedData::Vector3Vec(map) => {
547 if TimeDataMapControl::is_animated(map) {
548 Data::Vector3Vec(map.interpolate(time))
549 } else {
550 Data::Vector3Vec(map.iter().next().unwrap().1.clone())
551 }
552 }
553 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
554 AnimatedData::Matrix3Vec(map) => {
555 if TimeDataMapControl::is_animated(map) {
556 Data::Matrix3Vec(map.interpolate(time))
557 } else {
558 Data::Matrix3Vec(map.iter().next().unwrap().1.clone())
559 }
560 }
561 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
562 AnimatedData::Normal3Vec(map) => {
563 if TimeDataMapControl::is_animated(map) {
564 Data::Normal3Vec(map.interpolate(time))
565 } else {
566 Data::Normal3Vec(map.iter().next().unwrap().1.clone())
567 }
568 }
569 #[cfg(all(feature = "point3", feature = "vec_variants"))]
570 AnimatedData::Point3Vec(map) => {
571 if TimeDataMapControl::is_animated(map) {
572 Data::Point3Vec(map.interpolate(time))
573 } else {
574 Data::Point3Vec(map.iter().next().unwrap().1.clone())
575 }
576 }
577 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
578 AnimatedData::Matrix4Vec(map) => {
579 if TimeDataMapControl::is_animated(map) {
580 Data::Matrix4Vec(map.interpolate(time))
581 } else {
582 Data::Matrix4Vec(map.iter().next().unwrap().1.clone())
583 }
584 }
585 }
586 }
587}
588
589impl Hash for AnimatedData {
590 fn hash<H: Hasher>(&self, state: &mut H) {
591 std::mem::discriminant(self).hash(state);
592 match self {
593 AnimatedData::Boolean(map) => {
594 map.len().hash(state);
595 #[cfg(not(feature = "interpolation"))]
596 for (time, value) in &map.values {
597 time.hash(state);
598 value.0.hash(state);
599 }
600 #[cfg(feature = "interpolation")]
601 for (time, (value, spec)) in &map.values {
602 time.hash(state);
603 value.0.hash(state);
604 spec.hash(state);
605 }
606 }
607 AnimatedData::Integer(map) => {
608 map.len().hash(state);
609 #[cfg(not(feature = "interpolation"))]
610 for (time, value) in &map.values {
611 time.hash(state);
612 value.0.hash(state);
613 }
614 #[cfg(feature = "interpolation")]
615 for (time, (value, spec)) in &map.values {
616 time.hash(state);
617 value.0.hash(state);
618 spec.hash(state);
619 }
620 }
621 AnimatedData::Real(map) => {
622 map.len().hash(state);
623 #[cfg(not(feature = "interpolation"))]
624 for (time, value) in &map.values {
625 time.hash(state);
626 value.0.to_bits().hash(state);
627 }
628 #[cfg(feature = "interpolation")]
629 for (time, (value, spec)) in &map.values {
630 time.hash(state);
631 value.0.to_bits().hash(state);
632 spec.hash(state);
633 }
634 }
635 AnimatedData::String(map) => {
636 map.len().hash(state);
637 #[cfg(not(feature = "interpolation"))]
638 for (time, value) in &map.values {
639 time.hash(state);
640 value.0.hash(state);
641 }
642 #[cfg(feature = "interpolation")]
643 for (time, (value, spec)) in &map.values {
644 time.hash(state);
645 value.0.hash(state);
646 spec.hash(state);
647 }
648 }
649 AnimatedData::Color(map) => {
650 map.len().hash(state);
651 #[cfg(not(feature = "interpolation"))]
652 for (time, value) in &map.values {
653 time.hash(state);
654 value.0.iter().for_each(|v| v.to_bits().hash(state));
655 }
656 #[cfg(feature = "interpolation")]
657 for (time, (value, spec)) in &map.values {
658 time.hash(state);
659 value.0.iter().for_each(|v| v.to_bits().hash(state));
660 spec.hash(state);
661 }
662 }
663 #[cfg(feature = "vector2")]
664 AnimatedData::Vector2(map) => {
665 map.len().hash(state);
666 #[cfg(not(feature = "interpolation"))]
667 for (time, value) in &map.values {
668 time.hash(state);
669 value.0.iter().for_each(|v| v.to_bits().hash(state));
670 }
671 #[cfg(feature = "interpolation")]
672 for (time, (value, spec)) in &map.values {
673 time.hash(state);
674 value.0.iter().for_each(|v| v.to_bits().hash(state));
675 spec.hash(state);
676 }
677 }
678 #[cfg(feature = "vector3")]
679 AnimatedData::Vector3(map) => {
680 map.len().hash(state);
681 #[cfg(not(feature = "interpolation"))]
682 for (time, value) in &map.values {
683 time.hash(state);
684 value.0.iter().for_each(|v| v.to_bits().hash(state));
685 }
686 #[cfg(feature = "interpolation")]
687 for (time, (value, spec)) in &map.values {
688 time.hash(state);
689 value.0.iter().for_each(|v| v.to_bits().hash(state));
690 spec.hash(state);
691 }
692 }
693 #[cfg(feature = "matrix3")]
694 AnimatedData::Matrix3(map) => {
695 map.len().hash(state);
696 #[cfg(not(feature = "interpolation"))]
697 for (time, value) in &map.values {
698 time.hash(state);
699 value.0.iter().for_each(|v| v.to_bits().hash(state));
700 }
701 #[cfg(feature = "interpolation")]
702 for (time, (value, spec)) in &map.values {
703 time.hash(state);
704 value.0.iter().for_each(|v| v.to_bits().hash(state));
705 spec.hash(state);
706 }
707 }
708 #[cfg(feature = "normal3")]
709 AnimatedData::Normal3(map) => {
710 map.len().hash(state);
711 #[cfg(not(feature = "interpolation"))]
712 for (time, value) in &map.values {
713 time.hash(state);
714 value.0.iter().for_each(|v| v.to_bits().hash(state));
715 }
716 #[cfg(feature = "interpolation")]
717 for (time, (value, spec)) in &map.values {
718 time.hash(state);
719 value.0.iter().for_each(|v| v.to_bits().hash(state));
720 spec.hash(state);
721 }
722 }
723 #[cfg(feature = "point3")]
724 AnimatedData::Point3(map) => {
725 map.len().hash(state);
726 #[cfg(not(feature = "interpolation"))]
727 for (time, value) in &map.values {
728 time.hash(state);
729 value.0.coords.iter().for_each(|v| v.to_bits().hash(state));
730 }
731 #[cfg(feature = "interpolation")]
732 for (time, (value, spec)) in &map.values {
733 time.hash(state);
734 value.0.coords.iter().for_each(|v| v.to_bits().hash(state));
735 spec.hash(state);
736 }
737 }
738 #[cfg(feature = "matrix4")]
739 AnimatedData::Matrix4(map) => {
740 map.len().hash(state);
741 #[cfg(not(feature = "interpolation"))]
742 for (time, value) in &map.values {
743 time.hash(state);
744 value.0.iter().for_each(|v| v.to_bits().hash(state));
745 }
746 #[cfg(feature = "interpolation")]
747 for (time, (value, spec)) in &map.values {
748 time.hash(state);
749 value.0.iter().for_each(|v| v.to_bits().hash(state));
750 spec.hash(state);
751 }
752 }
753 AnimatedData::BooleanVec(map) => {
754 map.len().hash(state);
755 #[cfg(not(feature = "interpolation"))]
756 for (time, value) in &map.values {
757 time.hash(state);
758 value.0.hash(state);
759 }
760 #[cfg(feature = "interpolation")]
761 for (time, (value, spec)) in &map.values {
762 time.hash(state);
763 value.0.hash(state);
764 spec.hash(state);
765 }
766 }
767 AnimatedData::IntegerVec(map) => {
768 map.len().hash(state);
769 #[cfg(not(feature = "interpolation"))]
770 for (time, value) in &map.values {
771 time.hash(state);
772 value.0.hash(state);
773 }
774 #[cfg(feature = "interpolation")]
775 for (time, (value, spec)) in &map.values {
776 time.hash(state);
777 value.0.hash(state);
778 spec.hash(state);
779 }
780 }
781 AnimatedData::RealVec(map) => {
782 map.len().hash(state);
783 #[cfg(not(feature = "interpolation"))]
784 for (time, value) in &map.values {
785 time.hash(state);
786 value.0.len().hash(state);
787 value.0.iter().for_each(|v| v.to_bits().hash(state));
788 }
789 #[cfg(feature = "interpolation")]
790 for (time, (value, spec)) in &map.values {
791 time.hash(state);
792 value.0.len().hash(state);
793 value.0.iter().for_each(|v| v.to_bits().hash(state));
794 spec.hash(state);
795 }
796 }
797 AnimatedData::ColorVec(map) => {
798 map.len().hash(state);
799 #[cfg(not(feature = "interpolation"))]
800 for (time, value) in &map.values {
801 time.hash(state);
802 value.0.len().hash(state);
803 value.0.iter().for_each(|c| {
804 c.iter().for_each(|v| v.to_bits().hash(state));
805 });
806 }
807 #[cfg(feature = "interpolation")]
808 for (time, (value, spec)) in &map.values {
809 time.hash(state);
810 value.0.len().hash(state);
811 value.0.iter().for_each(|c| {
812 c.iter().for_each(|v| v.to_bits().hash(state));
813 });
814 spec.hash(state);
815 }
816 }
817 AnimatedData::StringVec(map) => {
818 map.len().hash(state);
819 #[cfg(not(feature = "interpolation"))]
820 for (time, value) in &map.values {
821 time.hash(state);
822 value.0.hash(state);
823 }
824 #[cfg(feature = "interpolation")]
825 for (time, (value, spec)) in &map.values {
826 time.hash(state);
827 value.0.hash(state);
828 spec.hash(state);
829 }
830 }
831 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
832 AnimatedData::Vector2Vec(map) => {
833 map.len().hash(state);
834 #[cfg(not(feature = "interpolation"))]
835 for (time, value) in &map.values {
836 time.hash(state);
837 value.0.len().hash(state);
838 value.0.iter().for_each(|v| {
839 v.iter().for_each(|f| f.to_bits().hash(state));
840 });
841 }
842 #[cfg(feature = "interpolation")]
843 for (time, (value, spec)) in &map.values {
844 time.hash(state);
845 value.0.len().hash(state);
846 value.0.iter().for_each(|v| {
847 v.iter().for_each(|f| f.to_bits().hash(state));
848 });
849 spec.hash(state);
850 }
851 }
852 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
853 AnimatedData::Vector3Vec(map) => {
854 map.len().hash(state);
855 #[cfg(not(feature = "interpolation"))]
856 for (time, value) in &map.values {
857 time.hash(state);
858 value.0.len().hash(state);
859 value.0.iter().for_each(|v| {
860 v.iter().for_each(|f| f.to_bits().hash(state));
861 });
862 }
863 #[cfg(feature = "interpolation")]
864 for (time, (value, spec)) in &map.values {
865 time.hash(state);
866 value.0.len().hash(state);
867 value.0.iter().for_each(|v| {
868 v.iter().for_each(|f| f.to_bits().hash(state));
869 });
870 spec.hash(state);
871 }
872 }
873 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
874 AnimatedData::Matrix3Vec(map) => {
875 map.len().hash(state);
876 #[cfg(not(feature = "interpolation"))]
877 for (time, value) in &map.values {
878 time.hash(state);
879 value.0.len().hash(state);
880 value.0.iter().for_each(|m| {
881 m.iter().for_each(|f| f.to_bits().hash(state));
882 });
883 }
884 #[cfg(feature = "interpolation")]
885 for (time, (value, spec)) in &map.values {
886 time.hash(state);
887 value.0.len().hash(state);
888 value.0.iter().for_each(|m| {
889 m.iter().for_each(|f| f.to_bits().hash(state));
890 });
891 spec.hash(state);
892 }
893 }
894 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
895 AnimatedData::Normal3Vec(map) => {
896 map.len().hash(state);
897 #[cfg(not(feature = "interpolation"))]
898 for (time, value) in &map.values {
899 time.hash(state);
900 value.0.len().hash(state);
901 value.0.iter().for_each(|v| {
902 v.iter().for_each(|f| f.to_bits().hash(state));
903 });
904 }
905 #[cfg(feature = "interpolation")]
906 for (time, (value, spec)) in &map.values {
907 time.hash(state);
908 value.0.len().hash(state);
909 value.0.iter().for_each(|v| {
910 v.iter().for_each(|f| f.to_bits().hash(state));
911 });
912 spec.hash(state);
913 }
914 }
915 #[cfg(all(feature = "point3", feature = "vec_variants"))]
916 AnimatedData::Point3Vec(map) => {
917 map.len().hash(state);
918 #[cfg(not(feature = "interpolation"))]
919 for (time, value) in &map.values {
920 time.hash(state);
921 value.0.len().hash(state);
922 value.0.iter().for_each(|p| {
923 p.coords.iter().for_each(|f| f.to_bits().hash(state));
924 });
925 }
926 #[cfg(feature = "interpolation")]
927 for (time, (value, spec)) in &map.values {
928 time.hash(state);
929 value.0.len().hash(state);
930 value.0.iter().for_each(|p| {
931 p.coords.iter().for_each(|f| f.to_bits().hash(state));
932 });
933 spec.hash(state);
934 }
935 }
936 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
937 AnimatedData::Matrix4Vec(map) => {
938 map.len().hash(state);
939 #[cfg(not(feature = "interpolation"))]
940 for (time, value) in &map.values {
941 time.hash(state);
942 value.0.len().hash(state);
943 value.0.iter().for_each(|m| {
944 m.iter().for_each(|f| f.to_bits().hash(state));
945 });
946 }
947 #[cfg(feature = "interpolation")]
948 for (time, (value, spec)) in &map.values {
949 time.hash(state);
950 value.0.len().hash(state);
951 value.0.iter().for_each(|m| {
952 m.iter().for_each(|f| f.to_bits().hash(state));
953 });
954 spec.hash(state);
955 }
956 }
957 }
958 }
959}
960
961impl_sample_for_animated_data!(
963 Real, Real;
964 Integer, Integer;
965 Color, Color;
966);
967
968impl_sample_for_animated_data!(
969 Vector2, Vector2, "vector2";
970 Vector3, Vector3, "vector3";
971 Matrix3, Matrix3, "matrix3";
972 Normal3, Normal3, "normal3";
973 Point3, Point3, "point3";
974 Matrix4, Matrix4, "matrix4";
975);
976
977impl AnimatedData {
978 pub fn hash_with_shutter<H: Hasher>(&self, state: &mut H, shutter: &Shutter) {
984 use smallvec::SmallVec;
985
986 const SAMPLE_POSITIONS: [f32; 5] = [0.0, 0.25, 0.5, 0.75, 1.0];
988
989 let samples: SmallVec<[Data; 5]> = SAMPLE_POSITIONS
991 .iter()
992 .map(|&pos| {
993 let time = shutter.evaluate(pos);
994 self.interpolate(time)
995 })
996 .collect();
997
998 let all_same = samples.windows(2).all(|w| w[0] == w[1]);
1000
1001 std::mem::discriminant(self).hash(state);
1003
1004 if all_same {
1005 1usize.hash(state); samples[0].hash(state);
1008 } else {
1009 samples.len().hash(state); for sample in &samples {
1012 sample.hash(state);
1013 }
1014 }
1015 }
1016}