Oxygen Engine
Modern C++ 3D Engine using OpenGL
Loading...
Searching...
No Matches
curve.h
1#ifndef OE_UTIL_CURVE_H
2#define OE_UTIL_CURVE_H
3
4#include <glm/gtx/easing.hpp>
5
6namespace oe::util
7{
11 template <typename T>
12 concept CurveValueConcept = requires(T t)
13 {
14 {0.5f * t} -> std::convertible_to<T>;
15 {t + t} -> std::convertible_to<T>;
16 };
17
21 template <typename T>
22 concept CurvePositionConcept = requires(T t)
23 {
24 {t} -> std::convertible_to<float>;
25 };
26
30 template <typename T, typename V, typename P>
31 concept CurvePointConcept = requires(T t)
32 {
33 {t.value} -> std::convertible_to<V>;
34 {t.position} -> std::convertible_to<P>;
35 };
36
41 {
42 DIRECT,
43 HOLD_LAST,
44 LINEAR,
45 CUBIC
46 };
47
51 template <CurveValueConcept V, CurvePositionConcept P = float>
53 {
57
66 constexpr auto operator<=>(const CurvePoint& other) const
67 {
68 return position <=> other.position;
69 }
70
80 [[nodiscard]] constexpr static V interpolate(const CurvePoint& begin_point, const CurvePoint& end_point, const P ratio) noexcept
81 {
82 if (end_point.interpolation == CurveInterpolation::HOLD_LAST)
83 {
84 return begin_point.value;
85 }
86 else if (end_point.interpolation == CurveInterpolation::DIRECT)
87 {
88 return end_point.value;
89 }
90
91 P factor = (end_point.position != begin_point.position)
92 ? (ratio - begin_point.position) / (end_point.position - begin_point.position)
93 : 1.0f
94 ;
95
96 if (end_point.interpolation == CurveInterpolation::CUBIC)
97 {
98 factor = glm::cubicEaseInOut(factor);
99 }
100
101 return glm::mix(begin_point.value, end_point.value, factor);
102 };
103 };
104
111 {
117 template<CurveValueConcept V, CurvePositionConcept T>
119
128 template <typename Type>
129 using PointStorageType = std::vector<Type>;
130 };
131
155 template <CurveValueConcept V, CurvePositionConcept T = float, typename CurveSettingsType = CurveSettings>
156 struct Curve
157 {
158 using PointType = typename CurveSettingsType::PointType<V, T>;
159 using ContainerType = typename CurveSettingsType::PointStorageType<PointType>;
160
161 // We expect to have PointType.position and PointType.value
163
175 [[nodiscard]] constexpr V eval(const T x) const noexcept
176 {
177 assert(std::is_sorted(control_points.cbegin(), control_points.cend()));
178
179 if (control_points.size() == 0)
180 {
181 return {};
182 }
183
184 if (control_points.size() == 1)
185 {
186 return control_points.at(0).value;
187 }
188
189 const auto pos_final = std::find_if(control_points.cbegin(), control_points.cend(), [&x](const PointType& point)
190 {
191 return point.position > x;
192 });
193
194 // Position is before the first element, return first element
195 if (pos_final == control_points.cbegin())
196 {
197 return pos_final->value;
198 }
199
200 // Position not found (considered after last element), return last element
201 if (pos_final == control_points.cend())
202 {
203 return (pos_final-1)->value;
204 }
205
206 const auto pos_begin = pos_final-1;
207
208 return PointType::interpolate(*pos_begin, *pos_final, x);
209 }
210
212 };
213}
214
215#endif
Curve point (= keyframe) must have value and position members.
Definition curve.h:31
Curve point position (= abscissa) must be convertible to a floating point value.
Definition curve.h:22
Curve point value type must overloads operators "addition between objects" and "multiplication with a...
Definition curve.h:12
Various utilities.
Definition byte_array.h:20
CurveInterpolation
Interpolation mode between points.
Definition curve.h:41
@ HOLD_LAST
Hold last value.
@ DIRECT
No interpolation, directly switch to this value.
@ LINEAR
Do a linear interpolation between last value and this one.
@ CUBIC
Do a cubic interpolation between last value and this one.
Point on a curve, also called a keyframe in some contexts.
Definition curve.h:53
CurveInterpolation interpolation
How to interpolate between last point and this point.
Definition curve.h:56
static constexpr V interpolate(const CurvePoint &begin_point, const CurvePoint &end_point, const P ratio) noexcept
Interpolate Value between two points.
Definition curve.h:80
V value
Value of this point.
Definition curve.h:55
P position
Position of this point on the curve.
Definition curve.h:54
constexpr auto operator<=>(const CurvePoint &other) const
Three-way comparison operator.
Definition curve.h:66
Curve Advanced settings.
Definition curve.h:111
std::vector< Type > PointStorageType
The container to use to store points of the curve.
Definition curve.h:129
General purpose curve (can be used for color gradients, animations, etc...)
Definition curve.h:157
ContainerType control_points
Points of the curve.
Definition curve.h:211
typename CurveSettingsType::PointStorageType< PointType > ContainerType
Type used to store all points.
Definition curve.h:159
typename CurveSettingsType::PointType< V, T > PointType
Type used as a point on the curve.
Definition curve.h:158
constexpr V eval(const T x) const noexcept
Compute a value on the curve based on its control points.
Definition curve.h:175