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
4namespace oe::util
5{
6 template <typename T>
7 concept CurvePointType = requires(T t)
8 {
9 {0.5f * t} -> std::convertible_to<T>;
10 {t + t} -> std::convertible_to<T>;
11 };
12
13 template <typename T>
14 concept CurveAbscissaType = requires(T t)
15 {
16 {t} -> std::convertible_to<float>;
17 };
18
23 {
24 DIRECT,
25 HOLD_LAST,
26 LINEAR
27 };
28
29 template <CurvePointType V, CurveAbscissaType T = float>
31 {
35
39 auto operator<=>(const CurvePoint& other) const
40 {
41 return position <=> other.position;
42 }
43 };
44
64 template <CurvePointType V, CurveAbscissaType T = float>
65 struct Curve
66 {
67 using Point = CurvePoint<V, T>;
68
74 constexpr V eval(const T x) const
75 {
76 assert(std::is_sorted(control_points.cbegin(), control_points.cend()) && "The Control points must be sorted by position!");
77
78 if (control_points.size() == 0)
79 {
80 return {};
81 }
82
83 if (control_points.size() == 1)
84 {
85 return control_points.at(0).value;
86 }
87
88 const auto pos_final = std::find_if(control_points.cbegin(), control_points.cend(), [&x](const Point& point)
89 {
90 return point.position > x;
91 });
92
93 // Position is before the first element, return first element
94 if (pos_final == control_points.cbegin())
95 {
96 return pos_final->value;
97 }
98
99 // Position not found (considered after last element), return last element
100 if (pos_final == control_points.cend())
101 {
102 return (pos_final-1)->value;
103 }
104
105 const auto pos_begin = pos_final-1;
106
107 if (pos_final->interpolation == CurveInterpolation::HOLD_LAST)
108 {
109 return pos_begin->value;
110 }
111 else if (pos_final->interpolation == CurveInterpolation::LINEAR)
112 {
113 T factor = (pos_final->position != pos_begin->position)
114 ? (x - pos_begin->position) / (pos_final->position - pos_begin->position)
115 : 1.0f
116 ;
117
118 return (1.0f-factor) * pos_begin->value + factor * pos_final->value;
119 }
120
121 // Curve Interpolation is NONE
122 return pos_final->value;
123 }
124
125 std::vector<Point> control_points;
126 };
127}
128
129#endif
Definition curve.h:14
Definition curve.h:7
Various utilities.
Definition byte_array.h:20
CurveInterpolation
Interpolation mode between points.
Definition curve.h:23
@ HOLD_LAST
Hold last value.
@ DIRECT
No interpolation, directly switch to this value.
@ LINEAR
Do a linear interpolation between last value and this one.
Definition curve.h:31
CurveInterpolation interpolation
How to interpolate between last point and this point.
Definition curve.h:34
V value
Value of this point.
Definition curve.h:33
auto operator<=>(const CurvePoint &other) const
For comparison, only take the abscissa into account.
Definition curve.h:39
T position
Abscissa position of this point.
Definition curve.h:32
General purpose curve (can be used for gradients, animations, etc...)
Definition curve.h:66
constexpr V eval(const T x) const
Compute a value on the curve based on control points.
Definition curve.h:74