#![allow(dead_code)]
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct AnticipationMorph {
pub target: f32,
pub current: f32,
pub anticipation_amt: f32,
pub phase: u8,
}
#[allow(dead_code)]
pub fn new_anticipation_morph(anticipation_amt: f32) -> AnticipationMorph {
AnticipationMorph { target: 0.0, current: 0.0, anticipation_amt, phase: 2 }
}
#[allow(dead_code)]
pub fn am_trigger(m: &mut AnticipationMorph, target: f32) {
m.target = target;
m.phase = 0;
}
#[allow(dead_code)]
pub fn am_step(m: &mut AnticipationMorph, dt: f32) {
match m.phase {
0 => {
let dir = if m.target > m.current { -1.0 } else { 1.0 };
m.current += dir * m.anticipation_amt * dt;
m.phase = 1;
}
1 => {
let diff = m.target - m.current;
m.current += diff * (5.0 * dt).min(1.0);
if (m.current - m.target).abs() < 1e-4 {
m.current = m.target;
m.phase = 2;
}
}
_ => { }
}
}
#[allow(dead_code)]
pub fn am_value(m: &AnticipationMorph) -> f32 {
m.current
}
#[allow(dead_code)]
pub fn am_phase(m: &AnticipationMorph) -> u8 {
m.phase
}
#[allow(dead_code)]
pub fn am_is_done(m: &AnticipationMorph) -> bool {
m.phase >= 2
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_trigger_sets_target() {
let mut m = new_anticipation_morph(0.2);
am_trigger(&mut m, 1.0);
assert!((m.target - 1.0).abs() < 1e-6);
}
#[test]
fn test_trigger_sets_phase_zero() {
let mut m = new_anticipation_morph(0.2);
am_trigger(&mut m, 1.0);
assert_eq!(am_phase(&m), 0);
}
#[test]
fn test_phase_transitions_to_one() {
let mut m = new_anticipation_morph(0.1);
am_trigger(&mut m, 1.0);
am_step(&mut m, 0.1);
assert_eq!(am_phase(&m), 1);
}
#[test]
fn test_phase_one_moves_toward_target() {
let mut m = new_anticipation_morph(0.0);
am_trigger(&mut m, 1.0);
am_step(&mut m, 0.0);
am_step(&mut m, 0.5);
assert!(m.current > 0.0);
}
#[test]
fn test_is_done_initially() {
let m = new_anticipation_morph(0.2);
assert!(am_is_done(&m));
}
#[test]
fn test_is_not_done_after_trigger() {
let mut m = new_anticipation_morph(0.2);
am_trigger(&mut m, 1.0);
assert!(!am_is_done(&m));
}
#[test]
fn test_anticipation_amt_stored() {
let m = new_anticipation_morph(0.35);
assert!((m.anticipation_amt - 0.35).abs() < 1e-6);
}
#[test]
fn test_value_finite_after_steps() {
let mut m = new_anticipation_morph(0.1);
am_trigger(&mut m, 0.5);
for _ in 0..20 {
am_step(&mut m, 0.1);
}
assert!(am_value(&m).is_finite());
}
}