Sorted out the animation vs. easing contradiction I believe. Now there's a separate easing_duration that's calculated from the total duration of all frames. Then a easing_position determines where in the total the animation is, which is fed to the asing functions as a ration of easing_position / easing_duration.

This commit is contained in:
Zed A. Shaw 2026-02-21 01:57:33 -05:00
parent 0c798c9e0d
commit 1baca783fc
9 changed files with 47 additions and 75 deletions

View file

@ -10,6 +10,8 @@
constexpr float SUB_FRAME_SENSITIVITY = 0.999f;
namespace animate2 {
using namespace std::chrono_literals;
std::vector<sf::IntRect> Animate2::calc_frames() {
dbc::check(sequence.frames.size() == sequence.durations.size(), "sequence.frames.size() != sequence.durations.size()");
@ -94,30 +96,28 @@ namespace animate2 {
* elapsed is DELTA, or use elapsed here?
*/
void Animate2::update() {
dbc::check(sequence.easing_duration > 0.0, "bad easing duration");
dbc::check(playing, "attempt to update animation that's not playing");
dbc::check(sequence.frame_count == sequence.frames.size(), "frame_count doesn't match frame.size()");
auto duration = sequence.durations.at(sequence.current);
auto elapsed = sequence.timer.getElapsedTime().toDuration();
// std::cout << "subframe: " << sequence.subframe << " elapsed: " << elapsed << " duration: " << duration << std::endl;
auto [ticks, alpha] = sequence.timer.commit();
int duration = sequence.durations.at(sequence.current);
sequence.subframe += ticks;
sequence.easing_position += ticks;
bool frame_change = false;
if(elapsed < duration) {
// BUG: subframe will just run crazy because I don't actually do delta time difference here
sequence.subframe = std::lerp(sequence.subframe, 1.0, sequence.timer.DELTA * transform.ease_rate);
} else {
if(sequence.subframe >= duration) {
sequence.timer.restart();
sequence.current++;
if(sequence.subframe > SUB_FRAME_SENSITIVITY) {
sequence.subframe = 0.0f;
}
sequence.subframe = 0;
frame_change = true;
}
if(sequence.current >= sequence.frame_count) {
sequence.loop_count++;
sequence.easing_position = 0;
playing = onLoop(sequence, transform);
}
@ -142,20 +142,18 @@ namespace animate2 {
}
}
std::pair<int, double> Animate2::commit() {
return sequence.timer.commit();
}
void Timer::start() {
clock.start();
prev_time = clock.getElapsedTime().asSeconds();
}
void Timer::reset() {
elapsed_ticks = 0;
clock.reset();
}
void Timer::restart() {
elapsed_ticks = 0;
clock.restart();
prev_time = clock.getElapsedTime().asSeconds();
}
@ -182,6 +180,8 @@ namespace animate2 {
accumulator -= tick_count * DELTA;
// that leaves the remaining errors for next loop
elapsed_ticks += tick_count;
// alpha is then what we lerp...but WHY?!
alpha = accumulator / DELTA;
@ -190,14 +190,9 @@ namespace animate2 {
}
void Transform::apply(Sequence& seq, sf::Vector2f& pos_out, sf::Vector2f& scale_out) {
// float dt = 1 - std::powf(ease_rate, seq.subframe + 0.0001);
float tick = easing_func(seq.subframe);
float tick = easing_func(seq.easing_position / seq.easing_duration);
motion_func(*this, pos_out, scale_out, tick, relative);
// fmt::println("sub: {}, tick: {}, tr: {},{}; pos: {},{}; scale: {},{}",
// seq.subframe, tick, min_y, max_y, pos_out.x, pos_out.y,
// scale_out.x, scale_out.y);
}
bool Animate2::has_form(const std::string& as_form) {
@ -224,6 +219,12 @@ namespace animate2 {
sequence = sequences.at(seq_name);
transform = transforms.at(tr_name);
// BUG: should this be configurable instead?
for(auto duration : sequence.durations) {
sequence.easing_duration += float(duration);
}
dbc::check(sequence.easing_duration > 0.0, "bad easing duration");
$frame_rects = calc_frames();
transform.easing_func = ease2::get_easing(transform.easing);
transform.motion_func = ease2::get_motion(transform.motion);