1use crate::{
2 macros::{impl_animated_data_insert, impl_data_type_ops, impl_sample_for_animated_data},
3 time_data_map::TimeDataMapControl,
4 *,
5};
6
7use crate::Result;
8use core::num::NonZeroU16;
9use enum_dispatch::enum_dispatch;
10use smallvec::SmallVec;
11use std::hash::Hasher;
12
13#[enum_dispatch(AnimatedDataOps)]
19#[derive(Debug, Clone, PartialEq, Eq)]
20#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
21#[cfg_attr(feature = "facet", derive(Facet))]
22#[cfg_attr(feature = "facet", facet(opaque))]
23#[cfg_attr(feature = "facet", repr(u8))]
24#[cfg_attr(feature = "rkyv", derive(Archive, RkyvSerialize, RkyvDeserialize))]
25pub enum AnimatedData {
26 Boolean(TimeDataMap<Boolean>),
28 Integer(TimeDataMap<Integer>),
30 Real(TimeDataMap<Real>),
32 String(TimeDataMap<String>),
34 Color(TimeDataMap<Color>),
36 #[cfg(feature = "vector2")]
38 Vector2(TimeDataMap<Vector2>),
39 #[cfg(feature = "vector3")]
41 Vector3(TimeDataMap<Vector3>),
42 #[cfg(feature = "matrix3")]
44 Matrix3(TimeDataMap<Matrix3>),
45 #[cfg(feature = "normal3")]
47 Normal3(TimeDataMap<Normal3>),
48 #[cfg(feature = "point3")]
50 Point3(TimeDataMap<Point3>),
51 #[cfg(feature = "matrix4")]
53 Matrix4(TimeDataMap<Matrix4>),
54 BooleanVec(TimeDataMap<BooleanVec>),
56 IntegerVec(TimeDataMap<IntegerVec>),
58 RealVec(TimeDataMap<RealVec>),
60 ColorVec(TimeDataMap<ColorVec>),
62 StringVec(TimeDataMap<StringVec>),
64 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
66 Vector2Vec(TimeDataMap<Vector2Vec>),
67 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
69 Vector3Vec(TimeDataMap<Vector3Vec>),
70 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
72 Matrix3Vec(TimeDataMap<Matrix3Vec>),
73 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
75 Normal3Vec(TimeDataMap<Normal3Vec>),
76 #[cfg(all(feature = "point3", feature = "vec_variants"))]
78 Point3Vec(TimeDataMap<Point3Vec>),
79 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
81 Matrix4Vec(TimeDataMap<Matrix4Vec>),
82}
83
84#[enum_dispatch]
86pub trait AnimatedDataOps {
87 fn len(&self) -> usize;
89 fn is_empty(&self) -> bool;
91 fn is_animated(&self) -> bool;
93}
94
95impl<T> AnimatedDataOps for TimeDataMap<T> {
96 fn len(&self) -> usize {
97 self.values.len()
98 }
99
100 fn is_empty(&self) -> bool {
101 self.values.is_empty()
102 }
103
104 fn is_animated(&self) -> bool {
105 self.values.len() > 1
106 }
107}
108
109impl_data_type_ops!(AnimatedData);
110
111#[cfg(all(feature = "interpolation", feature = "egui-keyframe"))]
113impl AnimatedData {
114 pub fn bezier_handles(&self, time: &Time) -> Option<egui_keyframe::BezierHandles> {
118 match self {
119 AnimatedData::Real(map) => map.interpolation(time).map(crate::key_to_bezier_handles),
120 AnimatedData::Integer(map) => map.interpolation(time).map(crate::key_to_bezier_handles),
121 _ => None,
123 }
124 }
125
126 pub fn set_bezier_handles(
130 &mut self,
131 time: &Time,
132 handles: egui_keyframe::BezierHandles,
133 ) -> Result<()> {
134 match self {
135 AnimatedData::Real(map) => {
136 map.set_interpolation_at(time, crate::bezier_handles_to_key(&handles))
137 }
138 AnimatedData::Integer(map) => {
139 map.set_interpolation_at(time, crate::bezier_handles_to_key(&handles))
140 }
141 _ => Err(Error::BezierNotSupported {
142 got: self.data_type(),
143 }),
144 }
145 }
146
147 pub fn set_keyframe_type(
151 &mut self,
152 time: &Time,
153 keyframe_type: egui_keyframe::KeyframeType,
154 ) -> Result<()> {
155 use crate::interpolation::{Interpolation, Key};
156
157 match keyframe_type {
158 egui_keyframe::KeyframeType::Hold => match self {
159 AnimatedData::Real(map) => map.set_interpolation_at(
160 time,
161 Key {
162 interpolation_in: Interpolation::Hold,
163 interpolation_out: Interpolation::Hold,
164 },
165 ),
166 AnimatedData::Integer(map) => map.set_interpolation_at(
167 time,
168 Key {
169 interpolation_in: Interpolation::Hold,
170 interpolation_out: Interpolation::Hold,
171 },
172 ),
173 _ => Err(Error::BezierNotSupported {
174 got: self.data_type(),
175 }),
176 },
177 egui_keyframe::KeyframeType::Linear => match self {
178 AnimatedData::Real(map) => map.set_interpolation_at(
179 time,
180 Key {
181 interpolation_in: Interpolation::Linear,
182 interpolation_out: Interpolation::Linear,
183 },
184 ),
185 AnimatedData::Integer(map) => map.set_interpolation_at(
186 time,
187 Key {
188 interpolation_in: Interpolation::Linear,
189 interpolation_out: Interpolation::Linear,
190 },
191 ),
192 _ => Err(Error::BezierNotSupported {
193 got: self.data_type(),
194 }),
195 },
196 egui_keyframe::KeyframeType::Bezier => {
197 self.set_bezier_handles(time, egui_keyframe::BezierHandles::default())
199 }
200 }
201 }
202}
203
204impl AnimatedData {
205 pub fn times(&self) -> SmallVec<[Time; 10]> {
207 match self {
208 AnimatedData::Boolean(map) => map.iter().map(|(t, _)| *t).collect(),
209 AnimatedData::Integer(map) => map.iter().map(|(t, _)| *t).collect(),
210 AnimatedData::Real(map) => map.iter().map(|(t, _)| *t).collect(),
211 AnimatedData::String(map) => map.iter().map(|(t, _)| *t).collect(),
212 AnimatedData::Color(map) => map.iter().map(|(t, _)| *t).collect(),
213 #[cfg(feature = "vector2")]
214 AnimatedData::Vector2(map) => map.iter().map(|(t, _)| *t).collect(),
215 #[cfg(feature = "vector3")]
216 AnimatedData::Vector3(map) => map.iter().map(|(t, _)| *t).collect(),
217 #[cfg(feature = "matrix3")]
218 AnimatedData::Matrix3(map) => map.iter().map(|(t, _)| *t).collect(),
219 #[cfg(feature = "normal3")]
220 AnimatedData::Normal3(map) => map.iter().map(|(t, _)| *t).collect(),
221 #[cfg(feature = "point3")]
222 AnimatedData::Point3(map) => map.iter().map(|(t, _)| *t).collect(),
223 #[cfg(feature = "matrix4")]
224 AnimatedData::Matrix4(map) => map.iter().map(|(t, _)| *t).collect(),
225 AnimatedData::BooleanVec(map) => map.iter().map(|(t, _)| *t).collect(),
226 AnimatedData::IntegerVec(map) => map.iter().map(|(t, _)| *t).collect(),
227 AnimatedData::RealVec(map) => map.iter().map(|(t, _)| *t).collect(),
228 AnimatedData::ColorVec(map) => map.iter().map(|(t, _)| *t).collect(),
229 AnimatedData::StringVec(map) => map.iter().map(|(t, _)| *t).collect(),
230 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
231 AnimatedData::Vector2Vec(map) => map.iter().map(|(t, _)| *t).collect(),
232 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
233 AnimatedData::Vector3Vec(map) => map.iter().map(|(t, _)| *t).collect(),
234 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
235 AnimatedData::Matrix3Vec(map) => map.iter().map(|(t, _)| *t).collect(),
236 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
237 AnimatedData::Normal3Vec(map) => map.iter().map(|(t, _)| *t).collect(),
238 #[cfg(all(feature = "point3", feature = "vec_variants"))]
239 AnimatedData::Point3Vec(map) => map.iter().map(|(t, _)| *t).collect(),
240 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
241 AnimatedData::Matrix4Vec(map) => map.iter().map(|(t, _)| *t).collect(),
242 }
243 }
244}
245
246impl From<(Time, Value)> for AnimatedData {
247 fn from((time, value): (Time, Value)) -> Self {
248 match value {
249 Value::Uniform(data) => AnimatedData::from((time, data)),
250 Value::Animated(animated_data) => {
251 animated_data
256 }
257 }
258 }
259}
260
261impl From<(Time, Data)> for AnimatedData {
262 fn from((time, data): (Time, Data)) -> Self {
263 match data {
264 Data::Boolean(v) => AnimatedData::Boolean(TimeDataMap::from((time, v))),
265 Data::Integer(v) => AnimatedData::Integer(TimeDataMap::from((time, v))),
266 Data::Real(v) => AnimatedData::Real(TimeDataMap::from((time, v))),
267 Data::String(v) => AnimatedData::String(TimeDataMap::from((time, v))),
268 Data::Color(v) => AnimatedData::Color(TimeDataMap::from((time, v))),
269 #[cfg(feature = "vector2")]
270 Data::Vector2(v) => AnimatedData::Vector2(TimeDataMap::from((time, v))),
271 #[cfg(feature = "vector3")]
272 Data::Vector3(v) => AnimatedData::Vector3(TimeDataMap::from((time, v))),
273 #[cfg(feature = "matrix3")]
274 Data::Matrix3(v) => AnimatedData::Matrix3(TimeDataMap::from((time, v))),
275 #[cfg(feature = "normal3")]
276 Data::Normal3(v) => AnimatedData::Normal3(TimeDataMap::from((time, v))),
277 #[cfg(feature = "point3")]
278 Data::Point3(v) => AnimatedData::Point3(TimeDataMap::from((time, v))),
279 #[cfg(feature = "matrix4")]
280 Data::Matrix4(v) => AnimatedData::Matrix4(TimeDataMap::from((time, v))),
281 Data::BooleanVec(v) => AnimatedData::BooleanVec(TimeDataMap::from((time, v))),
282 Data::IntegerVec(v) => AnimatedData::IntegerVec(TimeDataMap::from((time, v))),
283 Data::RealVec(v) => AnimatedData::RealVec(TimeDataMap::from((time, v))),
284 Data::ColorVec(v) => AnimatedData::ColorVec(TimeDataMap::from((time, v))),
285 Data::StringVec(v) => AnimatedData::StringVec(TimeDataMap::from((time, v))),
286 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
287 Data::Vector2Vec(v) => AnimatedData::Vector2Vec(TimeDataMap::from((time, v))),
288 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
289 Data::Vector3Vec(v) => AnimatedData::Vector3Vec(TimeDataMap::from((time, v))),
290 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
291 Data::Matrix3Vec(v) => AnimatedData::Matrix3Vec(TimeDataMap::from((time, v))),
292 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
293 Data::Normal3Vec(v) => AnimatedData::Normal3Vec(TimeDataMap::from((time, v))),
294 #[cfg(all(feature = "point3", feature = "vec_variants"))]
295 Data::Point3Vec(v) => AnimatedData::Point3Vec(TimeDataMap::from((time, v))),
296 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
297 Data::Matrix4Vec(v) => AnimatedData::Matrix4Vec(TimeDataMap::from((time, v))),
298 }
299 }
300}
301
302impl_animated_data_insert!(
303 insert_boolean, Boolean, Boolean;
304 insert_integer, Integer, Integer;
305 insert_real, Real, Real;
306 insert_string, String, String;
307 insert_color, Color, Color;
308);
309
310#[cfg(feature = "vector2")]
311impl_animated_data_insert!(
312 insert_vector2, Vector2, Vector2;
313);
314
315#[cfg(feature = "vector3")]
316impl_animated_data_insert!(
317 insert_vector3, Vector3, Vector3;
318);
319
320#[cfg(feature = "matrix3")]
321impl_animated_data_insert!(
322 insert_matrix3, Matrix3, Matrix3;
323);
324
325#[cfg(feature = "normal3")]
326impl_animated_data_insert!(
327 insert_normal3, Normal3, Normal3;
328);
329
330#[cfg(feature = "point3")]
331impl_animated_data_insert!(
332 insert_point3, Point3, Point3;
333);
334
335#[cfg(feature = "matrix4")]
336impl_animated_data_insert!(
337 insert_matrix4, Matrix4, Matrix4;
338);
339
340impl AnimatedData {
341 pub fn try_insert(&mut self, time: Time, value: Data) -> Result<()> {
344 match (self, value) {
345 (AnimatedData::Boolean(map), Data::Boolean(v)) => {
346 map.insert(time, v);
347 Ok(())
348 }
349 (AnimatedData::Integer(map), Data::Integer(v)) => {
350 map.insert(time, v);
351 Ok(())
352 }
353 (AnimatedData::Real(map), Data::Real(v)) => {
354 map.insert(time, v);
355 Ok(())
356 }
357 (AnimatedData::String(map), Data::String(v)) => {
358 map.insert(time, v);
359 Ok(())
360 }
361 (AnimatedData::Color(map), Data::Color(v)) => {
362 map.insert(time, v);
363 Ok(())
364 }
365 #[cfg(feature = "vector2")]
366 (AnimatedData::Vector2(map), Data::Vector2(v)) => {
367 map.insert(time, v);
368 Ok(())
369 }
370 #[cfg(feature = "vector3")]
371 (AnimatedData::Vector3(map), Data::Vector3(v)) => {
372 map.insert(time, v);
373 Ok(())
374 }
375 #[cfg(feature = "matrix3")]
376 (AnimatedData::Matrix3(map), Data::Matrix3(v)) => {
377 map.insert(time, v);
378 Ok(())
379 }
380 #[cfg(feature = "normal3")]
381 (AnimatedData::Normal3(map), Data::Normal3(v)) => {
382 map.insert(time, v);
383 Ok(())
384 }
385 #[cfg(feature = "point3")]
386 (AnimatedData::Point3(map), Data::Point3(v)) => {
387 map.insert(time, v);
388 Ok(())
389 }
390 #[cfg(feature = "matrix4")]
391 (AnimatedData::Matrix4(map), Data::Matrix4(v)) => {
392 map.insert(time, v);
393 Ok(())
394 }
395 (AnimatedData::BooleanVec(map), Data::BooleanVec(v)) => {
396 map.insert(time, v);
397 Ok(())
398 }
399 (AnimatedData::IntegerVec(map), Data::IntegerVec(v)) => {
400 map.insert(time, v);
401 Ok(())
402 }
403 (AnimatedData::RealVec(map), Data::RealVec(v)) => {
404 map.insert(time, v);
405 Ok(())
406 }
407 (AnimatedData::ColorVec(map), Data::ColorVec(v)) => {
408 map.insert(time, v);
409 Ok(())
410 }
411 (AnimatedData::StringVec(map), Data::StringVec(v)) => {
412 map.insert(time, v);
413 Ok(())
414 }
415 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
416 (AnimatedData::Vector2Vec(map), Data::Vector2Vec(v)) => {
417 map.insert(time, v);
418 Ok(())
419 }
420 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
421 (AnimatedData::Vector3Vec(map), Data::Vector3Vec(v)) => {
422 map.insert(time, v);
423 Ok(())
424 }
425 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
426 (AnimatedData::Matrix3Vec(map), Data::Matrix3Vec(v)) => {
427 map.insert(time, v);
428 Ok(())
429 }
430 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
431 (AnimatedData::Normal3Vec(map), Data::Normal3Vec(v)) => {
432 map.insert(time, v);
433 Ok(())
434 }
435 #[cfg(all(feature = "point3", feature = "vec_variants"))]
436 (AnimatedData::Point3Vec(map), Data::Point3Vec(v)) => {
437 map.insert(time, v);
438 Ok(())
439 }
440 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
441 (AnimatedData::Matrix4Vec(map), Data::Matrix4Vec(v)) => {
442 map.insert(time, v);
443 Ok(())
444 }
445 (s, v) => Err(Error::SampleTypeMismatch {
446 expected: s.data_type(),
447 got: v.data_type(),
448 }),
449 }
450 }
451
452 pub fn remove_at(&mut self, time: &Time) -> Option<Data> {
456 match self {
457 AnimatedData::Boolean(map) => map.remove(time).map(Data::Boolean),
458 AnimatedData::Integer(map) => map.remove(time).map(Data::Integer),
459 AnimatedData::Real(map) => map.remove(time).map(Data::Real),
460 AnimatedData::String(map) => map.remove(time).map(Data::String),
461 AnimatedData::Color(map) => map.remove(time).map(Data::Color),
462 #[cfg(feature = "vector2")]
463 AnimatedData::Vector2(map) => map.remove(time).map(Data::Vector2),
464 #[cfg(feature = "vector3")]
465 AnimatedData::Vector3(map) => map.remove(time).map(Data::Vector3),
466 #[cfg(feature = "matrix3")]
467 AnimatedData::Matrix3(map) => map.remove(time).map(Data::Matrix3),
468 #[cfg(feature = "normal3")]
469 AnimatedData::Normal3(map) => map.remove(time).map(Data::Normal3),
470 #[cfg(feature = "point3")]
471 AnimatedData::Point3(map) => map.remove(time).map(Data::Point3),
472 #[cfg(feature = "matrix4")]
473 AnimatedData::Matrix4(map) => map.remove(time).map(Data::Matrix4),
474 AnimatedData::BooleanVec(map) => map.remove(time).map(Data::BooleanVec),
475 AnimatedData::IntegerVec(map) => map.remove(time).map(Data::IntegerVec),
476 AnimatedData::RealVec(map) => map.remove(time).map(Data::RealVec),
477 AnimatedData::ColorVec(map) => map.remove(time).map(Data::ColorVec),
478 AnimatedData::StringVec(map) => map.remove(time).map(Data::StringVec),
479 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
480 AnimatedData::Vector2Vec(map) => map.remove(time).map(Data::Vector2Vec),
481 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
482 AnimatedData::Vector3Vec(map) => map.remove(time).map(Data::Vector3Vec),
483 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
484 AnimatedData::Matrix3Vec(map) => map.remove(time).map(Data::Matrix3Vec),
485 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
486 AnimatedData::Normal3Vec(map) => map.remove(time).map(Data::Normal3Vec),
487 #[cfg(all(feature = "point3", feature = "vec_variants"))]
488 AnimatedData::Point3Vec(map) => map.remove(time).map(Data::Point3Vec),
489 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
490 AnimatedData::Matrix4Vec(map) => map.remove(time).map(Data::Matrix4Vec),
491 }
492 }
493
494 pub fn sample_at(&self, time: Time) -> Option<Data> {
495 match self {
496 AnimatedData::Boolean(map) => map.get(&time).map(|v| Data::Boolean(v.clone())),
497 AnimatedData::Integer(map) => map.get(&time).map(|v| Data::Integer(v.clone())),
498 AnimatedData::Real(map) => map.get(&time).map(|v| Data::Real(v.clone())),
499 AnimatedData::String(map) => map.get(&time).map(|v| Data::String(v.clone())),
500 AnimatedData::Color(map) => map.get(&time).map(|v| Data::Color(*v)),
501 #[cfg(feature = "vector2")]
502 AnimatedData::Vector2(map) => map.get(&time).map(|v| Data::Vector2(v.clone())),
503 #[cfg(feature = "vector3")]
504 AnimatedData::Vector3(map) => map.get(&time).map(|v| Data::Vector3(v.clone())),
505 #[cfg(feature = "matrix3")]
506 AnimatedData::Matrix3(map) => map.get(&time).map(|v| Data::Matrix3(v.clone())),
507 #[cfg(feature = "normal3")]
508 AnimatedData::Normal3(map) => map.get(&time).map(|v| Data::Normal3(v.clone())),
509 #[cfg(feature = "point3")]
510 AnimatedData::Point3(map) => map.get(&time).map(|v| Data::Point3(v.clone())),
511 #[cfg(feature = "matrix4")]
512 AnimatedData::Matrix4(map) => map.get(&time).map(|v| Data::Matrix4(v.clone())),
513 AnimatedData::BooleanVec(map) => map.get(&time).map(|v| Data::BooleanVec(v.clone())),
514 AnimatedData::IntegerVec(map) => map.get(&time).map(|v| Data::IntegerVec(v.clone())),
515 AnimatedData::RealVec(map) => map.get(&time).map(|v| Data::RealVec(v.clone())),
516 AnimatedData::ColorVec(map) => map.get(&time).map(|v| Data::ColorVec(v.clone())),
517 AnimatedData::StringVec(map) => map.get(&time).map(|v| Data::StringVec(v.clone())),
518 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
519 AnimatedData::Vector2Vec(map) => map.get(&time).map(|v| Data::Vector2Vec(v.clone())),
520 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
521 AnimatedData::Vector3Vec(map) => map.get(&time).map(|v| Data::Vector3Vec(v.clone())),
522 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
523 AnimatedData::Matrix3Vec(map) => map.get(&time).map(|v| Data::Matrix3Vec(v.clone())),
524 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
525 AnimatedData::Normal3Vec(map) => map.get(&time).map(|v| Data::Normal3Vec(v.clone())),
526 #[cfg(all(feature = "point3", feature = "vec_variants"))]
527 AnimatedData::Point3Vec(map) => map.get(&time).map(|v| Data::Point3Vec(v.clone())),
528 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
529 AnimatedData::Matrix4Vec(map) => map.get(&time).map(|v| Data::Matrix4Vec(v.clone())),
530 }
531 }
532
533 pub fn interpolate(&self, time: Time) -> Data {
534 match self {
535 AnimatedData::Boolean(map) => Data::Boolean(map.closest_sample(time).clone()),
536 AnimatedData::Integer(map) => {
537 if TimeDataMapControl::is_animated(map) {
538 Data::Integer(map.interpolate(time))
539 } else {
540 Data::Integer(map.iter().next().unwrap().1.clone())
541 }
542 }
543 AnimatedData::Real(map) => {
544 if TimeDataMapControl::is_animated(map) {
545 Data::Real(map.interpolate(time))
546 } else {
547 Data::Real(map.iter().next().unwrap().1.clone())
548 }
549 }
550 AnimatedData::String(map) => Data::String(map.closest_sample(time).clone()),
551 AnimatedData::Color(map) => {
552 if TimeDataMapControl::is_animated(map) {
553 Data::Color(map.interpolate(time))
554 } else {
555 Data::Color(*map.iter().next().unwrap().1)
556 }
557 }
558 #[cfg(feature = "vector2")]
559 AnimatedData::Vector2(map) => {
560 if TimeDataMapControl::is_animated(map) {
561 Data::Vector2(map.interpolate(time))
562 } else {
563 Data::Vector2(map.iter().next().unwrap().1.clone())
564 }
565 }
566 #[cfg(feature = "vector3")]
567 AnimatedData::Vector3(map) => {
568 if TimeDataMapControl::is_animated(map) {
569 Data::Vector3(map.interpolate(time))
570 } else {
571 Data::Vector3(map.iter().next().unwrap().1.clone())
572 }
573 }
574 #[cfg(feature = "matrix3")]
575 AnimatedData::Matrix3(map) => {
576 if TimeDataMapControl::is_animated(map) {
577 Data::Matrix3(map.interpolate(time))
578 } else {
579 Data::Matrix3(map.iter().next().unwrap().1.clone())
580 }
581 }
582 #[cfg(feature = "normal3")]
583 AnimatedData::Normal3(map) => {
584 if TimeDataMapControl::is_animated(map) {
585 Data::Normal3(map.interpolate(time))
586 } else {
587 Data::Normal3(map.iter().next().unwrap().1.clone())
588 }
589 }
590 #[cfg(feature = "point3")]
591 AnimatedData::Point3(map) => {
592 if TimeDataMapControl::is_animated(map) {
593 Data::Point3(map.interpolate(time))
594 } else {
595 Data::Point3(map.iter().next().unwrap().1.clone())
596 }
597 }
598 #[cfg(feature = "matrix4")]
599 AnimatedData::Matrix4(map) => {
600 if TimeDataMapControl::is_animated(map) {
601 Data::Matrix4(map.interpolate(time))
602 } else {
603 Data::Matrix4(map.iter().next().unwrap().1.clone())
604 }
605 }
606 AnimatedData::BooleanVec(map) => Data::BooleanVec(map.closest_sample(time).clone()),
607 AnimatedData::IntegerVec(map) => {
608 if TimeDataMapControl::is_animated(map) {
609 Data::IntegerVec(map.interpolate(time))
610 } else {
611 Data::IntegerVec(map.iter().next().unwrap().1.clone())
612 }
613 }
614 AnimatedData::RealVec(map) => {
615 if TimeDataMapControl::is_animated(map) {
616 Data::RealVec(map.interpolate(time))
617 } else {
618 Data::RealVec(map.iter().next().unwrap().1.clone())
619 }
620 }
621 AnimatedData::ColorVec(map) => {
622 if TimeDataMapControl::is_animated(map) {
623 Data::ColorVec(map.interpolate(time))
624 } else {
625 Data::ColorVec(map.iter().next().unwrap().1.clone())
626 }
627 }
628 AnimatedData::StringVec(map) => Data::StringVec(map.closest_sample(time).clone()),
629 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
630 AnimatedData::Vector2Vec(map) => {
631 if TimeDataMapControl::is_animated(map) {
632 Data::Vector2Vec(map.interpolate(time))
633 } else {
634 Data::Vector2Vec(map.iter().next().unwrap().1.clone())
635 }
636 }
637 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
638 AnimatedData::Vector3Vec(map) => {
639 if TimeDataMapControl::is_animated(map) {
640 Data::Vector3Vec(map.interpolate(time))
641 } else {
642 Data::Vector3Vec(map.iter().next().unwrap().1.clone())
643 }
644 }
645 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
646 AnimatedData::Matrix3Vec(map) => {
647 if TimeDataMapControl::is_animated(map) {
648 Data::Matrix3Vec(map.interpolate(time))
649 } else {
650 Data::Matrix3Vec(map.iter().next().unwrap().1.clone())
651 }
652 }
653 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
654 AnimatedData::Normal3Vec(map) => {
655 if TimeDataMapControl::is_animated(map) {
656 Data::Normal3Vec(map.interpolate(time))
657 } else {
658 Data::Normal3Vec(map.iter().next().unwrap().1.clone())
659 }
660 }
661 #[cfg(all(feature = "point3", feature = "vec_variants"))]
662 AnimatedData::Point3Vec(map) => {
663 if TimeDataMapControl::is_animated(map) {
664 Data::Point3Vec(map.interpolate(time))
665 } else {
666 Data::Point3Vec(map.iter().next().unwrap().1.clone())
667 }
668 }
669 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
670 AnimatedData::Matrix4Vec(map) => {
671 if TimeDataMapControl::is_animated(map) {
672 Data::Matrix4Vec(map.interpolate(time))
673 } else {
674 Data::Matrix4Vec(map.iter().next().unwrap().1.clone())
675 }
676 }
677 }
678 }
679}
680
681impl Hash for AnimatedData {
682 fn hash<H: Hasher>(&self, state: &mut H) {
683 std::mem::discriminant(self).hash(state);
684 match self {
685 AnimatedData::Boolean(map) => {
686 map.len().hash(state);
687 #[cfg(not(feature = "interpolation"))]
688 for (time, value) in &map.values {
689 time.hash(state);
690 value.0.hash(state);
691 }
692 #[cfg(feature = "interpolation")]
693 for (time, (value, spec)) in &map.values {
694 time.hash(state);
695 value.0.hash(state);
696 spec.hash(state);
697 }
698 }
699 AnimatedData::Integer(map) => {
700 map.len().hash(state);
701 #[cfg(not(feature = "interpolation"))]
702 for (time, value) in &map.values {
703 time.hash(state);
704 value.0.hash(state);
705 }
706 #[cfg(feature = "interpolation")]
707 for (time, (value, spec)) in &map.values {
708 time.hash(state);
709 value.0.hash(state);
710 spec.hash(state);
711 }
712 }
713 AnimatedData::Real(map) => {
714 map.len().hash(state);
715 #[cfg(not(feature = "interpolation"))]
716 for (time, value) in &map.values {
717 time.hash(state);
718 value.0.to_bits().hash(state);
719 }
720 #[cfg(feature = "interpolation")]
721 for (time, (value, spec)) in &map.values {
722 time.hash(state);
723 value.0.to_bits().hash(state);
724 spec.hash(state);
725 }
726 }
727 AnimatedData::String(map) => {
728 map.len().hash(state);
729 #[cfg(not(feature = "interpolation"))]
730 for (time, value) in &map.values {
731 time.hash(state);
732 value.0.hash(state);
733 }
734 #[cfg(feature = "interpolation")]
735 for (time, (value, spec)) in &map.values {
736 time.hash(state);
737 value.0.hash(state);
738 spec.hash(state);
739 }
740 }
741 AnimatedData::Color(map) => {
742 map.len().hash(state);
743 #[cfg(not(feature = "interpolation"))]
744 for (time, value) in &map.values {
745 time.hash(state);
746 value.0.iter().for_each(|v| v.to_bits().hash(state));
747 }
748 #[cfg(feature = "interpolation")]
749 for (time, (value, spec)) in &map.values {
750 time.hash(state);
751 value.0.iter().for_each(|v| v.to_bits().hash(state));
752 spec.hash(state);
753 }
754 }
755 #[cfg(feature = "vector2")]
756 AnimatedData::Vector2(map) => {
757 map.len().hash(state);
758 #[cfg(not(feature = "interpolation"))]
759 for (time, value) in &map.values {
760 time.hash(state);
761 crate::math::vec2_as_slice(&value.0)
762 .iter()
763 .for_each(|v| v.to_bits().hash(state));
764 }
765 #[cfg(feature = "interpolation")]
766 for (time, (value, spec)) in &map.values {
767 time.hash(state);
768 crate::math::vec2_as_slice(&value.0)
769 .iter()
770 .for_each(|v| v.to_bits().hash(state));
771 spec.hash(state);
772 }
773 }
774 #[cfg(feature = "vector3")]
775 AnimatedData::Vector3(map) => {
776 map.len().hash(state);
777 #[cfg(not(feature = "interpolation"))]
778 for (time, value) in &map.values {
779 time.hash(state);
780 crate::math::vec3_as_slice(&value.0)
781 .iter()
782 .for_each(|v| v.to_bits().hash(state));
783 }
784 #[cfg(feature = "interpolation")]
785 for (time, (value, spec)) in &map.values {
786 time.hash(state);
787 crate::math::vec3_as_slice(&value.0)
788 .iter()
789 .for_each(|v| v.to_bits().hash(state));
790 spec.hash(state);
791 }
792 }
793 #[cfg(feature = "matrix3")]
794 AnimatedData::Matrix3(map) => {
795 map.len().hash(state);
796 #[cfg(not(feature = "interpolation"))]
797 for (time, value) in &map.values {
798 time.hash(state);
799 crate::math::mat3_iter(&value.0).for_each(|v| v.to_bits().hash(state));
800 }
801 #[cfg(feature = "interpolation")]
802 for (time, (value, spec)) in &map.values {
803 time.hash(state);
804 crate::math::mat3_iter(&value.0).for_each(|v| v.to_bits().hash(state));
805 spec.hash(state);
806 }
807 }
808 #[cfg(feature = "normal3")]
809 AnimatedData::Normal3(map) => {
810 map.len().hash(state);
811 #[cfg(not(feature = "interpolation"))]
812 for (time, value) in &map.values {
813 time.hash(state);
814 crate::math::vec3_as_slice(&value.0)
815 .iter()
816 .for_each(|v| v.to_bits().hash(state));
817 }
818 #[cfg(feature = "interpolation")]
819 for (time, (value, spec)) in &map.values {
820 time.hash(state);
821 crate::math::vec3_as_slice(&value.0)
822 .iter()
823 .for_each(|v| v.to_bits().hash(state));
824 spec.hash(state);
825 }
826 }
827 #[cfg(feature = "point3")]
828 AnimatedData::Point3(map) => {
829 map.len().hash(state);
830 #[cfg(not(feature = "interpolation"))]
831 for (time, value) in &map.values {
832 time.hash(state);
833 crate::math::point3_as_slice(&value.0)
834 .iter()
835 .for_each(|v| v.to_bits().hash(state));
836 }
837 #[cfg(feature = "interpolation")]
838 for (time, (value, spec)) in &map.values {
839 time.hash(state);
840 crate::math::point3_as_slice(&value.0)
841 .iter()
842 .for_each(|v| v.to_bits().hash(state));
843 spec.hash(state);
844 }
845 }
846 #[cfg(feature = "matrix4")]
847 AnimatedData::Matrix4(map) => {
848 map.len().hash(state);
849 #[cfg(not(feature = "interpolation"))]
850 for (time, value) in &map.values {
851 time.hash(state);
852 crate::math::mat4_iter(&value.0).for_each(|v| v.to_bits().hash(state));
853 }
854 #[cfg(feature = "interpolation")]
855 for (time, (value, spec)) in &map.values {
856 time.hash(state);
857 crate::math::mat4_iter(&value.0).for_each(|v| v.to_bits().hash(state));
858 spec.hash(state);
859 }
860 }
861 AnimatedData::BooleanVec(map) => {
862 map.len().hash(state);
863 #[cfg(not(feature = "interpolation"))]
864 for (time, value) in &map.values {
865 time.hash(state);
866 value.0.hash(state);
867 }
868 #[cfg(feature = "interpolation")]
869 for (time, (value, spec)) in &map.values {
870 time.hash(state);
871 value.0.hash(state);
872 spec.hash(state);
873 }
874 }
875 AnimatedData::IntegerVec(map) => {
876 map.len().hash(state);
877 #[cfg(not(feature = "interpolation"))]
878 for (time, value) in &map.values {
879 time.hash(state);
880 value.0.hash(state);
881 }
882 #[cfg(feature = "interpolation")]
883 for (time, (value, spec)) in &map.values {
884 time.hash(state);
885 value.0.hash(state);
886 spec.hash(state);
887 }
888 }
889 AnimatedData::RealVec(map) => {
890 map.len().hash(state);
891 #[cfg(not(feature = "interpolation"))]
892 for (time, value) in &map.values {
893 time.hash(state);
894 value.0.len().hash(state);
895 value.0.iter().for_each(|v| v.to_bits().hash(state));
896 }
897 #[cfg(feature = "interpolation")]
898 for (time, (value, spec)) in &map.values {
899 time.hash(state);
900 value.0.len().hash(state);
901 value.0.iter().for_each(|v| v.to_bits().hash(state));
902 spec.hash(state);
903 }
904 }
905 AnimatedData::ColorVec(map) => {
906 map.len().hash(state);
907 #[cfg(not(feature = "interpolation"))]
908 for (time, value) in &map.values {
909 time.hash(state);
910 value.0.len().hash(state);
911 value.0.iter().for_each(|c| {
912 c.iter().for_each(|v| v.to_bits().hash(state));
913 });
914 }
915 #[cfg(feature = "interpolation")]
916 for (time, (value, spec)) in &map.values {
917 time.hash(state);
918 value.0.len().hash(state);
919 value.0.iter().for_each(|c| {
920 c.iter().for_each(|v| v.to_bits().hash(state));
921 });
922 spec.hash(state);
923 }
924 }
925 AnimatedData::StringVec(map) => {
926 map.len().hash(state);
927 #[cfg(not(feature = "interpolation"))]
928 for (time, value) in &map.values {
929 time.hash(state);
930 value.0.hash(state);
931 }
932 #[cfg(feature = "interpolation")]
933 for (time, (value, spec)) in &map.values {
934 time.hash(state);
935 value.0.hash(state);
936 spec.hash(state);
937 }
938 }
939 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
940 AnimatedData::Vector2Vec(map) => {
941 map.len().hash(state);
942 #[cfg(not(feature = "interpolation"))]
943 for (time, value) in &map.values {
944 time.hash(state);
945 value.0.len().hash(state);
946 value.0.iter().for_each(|v| {
947 crate::math::vec2_as_slice(v)
948 .iter()
949 .for_each(|f| f.to_bits().hash(state));
950 });
951 }
952 #[cfg(feature = "interpolation")]
953 for (time, (value, spec)) in &map.values {
954 time.hash(state);
955 value.0.len().hash(state);
956 value.0.iter().for_each(|v| {
957 crate::math::vec2_as_slice(v)
958 .iter()
959 .for_each(|f| f.to_bits().hash(state));
960 });
961 spec.hash(state);
962 }
963 }
964 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
965 AnimatedData::Vector3Vec(map) => {
966 map.len().hash(state);
967 #[cfg(not(feature = "interpolation"))]
968 for (time, value) in &map.values {
969 time.hash(state);
970 value.0.len().hash(state);
971 value.0.iter().for_each(|v| {
972 crate::math::vec3_as_slice(v)
973 .iter()
974 .for_each(|f| f.to_bits().hash(state));
975 });
976 }
977 #[cfg(feature = "interpolation")]
978 for (time, (value, spec)) in &map.values {
979 time.hash(state);
980 value.0.len().hash(state);
981 value.0.iter().for_each(|v| {
982 crate::math::vec3_as_slice(v)
983 .iter()
984 .for_each(|f| f.to_bits().hash(state));
985 });
986 spec.hash(state);
987 }
988 }
989 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
990 AnimatedData::Matrix3Vec(map) => {
991 map.len().hash(state);
992 #[cfg(not(feature = "interpolation"))]
993 for (time, value) in &map.values {
994 time.hash(state);
995 value.0.len().hash(state);
996 value.0.iter().for_each(|m| {
997 crate::math::mat3_iter(m).for_each(|f| f.to_bits().hash(state));
998 });
999 }
1000 #[cfg(feature = "interpolation")]
1001 for (time, (value, spec)) in &map.values {
1002 time.hash(state);
1003 value.0.len().hash(state);
1004 value.0.iter().for_each(|m| {
1005 crate::math::mat3_iter(m).for_each(|f| f.to_bits().hash(state));
1006 });
1007 spec.hash(state);
1008 }
1009 }
1010 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
1011 AnimatedData::Normal3Vec(map) => {
1012 map.len().hash(state);
1013 #[cfg(not(feature = "interpolation"))]
1014 for (time, value) in &map.values {
1015 time.hash(state);
1016 value.0.len().hash(state);
1017 value.0.iter().for_each(|v| {
1018 crate::math::vec3_as_slice(v)
1019 .iter()
1020 .for_each(|f| f.to_bits().hash(state));
1021 });
1022 }
1023 #[cfg(feature = "interpolation")]
1024 for (time, (value, spec)) in &map.values {
1025 time.hash(state);
1026 value.0.len().hash(state);
1027 value.0.iter().for_each(|v| {
1028 crate::math::vec3_as_slice(v)
1029 .iter()
1030 .for_each(|f| f.to_bits().hash(state));
1031 });
1032 spec.hash(state);
1033 }
1034 }
1035 #[cfg(all(feature = "point3", feature = "vec_variants"))]
1036 AnimatedData::Point3Vec(map) => {
1037 map.len().hash(state);
1038 #[cfg(not(feature = "interpolation"))]
1039 for (time, value) in &map.values {
1040 time.hash(state);
1041 value.0.len().hash(state);
1042 value.0.iter().for_each(|p| {
1043 crate::math::point3_as_slice(p)
1044 .iter()
1045 .for_each(|f| f.to_bits().hash(state));
1046 });
1047 }
1048 #[cfg(feature = "interpolation")]
1049 for (time, (value, spec)) in &map.values {
1050 time.hash(state);
1051 value.0.len().hash(state);
1052 value.0.iter().for_each(|p| {
1053 crate::math::point3_as_slice(p)
1054 .iter()
1055 .for_each(|f| f.to_bits().hash(state));
1056 });
1057 spec.hash(state);
1058 }
1059 }
1060 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
1061 AnimatedData::Matrix4Vec(map) => {
1062 map.len().hash(state);
1063 #[cfg(not(feature = "interpolation"))]
1064 for (time, value) in &map.values {
1065 time.hash(state);
1066 value.0.len().hash(state);
1067 value.0.iter().for_each(|m| {
1068 crate::math::mat4_iter(m).for_each(|f| f.to_bits().hash(state));
1069 });
1070 }
1071 #[cfg(feature = "interpolation")]
1072 for (time, (value, spec)) in &map.values {
1073 time.hash(state);
1074 value.0.len().hash(state);
1075 value.0.iter().for_each(|m| {
1076 crate::math::mat4_iter(m).for_each(|f| f.to_bits().hash(state));
1077 });
1078 spec.hash(state);
1079 }
1080 }
1081 }
1082 }
1083}
1084
1085impl_sample_for_animated_data!(
1087 Real, Real;
1088 Integer, Integer;
1089 Color, Color;
1090);
1091
1092impl_sample_for_animated_data!(
1093 Vector2, Vector2, "vector2";
1094 Vector3, Vector3, "vector3";
1095 Matrix3, Matrix3, "matrix3";
1096 Normal3, Normal3, "normal3";
1097 Point3, Point3, "point3";
1098 Matrix4, Matrix4, "matrix4";
1099);
1100
1101impl AnimatedData {
1102 pub fn hash_with_shutter<H: Hasher>(&self, state: &mut H, shutter: &Shutter) {
1108 use smallvec::SmallVec;
1109
1110 const SAMPLE_POSITIONS: [f32; 5] = [0.0, 0.25, 0.5, 0.75, 1.0];
1112
1113 let samples: SmallVec<[Data; 5]> = SAMPLE_POSITIONS
1115 .iter()
1116 .map(|&pos| {
1117 let time = shutter.evaluate(pos);
1118 self.interpolate(time)
1119 })
1120 .collect();
1121
1122 let all_same = samples.windows(2).all(|w| w[0] == w[1]);
1124
1125 std::mem::discriminant(self).hash(state);
1127
1128 if all_same {
1129 1usize.hash(state); samples[0].hash(state);
1132 } else {
1133 samples.len().hash(state); for sample in &samples {
1136 sample.hash(state);
1137 }
1138 }
1139 }
1140}
1141
1142impl crate::traits::AnimatedDataSystem for AnimatedData {
1144 type Data = Data;
1145
1146 fn keyframe_count(&self) -> usize {
1147 AnimatedDataOps::len(self)
1148 }
1149
1150 fn is_keyframes_empty(&self) -> bool {
1151 AnimatedDataOps::is_empty(self)
1152 }
1153
1154 fn has_animation(&self) -> bool {
1155 AnimatedDataOps::is_animated(self)
1156 }
1157
1158 fn times(&self) -> SmallVec<[Time; 10]> {
1159 AnimatedData::times(self)
1160 }
1161
1162 fn interpolate(&self, time: Time) -> Data {
1163 AnimatedData::interpolate(self, time)
1164 }
1165
1166 fn sample_at(&self, time: Time) -> Option<Data> {
1167 AnimatedData::sample_at(self, time)
1168 }
1169
1170 fn try_insert(&mut self, time: Time, value: Data) -> Result<()> {
1171 AnimatedData::try_insert(self, time, value)
1172 }
1173
1174 fn remove_at(&mut self, time: &Time) -> Option<Data> {
1175 AnimatedData::remove_at(self, time)
1176 }
1177
1178 fn discriminant(&self) -> DataType {
1179 DataTypeOps::data_type(self)
1180 }
1181
1182 fn from_single(time: Time, value: Data) -> Self {
1183 AnimatedData::from((time, value))
1184 }
1185
1186 fn variant_name(&self) -> &'static str {
1187 DataTypeOps::type_name(self)
1188 }
1189}