Two releases since matma 0.1.0, both about curves.
0.2.0: the curves module
Released the same evening as 0.1.0. The engine had a spline.cpp and an animation_curve.cpp sitting next to vkm, and they’re now ported as matma::curves, generic over the vector type (it needs alloc):
hermite,catmull_romandcardinalevaluation, with tangents.Spline<V>: a Catmull-Rom / cardinal spline through waypoints with phantom end knots, so the curve passes through every waypoint, ends included. Defaults to tension 0 and centripetal parameterization (alpha 0.5).SplineArcLength: an arc-length table on top of a spline for constant-speed travel (distance ->u), even sampling and nearest-point queries.AnimationCurve: Unity-style keyframes with presets and tangent handles.
use matma::*;
let mut path = Spline::<float3>::new();
path.add(float3::new(0.0, 1.0, 5.0));
path.add(float3::new(3.0, 2.0, 2.0));
path.add(float3::new(3.0, 1.5, -2.0));
path.add(float3::new(-1.0, 1.0, -4.0));
let p = path.evaluate(1.5); // u = segment index + fraction
let polyline = path.sample(8); // 3 segments * 8 + 1 points
let arc = SplineArcLength::build(&path, 32); // rebuild after editing the path
let pos = arc.evaluate_by_distance(&path, 2.0); // 2 world units along the curve
let mid = arc.evaluate_uniform(&path, 0.5); // halfway by distance, not by u
let u = arc.nearest_u(&path, float3::new(2.0, 1.0, 0.0));
let mut fade = AnimationCurve::<f32>::from_preset(Preset::EaseInOut);
fade.add_key(0.6, 1.2);
let alpha = fade.evaluate(0.3);
The only thing that stayed behind is the Timer overload, which belongs to the engine. cargo run --example curves walks through all of it.
0.3.0: MonotoneCurve
This one is new - it was never in vkm. Smooth curves through keys are great until you use them as a remap ramp. Take speed -> field of view: flat at 60° up to 10 m/s, then up to 80° by 20 m/s. A Catmull-Rom through those keys dips below 60 before 10 m/s and overshoots 80 after 20 m/s, because it only cares about being smooth.
MonotoneCurve is a monotone cubic Hermite y = f(x) using the Fritsch-Carlson method: tangents are limited so the curve never leaves the range of its neighbouring keys. Flat stays flat, rising stays rising.
let fov = MonotoneCurve::from_keys([ // speed -> FOV, never over/undershoots
float2::new(0.0, 60.0),
float2::new(10.0, 60.0),
float2::new(20.0, 80.0),
float2::new(40.0, 82.0),
]);
let deg = fov.evaluate(15.0); // between 60 and 80, guaranteed
let slope = fov.derivative(15.0);
let lut = fov.sample(64); // bake to a table for a shader or a hot loop
AnimationCurve picked up the same idea as set_monotone_tangents() - the “make monotone” button: keep your keys, drop the overshoot between them.