mirror of
https://github.com/LNH-team/pico-launcher.git
synced 2026-06-02 09:06:54 +02:00
Initial commit
This commit is contained in:
35
arm9/source/animation/Animator.cpp
Normal file
35
arm9/source/animation/Animator.cpp
Normal 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;
|
||||
}
|
||||
50
arm9/source/animation/Animator.h
Normal file
50
arm9/source/animation/Animator.h
Normal 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;
|
||||
};
|
||||
48
arm9/source/animation/CubicBezierCurve.h
Normal file
48
arm9/source/animation/CubicBezierCurve.h
Normal 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;
|
||||
}
|
||||
}
|
||||
};
|
||||
8
arm9/source/animation/Curve.h
Normal file
8
arm9/source/animation/Curve.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "common.h"
|
||||
|
||||
class Curve
|
||||
{
|
||||
public:
|
||||
virtual fix32<26> Compute(fix32<26> t) const = 0;
|
||||
};
|
||||
20
arm9/source/animation/Interpolator.h
Normal file
20
arm9/source/animation/Interpolator.h
Normal 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;
|
||||
}
|
||||
};
|
||||
11
arm9/source/animation/LinearCurve.h
Normal file
11
arm9/source/animation/LinearCurve.h
Normal 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;
|
||||
}
|
||||
};
|
||||
48
arm9/source/animation/ThreePointCubicBezierCurve.h
Normal file
48
arm9/source/animation/ThreePointCubicBezierCurve.h
Normal 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;
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user