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