diff options
feat: oh god the horrors
Diffstat (limited to 'src/interpolation.rs')
-rw-r--r-- | src/interpolation.rs | 50 |
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), + } + } +} |