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().get()
104 }
105
106 fn is_empty(&self) -> bool {
107 false
108 }
109
110 fn is_animated(&self) -> bool {
111 self.values.len().get() > 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> {
484 match self {
487 AnimatedData::Boolean(map) => map.remove(time).ok()?.map(Data::Boolean),
488 AnimatedData::Integer(map) => map.remove(time).ok()?.map(Data::Integer),
489 AnimatedData::Real(map) => map.remove(time).ok()?.map(Data::Real),
490 AnimatedData::String(map) => map.remove(time).ok()?.map(Data::String),
491 AnimatedData::Color(map) => map.remove(time).ok()?.map(Data::Color),
492 #[cfg(feature = "vector2")]
493 AnimatedData::Vector2(map) => map.remove(time).ok()?.map(Data::Vector2),
494 #[cfg(feature = "vector3")]
495 AnimatedData::Vector3(map) => map.remove(time).ok()?.map(Data::Vector3),
496 #[cfg(feature = "matrix3")]
497 AnimatedData::Matrix3(map) => map.remove(time).ok()?.map(Data::Matrix3),
498 #[cfg(feature = "normal3")]
499 AnimatedData::Normal3(map) => map.remove(time).ok()?.map(Data::Normal3),
500 #[cfg(feature = "point3")]
501 AnimatedData::Point3(map) => map.remove(time).ok()?.map(Data::Point3),
502 #[cfg(feature = "matrix4")]
503 AnimatedData::Matrix4(map) => map.remove(time).ok()?.map(Data::Matrix4),
504 AnimatedData::BooleanVec(map) => map.remove(time).ok()?.map(Data::BooleanVec),
505 AnimatedData::IntegerVec(map) => map.remove(time).ok()?.map(Data::IntegerVec),
506 AnimatedData::RealVec(map) => map.remove(time).ok()?.map(Data::RealVec),
507 AnimatedData::ColorVec(map) => map.remove(time).ok()?.map(Data::ColorVec),
508 AnimatedData::StringVec(map) => map.remove(time).ok()?.map(Data::StringVec),
509 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
510 AnimatedData::Vector2Vec(map) => map.remove(time).ok()?.map(Data::Vector2Vec),
511 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
512 AnimatedData::Vector3Vec(map) => map.remove(time).ok()?.map(Data::Vector3Vec),
513 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
514 AnimatedData::Matrix3Vec(map) => map.remove(time).ok()?.map(Data::Matrix3Vec),
515 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
516 AnimatedData::Normal3Vec(map) => map.remove(time).ok()?.map(Data::Normal3Vec),
517 #[cfg(all(feature = "point3", feature = "vec_variants"))]
518 AnimatedData::Point3Vec(map) => map.remove(time).ok()?.map(Data::Point3Vec),
519 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
520 AnimatedData::Matrix4Vec(map) => map.remove(time).ok()?.map(Data::Matrix4Vec),
521 #[cfg(feature = "curves")]
522 AnimatedData::RealCurve(map) => map.remove(time).ok()?.map(Data::RealCurve),
523 #[cfg(feature = "curves")]
524 AnimatedData::ColorCurve(map) => map.remove(time).ok()?.map(Data::ColorCurve),
525 }
526 }
527
528 pub fn sample_at(&self, time: Time) -> Option<Data> {
529 match self {
530 AnimatedData::Boolean(map) => map.get(&time).map(|v| Data::Boolean(v.clone())),
531 AnimatedData::Integer(map) => map.get(&time).map(|v| Data::Integer(v.clone())),
532 AnimatedData::Real(map) => map.get(&time).map(|v| Data::Real(v.clone())),
533 AnimatedData::String(map) => map.get(&time).map(|v| Data::String(v.clone())),
534 AnimatedData::Color(map) => map.get(&time).map(|v| Data::Color(*v)),
535 #[cfg(feature = "vector2")]
536 AnimatedData::Vector2(map) => map.get(&time).map(|v| Data::Vector2(v.clone())),
537 #[cfg(feature = "vector3")]
538 AnimatedData::Vector3(map) => map.get(&time).map(|v| Data::Vector3(v.clone())),
539 #[cfg(feature = "matrix3")]
540 AnimatedData::Matrix3(map) => map.get(&time).map(|v| Data::Matrix3(v.clone())),
541 #[cfg(feature = "normal3")]
542 AnimatedData::Normal3(map) => map.get(&time).map(|v| Data::Normal3(v.clone())),
543 #[cfg(feature = "point3")]
544 AnimatedData::Point3(map) => map.get(&time).map(|v| Data::Point3(v.clone())),
545 #[cfg(feature = "matrix4")]
546 AnimatedData::Matrix4(map) => map.get(&time).map(|v| Data::Matrix4(v.clone())),
547 AnimatedData::BooleanVec(map) => map.get(&time).map(|v| Data::BooleanVec(v.clone())),
548 AnimatedData::IntegerVec(map) => map.get(&time).map(|v| Data::IntegerVec(v.clone())),
549 AnimatedData::RealVec(map) => map.get(&time).map(|v| Data::RealVec(v.clone())),
550 AnimatedData::ColorVec(map) => map.get(&time).map(|v| Data::ColorVec(v.clone())),
551 AnimatedData::StringVec(map) => map.get(&time).map(|v| Data::StringVec(v.clone())),
552 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
553 AnimatedData::Vector2Vec(map) => map.get(&time).map(|v| Data::Vector2Vec(v.clone())),
554 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
555 AnimatedData::Vector3Vec(map) => map.get(&time).map(|v| Data::Vector3Vec(v.clone())),
556 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
557 AnimatedData::Matrix3Vec(map) => map.get(&time).map(|v| Data::Matrix3Vec(v.clone())),
558 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
559 AnimatedData::Normal3Vec(map) => map.get(&time).map(|v| Data::Normal3Vec(v.clone())),
560 #[cfg(all(feature = "point3", feature = "vec_variants"))]
561 AnimatedData::Point3Vec(map) => map.get(&time).map(|v| Data::Point3Vec(v.clone())),
562 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
563 AnimatedData::Matrix4Vec(map) => map.get(&time).map(|v| Data::Matrix4Vec(v.clone())),
564 #[cfg(feature = "curves")]
565 AnimatedData::RealCurve(map) => map.get(&time).map(|v| Data::RealCurve(v.clone())),
566 #[cfg(feature = "curves")]
567 AnimatedData::ColorCurve(map) => map.get(&time).map(|v| Data::ColorCurve(v.clone())),
568 }
569 }
570
571 pub fn interpolate(&self, time: Time) -> Data {
572 match self {
573 AnimatedData::Boolean(map) => Data::Boolean(map.closest_sample(time).clone()),
574 AnimatedData::Integer(map) => {
575 if TimeDataMapControl::is_animated(map) {
576 Data::Integer(map.interpolate(time))
577 } else {
578 Data::Integer(map.iter().next().unwrap().1.clone())
580 }
581 }
582 AnimatedData::Real(map) => {
583 if TimeDataMapControl::is_animated(map) {
584 Data::Real(map.interpolate(time))
585 } else {
586 Data::Real(map.iter().next().unwrap().1.clone())
588 }
589 }
590 AnimatedData::String(map) => Data::String(map.closest_sample(time).clone()),
591 AnimatedData::Color(map) => {
592 if TimeDataMapControl::is_animated(map) {
593 Data::Color(map.interpolate(time))
594 } else {
595 Data::Color(*map.iter().next().unwrap().1)
597 }
598 }
599 #[cfg(feature = "vector2")]
600 AnimatedData::Vector2(map) => {
601 if TimeDataMapControl::is_animated(map) {
602 Data::Vector2(map.interpolate(time))
603 } else {
604 Data::Vector2(map.iter().next().unwrap().1.clone())
606 }
607 }
608 #[cfg(feature = "vector3")]
609 AnimatedData::Vector3(map) => {
610 if TimeDataMapControl::is_animated(map) {
611 Data::Vector3(map.interpolate(time))
612 } else {
613 Data::Vector3(map.iter().next().unwrap().1.clone())
615 }
616 }
617 #[cfg(feature = "matrix3")]
618 AnimatedData::Matrix3(map) => {
619 if TimeDataMapControl::is_animated(map) {
620 Data::Matrix3(map.interpolate(time))
621 } else {
622 Data::Matrix3(map.iter().next().unwrap().1.clone())
624 }
625 }
626 #[cfg(feature = "normal3")]
627 AnimatedData::Normal3(map) => {
628 if TimeDataMapControl::is_animated(map) {
629 Data::Normal3(map.interpolate(time))
630 } else {
631 Data::Normal3(map.iter().next().unwrap().1.clone())
633 }
634 }
635 #[cfg(feature = "point3")]
636 AnimatedData::Point3(map) => {
637 if TimeDataMapControl::is_animated(map) {
638 Data::Point3(map.interpolate(time))
639 } else {
640 Data::Point3(map.iter().next().unwrap().1.clone())
642 }
643 }
644 #[cfg(feature = "matrix4")]
645 AnimatedData::Matrix4(map) => {
646 if TimeDataMapControl::is_animated(map) {
647 Data::Matrix4(map.interpolate(time))
648 } else {
649 Data::Matrix4(map.iter().next().unwrap().1.clone())
651 }
652 }
653 AnimatedData::BooleanVec(map) => Data::BooleanVec(map.closest_sample(time).clone()),
654 AnimatedData::IntegerVec(map) => {
655 if TimeDataMapControl::is_animated(map) {
656 Data::IntegerVec(map.interpolate(time))
657 } else {
658 Data::IntegerVec(map.iter().next().unwrap().1.clone())
660 }
661 }
662 AnimatedData::RealVec(map) => {
663 if TimeDataMapControl::is_animated(map) {
664 Data::RealVec(map.interpolate(time))
665 } else {
666 Data::RealVec(map.iter().next().unwrap().1.clone())
668 }
669 }
670 AnimatedData::ColorVec(map) => {
671 if TimeDataMapControl::is_animated(map) {
672 Data::ColorVec(map.interpolate(time))
673 } else {
674 Data::ColorVec(map.iter().next().unwrap().1.clone())
676 }
677 }
678 AnimatedData::StringVec(map) => Data::StringVec(map.closest_sample(time).clone()),
679 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
680 AnimatedData::Vector2Vec(map) => {
681 if TimeDataMapControl::is_animated(map) {
682 Data::Vector2Vec(map.interpolate(time))
683 } else {
684 Data::Vector2Vec(map.iter().next().unwrap().1.clone())
686 }
687 }
688 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
689 AnimatedData::Vector3Vec(map) => {
690 if TimeDataMapControl::is_animated(map) {
691 Data::Vector3Vec(map.interpolate(time))
692 } else {
693 Data::Vector3Vec(map.iter().next().unwrap().1.clone())
695 }
696 }
697 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
698 AnimatedData::Matrix3Vec(map) => {
699 if TimeDataMapControl::is_animated(map) {
700 Data::Matrix3Vec(map.interpolate(time))
701 } else {
702 Data::Matrix3Vec(map.iter().next().unwrap().1.clone())
704 }
705 }
706 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
707 AnimatedData::Normal3Vec(map) => {
708 if TimeDataMapControl::is_animated(map) {
709 Data::Normal3Vec(map.interpolate(time))
710 } else {
711 Data::Normal3Vec(map.iter().next().unwrap().1.clone())
713 }
714 }
715 #[cfg(all(feature = "point3", feature = "vec_variants"))]
716 AnimatedData::Point3Vec(map) => {
717 if TimeDataMapControl::is_animated(map) {
718 Data::Point3Vec(map.interpolate(time))
719 } else {
720 Data::Point3Vec(map.iter().next().unwrap().1.clone())
722 }
723 }
724 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
725 AnimatedData::Matrix4Vec(map) => {
726 if TimeDataMapControl::is_animated(map) {
727 Data::Matrix4Vec(map.interpolate(time))
728 } else {
729 Data::Matrix4Vec(map.iter().next().unwrap().1.clone())
731 }
732 }
733 #[cfg(feature = "curves")]
734 AnimatedData::RealCurve(map) => Data::RealCurve(map.closest_sample(time).clone()),
735 #[cfg(feature = "curves")]
736 AnimatedData::ColorCurve(map) => Data::ColorCurve(map.closest_sample(time).clone()),
737 }
738 }
739}
740
741impl Hash for AnimatedData {
742 fn hash<H: Hasher>(&self, state: &mut H) {
743 std::mem::discriminant(self).hash(state);
744 match self {
745 AnimatedData::Boolean(map) => {
746 map.len().hash(state);
747 #[cfg(not(feature = "interpolation"))]
748 for (time, value) in map.values.as_btree_map() {
749 time.hash(state);
750 value.0.hash(state);
751 }
752 #[cfg(feature = "interpolation")]
753 for (time, (value, spec)) in map.values.as_btree_map() {
754 time.hash(state);
755 value.0.hash(state);
756 spec.hash(state);
757 }
758 }
759 AnimatedData::Integer(map) => {
760 map.len().hash(state);
761 #[cfg(not(feature = "interpolation"))]
762 for (time, value) in map.values.as_btree_map() {
763 time.hash(state);
764 value.0.hash(state);
765 }
766 #[cfg(feature = "interpolation")]
767 for (time, (value, spec)) in map.values.as_btree_map() {
768 time.hash(state);
769 value.0.hash(state);
770 spec.hash(state);
771 }
772 }
773 AnimatedData::Real(map) => {
774 map.len().hash(state);
775 #[cfg(not(feature = "interpolation"))]
776 for (time, value) in map.values.as_btree_map() {
777 time.hash(state);
778 value.0.to_bits().hash(state);
779 }
780 #[cfg(feature = "interpolation")]
781 for (time, (value, spec)) in map.values.as_btree_map() {
782 time.hash(state);
783 value.0.to_bits().hash(state);
784 spec.hash(state);
785 }
786 }
787 AnimatedData::String(map) => {
788 map.len().hash(state);
789 #[cfg(not(feature = "interpolation"))]
790 for (time, value) in map.values.as_btree_map() {
791 time.hash(state);
792 value.0.hash(state);
793 }
794 #[cfg(feature = "interpolation")]
795 for (time, (value, spec)) in map.values.as_btree_map() {
796 time.hash(state);
797 value.0.hash(state);
798 spec.hash(state);
799 }
800 }
801 AnimatedData::Color(map) => {
802 map.len().hash(state);
803 #[cfg(not(feature = "interpolation"))]
804 for (time, value) in map.values.as_btree_map() {
805 time.hash(state);
806 value.0.iter().for_each(|v| v.to_bits().hash(state));
807 }
808 #[cfg(feature = "interpolation")]
809 for (time, (value, spec)) in map.values.as_btree_map() {
810 time.hash(state);
811 value.0.iter().for_each(|v| v.to_bits().hash(state));
812 spec.hash(state);
813 }
814 }
815 #[cfg(feature = "vector2")]
816 AnimatedData::Vector2(map) => {
817 map.len().hash(state);
818 #[cfg(not(feature = "interpolation"))]
819 for (time, value) in map.values.as_btree_map() {
820 time.hash(state);
821 crate::math::vec2_as_slice(&value.0)
822 .iter()
823 .for_each(|v| v.to_bits().hash(state));
824 }
825 #[cfg(feature = "interpolation")]
826 for (time, (value, spec)) in map.values.as_btree_map() {
827 time.hash(state);
828 crate::math::vec2_as_slice(&value.0)
829 .iter()
830 .for_each(|v| v.to_bits().hash(state));
831 spec.hash(state);
832 }
833 }
834 #[cfg(feature = "vector3")]
835 AnimatedData::Vector3(map) => {
836 map.len().hash(state);
837 #[cfg(not(feature = "interpolation"))]
838 for (time, value) in map.values.as_btree_map() {
839 time.hash(state);
840 crate::math::vec3_as_slice(&value.0)
841 .iter()
842 .for_each(|v| v.to_bits().hash(state));
843 }
844 #[cfg(feature = "interpolation")]
845 for (time, (value, spec)) in map.values.as_btree_map() {
846 time.hash(state);
847 crate::math::vec3_as_slice(&value.0)
848 .iter()
849 .for_each(|v| v.to_bits().hash(state));
850 spec.hash(state);
851 }
852 }
853 #[cfg(feature = "matrix3")]
854 AnimatedData::Matrix3(map) => {
855 map.len().hash(state);
856 #[cfg(not(feature = "interpolation"))]
857 for (time, value) in map.values.as_btree_map() {
858 time.hash(state);
859 crate::math::mat3_iter(&value.0).for_each(|v| v.to_bits().hash(state));
860 }
861 #[cfg(feature = "interpolation")]
862 for (time, (value, spec)) in map.values.as_btree_map() {
863 time.hash(state);
864 crate::math::mat3_iter(&value.0).for_each(|v| v.to_bits().hash(state));
865 spec.hash(state);
866 }
867 }
868 #[cfg(feature = "normal3")]
869 AnimatedData::Normal3(map) => {
870 map.len().hash(state);
871 #[cfg(not(feature = "interpolation"))]
872 for (time, value) in map.values.as_btree_map() {
873 time.hash(state);
874 crate::math::vec3_as_slice(&value.0)
875 .iter()
876 .for_each(|v| v.to_bits().hash(state));
877 }
878 #[cfg(feature = "interpolation")]
879 for (time, (value, spec)) in map.values.as_btree_map() {
880 time.hash(state);
881 crate::math::vec3_as_slice(&value.0)
882 .iter()
883 .for_each(|v| v.to_bits().hash(state));
884 spec.hash(state);
885 }
886 }
887 #[cfg(feature = "point3")]
888 AnimatedData::Point3(map) => {
889 map.len().hash(state);
890 #[cfg(not(feature = "interpolation"))]
891 for (time, value) in map.values.as_btree_map() {
892 time.hash(state);
893 crate::math::point3_as_slice(&value.0)
894 .iter()
895 .for_each(|v| v.to_bits().hash(state));
896 }
897 #[cfg(feature = "interpolation")]
898 for (time, (value, spec)) in map.values.as_btree_map() {
899 time.hash(state);
900 crate::math::point3_as_slice(&value.0)
901 .iter()
902 .for_each(|v| v.to_bits().hash(state));
903 spec.hash(state);
904 }
905 }
906 #[cfg(feature = "matrix4")]
907 AnimatedData::Matrix4(map) => {
908 map.len().hash(state);
909 #[cfg(not(feature = "interpolation"))]
910 for (time, value) in map.values.as_btree_map() {
911 time.hash(state);
912 crate::math::mat4_iter(&value.0).for_each(|v| v.to_bits().hash(state));
913 }
914 #[cfg(feature = "interpolation")]
915 for (time, (value, spec)) in map.values.as_btree_map() {
916 time.hash(state);
917 crate::math::mat4_iter(&value.0).for_each(|v| v.to_bits().hash(state));
918 spec.hash(state);
919 }
920 }
921 AnimatedData::BooleanVec(map) => {
922 map.len().hash(state);
923 #[cfg(not(feature = "interpolation"))]
924 for (time, value) in map.values.as_btree_map() {
925 time.hash(state);
926 value.0.hash(state);
927 }
928 #[cfg(feature = "interpolation")]
929 for (time, (value, spec)) in map.values.as_btree_map() {
930 time.hash(state);
931 value.0.hash(state);
932 spec.hash(state);
933 }
934 }
935 AnimatedData::IntegerVec(map) => {
936 map.len().hash(state);
937 #[cfg(not(feature = "interpolation"))]
938 for (time, value) in map.values.as_btree_map() {
939 time.hash(state);
940 value.0.hash(state);
941 }
942 #[cfg(feature = "interpolation")]
943 for (time, (value, spec)) in map.values.as_btree_map() {
944 time.hash(state);
945 value.0.hash(state);
946 spec.hash(state);
947 }
948 }
949 AnimatedData::RealVec(map) => {
950 map.len().hash(state);
951 #[cfg(not(feature = "interpolation"))]
952 for (time, value) in map.values.as_btree_map() {
953 time.hash(state);
954 value.0.len().hash(state);
955 value.0.iter().for_each(|v| v.to_bits().hash(state));
956 }
957 #[cfg(feature = "interpolation")]
958 for (time, (value, spec)) in map.values.as_btree_map() {
959 time.hash(state);
960 value.0.len().hash(state);
961 value.0.iter().for_each(|v| v.to_bits().hash(state));
962 spec.hash(state);
963 }
964 }
965 AnimatedData::ColorVec(map) => {
966 map.len().hash(state);
967 #[cfg(not(feature = "interpolation"))]
968 for (time, value) in map.values.as_btree_map() {
969 time.hash(state);
970 value.0.len().hash(state);
971 value.0.iter().for_each(|c| {
972 c.iter().for_each(|v| v.to_bits().hash(state));
973 });
974 }
975 #[cfg(feature = "interpolation")]
976 for (time, (value, spec)) in map.values.as_btree_map() {
977 time.hash(state);
978 value.0.len().hash(state);
979 value.0.iter().for_each(|c| {
980 c.iter().for_each(|v| v.to_bits().hash(state));
981 });
982 spec.hash(state);
983 }
984 }
985 AnimatedData::StringVec(map) => {
986 map.len().hash(state);
987 #[cfg(not(feature = "interpolation"))]
988 for (time, value) in map.values.as_btree_map() {
989 time.hash(state);
990 value.0.hash(state);
991 }
992 #[cfg(feature = "interpolation")]
993 for (time, (value, spec)) in map.values.as_btree_map() {
994 time.hash(state);
995 value.0.hash(state);
996 spec.hash(state);
997 }
998 }
999 #[cfg(all(feature = "vector2", feature = "vec_variants"))]
1000 AnimatedData::Vector2Vec(map) => {
1001 map.len().hash(state);
1002 #[cfg(not(feature = "interpolation"))]
1003 for (time, value) in map.values.as_btree_map() {
1004 time.hash(state);
1005 value.0.len().hash(state);
1006 value.0.iter().for_each(|v| {
1007 crate::math::vec2_as_slice(v)
1008 .iter()
1009 .for_each(|f| f.to_bits().hash(state));
1010 });
1011 }
1012 #[cfg(feature = "interpolation")]
1013 for (time, (value, spec)) in map.values.as_btree_map() {
1014 time.hash(state);
1015 value.0.len().hash(state);
1016 value.0.iter().for_each(|v| {
1017 crate::math::vec2_as_slice(v)
1018 .iter()
1019 .for_each(|f| f.to_bits().hash(state));
1020 });
1021 spec.hash(state);
1022 }
1023 }
1024 #[cfg(all(feature = "vector3", feature = "vec_variants"))]
1025 AnimatedData::Vector3Vec(map) => {
1026 map.len().hash(state);
1027 #[cfg(not(feature = "interpolation"))]
1028 for (time, value) in map.values.as_btree_map() {
1029 time.hash(state);
1030 value.0.len().hash(state);
1031 value.0.iter().for_each(|v| {
1032 crate::math::vec3_as_slice(v)
1033 .iter()
1034 .for_each(|f| f.to_bits().hash(state));
1035 });
1036 }
1037 #[cfg(feature = "interpolation")]
1038 for (time, (value, spec)) in map.values.as_btree_map() {
1039 time.hash(state);
1040 value.0.len().hash(state);
1041 value.0.iter().for_each(|v| {
1042 crate::math::vec3_as_slice(v)
1043 .iter()
1044 .for_each(|f| f.to_bits().hash(state));
1045 });
1046 spec.hash(state);
1047 }
1048 }
1049 #[cfg(all(feature = "matrix3", feature = "vec_variants"))]
1050 AnimatedData::Matrix3Vec(map) => {
1051 map.len().hash(state);
1052 #[cfg(not(feature = "interpolation"))]
1053 for (time, value) in map.values.as_btree_map() {
1054 time.hash(state);
1055 value.0.len().hash(state);
1056 value.0.iter().for_each(|m| {
1057 crate::math::mat3_iter(m).for_each(|f| f.to_bits().hash(state));
1058 });
1059 }
1060 #[cfg(feature = "interpolation")]
1061 for (time, (value, spec)) in map.values.as_btree_map() {
1062 time.hash(state);
1063 value.0.len().hash(state);
1064 value.0.iter().for_each(|m| {
1065 crate::math::mat3_iter(m).for_each(|f| f.to_bits().hash(state));
1066 });
1067 spec.hash(state);
1068 }
1069 }
1070 #[cfg(all(feature = "normal3", feature = "vec_variants"))]
1071 AnimatedData::Normal3Vec(map) => {
1072 map.len().hash(state);
1073 #[cfg(not(feature = "interpolation"))]
1074 for (time, value) in map.values.as_btree_map() {
1075 time.hash(state);
1076 value.0.len().hash(state);
1077 value.0.iter().for_each(|v| {
1078 crate::math::vec3_as_slice(v)
1079 .iter()
1080 .for_each(|f| f.to_bits().hash(state));
1081 });
1082 }
1083 #[cfg(feature = "interpolation")]
1084 for (time, (value, spec)) in map.values.as_btree_map() {
1085 time.hash(state);
1086 value.0.len().hash(state);
1087 value.0.iter().for_each(|v| {
1088 crate::math::vec3_as_slice(v)
1089 .iter()
1090 .for_each(|f| f.to_bits().hash(state));
1091 });
1092 spec.hash(state);
1093 }
1094 }
1095 #[cfg(all(feature = "point3", feature = "vec_variants"))]
1096 AnimatedData::Point3Vec(map) => {
1097 map.len().hash(state);
1098 #[cfg(not(feature = "interpolation"))]
1099 for (time, value) in map.values.as_btree_map() {
1100 time.hash(state);
1101 value.0.len().hash(state);
1102 value.0.iter().for_each(|p| {
1103 crate::math::point3_as_slice(p)
1104 .iter()
1105 .for_each(|f| f.to_bits().hash(state));
1106 });
1107 }
1108 #[cfg(feature = "interpolation")]
1109 for (time, (value, spec)) in map.values.as_btree_map() {
1110 time.hash(state);
1111 value.0.len().hash(state);
1112 value.0.iter().for_each(|p| {
1113 crate::math::point3_as_slice(p)
1114 .iter()
1115 .for_each(|f| f.to_bits().hash(state));
1116 });
1117 spec.hash(state);
1118 }
1119 }
1120 #[cfg(all(feature = "matrix4", feature = "vec_variants"))]
1121 AnimatedData::Matrix4Vec(map) => {
1122 map.len().hash(state);
1123 #[cfg(not(feature = "interpolation"))]
1124 for (time, value) in map.values.as_btree_map() {
1125 time.hash(state);
1126 value.0.len().hash(state);
1127 value.0.iter().for_each(|m| {
1128 crate::math::mat4_iter(m).for_each(|f| f.to_bits().hash(state));
1129 });
1130 }
1131 #[cfg(feature = "interpolation")]
1132 for (time, (value, spec)) in map.values.as_btree_map() {
1133 time.hash(state);
1134 value.0.len().hash(state);
1135 value.0.iter().for_each(|m| {
1136 crate::math::mat4_iter(m).for_each(|f| f.to_bits().hash(state));
1137 });
1138 spec.hash(state);
1139 }
1140 }
1141 #[cfg(feature = "curves")]
1142 AnimatedData::RealCurve(map) => {
1143 map.len().hash(state);
1144 #[cfg(not(feature = "interpolation"))]
1145 for (time, value) in map.values.as_btree_map() {
1146 time.hash(state);
1147 value.hash(state);
1148 }
1149 #[cfg(feature = "interpolation")]
1150 for (time, (value, spec)) in map.values.as_btree_map() {
1151 time.hash(state);
1152 value.hash(state);
1153 spec.hash(state);
1154 }
1155 }
1156 #[cfg(feature = "curves")]
1157 AnimatedData::ColorCurve(map) => {
1158 map.len().hash(state);
1159 #[cfg(not(feature = "interpolation"))]
1160 for (time, value) in map.values.as_btree_map() {
1161 time.hash(state);
1162 value.hash(state);
1163 }
1164 #[cfg(feature = "interpolation")]
1165 for (time, (value, spec)) in map.values.as_btree_map() {
1166 time.hash(state);
1167 value.hash(state);
1168 spec.hash(state);
1169 }
1170 }
1171 }
1172 }
1173}
1174
1175impl_sample_for_animated_data!(
1177 Real, Real;
1178 Integer, Integer;
1179 Color, Color;
1180);
1181
1182impl_sample_for_animated_data!(
1183 Vector2, Vector2, "vector2";
1184 Vector3, Vector3, "vector3";
1185 Matrix3, Matrix3, "matrix3";
1186 Normal3, Normal3, "normal3";
1187 Point3, Point3, "point3";
1188 Matrix4, Matrix4, "matrix4";
1189);
1190
1191impl AnimatedData {
1192 pub fn hash_with_shutter<H: Hasher>(&self, state: &mut H, shutter: &Shutter) {
1198 use smallvec::SmallVec;
1199
1200 const SAMPLE_POSITIONS: [f32; 5] = [0.0, 0.25, 0.5, 0.75, 1.0];
1202
1203 let samples: SmallVec<[Data; 5]> = SAMPLE_POSITIONS
1205 .iter()
1206 .map(|&pos| {
1207 let time = shutter.evaluate(pos);
1208 self.interpolate(time)
1209 })
1210 .collect();
1211
1212 let all_same = samples.windows(2).all(|w| w[0] == w[1]);
1214
1215 std::mem::discriminant(self).hash(state);
1217
1218 if all_same {
1219 1usize.hash(state); samples[0].hash(state);
1222 } else {
1223 samples.len().hash(state); for sample in &samples {
1226 sample.hash(state);
1227 }
1228 }
1229 }
1230}
1231
1232impl crate::traits::AnimatedDataSystem for AnimatedData {
1234 type Data = Data;
1235
1236 fn keyframe_count(&self) -> usize {
1237 AnimatedDataOps::len(self)
1238 }
1239
1240 fn is_keyframes_empty(&self) -> bool {
1241 AnimatedDataOps::is_empty(self)
1242 }
1243
1244 fn has_animation(&self) -> bool {
1245 AnimatedDataOps::is_animated(self)
1246 }
1247
1248 fn times(&self) -> SmallVec<[Time; 10]> {
1249 AnimatedData::times(self)
1250 }
1251
1252 fn interpolate(&self, time: Time) -> Data {
1253 AnimatedData::interpolate(self, time)
1254 }
1255
1256 fn sample_at(&self, time: Time) -> Option<Data> {
1257 AnimatedData::sample_at(self, time)
1258 }
1259
1260 fn try_insert(&mut self, time: Time, value: Data) -> Result<()> {
1261 AnimatedData::try_insert(self, time, value)
1262 }
1263
1264 fn remove_at(&mut self, time: &Time) -> Option<Data> {
1265 AnimatedData::remove_at(self, time)
1266 }
1267
1268 fn discriminant(&self) -> DataType {
1269 DataTypeOps::data_type(self)
1270 }
1271
1272 fn from_single(time: Time, value: Data) -> Self {
1273 AnimatedData::from((time, value))
1274 }
1275
1276 fn variant_name(&self) -> &'static str {
1277 DataTypeOps::type_name(self)
1278 }
1279}