1#pragma once
2
3#include <array>
4#include "basis/seadRawPrint.h"
5#include "basis/seadTypes.h"
6#include "math/seadVector.h"
7
8namespace sead::hostio
9{
10class ICurve
11{
12public:
13 virtual f32 interpolateToF32(f32 t) = 0;
14 virtual Vector2f interpolateToVec2f(f32 t) = 0;
15};
16
17enum class CurveType
18{
19 Linear = 0,
20 Hermit = 1,
21 Step = 2,
22 Sin = 3,
23 Cos = 4,
24 SinPow2 = 5,
25 Linear2D = 6,
26 Hermit2D = 7,
27 Step2D = 8,
28 NonUniformSpline = 9,
29 Hermit2DSmooth = 10,
30};
31inline constexpr int cNumCurveType = 11;
32
33struct CurveDataInfo
34{
35 u8 curveType;
36 u8 _1;
37 u8 numFloats;
38 u8 numUse;
39};
40
41struct CurveData
42{
43 u32 numUse;
44 u32 curveType;
45 f32 f[30];
46};
47static_assert(sizeof(CurveData) == 0x80);
48
49template <typename T>
50class Curve : public ICurve
51{
52public:
53 Curve()
54 {
55 mInfo.curveType = 0;
56 mInfo.numUse = 0;
57 mInfo._1 = 4;
58 mInfo.numFloats = 0;
59 mFloats = nullptr;
60 }
61
62 f32 interpolateToF32(f32 t) override;
63 Vector2f interpolateToVec2f(f32 t) override;
64
65 CurveType getCurveType() const { return CurveType(mInfo.curveType); }
66
67 void setData(CurveData* data, CurveType type, u32 num_floats, u32 num_use)
68 {
69 data->curveType = u8(type);
70 data->numUse = num_use;
71 setCurveType(type);
72 setFloats(data, num_floats);
73 setNumUse(num_use);
74 }
75
76 void setFloats(CurveData* data, u32 num_floats)
77 {
78 mInfo.numFloats = num_floats;
79 mFloats = data->f;
80 }
81
82 void setCurveType(CurveType type)
83 {
84 SEAD_ASSERT(mInfo.curveType < cNumCurveType);
85 mInfo.curveType = u8(type);
86 }
87
88 void setNumUse(u32 numUse)
89 {
90 SEAD_ASSERT(numUse <= 0xff);
91 mInfo.numUse = numUse;
92 }
93
94 f32* mFloats;
95 CurveDataInfo mInfo;
96};
97
98template <typename T>
99T curveLinear_(f32 t, const CurveDataInfo* info, const T* f);
100template <typename T>
101T curveHermit_(f32 t, const CurveDataInfo* info, const T* f);
102template <typename T>
103T curveStep_(f32 t, const CurveDataInfo* info, const T* f);
104template <typename T>
105T curveSin_(f32 t_, const CurveDataInfo* info, const T* f);
106template <typename T>
107T curveCos_(f32 t, const CurveDataInfo* info, const T* f);
108template <typename T>
109T curveSinPow2_(f32 t, const CurveDataInfo* info, const T* f);
110template <typename T>
111T curveLinear2D_(f32 t, const CurveDataInfo* info, const T* f);
112template <typename T>
113T curveHermit2D_(f32 t, const CurveDataInfo* info, const T* f);
114template <typename T>
115T curveStep2D_(f32 t, const CurveDataInfo* info, const T* f);
116template <typename T>
117T curveNonuniformSpline_(f32 t, const CurveDataInfo* info, const T* f);
118template <typename T>
119T curveHermit2DSmooth_(f32 t, const CurveDataInfo* info, const T* f);
120
121template <typename T>
122using CurveFunctionTable = std::array<decltype(curveLinear_<T>)*, cNumCurveType>;
123
124extern CurveFunctionTable<f32> sCurveFunctionTbl_f32;
125extern CurveFunctionTable<f64> sCurveFunctionTbl_f64;
126
127template <typename T>
128Vector2<T> curveLinearVec2_(f32 t, const CurveDataInfo* info, const T* f);
129template <typename T>
130Vector2<T> curveHermitVec2_(f32 t, const CurveDataInfo* info, const T* f);
131template <typename T>
132Vector2<T> curveStepVec2_(f32 t, const CurveDataInfo* info, const T* f);
133template <typename T>
134Vector2<T> curveSinVec2_(f32 t, const CurveDataInfo* info, const T* f);
135template <typename T>
136Vector2<T> curveCosVec2_(f32 t, const CurveDataInfo* info, const T* f);
137template <typename T>
138Vector2<T> curveSinPow2Vec2_(f32 t, const CurveDataInfo* info, const T* f);
139template <typename T>
140Vector2<T> curveLinear2DVec2_(f32 t, const CurveDataInfo* info, const T* f);
141template <typename T>
142Vector2<T> curveHermit2DVec2_(f32 t, const CurveDataInfo* info, const T* f);
143template <typename T>
144Vector2<T> curveStep2DVec2_(f32 t, const CurveDataInfo* info, const T* f);
145template <typename T>
146Vector2<T> curveNonuniformSplineVec2_(f32 t, const CurveDataInfo* info, const T* f);
147template <typename T>
148Vector2<T> curveHermit2DSmoothVec2_(f32 t, const CurveDataInfo* info, const T* f);
149
150template <typename T>
151using CurveFunctionTableVec2 = std::array<decltype(curveLinearVec2_<T>)*, cNumCurveType>;
152
153extern CurveFunctionTableVec2<f32> sCurveFunctionTbl_Vec2f;
154extern CurveFunctionTableVec2<f64> sCurveFunctionTbl_Vec2d;
155
156template <>
157inline f32 Curve<f32>::interpolateToF32(f32 t)
158{
159 return sCurveFunctionTbl_f32[u8(mInfo.curveType)](t, &mInfo, mFloats);
160}
161
162template <>
163inline Vector2f Curve<f32>::interpolateToVec2f(f32 t)
164{
165 return sCurveFunctionTbl_Vec2f[u8(mInfo.curveType)](t, &mInfo, mFloats);
166}
167} // namespace sead::hostio
168