|
5 | 5 | pub mod adaptors;
|
6 | 6 | pub mod cores;
|
7 | 7 | pub mod interval;
|
| 8 | +pub mod sample_curves; |
8 | 9 |
|
9 |
| -use adaptors::*; |
| 10 | +// bevy_math::curve re-exports all commonly-needed curve-related items. |
10 | 11 | pub use interval::{interval, Interval};
|
11 |
| -use itertools::Itertools; |
| 12 | +pub use sample_curves::*; |
| 13 | + |
| 14 | +use adaptors::*; |
| 15 | +use cores::{EvenCore, UnevenCore}; |
12 | 16 |
|
13 | 17 | use crate::{StableInterpolate, VectorSpace};
|
14 | 18 | use core::{marker::PhantomData, ops::Deref};
|
15 |
| -use cores::{EvenCore, EvenCoreError, UnevenCore, UnevenCoreError}; |
16 | 19 | use interval::InvalidIntervalError;
|
| 20 | +use itertools::Itertools; |
17 | 21 | use thiserror::Error;
|
18 | 22 |
|
19 | 23 | /// A trait for a type that can represent values of type `T` parametrized over a fixed interval.
|
@@ -936,199 +940,6 @@ where
|
936 | 940 | }
|
937 | 941 | }
|
938 | 942 |
|
939 |
| -/// A curve that is defined by explicit neighbor interpolation over a set of samples. |
940 |
| -#[derive(Clone, Debug)] |
941 |
| -#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] |
942 |
| -#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))] |
943 |
| -pub struct SampleCurve<T, I> { |
944 |
| - core: EvenCore<T>, |
945 |
| - interpolation: I, |
946 |
| -} |
947 |
| - |
948 |
| -impl<T, I> Curve<T> for SampleCurve<T, I> |
949 |
| -where |
950 |
| - T: Clone, |
951 |
| - I: Fn(&T, &T, f32) -> T, |
952 |
| -{ |
953 |
| - #[inline] |
954 |
| - fn domain(&self) -> Interval { |
955 |
| - self.core.domain() |
956 |
| - } |
957 |
| - |
958 |
| - #[inline] |
959 |
| - fn sample_unchecked(&self, t: f32) -> T { |
960 |
| - self.core.sample_with(t, &self.interpolation) |
961 |
| - } |
962 |
| -} |
963 |
| - |
964 |
| -impl<T, I> SampleCurve<T, I> { |
965 |
| - /// Create a new [`SampleCurve`] using the specified `interpolation` to interpolate between |
966 |
| - /// the given `samples`. An error is returned if there are not at least 2 samples or if the |
967 |
| - /// given `domain` is unbounded. |
968 |
| - /// |
969 |
| - /// The interpolation takes two values by reference together with a scalar parameter and |
970 |
| - /// produces an owned value. The expectation is that `interpolation(&x, &y, 0.0)` and |
971 |
| - /// `interpolation(&x, &y, 1.0)` are equivalent to `x` and `y` respectively. |
972 |
| - pub fn new( |
973 |
| - domain: Interval, |
974 |
| - samples: impl IntoIterator<Item = T>, |
975 |
| - interpolation: I, |
976 |
| - ) -> Result<Self, EvenCoreError> |
977 |
| - where |
978 |
| - I: Fn(&T, &T, f32) -> T, |
979 |
| - { |
980 |
| - Ok(Self { |
981 |
| - core: EvenCore::new(domain, samples)?, |
982 |
| - interpolation, |
983 |
| - }) |
984 |
| - } |
985 |
| -} |
986 |
| - |
987 |
| -/// A curve that is defined by neighbor interpolation over a set of samples. |
988 |
| -#[derive(Clone, Debug)] |
989 |
| -#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] |
990 |
| -#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))] |
991 |
| -pub struct SampleAutoCurve<T> { |
992 |
| - core: EvenCore<T>, |
993 |
| -} |
994 |
| - |
995 |
| -impl<T> Curve<T> for SampleAutoCurve<T> |
996 |
| -where |
997 |
| - T: StableInterpolate, |
998 |
| -{ |
999 |
| - #[inline] |
1000 |
| - fn domain(&self) -> Interval { |
1001 |
| - self.core.domain() |
1002 |
| - } |
1003 |
| - |
1004 |
| - #[inline] |
1005 |
| - fn sample_unchecked(&self, t: f32) -> T { |
1006 |
| - self.core |
1007 |
| - .sample_with(t, <T as StableInterpolate>::interpolate_stable) |
1008 |
| - } |
1009 |
| -} |
1010 |
| - |
1011 |
| -impl<T> SampleAutoCurve<T> { |
1012 |
| - /// Create a new [`SampleCurve`] using type-inferred interpolation to interpolate between |
1013 |
| - /// the given `samples`. An error is returned if there are not at least 2 samples or if the |
1014 |
| - /// given `domain` is unbounded. |
1015 |
| - pub fn new( |
1016 |
| - domain: Interval, |
1017 |
| - samples: impl IntoIterator<Item = T>, |
1018 |
| - ) -> Result<Self, EvenCoreError> { |
1019 |
| - Ok(Self { |
1020 |
| - core: EvenCore::new(domain, samples)?, |
1021 |
| - }) |
1022 |
| - } |
1023 |
| -} |
1024 |
| - |
1025 |
| -/// A curve that is defined by interpolation over unevenly spaced samples with explicit |
1026 |
| -/// interpolation. |
1027 |
| -#[derive(Clone, Debug)] |
1028 |
| -#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] |
1029 |
| -#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))] |
1030 |
| -pub struct UnevenSampleCurve<T, I> { |
1031 |
| - core: UnevenCore<T>, |
1032 |
| - interpolation: I, |
1033 |
| -} |
1034 |
| - |
1035 |
| -impl<T, I> Curve<T> for UnevenSampleCurve<T, I> |
1036 |
| -where |
1037 |
| - T: Clone, |
1038 |
| - I: Fn(&T, &T, f32) -> T, |
1039 |
| -{ |
1040 |
| - #[inline] |
1041 |
| - fn domain(&self) -> Interval { |
1042 |
| - self.core.domain() |
1043 |
| - } |
1044 |
| - |
1045 |
| - #[inline] |
1046 |
| - fn sample_unchecked(&self, t: f32) -> T { |
1047 |
| - self.core.sample_with(t, &self.interpolation) |
1048 |
| - } |
1049 |
| -} |
1050 |
| - |
1051 |
| -impl<T, I> UnevenSampleCurve<T, I> { |
1052 |
| - /// Create a new [`UnevenSampleCurve`] using the provided `interpolation` to interpolate |
1053 |
| - /// between adjacent `timed_samples`. The given samples are filtered to finite times and |
1054 |
| - /// sorted internally; if there are not at least 2 valid timed samples, an error will be |
1055 |
| - /// returned. |
1056 |
| - /// |
1057 |
| - /// The interpolation takes two values by reference together with a scalar parameter and |
1058 |
| - /// produces an owned value. The expectation is that `interpolation(&x, &y, 0.0)` and |
1059 |
| - /// `interpolation(&x, &y, 1.0)` are equivalent to `x` and `y` respectively. |
1060 |
| - pub fn new( |
1061 |
| - timed_samples: impl IntoIterator<Item = (f32, T)>, |
1062 |
| - interpolation: I, |
1063 |
| - ) -> Result<Self, UnevenCoreError> { |
1064 |
| - Ok(Self { |
1065 |
| - core: UnevenCore::new(timed_samples)?, |
1066 |
| - interpolation, |
1067 |
| - }) |
1068 |
| - } |
1069 |
| - |
1070 |
| - /// This [`UnevenSampleAutoCurve`], but with the sample times moved by the map `f`. |
1071 |
| - /// In principle, when `f` is monotone, this is equivalent to [`Curve::reparametrize`], |
1072 |
| - /// but the function inputs to each are inverses of one another. |
1073 |
| - /// |
1074 |
| - /// The samples are re-sorted by time after mapping and deduplicated by output time, so |
1075 |
| - /// the function `f` should generally be injective over the sample times of the curve. |
1076 |
| - pub fn map_sample_times(self, f: impl Fn(f32) -> f32) -> UnevenSampleCurve<T, I> { |
1077 |
| - Self { |
1078 |
| - core: self.core.map_sample_times(f), |
1079 |
| - interpolation: self.interpolation, |
1080 |
| - } |
1081 |
| - } |
1082 |
| -} |
1083 |
| - |
1084 |
| -/// A curve that is defined by interpolation over unevenly spaced samples. |
1085 |
| -#[derive(Clone, Debug)] |
1086 |
| -#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] |
1087 |
| -#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))] |
1088 |
| -pub struct UnevenSampleAutoCurve<T> { |
1089 |
| - core: UnevenCore<T>, |
1090 |
| -} |
1091 |
| - |
1092 |
| -impl<T> Curve<T> for UnevenSampleAutoCurve<T> |
1093 |
| -where |
1094 |
| - T: StableInterpolate, |
1095 |
| -{ |
1096 |
| - #[inline] |
1097 |
| - fn domain(&self) -> Interval { |
1098 |
| - self.core.domain() |
1099 |
| - } |
1100 |
| - |
1101 |
| - #[inline] |
1102 |
| - fn sample_unchecked(&self, t: f32) -> T { |
1103 |
| - self.core |
1104 |
| - .sample_with(t, <T as StableInterpolate>::interpolate_stable) |
1105 |
| - } |
1106 |
| -} |
1107 |
| - |
1108 |
| -impl<T> UnevenSampleAutoCurve<T> { |
1109 |
| - /// Create a new [`UnevenSampleAutoCurve`] from a given set of timed samples, interpolated |
1110 |
| - /// using the The samples are filtered to finite times and |
1111 |
| - /// sorted internally; if there are not at least 2 valid timed samples, an error will be |
1112 |
| - /// returned. |
1113 |
| - pub fn new(timed_samples: impl IntoIterator<Item = (f32, T)>) -> Result<Self, UnevenCoreError> { |
1114 |
| - Ok(Self { |
1115 |
| - core: UnevenCore::new(timed_samples)?, |
1116 |
| - }) |
1117 |
| - } |
1118 |
| - |
1119 |
| - /// This [`UnevenSampleAutoCurve`], but with the sample times moved by the map `f`. |
1120 |
| - /// In principle, when `f` is monotone, this is equivalent to [`Curve::reparametrize`], |
1121 |
| - /// but the function inputs to each are inverses of one another. |
1122 |
| - /// |
1123 |
| - /// The samples are re-sorted by time after mapping and deduplicated by output time, so |
1124 |
| - /// the function `f` should generally be injective over the sample times of the curve. |
1125 |
| - pub fn map_sample_times(self, f: impl Fn(f32) -> f32) -> UnevenSampleAutoCurve<T> { |
1126 |
| - Self { |
1127 |
| - core: self.core.map_sample_times(f), |
1128 |
| - } |
1129 |
| - } |
1130 |
| -} |
1131 |
| - |
1132 | 943 | /// Create a [`Curve`] that constantly takes the given `value` over the given `domain`.
|
1133 | 944 | pub fn constant_curve<T: Clone>(domain: Interval, value: T) -> ConstantCurve<T> {
|
1134 | 945 | ConstantCurve { domain, value }
|
|
0 commit comments