aboutsummaryrefslogtreecommitdiffstats
path: root/src/interpolation.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/interpolation.rs')
-rw-r--r--src/interpolation.rs50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/interpolation.rs b/src/interpolation.rs
new file mode 100644
index 0000000..de6b6df
--- /dev/null
+++ b/src/interpolation.rs
@@ -0,0 +1,50 @@
+use std::ops::{Add, Mul, Sub};
+
+pub fn raw_lerp<T>(a: T, b: T, t: f64) -> T
+where
+ T: Copy + Add<Output = T> + Sub<Output = T> + Mul<f64, Output = T>,
+{
+ a + (b - a) * t
+}
+
+pub enum TimingFunction {
+ Lerp,
+}
+pub struct KeyFrame<ValueType> {
+ // We could make a TimeType generic (I initially did), however it's safe to assume we use a 64-bit float for this
+ pub time: f64,
+ pub val: ValueType,
+}
+impl<ValueType> KeyFrame<ValueType> {
+ pub fn new(time: f64, val: ValueType) -> KeyFrame<ValueType> {
+ KeyFrame { time, val }
+ }
+}
+impl<
+ ValueType: PartialOrd
+ + Copy
+ + Add<Output = ValueType>
+ + Sub<Output = ValueType>
+ + Mul<f64, Output = ValueType>,
+ > KeyFrame<ValueType>
+{
+ /** Simply passes the data to the timing function involved. Does not do bounding. */
+ pub fn raw_value_at(
+ from: &KeyFrame<ValueType>,
+ to: &KeyFrame<ValueType>,
+ time: f64,
+ timing_function: TimingFunction,
+ ) -> ValueType {
+ // Order them so `from` is always the lower bound
+ let (from, to) = if from.time < to.time {
+ (from, to)
+ } else {
+ (to, from)
+ };
+ let length = to.time - from.time;
+ let position = (time - from.time) / length;
+ match timing_function {
+ TimingFunction::Lerp => raw_lerp(from.val, to.val, position),
+ }
+ }
+}