macro_rules! include {
($module: ident) => {
mod $module;
pub use $module::*;
};
}
include!(animation_dyn);
include!(quadratic_bezier);
include!(cubic_bezier);
macro_rules! custom_lerp_preset {
($preset: ident, $lerp: ident) => {
pub fn $preset(end: crate::Transform, last_for_seconds: f64) -> CustomLerp {
return CustomLerp::new(
functions::$lerp,
end,
last_for_seconds,
);
}
};
}
custom_lerp_preset!(linear, lerp);
custom_lerp_preset!(smooth, lerp_smooth);
pub mod functions {
pub fn lerp(a: f64, b: f64, t: f64) -> f64 {
return a + (b - a) * t;
}
pub fn lerp_smooth(a: f64, b: f64, t: f64) -> f64 {
return lerp(a, b, t * t * (3.0 - 2.0 * t));
}
pub fn quadratic_bezier(a: f64, control: f64, b: f64, t: f64) -> f64 {
let l1 = lerp(a, control, t);
let l2 = lerp(control, b, t);
return lerp(l1, l2, t);
}
pub fn cubic_bezier(a: f64, a_control: f64, b: f64, b_control: f64, t: f64) -> f64 {
let l1 = lerp(a, a_control, t);
let l2 = lerp(a_control, b_control, t);
let l3 = lerp(b_control, b, t);
let q1 = lerp(l1, l2, t);
let q2 = lerp(l2, l3, t);
return lerp(q1, q2, t);
}
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
pub struct CustomLerp {
pub lerp: fn(f64, f64, f64) -> f64,
pub end: crate::Transform,
pub last_for_seconds: f64,
}
impl CustomLerp {
pub fn new(
lerp: fn(f64, f64, f64) -> f64,
end: crate::Transform,
last_for_seconds: f64,
) -> Self {
Self {
lerp,
end,
last_for_seconds,
}
}
}
impl crate::Animation for CustomLerp {
fn animated_transform(&mut self, original_transform: crate::Transform, duration_seconds: f64) -> crate::Transform {
let t: f64;
if self.last_for_seconds == 0.0 {
t = 0.0;
} else {
if duration_seconds <= self.last_for_seconds {
t = (self.last_for_seconds - duration_seconds) / self.last_for_seconds;
} else {
t = 0.0;
}
}
return self.end.apply_lerp(original_transform, t, self.lerp);
}
fn is_done(&self, duration_seconds: f64) -> bool {
return duration_seconds >= self.last_for_seconds;
}
}