aboutsummaryrefslogblamecommitdiffstats
path: root/src/interpolation.rs
blob: de6b6dfb49052f85e3200a6e29ea72f018986737 (plain) (tree)

















































                                                                                                                   
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),
    }
  }
}