diff --git a/animate2.cpp b/animate2.cpp index 080afe5..d50fce4 100644 --- a/animate2.cpp +++ b/animate2.cpp @@ -4,6 +4,7 @@ #include "dbc.hpp" #include "rand.hpp" + namespace animate2 { std::vector Animate2::calc_frames() { std::vector frames; @@ -77,70 +78,11 @@ namespace animate2 { float Transform::twitching(Sequence& seq) { float tick = 1 - std::powf(ease_rate, seq.subframe + 0.0001); - - switch(easing) { - case ease::NONE: - return 0.0; - case ease::SINE: - return std::abs(std::sin(seq.subframe * ease_rate)); - case ease::OUT_CIRC: - return ease::out_circ(tick); - case ease::OUT_BOUNCE: - return ease::out_bounce(tick); - case ease::IN_OUT_BACK: - return ease::in_out_back(tick); - case ease::RANDOM: - return Random::uniform_real(0.0001f, 1.0f); - case ease::NORM_DIST: - return Random::normal(0.5f, 0.1f); - case ease::LINEAR: - return tick; - default: - dbc::sentinel( - fmt::format("Invalid easing {} given to animation", - int(easing))); - } + return easing(tick); } void Transform::lerp(Sequence& seq, sf::Vector2f& pos_out, sf::Vector2f& scale_out) { - float tick = twitching(seq); - - if(stationary) { - switch(motion) { - case ease::SHAKE: { - pos_out.x += std::lerp(min_x, max_x, tick); - } break; - case ease::BOUNCE: { - pos_out.y -= std::lerp(min_y, max_y, tick); - } break; - case ease::RUSH: { - scale_out.x = std::lerp(min_x, max_x, tick); - scale_out.y = std::lerp(min_y, max_y, tick); - pos_out.y = pos_out.y - (pos_out.y * scale_out.y - pos_out.y); - } break; - case ease::SQUEEZE: { - scale_out.x *= std::lerp(min_x, max_x, tick); - } break; - case ease::SQUASH: { - scale_out.y *= std::lerp(min_y, max_y, tick); - } break; - case ease::STRETCH: { - scale_out.x = std::lerp(min_x, max_x, tick); - } break; - case ease::GROW: { - scale_out.y = std::lerp(min_y, max_y, tick); - } break; - case ease::SLIDE: { - pos_out.x = std::lerp(min_x, max_x, tick); - pos_out.y = std::lerp(min_y, max_y, tick); - } break; - default: - dbc::sentinel("Unknown animation.motion setting."); - } - } else { - dbc::sentinel("scale should not run"); - scale_out.x = std::lerp(scale_out.x * min_x, scale_out.x * max_x, tick); - scale_out.y = std::lerp(scale_out.y * min_y, scale_out.y * max_y, tick); - } + float tick = std::abs(twitching(seq)); + return motion(*this, pos_out, scale_out, tick); } } diff --git a/animate2.hpp b/animate2.hpp index d5f2d1d..b153da9 100644 --- a/animate2.hpp +++ b/animate2.hpp @@ -1,12 +1,12 @@ #pragma once #include #include -#include "easings.hpp" #include #include #include #include #include +#include "ease2.hpp" namespace animate2 { struct Sheet { @@ -44,11 +44,11 @@ namespace animate2 { std::shared_ptr shader{nullptr}; // change to using a callback function for these - ease::Style easing = ease::IN_OUT_BACK; - ease::Motion motion = ease::RUSH; + ease2::EaseFunc easing = ease2::in_out_back; + ease2::MoveFunc motion = ease2::move_rush; float twitching(Sequence& seq); - void lerp(Sequence& seq, sf::Vector2f& scale_out, sf::Vector2f& pos_out); + void lerp(Sequence& seq, sf::Vector2f& pos_out, sf::Vector2f& scale_out); }; /* Gets the number of times it looped, and returns if it should stop. */ diff --git a/animation.cpp b/animation.cpp index 67476f2..408a6bc 100644 --- a/animation.cpp +++ b/animation.cpp @@ -41,7 +41,7 @@ namespace components { } void Animation::lerp(sf::Vector2f& scale_out, sf::Vector2f& pos_out) { - float tick = twitching(); + float tick = std::abs(twitching()); if(stationary) { switch(motion) { @@ -55,6 +55,7 @@ namespace components { scale_out.x = std::lerp(min_x, max_x, tick); scale_out.y = std::lerp(min_y, max_y, tick); pos_out.y = pos_out.y - (pos_out.y * scale_out.y - pos_out.y); + fmt::println("RUSH pos={},{}; scale={},{}; tic={}", pos_out.x, pos_out.y, scale_out.x, scale_out.y, tick); } break; case ease::SQUEEZE: { scale_out.x *= std::lerp(min_x, max_x, tick); @@ -73,6 +74,8 @@ namespace components { pos_out.x = std::lerp(min_x, max_x, tick); pos_out.y = std::lerp(min_y, max_y, tick); } break; + case ease::NO_MOTION: + break; default: dbc::sentinel("Unknown animation.motion setting."); } diff --git a/assets/animations.json b/assets/animations.json index 531f6fa..2f74d9e 100644 --- a/assets/animations.json +++ b/assets/animations.json @@ -238,7 +238,7 @@ "torch_fixture": { "_type": "Animation", "easing": 0, - "motion": 0, + "motion": 1000, "ease_rate": 0.1, "min_x": 0.6, "min_y": 0.6, diff --git a/ease2.cpp b/ease2.cpp new file mode 100644 index 0000000..1493487 --- /dev/null +++ b/ease2.cpp @@ -0,0 +1,100 @@ +#include "easings.hpp" +#include "rand.hpp" +#include "animate2.hpp" +#include + +namespace ease2 { + using namespace animate2; + + double none(float tick) { + return 0.0; + } + + double sine(double x) { + // old one? return std::abs(std::sin(seq.subframe * ease_rate)); + return (std::sin(x) + 1.0) / 2.0; + } + + double out_circ(double x) { + return std::sqrt(1.0f - ((x - 1.0f) * (x - 1.0f))); + } + + double out_bounce(double x) { + constexpr const double n1 = 7.5625; + constexpr const double d1 = 2.75; + + if (x < 1 / d1) { + return n1 * x * x; + } else if (x < 2 / d1) { + x -= 1.5; + return n1 * (x / d1) * x + 0.75; + } else if (x < 2.5 / d1) { + x -= 2.25; + return n1 * (x / d1) * x + 0.9375; + } else { + x -= 2.625; + return n1 * (x / d1) * x + 0.984375; + } + } + + double in_out_back(double x) { + constexpr const double c1 = 1.70158; + constexpr const double c2 = c1 * 1.525; + + return x < 0.5 + ? (std::pow(2.0 * x, 2.0) * ((c2 + 1.0) * 2.0 * x - c2)) / 2.0 + : (std::pow(2.0 * x - 2.0, 2.0) * ((c2 + 1.0) * (x * 2.0 - 2.0) + c2) + 2.0) / 2.0; + } + + float random(float tick) { + return Random::uniform_real(0.0001f, 1.0f); + } + + float normal_dist(float tick) { + return Random::normal(0.5f, 0.1f); + } + + void move_shake(Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick) { + pos_out.x += std::lerp(tr.min_x, tr.max_x, tick); + } + + void move_bounce(Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick) { + pos_out.y -= std::lerp(tr.min_y, tr.max_y, tick); + } + + void move_rush(Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick) { + scale_out.x = std::lerp(tr.min_x, tr.max_x, tick); + scale_out.y = std::lerp(tr.min_y, tr.max_y, tick); + pos_out.y = pos_out.y - (pos_out.y * scale_out.y - pos_out.y); + fmt::println("RUSH pos={},{}; scale={},{}; tic={}", pos_out.x, pos_out.y, scale_out.x, scale_out.y, tick); + } + + void scale_squeeze(Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick) { + scale_out.x *= std::lerp(tr.min_x, tr.max_x, tick); + } + + void scale_squash(Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick) { + scale_out.y *= std::lerp(tr.min_y, tr.max_y, tick); + } + + void scale_strech(Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick) { + scale_out.x = std::lerp(tr.min_x, tr.max_x, tick); + } + + void scale_grow(Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick) { + scale_out.y = std::lerp(tr.min_y, tr.max_y, tick); + } + + void move_slide(Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick) { + pos_out.x = std::lerp(tr.min_x, tr.max_x, tick); + pos_out.y = std::lerp(tr.min_y, tr.max_y, tick); + } + + void move_none(Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick) { + } + + void scale_only(Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick) { + scale_out.x = std::lerp(scale_out.x * tr.min_x, scale_out.x * tr.max_x, tick); + scale_out.y = std::lerp(scale_out.y * tr.min_y, scale_out.y * tr.max_y, tick); + } +} diff --git a/ease2.hpp b/ease2.hpp new file mode 100644 index 0000000..1ebdc41 --- /dev/null +++ b/ease2.hpp @@ -0,0 +1,28 @@ +#include +#include "animate2.hpp" + +namespace animate2 { + struct Transform; +} + +namespace ease2 { + using EaseFunc = std::function; + using MoveFunc = std::function; + + double sine(double x); + double out_circ(double x); + double out_bounce(double x); + double in_out_back(double x); + double random(double tick); + double normal_dist(double tick); + + void move_bounce(animate2::Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick); + void move_rush(animate2::Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick); + void scale_squeeze(animate2::Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick); + void scale_squash(animate2::Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick); + void scale_strech(animate2::Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick); + void scale_grow(animate2::Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick); + void move_slide(animate2::Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick); + void move_none(animate2::Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick); + void scale_only(animate2::Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick); +} diff --git a/easings.hpp b/easings.hpp index fb1d60d..4788871 100644 --- a/easings.hpp +++ b/easings.hpp @@ -22,7 +22,8 @@ namespace ease { SQUASH=4, STRETCH=5, GROW=6, - SLIDE=7 + SLIDE=7, + NO_MOTION=1000, }; inline double sine(double x) { diff --git a/meson.build b/meson.build index 54427f0..2acac0e 100644 --- a/meson.build +++ b/meson.build @@ -134,6 +134,7 @@ sources = [ 'systems.cpp', 'textures.cpp', 'worldbuilder.cpp', + 'ease2.cpp', ] executable('runtests', sources + [ diff --git a/tests/animate2.cpp b/tests/animate2.cpp index 8873aa8..8bd74b2 100644 --- a/tests/animate2.cpp +++ b/tests/animate2.cpp @@ -25,7 +25,7 @@ Animate2 crafter() { Sequence sequence{ .frames{0,1}, - .durations{Random::milliseconds(33, 100), Random::milliseconds(33, 100)} + .durations{Random::milliseconds(1, 33), Random::milliseconds(1, 33)} }; REQUIRE(sequence.frame_count == sequence.frames.size()); @@ -36,16 +36,16 @@ Animate2 crafter() { .min_y{0.6f}, .max_x{0.8f}, .max_y{0.8f}, - .simple{true}, + .simple{false}, .flipped{false}, .ease_rate{0.5f}, - .speed{0.1f}, - .scaled{false}, + .speed{0.02f}, + .scaled{true}, .stationary{true}, .toggled{false}, .looped{false}, - .easing = ease::IN_OUT_BACK, - .motion = ease::RUSH, + .easing = ease2::in_out_back, + .motion = ease2::move_rush, }; return {sheet, sequence, transform}; @@ -168,6 +168,7 @@ TEST_CASE("confirm transition changes work", "[animation-new]") { while(anim.playing) { anim.update(); anim.motion(pos, scale); + std::this_thread::sleep_for(10ms); fmt::println("POSITION: {},{}; SCALE: {},{}; current: {}; subframe: {}", pos.x, pos.y, scale.x, scale.y, anim.$sequence.current, anim.$sequence.subframe); }