1use crate::*;
2use enum_dispatch::enum_dispatch;
3use mitsein::btree_map1::BTreeMap1;
4
5use std::{
6 collections::BTreeMap,
7 iter::FromIterator,
8 ops::{Add, Mul, Sub},
9};
10
11mod sample;
12pub use sample::*;
13
14#[derive(Clone, Debug, PartialEq, Hash)]
28#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
29#[cfg_attr(
30 feature = "serde",
31 serde(bound(
32 serialize = "K: Serialize + Ord, V: Serialize",
33 deserialize = "K: Deserialize<'de> + Ord, V: Deserialize<'de>",
34 ))
35)]
36#[cfg_attr(feature = "facet", derive(Facet))]
37#[cfg_attr(feature = "facet", facet(opaque))]
38pub struct KeyDataMap<K, V> {
39 #[cfg(not(feature = "interpolation"))]
43 pub values: BTreeMap1<K, V>,
44 #[cfg(feature = "interpolation")]
45 pub values: BTreeMap1<K, (V, Option<crate::Key<V>>)>,
46}
47
48pub type TimeDataMap<V> = KeyDataMap<Time, V>;
50
51impl<K: Eq, V: Eq> Eq for KeyDataMap<K, V> {}
53
54#[cfg(feature = "rkyv")]
61const _: () = {
62 use rkyv::rancor::{Fallible, Source};
63 use rkyv::{
64 Archive, Deserialize, Place, Serialize,
65 collections::btree_map::{ArchivedBTreeMap, BTreeMapResolver},
66 traits::Portable,
67 };
68 use std::collections::BTreeMap;
69
70 #[repr(transparent)]
73 pub struct ArchivedKeyDataMap<K, V>(ArchivedBTreeMap<K, V>);
74
75 unsafe impl<K: Portable, V: Portable> Portable for ArchivedKeyDataMap<K, V> {}
78
79 #[cfg(not(feature = "interpolation"))]
82 impl<K, V> Archive for super::KeyDataMap<K, V>
83 where
84 K: Archive + Ord,
85 K::Archived: Ord,
86 V: Archive,
87 {
88 type Archived = ArchivedKeyDataMap<K::Archived, V::Archived>;
89 type Resolver = BTreeMapResolver;
90
91 fn resolve(&self, resolver: Self::Resolver, out: Place<Self::Archived>) {
92 let out = unsafe { out.cast_unchecked::<ArchivedBTreeMap<K::Archived, V::Archived>>() };
94 ArchivedBTreeMap::resolve_from_len(self.values.len().get(), resolver, out);
95 }
96 }
97
98 #[cfg(not(feature = "interpolation"))]
99 impl<K, V, S> Serialize<S> for super::KeyDataMap<K, V>
100 where
101 K: Serialize<S> + Ord,
102 K::Archived: Ord,
103 V: Serialize<S>,
104 S: rkyv::ser::Allocator + Fallible + rkyv::ser::Writer + ?Sized,
105 S::Error: Source,
106 {
107 fn serialize(&self, serializer: &mut S) -> std::result::Result<Self::Resolver, S::Error> {
108 <ArchivedBTreeMap<K::Archived, V::Archived>>::serialize_from_ordered_iter::<
109 _,
110 _,
111 _,
112 K,
113 V,
114 _,
115 >(self.values.as_btree_map().iter(), serializer)
116 }
117 }
118
119 #[cfg(not(feature = "interpolation"))]
120 impl<K, V, D> Deserialize<super::KeyDataMap<K, V>, D>
121 for ArchivedKeyDataMap<K::Archived, V::Archived>
122 where
123 K: Archive + Ord,
124 K::Archived: Deserialize<K, D> + Ord,
125 V: Archive,
126 V::Archived: Deserialize<V, D>,
127 D: Fallible + ?Sized,
128 {
129 fn deserialize(
130 &self,
131 deserializer: &mut D,
132 ) -> std::result::Result<super::KeyDataMap<K, V>, D::Error> {
133 let btree: BTreeMap<K, V> = self.0.deserialize(deserializer)?;
134 Ok(super::KeyDataMap {
136 values: mitsein::btree_map1::BTreeMap1::try_from(btree)
137 .expect("archived KeyDataMap was empty"),
138 })
139 }
140 }
141
142 #[cfg(feature = "interpolation")]
149 type ArchivedInterp<V> = <(V, Option<crate::Key<V>>) as Archive>::Archived;
150
151 #[cfg(feature = "interpolation")]
152 impl<K, V> Archive for super::KeyDataMap<K, V>
153 where
154 K: Archive + Ord,
155 K::Archived: Ord,
156 V: Archive,
157 (V, Option<crate::Key<V>>): Archive,
158 {
159 type Archived = ArchivedKeyDataMap<K::Archived, ArchivedInterp<V>>;
160 type Resolver = BTreeMapResolver;
161
162 fn resolve(&self, resolver: Self::Resolver, out: Place<Self::Archived>) {
163 let out =
165 unsafe { out.cast_unchecked::<ArchivedBTreeMap<K::Archived, ArchivedInterp<V>>>() };
166 ArchivedBTreeMap::resolve_from_len(self.values.len().get(), resolver, out);
167 }
168 }
169
170 #[cfg(feature = "interpolation")]
171 impl<K, V, S> Serialize<S> for super::KeyDataMap<K, V>
172 where
173 K: Serialize<S> + Ord,
174 K::Archived: Ord,
175 V: Serialize<S>,
176 (V, Option<crate::Key<V>>): Serialize<S>,
177 S: rkyv::ser::Allocator + Fallible + rkyv::ser::Writer + ?Sized,
178 S::Error: Source,
179 {
180 fn serialize(&self, serializer: &mut S) -> std::result::Result<Self::Resolver, S::Error> {
181 <ArchivedBTreeMap<K::Archived, ArchivedInterp<V>>>::serialize_from_ordered_iter::<
182 _,
183 _,
184 _,
185 K,
186 (V, Option<crate::Key<V>>),
187 _,
188 >(self.values.as_btree_map().iter(), serializer)
189 }
190 }
191
192 #[cfg(feature = "interpolation")]
193 impl<K, V, D> Deserialize<super::KeyDataMap<K, V>, D>
194 for ArchivedKeyDataMap<K::Archived, ArchivedInterp<V>>
195 where
196 K: Archive + Ord,
197 K::Archived: Deserialize<K, D> + Ord,
198 V: Archive,
199 (V, Option<crate::Key<V>>): Archive,
200 ArchivedInterp<V>: Deserialize<(V, Option<crate::Key<V>>), D>,
201 D: Fallible + ?Sized,
202 {
203 fn deserialize(
204 &self,
205 deserializer: &mut D,
206 ) -> std::result::Result<super::KeyDataMap<K, V>, D::Error> {
207 let btree: BTreeMap<K, (V, Option<crate::Key<V>>)> =
208 self.0.deserialize(deserializer)?;
209 Ok(super::KeyDataMap {
211 values: mitsein::btree_map1::BTreeMap1::try_from(btree)
212 .expect("archived KeyDataMap was empty"),
213 })
214 }
215 }
216};
217
218#[cfg(not(feature = "interpolation"))]
220impl<K, V> AsRef<BTreeMap<K, V>> for KeyDataMap<K, V> {
221 fn as_ref(&self) -> &BTreeMap<K, V> {
222 self.values.as_btree_map()
223 }
224}
225
226impl<K: Ord, V> KeyDataMap<K, V> {
227 #[inline]
229 pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
230 #[cfg(not(feature = "interpolation"))]
231 {
232 self.values.as_btree_map().iter()
233 }
234 #[cfg(feature = "interpolation")]
235 {
236 self.values.as_btree_map().iter().map(|(k, (v, _))| (k, v))
237 }
238 }
239
240 #[inline]
242 pub fn is_empty(&self) -> bool {
243 false
244 }
245
246 #[inline]
248 pub fn len(&self) -> usize {
249 self.values.len().get()
250 }
251
252 #[inline]
258 pub fn remove(&mut self, key: &K) -> crate::Result<Option<V>> {
259 if !self.values.contains_key(key) {
260 return Ok(None);
261 }
262 if self.values.len().get() == 1 {
263 return Err(crate::Error::LastSample);
264 }
265 #[cfg(not(feature = "interpolation"))]
267 {
268 Ok(unsafe { self.values.as_mut_btree_map() }.remove(key))
269 }
270 #[cfg(feature = "interpolation")]
271 {
272 Ok(unsafe { self.values.as_mut_btree_map() }
273 .remove(key)
274 .map(|(v, _)| v))
275 }
276 }
277}
278
279impl<K: Ord, V> TryFrom<BTreeMap<K, V>> for KeyDataMap<K, V> {
281 type Error = crate::Error;
282
283 fn try_from(values: BTreeMap<K, V>) -> crate::Result<Self> {
284 #[cfg(not(feature = "interpolation"))]
285 {
286 let values = BTreeMap1::try_from(values).map_err(|_| crate::Error::EmptySamples)?;
287 Ok(Self { values })
288 }
289 #[cfg(feature = "interpolation")]
290 {
291 let interp_values: BTreeMap<K, (V, Option<crate::Key<V>>)> =
292 values.into_iter().map(|(k, v)| (k, (v, None))).collect();
293 let values =
294 BTreeMap1::try_from(interp_values).map_err(|_| crate::Error::EmptySamples)?;
295 Ok(Self { values })
296 }
297 }
298}
299
300#[cfg(not(feature = "interpolation"))]
302impl<K: Ord, V> From<BTreeMap1<K, V>> for KeyDataMap<K, V> {
303 fn from(values: BTreeMap1<K, V>) -> Self {
304 Self { values }
305 }
306}
307
308impl<K: Ord, V> KeyDataMap<K, V> {
309 pub fn from_single(key: K, value: V) -> Self {
311 #[cfg(not(feature = "interpolation"))]
312 {
313 Self {
314 values: BTreeMap1::from_one((key, value)),
315 }
316 }
317 #[cfg(feature = "interpolation")]
318 {
319 Self {
320 values: BTreeMap1::from_one((key, (value, None))),
321 }
322 }
323 }
324}
325
326#[enum_dispatch]
328pub trait TimeDataMapControl<T> {
329 fn len(&self) -> usize;
331 fn is_empty(&self) -> bool;
333 fn is_animated(&self) -> bool;
335}
336
337impl<V> TimeDataMapControl<V> for KeyDataMap<Time, V> {
338 fn len(&self) -> usize {
339 self.values.len().get()
340 }
341
342 fn is_empty(&self) -> bool {
343 false
344 }
345
346 fn is_animated(&self) -> bool {
347 self.values.len().get() > 1
348 }
349}
350
351#[cfg(feature = "builtin-types")]
352impl<K: Ord, V> crate::DataTypeOps for KeyDataMap<K, V>
353where
354 V: crate::DataTypeOps,
355{
356 fn data_type(&self) -> crate::DataType {
357 #[cfg(not(feature = "interpolation"))]
359 {
360 self.values.first_key_value().1.data_type()
361 }
362 #[cfg(feature = "interpolation")]
363 {
364 self.values.first_key_value().1.0.data_type()
365 }
366 }
367
368 fn type_name(&self) -> &'static str {
369 #[cfg(not(feature = "interpolation"))]
371 {
372 self.values.first_key_value().1.type_name()
373 }
374 #[cfg(feature = "interpolation")]
375 {
376 self.values.first_key_value().1.0.type_name()
377 }
378 }
379}
380
381#[cfg(feature = "builtin-types")]
384macro_rules! impl_from_at_time {
385 ($($t:ty),+) => {
386 $(
387 impl From<(Time, $t)> for TimeDataMap<$t> {
388 fn from((time, value): (Time, $t)) -> Self {
389 KeyDataMap::from_single(time, value)
390 }
391 }
392 )+
393 };
394}
395
396#[cfg(feature = "builtin-types")]
397impl_from_at_time!(
398 Boolean, Real, Integer, String, Color, BooleanVec, RealVec, IntegerVec, StringVec, ColorVec,
399 Data
400);
401
402#[cfg(all(feature = "builtin-types", feature = "curves"))]
403impl_from_at_time!(RealCurve, ColorCurve);
404
405#[cfg(all(feature = "builtin-types", feature = "vector2"))]
406impl_from_at_time!(Vector2);
407#[cfg(all(feature = "builtin-types", feature = "vector3"))]
408impl_from_at_time!(Vector3);
409#[cfg(all(feature = "builtin-types", feature = "matrix3"))]
410impl_from_at_time!(Matrix3);
411#[cfg(all(feature = "builtin-types", feature = "normal3"))]
412impl_from_at_time!(Normal3);
413#[cfg(all(feature = "builtin-types", feature = "point3"))]
414impl_from_at_time!(Point3);
415#[cfg(all(feature = "builtin-types", feature = "matrix4"))]
416impl_from_at_time!(Matrix4);
417
418#[cfg(all(
419 feature = "builtin-types",
420 feature = "vector2",
421 feature = "vec_variants"
422))]
423impl_from_at_time!(Vector2Vec);
424#[cfg(all(
425 feature = "builtin-types",
426 feature = "vector3",
427 feature = "vec_variants"
428))]
429impl_from_at_time!(Vector3Vec);
430#[cfg(all(
431 feature = "builtin-types",
432 feature = "matrix3",
433 feature = "vec_variants"
434))]
435impl_from_at_time!(Matrix3Vec);
436#[cfg(all(
437 feature = "builtin-types",
438 feature = "normal3",
439 feature = "vec_variants"
440))]
441impl_from_at_time!(Normal3Vec);
442#[cfg(all(
443 feature = "builtin-types",
444 feature = "point3",
445 feature = "vec_variants"
446))]
447impl_from_at_time!(Point3Vec);
448#[cfg(all(
449 feature = "builtin-types",
450 feature = "matrix4",
451 feature = "vec_variants"
452))]
453impl_from_at_time!(Matrix4Vec);
454
455impl<K: Ord, V> KeyDataMap<K, V> {
456 pub fn insert(&mut self, key: K, value: V) {
458 #[cfg(not(feature = "interpolation"))]
459 {
460 self.values.insert(key, value);
461 }
462 #[cfg(feature = "interpolation")]
463 {
464 self.values.insert(key, (value, None));
465 }
466 }
467
468 pub fn get(&self, key: &K) -> Option<&V> {
470 #[cfg(not(feature = "interpolation"))]
471 {
472 self.values.get(key)
473 }
474 #[cfg(feature = "interpolation")]
475 {
476 self.values.get(key).map(|(v, _)| v)
477 }
478 }
479}
480
481impl<K, V> KeyDataMap<K, V>
482where
483 K: Ord + Copy + Into<f32>,
484 V: Clone + Add<Output = V> + Mul<f32, Output = V> + Sub<Output = V>,
485{
486 pub fn interpolate(&self, key: K) -> V {
487 #[cfg(not(feature = "interpolation"))]
488 {
489 interpolate(self.values.as_btree_map(), key)
490 }
491 #[cfg(feature = "interpolation")]
492 {
493 interpolate_with_specs(self.values.as_btree_map(), key)
494 }
495 }
496}
497
498#[cfg(feature = "interpolation")]
500impl<K: Ord, V> KeyDataMap<K, V> {
501 pub fn insert_with_interpolation(&mut self, key: K, value: V, spec: crate::Key<V>) {
506 self.values.insert(key, (value, Some(spec)));
507 }
508
509 pub fn interpolation(&self, key: &K) -> Option<&crate::Key<V>> {
513 self.values.get(key)?.1.as_ref()
514 }
515
516 pub fn set_interpolation_at(&mut self, key: &K, spec: crate::Key<V>) -> crate::Result<()> {
521 if let Some(entry) = self.values.get_mut(key) {
522 entry.1 = Some(spec);
523 Ok(())
524 } else {
525 Err(crate::Error::KeyNotFound)
526 }
527 }
528
529 pub fn clear_interpolation(&mut self) {
533 for (_, interp) in unsafe { self.values.as_mut_btree_map() }.values_mut() {
535 *interp = None;
536 }
537 }
538
539 pub fn has_interpolation(&self) -> bool {
543 self.values
544 .as_btree_map()
545 .values()
546 .any(|(_, interp)| interp.is_some())
547 }
548}
549
550impl<K: Ord, V, U> FromIterator<(K, U)> for KeyDataMap<K, V>
551where
552 U: Into<V>,
553{
554 fn from_iter<I>(iter: I) -> Self
555 where
556 I: IntoIterator<Item = (K, U)>,
557 {
558 let btree: BTreeMap<K, V> = iter.into_iter().map(|(k, v)| (k, v.into())).collect();
559 Self::try_from(btree).expect("KeyDataMap::from_iter called with empty iterator")
562 }
563}
564
565impl<K: Ord + Copy + Into<f32>, V> KeyDataMap<K, V> {
566 pub fn sample_closest_at(&self, key: K) -> &V {
567 let k_f32: f32 = key.into();
568 let map = self.values.as_btree_map();
569 #[cfg(not(feature = "interpolation"))]
570 {
571 let greater_or_equal = map.range(key..).next();
572 let less_than = map.range(..key).next_back();
573
574 match (less_than, greater_or_equal) {
575 (Some((lower_k, lower_v)), Some((upper_k, upper_v))) => {
576 let lo: f32 = (*lower_k).into();
577 let hi: f32 = (*upper_k).into();
578 if (k_f32 - lo).abs() <= (hi - k_f32).abs() {
579 lower_v
580 } else {
581 upper_v
582 }
583 }
584 (Some(entry), None) | (None, Some(entry)) => entry.1,
585 (None, None) => {
587 unreachable!("BTreeMap1 guarantees KeyDataMap is never empty")
588 }
589 }
590 }
591 #[cfg(feature = "interpolation")]
592 {
593 let greater_or_equal = map.range(key..).next();
594 let less_than = map.range(..key).next_back();
595
596 match (less_than, greater_or_equal) {
597 (Some((lower_k, (lower_v, _))), Some((upper_k, (upper_v, _)))) => {
598 let lo: f32 = (*lower_k).into();
599 let hi: f32 = (*upper_k).into();
600 if (k_f32 - lo).abs() <= (hi - k_f32).abs() {
601 lower_v
602 } else {
603 upper_v
604 }
605 }
606 (Some((_, (v, _))), None) | (None, Some((_, (v, _)))) => v,
607 (None, None) => {
609 unreachable!("BTreeMap1 guarantees KeyDataMap is never empty")
610 }
611 }
612 }
613 }
614
615 pub fn sample_at(&self, key: K) -> Option<&V> {
617 self.get(&key)
618 }
619
620 pub fn sample_at_or_before(&self, key: K) -> Option<&V> {
622 let map = self.values.as_btree_map();
623 #[cfg(not(feature = "interpolation"))]
624 {
625 map.range(..=key).next_back().map(|(_, v)| v)
626 }
627 #[cfg(feature = "interpolation")]
628 {
629 map.range(..=key).next_back().map(|(_, (v, _))| v)
630 }
631 }
632
633 pub fn sample_at_or_after(&self, key: K) -> Option<&V> {
635 let map = self.values.as_btree_map();
636 #[cfg(not(feature = "interpolation"))]
637 {
638 map.range(key..).next().map(|(_, v)| v)
639 }
640 #[cfg(feature = "interpolation")]
641 {
642 map.range(key..).next().map(|(_, (v, _))| v)
643 }
644 }
645
646 pub fn sample_surrounding<const N: usize>(&self, key: K) -> SmallVec<[(K, &V); N]> {
651 let map = self.values.as_btree_map();
652 let before_count = N / 2;
654
655 #[cfg(not(feature = "interpolation"))]
656 {
657 let mut result = map
658 .range(..key)
659 .rev()
660 .take(before_count)
661 .map(|(k, v)| (*k, v))
662 .collect::<SmallVec<[_; N]>>();
663 result.reverse();
664
665 let after_count = N - result.len();
667 result.extend(map.range(key..).take(after_count).map(|(k, v)| (*k, v)));
668 result
669 }
670
671 #[cfg(feature = "interpolation")]
672 {
673 let mut result = map
674 .range(..key)
675 .rev()
676 .take(before_count)
677 .map(|(k, (v, _))| (*k, v))
678 .collect::<SmallVec<[_; N]>>();
679 result.reverse();
680
681 let after_count = N - result.len();
683 result.extend(
684 map.range(key..)
685 .take(after_count)
686 .map(|(k, (v, _))| (*k, v)),
687 );
688 result
689 }
690 }
691
692 #[deprecated(since = "0.2.3", note = "renamed to `sample_closest_at`")]
694 pub fn closest_sample(&self, key: K) -> &V {
695 self.sample_closest_at(key)
696 }
697}
698
699#[cfg(feature = "matrix3")]
706#[derive(Clone)]
707struct Trans2(f32, f32);
708
709#[cfg(feature = "matrix3")]
710impl Add for Trans2 {
711 type Output = Self;
712 fn add(self, rhs: Self) -> Self {
713 Trans2(self.0 + rhs.0, self.1 + rhs.1)
714 }
715}
716
717#[cfg(feature = "matrix3")]
718impl Sub for Trans2 {
719 type Output = Self;
720 fn sub(self, rhs: Self) -> Self {
721 Trans2(self.0 - rhs.0, self.1 - rhs.1)
722 }
723}
724
725#[cfg(feature = "matrix3")]
726impl Mul<f32> for Trans2 {
727 type Output = Self;
728 fn mul(self, s: f32) -> Self {
729 Trans2(self.0 * s, self.1 * s)
730 }
731}
732
733#[cfg(feature = "matrix3")]
735#[derive(Clone)]
736struct DiagStretch(f32, f32);
737
738#[cfg(feature = "matrix3")]
739impl Add for DiagStretch {
740 type Output = Self;
741 fn add(self, rhs: Self) -> Self {
742 DiagStretch(self.0 + rhs.0, self.1 + rhs.1)
743 }
744}
745
746#[cfg(feature = "matrix3")]
747impl Sub for DiagStretch {
748 type Output = Self;
749 fn sub(self, rhs: Self) -> Self {
750 DiagStretch(self.0 - rhs.0, self.1 - rhs.1)
751 }
752}
753
754#[cfg(feature = "matrix3")]
755impl Mul<f32> for DiagStretch {
756 type Output = Self;
757 fn mul(self, s: f32) -> Self {
758 DiagStretch(self.0 * s, self.1 * s)
759 }
760}
761
762#[cfg(feature = "matrix3")]
764#[inline(always)]
765fn interpolate_rotation(map: &BTreeMap<Time, f32>, time: Time) -> f32 {
766 if map.len() == 1 {
767 return *map.values().next().unwrap();
769 }
770
771 let first = map.iter().next().unwrap();
773 let last = map.iter().next_back().unwrap();
774
775 if time <= *first.0 {
776 return *first.1;
777 }
778
779 if time >= *last.0 {
780 return *last.1;
781 }
782
783 let lower = map.range(..=time).next_back().unwrap();
785 let upper = map.range(time..).next().unwrap();
786
787 let t0 = f32::from(*lower.0);
788 let t1 = f32::from(*upper.0);
789 let a0 = *lower.1;
790 let a1 = *upper.1;
791
792 let t: f32 = (f32::from(time) - t0) / (t1 - t0);
794
795 use std::f32::consts::{PI, TAU};
797 let mut diff = a1 - a0;
798 if diff > PI {
799 diff -= TAU;
800 } else if diff < -PI {
801 diff += TAU;
802 }
803 a0 + diff * t
804}
805
806#[cfg(feature = "interpolation")]
809fn bezier_handle_to_slope<V>(
810 handle: &crate::BezierHandle<V>,
811 t1: f32,
812 t2: f32,
813 _v1: &V,
814 _v2: &V,
815) -> Option<V>
816where
817 V: Clone + Add<Output = V> + Sub<Output = V> + Mul<f32, Output = V>,
818{
819 match handle {
820 crate::BezierHandle::SlopePerSecond(s) => Some(s.clone()),
821 crate::BezierHandle::SlopePerFrame(s) => {
822 let frames = (t2 - t1).max(f32::EPSILON);
823 Some(s.clone() * (frames / (t2 - t1)))
824 }
825 crate::BezierHandle::Delta { time, value } => {
826 let time_f32: f32 = (*time).into();
827 if time_f32.abs() <= f32::EPSILON {
828 None
829 } else {
830 Some(value.clone() * (1.0 / time_f32))
831 }
832 }
833 crate::BezierHandle::Angle(_) => None, }
835}
836
837#[cfg(feature = "interpolation")]
838#[allow(clippy::too_many_arguments)]
839fn smooth_tangent<K, V>(
840 t1: f32,
841 v1: &V,
842 t2: f32,
843 v2: &V,
844 map: &BTreeMap<K, (V, Option<crate::Key<V>>)>,
845 _key: K,
846 anchor: K,
847 incoming: bool,
848) -> V
849where
850 K: Ord + Copy + Into<f32>,
851 V: Clone + Add<Output = V> + Mul<f32, Output = V> + Sub<Output = V>,
852{
853 use smallvec::SmallVec;
854
855 let mut window = SmallVec::<[(K, V); 2]>::new();
857
858 if incoming {
859 if let Some(prev) = map.range(..anchor).next_back() {
860 window.push((*prev.0, prev.1.0.clone()));
861 }
862 window.push((anchor, v1.clone()));
863 } else {
864 window.push((anchor, v1.clone()));
865 if let Some(next) = map.range(anchor..).nth(1) {
866 window.push((*next.0, next.1.0.clone()));
867 }
868 }
869
870 if window.len() == 2 {
871 let (k0, p0) = &window[0];
872 let (k1, p1) = &window[1];
873 let k0_f: f32 = (*k0).into();
874 let k1_f: f32 = (*k1).into();
875 let dt = (k1_f - k0_f).max(f32::EPSILON);
876 (p1.clone() - p0.clone()) * (1.0 / dt)
877 } else {
878 (v2.clone() - v1.clone()) * (1.0 / (t2 - t1).max(f32::EPSILON))
880 }
881}
882
883#[cfg(feature = "interpolation")]
884fn evaluate_mixed_bezier<K, V>(
885 key: K,
886 k1: K,
887 v1: &V,
888 slope_out: &V,
889 k2: K,
890 v2: &V,
891 slope_in: &V,
892) -> V
893where
894 K: Copy + Into<f32>,
895 V: Clone + Add<Output = V> + Mul<f32, Output = V> + Sub<Output = V>,
896{
897 use crate::interpolation::bezier_helpers::*;
898
899 let (p1, p2) = control_points_from_slopes(k1.into(), v1, slope_out, k2.into(), v2, slope_in);
900
901 evaluate_bezier_component_wise(
902 key.into(),
903 (k1.into(), v1),
904 (p1.0, &p1.1),
905 (p2.0, &p2.1),
906 (k2.into(), v2),
907 )
908}
909
910#[cfg(feature = "interpolation")]
915#[inline(always)]
916pub(crate) fn interpolate_with_specs<K, V>(
917 map: &BTreeMap<K, (V, Option<crate::Key<V>>)>,
918 key: K,
919) -> V
920where
921 K: Ord + Copy + Into<f32>,
922 V: Clone + Add<Output = V> + Mul<f32, Output = V> + Sub<Output = V>,
923{
924 if map.len() == 1 {
925 return map.values().next().unwrap().0.clone();
927 }
928
929 let first = map.iter().next().unwrap();
931 let last = map.iter().next_back().unwrap();
932
933 if key <= *first.0 {
934 return first.1.0.clone();
935 }
936
937 if key >= *last.0 {
938 return last.1.0.clone();
939 }
940
941 let lower = map.range(..key).next_back().unwrap();
943 let upper = map.range(key..).next().unwrap();
944
945 if lower.0 == upper.0 {
947 return lower.1.0.clone();
948 }
949
950 let (k1, (v1, spec1)) = lower;
951 let (k2, (v2, spec2)) = upper;
952
953 let interp_out = spec1.as_ref().map(|s| &s.interpolation_out);
955 let interp_in = spec2.as_ref().map(|s| &s.interpolation_in);
956
957 match (interp_out, interp_in) {
958 (Some(crate::Interpolation::Hold), _) | (_, Some(crate::Interpolation::Hold)) => v1.clone(),
960
961 (
963 Some(crate::Interpolation::Bezier(out_handle)),
964 Some(crate::Interpolation::Bezier(in_handle)),
965 ) => {
966 use crate::interpolation::bezier_helpers::*;
967
968 if let (Some(slope_out), Some(slope_in)) = (
969 bezier_handle_to_slope(out_handle, (*k1).into(), (*k2).into(), v1, v2),
970 bezier_handle_to_slope(in_handle, (*k1).into(), (*k2).into(), v1, v2),
971 ) {
972 let (p1, p2) = control_points_from_slopes(
973 (*k1).into(),
974 v1,
975 &slope_out,
976 (*k2).into(),
977 v2,
978 &slope_in,
979 );
980
981 evaluate_bezier_component_wise(
982 key.into(),
983 ((*k1).into(), v1),
984 (p1.0, &p1.1),
985 (p2.0, &p2.1),
986 ((*k2).into(), v2),
987 )
988 } else {
989 linear_interp(*k1, *k2, v1, v2, key)
991 }
992 }
993
994 (Some(crate::Interpolation::Bezier(out_handle)), Some(crate::Interpolation::Smooth)) => {
996 if let Some(slope_out) =
997 bezier_handle_to_slope(out_handle, (*k1).into(), (*k2).into(), v1, v2)
998 {
999 let slope_in =
1000 smooth_tangent((*k1).into(), v1, (*k2).into(), v2, map, key, *k1, false);
1001
1002 evaluate_mixed_bezier(key, *k1, v1, &slope_out, *k2, v2, &slope_in)
1003 } else {
1004 linear_interp(*k1, *k2, v1, v2, key)
1005 }
1006 }
1007 (Some(crate::Interpolation::Smooth), Some(crate::Interpolation::Bezier(in_handle))) => {
1008 if let Some(slope_in) =
1009 bezier_handle_to_slope(in_handle, (*k1).into(), (*k2).into(), v1, v2)
1010 {
1011 let slope_out =
1012 smooth_tangent((*k1).into(), v1, (*k2).into(), v2, map, key, *k1, true);
1013
1014 evaluate_mixed_bezier(key, *k1, v1, &slope_out, *k2, v2, &slope_in)
1015 } else {
1016 linear_interp(*k1, *k2, v1, v2, key)
1017 }
1018 }
1019
1020 (Some(crate::Interpolation::Smooth), Some(crate::Interpolation::Smooth)) | (None, None) => {
1022 let values_only: BTreeMap<K, V> =
1023 map.iter().map(|(k, (v, _))| (*k, v.clone())).collect();
1024 interpolate(&values_only, key)
1025 }
1026
1027 _ => linear_interp(*k1, *k2, v1, v2, key),
1029 }
1030}
1031
1032#[inline(always)]
1033pub(crate) fn interpolate<K, V>(map: &BTreeMap<K, V>, key: K) -> V
1034where
1035 K: Ord + Copy + Into<f32>,
1036 V: Clone + Add<Output = V> + Mul<f32, Output = V> + Sub<Output = V>,
1037{
1038 if map.len() == 1 {
1039 return map.values().next().unwrap().clone();
1041 }
1042
1043 let first = map.iter().next().unwrap();
1045 let last = map.iter().next_back().unwrap();
1046
1047 if key <= *first.0 {
1048 return first.1.clone();
1049 }
1050
1051 if key >= *last.0 {
1052 return last.1.clone();
1053 }
1054
1055 let lower = map.range(..key).next_back().unwrap();
1057 let upper = map.range(key..).next().unwrap();
1058
1059 let mut window = SmallVec::<[(K, &V); 4]>::new();
1064
1065 window.extend(map.range(..*lower.0).rev().take(2).map(|(k, v)| (*k, v)));
1067
1068 window.push((*lower.0, lower.1));
1070
1071 if lower.0 != upper.0 {
1072 window.push((*upper.0, upper.1));
1073 }
1074
1075 window.extend(map.range(*upper.0..).skip(1).take(1).map(|(k, v)| (*k, v)));
1077
1078 window.reverse();
1080
1081 match window.len() {
1082 4 => {
1083 let (t0, p0) = window[0];
1084 let (t1, p1) = window[1];
1085 let (t2, p2) = window[2];
1086 let (t3, p3) = window[3];
1087 hermite_interp(HermiteParams {
1088 t0,
1089 t1,
1090 t2,
1091 t3,
1092 p0,
1093 p1,
1094 p2,
1095 p3,
1096 t: key,
1097 })
1098 }
1099 3 => {
1100 let (t0, p0) = window[0];
1101 let (t1, p1) = window[1];
1102 let (t2, p2) = window[2];
1103 quadratic_interp(t0, t1, t2, p0, p1, p2, key)
1104 }
1105 2 => {
1106 let (x0, y0) = window[0];
1107 let (x1, y1) = window[1];
1108 linear_interp(x0, x1, y0, y1, key)
1109 }
1110 1 => {
1111 window[0].1.clone()
1113 }
1114 0 => {
1115 panic!("Interpolation window is empty - this is a bug in token-value-map")
1117 }
1118 _ => {
1119 let (t0, p0) = window[0];
1121 let (t1, p1) = window[1];
1122 let (t2, p2) = window[2];
1123 let (t3, p3) = window[3];
1124 hermite_interp(HermiteParams {
1125 t0,
1126 t1,
1127 t2,
1128 t3,
1129 p0,
1130 p1,
1131 p2,
1132 p3,
1133 t: key,
1134 })
1135 }
1136 }
1137}
1138
1139#[inline(always)]
1140fn linear_interp<V, T>(x0: T, x1: T, y0: &V, y1: &V, x: T) -> V
1141where
1142 V: Clone + Add<Output = V> + Mul<f32, Output = V> + Sub<Output = V>,
1143 T: Into<f32>,
1144{
1145 let x0 = x0.into();
1146 let x1 = x1.into();
1147 let x = x.into();
1148 let alpha = (x - x0) / (x1 - x0);
1149 y0.clone() + (y1.clone() - y0.clone()) * alpha
1150}
1151
1152#[inline(always)]
1153fn quadratic_interp<V, T>(x0: T, x1: T, x2: T, y0: &V, y1: &V, y2: &V, x: T) -> V
1154where
1155 V: Clone + Add<Output = V> + Mul<f32, Output = V> + Sub<Output = V>,
1156 T: Into<f32>,
1157{
1158 let x0 = x0.into();
1159 let x1 = x1.into();
1160 let x2 = x2.into();
1161 let x = x.into();
1162 let a = (x - x1) * (x - x2) / ((x0 - x1) * (x0 - x2));
1163 let b = (x - x0) * (x - x2) / ((x1 - x0) * (x1 - x2));
1164 let c = (x - x0) * (x - x1) / ((x2 - x0) * (x2 - x1));
1165
1166 y0.clone() * a + y1.clone() * b + y2.clone() * c
1167}
1168
1169struct HermiteParams<V, T> {
1170 t0: T,
1171 t1: T,
1172 t2: T,
1173 t3: T,
1174 p0: V,
1175 p1: V,
1176 p2: V,
1177 p3: V,
1178 t: T,
1179}
1180
1181#[inline(always)]
1182fn hermite_interp<V, T>(params: HermiteParams<&V, T>) -> V
1183where
1184 V: Clone + Add<Output = V> + Mul<f32, Output = V> + Sub<Output = V>,
1185 T: Into<f32>,
1186{
1187 let t0 = params.t0.into();
1188 let t1 = params.t1.into();
1189 let t2 = params.t2.into();
1190 let t3 = params.t3.into();
1191 let t = params.t.into();
1192
1193 let tau = if (t2 - t1).abs() < f32::EPSILON {
1195 0.0 } else {
1197 (t - t1) / (t2 - t1)
1198 };
1199
1200 let tension1 = if (t1 - t0).abs() < f32::EPSILON {
1204 1.0
1205 } else {
1206 (t2 - t1) / (t1 - t0)
1207 };
1208 let tension2 = if (t3 - t2).abs() < f32::EPSILON {
1209 1.0
1210 } else {
1211 (t2 - t1) / (t3 - t2)
1212 };
1213
1214 let m1 = (params.p2.clone() - params.p0.clone()) * (0.5 * tension1);
1216 let m2 = (params.p3.clone() - params.p1.clone()) * (0.5 * tension2);
1217
1218 let tau2 = tau * tau;
1220 let tau3 = tau2 * tau;
1221
1222 let h00 = 2.0 * tau3 - 3.0 * tau2 + 1.0;
1223 let h10 = tau3 - 2.0 * tau2 + tau;
1224 let h01 = -2.0 * tau3 + 3.0 * tau2;
1225 let h11 = tau3 - tau2;
1226
1227 params.p1.clone() * h00 + m1 * h10 + params.p2.clone() * h01 + m2 * h11
1229}
1230
1231#[cfg(feature = "matrix3")]
1236#[inline(always)]
1237fn decompose_matrix(matrix: &crate::math::Mat3Impl) -> (Trans2, f32, DiagStretch) {
1238 use crate::math::mat3;
1239
1240 let tx = mat3(matrix, 0, 2);
1242 let ty = mat3(matrix, 1, 2);
1243
1244 let a = mat3(matrix, 0, 0);
1246 let b = mat3(matrix, 0, 1);
1247 let c = mat3(matrix, 1, 0);
1248 let d = mat3(matrix, 1, 1);
1249
1250 let e = (a + d) * 0.5;
1252 let f = (a - d) * 0.5;
1253 let g = (c + b) * 0.5;
1254 let h = (c - b) * 0.5;
1255
1256 let q = (e * e + h * h).sqrt();
1257 let r = (f * f + g * g).sqrt();
1258
1259 let s1 = q + r;
1260 let s2 = q - r;
1261
1262 let theta1 = g.atan2(f);
1263 let theta2 = h.atan2(e);
1264
1265 let rotation_angle = (theta2 + theta1) * 0.5;
1267
1268 (Trans2(tx, ty), rotation_angle, DiagStretch(s1, s2))
1269}
1270
1271#[cfg(feature = "matrix3")]
1275#[inline(always)]
1276fn recompose_matrix(
1277 translation: Trans2,
1278 rotation_angle: f32,
1279 stretch: DiagStretch,
1280) -> crate::math::Mat3Impl {
1281 let cos = rotation_angle.cos();
1282 let sin = rotation_angle.sin();
1283
1284 crate::math::mat3_from_column_slice(&[
1286 stretch.0 * cos,
1287 stretch.0 * sin,
1288 0.0,
1289 -stretch.1 * sin,
1290 stretch.1 * cos,
1291 0.0,
1292 translation.0,
1293 translation.1,
1294 1.0,
1295 ])
1296}