From 0b9a627a1c341bdc7f40a35b65b809890d847242 Mon Sep 17 00:00:00 2001 From: actboy168 Date: Sat, 20 Jan 2024 15:53:28 +0800 Subject: [PATCH] rewrite tween --- pkg/ant.rmlui/src/core/ElementAnimation.cpp | 2 +- pkg/ant.rmlui/src/core/Tween.cpp | 173 +++++++----------- pkg/ant.rmlui/src/core/Tween.h | 48 +++-- .../src/css/PropertyParserAnimation.cpp | 66 +++---- 4 files changed, 138 insertions(+), 151 deletions(-) diff --git a/pkg/ant.rmlui/src/core/ElementAnimation.cpp b/pkg/ant.rmlui/src/core/ElementAnimation.cpp index 9eeacb672b..3a0ff80c5a 100644 --- a/pkg/ant.rmlui/src/core/ElementAnimation.cpp +++ b/pkg/ant.rmlui/src/core/ElementAnimation.cpp @@ -83,7 +83,7 @@ Property ElementInterpolate::Update(float t0, float t1, float t, const Tween& tw if (t1 - t0 > eps) alpha = (t - t0) / (t1 - t0); alpha = std::clamp(alpha, 0.0f, 1.0f); - alpha = tween.get(alpha); + alpha = TweenGet(tween, alpha); if (alpha > 1.f) alpha = 1.f; if (alpha < 0.f) alpha = 0.f; return PropertyVisit(InterpolateVisitor { id, p0, p1, alpha }, p0, p1); diff --git a/pkg/ant.rmlui/src/core/Tween.cpp b/pkg/ant.rmlui/src/core/Tween.cpp index ffb6636a22..cc26527b2d 100644 --- a/pkg/ant.rmlui/src/core/Tween.cpp +++ b/pkg/ant.rmlui/src/core/Tween.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -13,8 +14,6 @@ static constexpr float const_pi = static_cast(3.141592653589793); namespace Rml { -namespace TweenFunctions { - // Tweening functions below. // Partly based on http://libclaw.sourceforge.net/tweeners.html @@ -76,127 +75,91 @@ static float sine(float t) { return 1.f - cosf(t * const_pi * 0.5f); } -} +enum class Direction : uint8_t { + In = 0, + Out, + InOut +}; -static float TweenIn(Tween::Type type, float t) { - using namespace TweenFunctions; - switch (type) { - case Tween::Type::Back: - return back(t); - case Tween::Type::Bounce: - return bounce(t); - case Tween::Type::Circular: - return circular(t); - case Tween::Type::Cubic: - return cubic(t); - case Tween::Type::Elastic: - return elastic(t); - case Tween::Type::Exponential: - return exponential(t); - case Tween::Type::Linear: - return linear(t); - case Tween::Type::Quadratic: - return quadratic(t); - case Tween::Type::Quartic: - return quartic(t); - case Tween::Type::Quintic: - return quintic(t); - case Tween::Type::Sine: - return sine(t); - default: - std::unreachable(); - } +static float TweenIn(float t) { + return t; } -static float TweenOut(Tween::Type type, float t) { - return 1.0f - TweenIn(type, 1.0f - t); +static float TweenOut(float t) { + return 1.0f - TweenIn(1.0f - t); } -static float TweenInOut(Tween::Type type, float t) { +static float TweenInOut(float t) { if (t < 0.5f) - return TweenIn(type, 2.0f * t) * 0.5f; + return TweenIn(2.0f * t) * 0.5f; else - return 0.5f + TweenOut(type, 2.0f * t - 1.0f) * 0.5f; -} - -static std::string TweenToString(Tween::Type type) { - switch (type) { - case Tween::Type::Back: - return "back"; - case Tween::Type::Bounce: - return "bounce"; - case Tween::Type::Circular: - return "circular"; - case Tween::Type::Cubic: - return "cubic"; - case Tween::Type::Elastic: - return "elastic"; - case Tween::Type::Exponential: - return "exponential"; - case Tween::Type::Linear: - return "linear"; - case Tween::Type::Quadratic: - return "quadratic"; - case Tween::Type::Quartic: - return "quartic"; - case Tween::Type::Quintic: - return "quintic"; - case Tween::Type::Sine: - return "sine"; - default: - std::unreachable(); - } + return 0.5f + TweenOut(2.0f * t - 1.0f) * 0.5f; } -static std::string TweenToString(Tween::Direction direction) { - switch (direction) { - case Tween::Direction::In: - return "-in"; - case Tween::Direction::Out: - return "-out"; - case Tween::Direction::InOut: - return "-in-out"; - default: - std::unreachable(); - } -} - -static Tween::Type TweenGetType(uint8_t v) { - return (Tween::Type)((v >> 4) & 0xF); -} - -static Tween::Direction TweenGetDirection(uint8_t v) { - return (Tween::Direction)(v & 0xF); -} - -static uint8_t TweenMake(Tween::Type type, Tween::Direction direction) { - return (uint8_t(type) << 4) | uint8_t(direction); -} - -Tween::Tween() - : v(0) -{ } - -Tween::Tween(Type type, Direction direction) - : v(TweenMake(type, direction)) -{ } - -float Tween::get(float t) const { - switch (TweenGetDirection(v)) { +static float TweenGet(Direction dir, float t) { + switch (dir) { case Direction::In: - return TweenIn(TweenGetType(v), t); + return TweenIn(t); case Direction::Out: - return TweenOut(TweenGetType(v), t); + return TweenOut(t); case Direction::InOut: - return TweenInOut(TweenGetType(v), t); + return TweenInOut(t); default: std::unreachable(); } return t; } -std::string Tween::ToString() const { - return TweenToString(TweenGetType(v)) + TweenToString(TweenGetDirection(v)); +float TweenGet(Tween tween, float t) { + Direction dir = (Direction)(std::to_underlying(tween) % 3); + switch (tween) { + case Tween::LinearIn: + case Tween::LinearOut: + case Tween::LinearInOut: + return TweenGet(dir, linear(t)); + case Tween::BackIn: + case Tween::BackOut: + case Tween::BackInOut: + return TweenGet(dir, back(t)); + case Tween::BounceIn: + case Tween::BounceOut: + case Tween::BounceInOut: + return TweenGet(dir, bounce(t)); + case Tween::CircularIn: + case Tween::CircularOut: + case Tween::CircularInOut: + return TweenGet(dir, circular(t)); + case Tween::CubicIn: + case Tween::CubicOut: + case Tween::CubicInOut: + return TweenGet(dir, cubic(t)); + case Tween::ElasticIn: + case Tween::ElasticOut: + case Tween::ElasticInOut: + return TweenGet(dir, elastic(t)); + case Tween::ExponentialIn: + case Tween::ExponentialOut: + case Tween::ExponentialInOut: + return TweenGet(dir, exponential(t)); + case Tween::QuadraticIn: + case Tween::QuadraticOut: + case Tween::QuadraticInOut: + return TweenGet(dir, quadratic(t)); + case Tween::QuarticIn: + case Tween::QuarticOut: + case Tween::QuarticInOut: + return TweenGet(dir, quartic(t)); + case Tween::QuinticIn: + case Tween::QuinticOut: + case Tween::QuinticInOut: + return TweenGet(dir, quintic(t)); + case Tween::SineIn: + case Tween::SineOut: + case Tween::SineInOut: + return TweenGet(dir, sine(t)); + default: + std::unreachable(); + } } } diff --git a/pkg/ant.rmlui/src/core/Tween.h b/pkg/ant.rmlui/src/core/Tween.h index b14250013e..7daf223082 100644 --- a/pkg/ant.rmlui/src/core/Tween.h +++ b/pkg/ant.rmlui/src/core/Tween.h @@ -5,18 +5,42 @@ namespace Rml { -class Tween { -public: - enum class Type : uint8_t { Linear = 0, Back, Bounce, Circular, Cubic, Elastic, Exponential, Quadratic, Quartic, Quintic, Sine }; - enum class Direction : uint8_t { In = 0, Out, InOut }; - - Tween(); - Tween(Type type, Direction direction); - float get(float t) const; - std::string ToString() const; - -private: - uint8_t v; +enum class Tween : uint8_t { + LinearIn, + LinearOut, + LinearInOut, + BackIn, + BackOut, + BackInOut, + BounceIn, + BounceOut, + BounceInOut, + CircularIn, + CircularOut, + CircularInOut, + CubicIn, + CubicOut, + CubicInOut, + ElasticIn, + ElasticOut, + ElasticInOut, + ExponentialIn, + ExponentialOut, + ExponentialInOut, + QuadraticIn, + QuadraticOut, + QuadraticInOut, + QuarticIn, + QuarticOut, + QuarticInOut, + QuinticIn, + QuinticOut, + QuinticInOut, + SineIn, + SineOut, + SineInOut, }; +float TweenGet(Tween tween, float t); + } diff --git a/pkg/ant.rmlui/src/css/PropertyParserAnimation.cpp b/pkg/ant.rmlui/src/css/PropertyParserAnimation.cpp index c5c8a91467..ff94979331 100644 --- a/pkg/ant.rmlui/src/css/PropertyParserAnimation.cpp +++ b/pkg/ant.rmlui/src/css/PropertyParserAnimation.cpp @@ -24,39 +24,39 @@ static const std::unordered_map keywords = { {"all", {Keyword::ALL}}, {"alternate", {Keyword::ALTERNATE}}, {"infinite", {Keyword::INFINITE}}, - {"back-in", {Keyword::TWEEN, {Tween::Type::Back, Tween::Direction::In}}}, - {"back-out", {Keyword::TWEEN, {Tween::Type::Back, Tween::Direction::Out}}}, - {"back-in-out", {Keyword::TWEEN, {Tween::Type::Back, Tween::Direction::InOut}}}, - {"bounce-in", {Keyword::TWEEN, {Tween::Type::Bounce, Tween::Direction::In}}}, - {"bounce-out", {Keyword::TWEEN, {Tween::Type::Bounce, Tween::Direction::Out}}}, - {"bounce-in-out", {Keyword::TWEEN, {Tween::Type::Bounce, Tween::Direction::InOut}}}, - {"circular-in", {Keyword::TWEEN, {Tween::Type::Circular, Tween::Direction::In}}}, - {"circular-out", {Keyword::TWEEN, {Tween::Type::Circular, Tween::Direction::Out}}}, - {"circular-in-out", {Keyword::TWEEN, {Tween::Type::Circular, Tween::Direction::InOut}}}, - {"cubic-in", {Keyword::TWEEN, {Tween::Type::Cubic, Tween::Direction::In}}}, - {"cubic-out", {Keyword::TWEEN, {Tween::Type::Cubic, Tween::Direction::Out}}}, - {"cubic-in-out", {Keyword::TWEEN, {Tween::Type::Cubic, Tween::Direction::InOut}}}, - {"elastic-in", {Keyword::TWEEN, {Tween::Type::Elastic, Tween::Direction::In}}}, - {"elastic-out", {Keyword::TWEEN, {Tween::Type::Elastic, Tween::Direction::Out}}}, - {"elastic-in-out", {Keyword::TWEEN, {Tween::Type::Elastic, Tween::Direction::InOut}}}, - {"exponential-in", {Keyword::TWEEN, {Tween::Type::Exponential, Tween::Direction::In}}}, - {"exponential-out", {Keyword::TWEEN, {Tween::Type::Exponential, Tween::Direction::Out}}}, - {"exponential-in-out", {Keyword::TWEEN, {Tween::Type::Exponential, Tween::Direction::InOut}}}, - {"linear-in", {Keyword::TWEEN, {Tween::Type::Linear, Tween::Direction::In}}}, - {"linear-out", {Keyword::TWEEN, {Tween::Type::Linear, Tween::Direction::Out}}}, - {"linear-in-out", {Keyword::TWEEN, {Tween::Type::Linear, Tween::Direction::InOut}}}, - {"quadratic-in", {Keyword::TWEEN, {Tween::Type::Quadratic, Tween::Direction::In}}}, - {"quadratic-out", {Keyword::TWEEN, {Tween::Type::Quadratic, Tween::Direction::Out}}}, - {"quadratic-in-out", {Keyword::TWEEN, {Tween::Type::Quadratic, Tween::Direction::InOut}}}, - {"quartic-in", {Keyword::TWEEN, {Tween::Type::Quartic, Tween::Direction::In}}}, - {"quartic-out", {Keyword::TWEEN, {Tween::Type::Quartic, Tween::Direction::Out}}}, - {"quartic-in-out", {Keyword::TWEEN, {Tween::Type::Quartic, Tween::Direction::InOut}}}, - {"quintic-in", {Keyword::TWEEN, {Tween::Type::Quintic, Tween::Direction::In}}}, - {"quintic-out", {Keyword::TWEEN, {Tween::Type::Quintic, Tween::Direction::Out}}}, - {"quintic-in-out", {Keyword::TWEEN, {Tween::Type::Quintic, Tween::Direction::InOut}}}, - {"sine-in", {Keyword::TWEEN, {Tween::Type::Sine, Tween::Direction::In}}}, - {"sine-out", {Keyword::TWEEN, {Tween::Type::Sine, Tween::Direction::Out}}}, - {"sine-in-out", {Keyword::TWEEN, {Tween::Type::Sine, Tween::Direction::InOut}}}, + {"back-in", {Keyword::TWEEN, Tween::BackIn}}, + {"back-out", {Keyword::TWEEN, Tween::BackOut}}, + {"back-in-out", {Keyword::TWEEN, Tween::BackInOut}}, + {"bounce-in", {Keyword::TWEEN, Tween::BounceIn}}, + {"bounce-out", {Keyword::TWEEN, Tween::BounceOut}}, + {"bounce-in-out", {Keyword::TWEEN, Tween::BounceInOut}}, + {"circular-in", {Keyword::TWEEN, Tween::CircularIn}}, + {"circular-out", {Keyword::TWEEN, Tween::CircularOut}}, + {"circular-in-out", {Keyword::TWEEN, Tween::CircularInOut}}, + {"cubic-in", {Keyword::TWEEN, Tween::CubicIn}}, + {"cubic-out", {Keyword::TWEEN, Tween::CubicOut}}, + {"cubic-in-out", {Keyword::TWEEN, Tween::CubicInOut}}, + {"elastic-in", {Keyword::TWEEN, Tween::ElasticIn}}, + {"elastic-out", {Keyword::TWEEN, Tween::ElasticOut}}, + {"elastic-in-out", {Keyword::TWEEN, Tween::ElasticInOut}}, + {"exponential-in", {Keyword::TWEEN, Tween::ExponentialIn}}, + {"exponential-out", {Keyword::TWEEN, Tween::ExponentialOut}}, + {"exponential-in-out", {Keyword::TWEEN, Tween::ExponentialInOut}}, + {"linear-in", {Keyword::TWEEN, Tween::LinearIn}}, + {"linear-out", {Keyword::TWEEN, Tween::LinearOut}}, + {"linear-in-out", {Keyword::TWEEN, Tween::LinearInOut}}, + {"quadratic-in", {Keyword::TWEEN, Tween::QuadraticIn}}, + {"quadratic-out", {Keyword::TWEEN, Tween::QuadraticOut}}, + {"quadratic-in-out", {Keyword::TWEEN, Tween::QuadraticInOut}}, + {"quartic-in", {Keyword::TWEEN, Tween::QuarticIn}}, + {"quartic-out", {Keyword::TWEEN, Tween::QuarticOut}}, + {"quartic-in-out", {Keyword::TWEEN, Tween::QuarticInOut}}, + {"quintic-in", {Keyword::TWEEN, Tween::QuinticIn}}, + {"quintic-out", {Keyword::TWEEN, Tween::QuinticOut}}, + {"quintic-in-out", {Keyword::TWEEN, Tween::QuinticInOut}}, + {"sine-in", {Keyword::TWEEN, Tween::SineIn}}, + {"sine-out", {Keyword::TWEEN, Tween::SineOut}}, + {"sine-in-out", {Keyword::TWEEN, Tween::SineInOut}}, }; Property PropertyParseAnimation(PropertyId id, const std::string& value) {