Quick Start
Include the umbrella header (or the individual headers under anim/):
#include <anim.hpp>
Creating and evaluating a channel
Channels are created and owned by an Animation; you do not construct them
directly. Add keyframes with create_keyframe, then evaluate the curve.
#include <anim.hpp>
#include <iostream>
int main() {
anim::Animation animation("demo");
// Channels are created through the animation, which keeps them sorted
// and assigns each a unique id.
anim::Channel& channel = animation.create_channel("value");
// create_keyframe(time, value, function, handle_mode)
channel.create_keyframe(0.0, 0.0, anim::Function::Linear);
channel.create_keyframe(1.0, 1.0); // default: Bezier / Smooth
channel.create_keyframe(2.0, 0.0, anim::Function::Bezier,
anim::HandleMode::Flat);
// Evaluate single times
std::cout << "t=0.5 -> " << channel.evaluate(0.5) << "\n";
std::cout << "t=1.5 -> " << channel.evaluate(1.5) << "\n";
// Evaluate a range: 5 evenly spaced samples from t=0 to t=2
for (double v : channel.evaluate_range(0.0, 2.0, 5)) {
std::cout << v << " ";
}
std::cout << "\n";
return 0;
}
Keyframes with explicit Bézier handles
Handles are anim::Point values in (time, value) space:
anim::Channel& ch = animation.create_channel("curve");
// create_keyframe(time, value, in_handle, out_handle, function, handle_mode)
ch.create_keyframe(0.0, 0.0,
anim::Point(-0.3, 0.0), // in-handle
anim::Point( 0.3, 0.0), // out-handle
anim::Function::Bezier,
anim::HandleMode::Aligned);
Multiple channels
anim::Animation transform("transform");
anim::Channel& pos_x = transform.create_channel("position.x");
anim::Channel& pos_y = transform.create_channel("position.y");
pos_x.create_keyframe(0.0, 0.0, anim::Function::Linear);
pos_x.create_keyframe(1.0, 10.0, anim::Function::Linear);
pos_y.create_keyframe(0.0, 0.0);
pos_y.create_keyframe(1.0, 5.0);
double x = transform.channel("position.x").evaluate(0.5);
double y = transform.channel("position.y").evaluate(0.5);
Extending beyond the keyframe range
Each channel decides how to evaluate times before its first keyframe and after its last:
anim::Channel& ch = animation.create_channel("looping");
ch.create_keyframe(0.0, 0.0, anim::Function::Linear);
ch.create_keyframe(1.0, 1.0, anim::Function::Linear);
ch.set_extend_start(anim::Extend::Repeat); // loop before the start
ch.set_extend_end(anim::Extend::Mirror); // ping-pong after the end