Initial commit

This commit is contained in:
Gericom
2025-11-22 17:21:45 +01:00
commit 5d6f67c612
517 changed files with 63025 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
#include "common.h"
#include "core/math/fixed.h"
#include "Animator.h"
template <>
bool Animator<int>::Update()
{
if (++_frame >= _duration)
{
_frame = _duration;
_value = _to;
return true;
}
auto relativePos = _curve->Compute(_frame * _invDuration);
_value = _from + (relativePos.LongMul(_to - _from) + 0.5).Int();
return false;
}
template <>
bool Animator<fix32<12>>::Update()
{
if (++_frame >= _duration)
{
_frame = _duration;
_value = _to;
return true;
}
auto relativePos = _curve->Compute(_frame * _invDuration);
_value = _from + fix32<12>(relativePos.LongMul(_to - _from));
return false;
}

View File

@@ -0,0 +1,50 @@
#pragma once
#include "Curve.h"
template <typename T>
class Animator
{
public:
constexpr Animator()
: _from(), _to(), _value(), _duration(0), _frame(0), _curve(nullptr) { }
/// @brief Constructs an Animator with the given initialValue.
/// @param initialValue The initial value for the animator.
constexpr Animator(const T& initialValue)
: _from(initialValue), _to(initialValue), _value(initialValue), _duration(0), _frame(0), _curve(nullptr) { }
/// @brief Constructs an Animator that animates from from to to with the given duration and curve.
/// @param from The start value.
/// @param to The end value.
/// @param duration The duration of the animation.
/// @param curve The curve to use for the animation.
constexpr Animator(const T& from, const T& to, u32 duration, const Curve* curve)
: _from(from), _to(to), _value(_from), _duration(duration), _invDuration(fix32<26>(1) / duration), _frame(0), _curve(curve) { }
bool Update();
constexpr const T& GetValue() const { return _value; }
constexpr const T& GetTargetValue() const { return _to; }
constexpr u32 GetDuration() const { return _duration; }
constexpr u32 GetFrame() const { return _frame; }
constexpr bool IsFinished() const { return _frame == _duration; }
/// @brief Restarts this animator from the current value to a new target
/// with the given duration and curve.
/// @param target The new target value.
/// @param duration The duration of the animation.
/// @param curve The curve to use.
void Goto(const T& target, u32 duration, const Curve* curve)
{
*this = Animator(_value, target, duration, curve);
}
private:
T _from;
T _to;
T _value;
u32 _duration;
fix32<26> _invDuration;
u32 _frame;
const Curve* _curve;
};

View File

@@ -0,0 +1,48 @@
#pragma once
#include "Curve.h"
class CubicBezierCurve : public Curve
{
using fx = fix16<13>;
const fx _cx;
const fx _bx;
const fx _ax;
const fx _cy;
const fx _by;
const fx _ay;
[[gnu::noinline]]
static constexpr fix32<26> SampleCurve(fx ax, fx bx, fx cx, fx t)
{
return ((ax * t + bx) * t + cx).LongMul(t);
}
public:
constexpr CubicBezierCurve(fx p1x, fx p1y, fx p2x, fx p2y)
: _cx(3 * p1x)
, _bx(3 * (p2x - p1x) - _cx)
, _ax(1 - _cx - _bx)
, _cy(3 * p1y)
, _by(3 * (p2y - p1y) - _cy)
, _ay(1 - _cy - _by) { }
[[gnu::noinline]]
fix32<26> Compute(fix32<26> t) const override
{
fx start = 0.0;
fx end = 1.0;
while (true)
{
const fx midpoint = (start + end) >> 1;
const fix32<26> estimate = SampleCurve(_ax, _bx, _cx, midpoint);
if ((t - estimate).Abs() < 0.001)
return SampleCurve(_ay, _by, _cy, midpoint);
if (estimate < t)
start = midpoint;
else
end = midpoint;
}
}
};

View File

@@ -0,0 +1,8 @@
#pragma once
#include "common.h"
class Curve
{
public:
virtual fix32<26> Compute(fix32<26> t) const = 0;
};

View File

@@ -0,0 +1,20 @@
#pragma once
#include "common.h"
class Interpolator
{
public:
template <typename T>
static constexpr T InterpolateLinear(T a, T b, T t)
{
return a + (b - a) * t;
}
template <typename T, u32 FractionBits>
static constexpr fixed<T, FractionBits> InterpolateCubic(
fixed<T, FractionBits> cf0, fixed<T, FractionBits> cf1,
fixed<T, FractionBits> cf2, fixed<T, FractionBits> cf3, fixed<T, FractionBits> t)
{
return ((((cf0 * t + cf1) * t) + cf2) * t) + cf3;
}
};

View File

@@ -0,0 +1,11 @@
#pragma once
#include "Curve.h"
class LinearCurve : public Curve
{
public:
fix32<26> Compute(fix32<26> t) const override
{
return t;
}
};

View File

@@ -0,0 +1,48 @@
#pragma once
#include "Curve.h"
#include "CubicBezierCurve.h"
class ThreePointCubicBezierCurve : public Curve
{
using fx = fix16<13>;
fix32<26> _midPointX;
fix32<26> _midPointY;
fix32<26> _invMidPointX;
fix32<26> _invOneMinusMidPointX;
const CubicBezierCurve _firstCurve;
const CubicBezierCurve _secondCurve;
public:
constexpr ThreePointCubicBezierCurve(
fx a1x, fx a1y, fx b1x, fx b1y,
fx midpointx, fx midpointy,
fx a2x, fx a2y, fx b2x, fx b2y)
: _midPointX(midpointx)
, _midPointY(midpointy)
, _invMidPointX(fix32<26>(1) / midpointx)
, _invOneMinusMidPointX(fix32<26>(1) / (1 - midpointx))
, _firstCurve(
a1x / midpointx,
a1y / midpointy,
b1x / midpointx,
b1y / midpointy)
, _secondCurve(
(a2x - midpointx) / (1 - midpointx),
(a2y - midpointy) / (1 - midpointy),
(b2x - midpointx) / (1 - midpointx),
(b2y - midpointy) / (1 - midpointy)) { }
[[gnu::noinline]]
fix32<26> Compute(fix32<26> t) const override
{
if (t < _midPointX)
return _firstCurve.Compute(t * _invMidPointX) * _midPointY;
else
{
fix32<26> scaledT = (t - _midPointX) * _invOneMinusMidPointX;
return _secondCurve.Compute(scaledT) * (1 - _midPointY) + _midPointY;
}
}
};