22 if (forceReset || time < _left || time >= _right) {
30 const float t = (_recip == 0.0f) ? 0.0f : (time - _left) * _recip;
32 return _p0 + (_p1 - _p0) * t;
36 const float s = t * t * (3.0f - 2.0f * t);
37 return _p0 + (_p1 - _p0) * s;
40 return evaluateHermite(_p0, _p1, _m0, _m1, t);
43 void CurveEvaluator::reset(
const float time)
46 _left = -std::numeric_limits<float>::infinity();
47 _right = std::numeric_limits<float>::infinity();
49 _p0 = _p1 = _m0 = _m1 = 0.0f;
53 const auto& keys = _curve->
keys;
54 const size_t len = keys.size();
57 _left = -std::numeric_limits<float>::infinity();
58 _right = std::numeric_limits<float>::infinity();
60 _p0 = _p1 = _m0 = _m1 = 0.0f;
64 if (time < keys[0].first) {
65 _left = -std::numeric_limits<float>::infinity();
66 _right = keys[0].first;
68 _p0 = _p1 = keys[0].second;
73 if (time >= keys[len - 1].first) {
74 _left = keys[len - 1].first;
75 _right = std::numeric_limits<float>::infinity();
77 _p0 = _p1 = keys[len - 1].second;
83 while (time >= keys[index + 1].first) {
87 _left = keys[index].first;
88 _right = keys[index + 1].first;
89 const float diff = 1.0f / (_right - _left);
90 _recip = std::isfinite(diff) ? diff : 0.0f;
91 _p0 = keys[index].second;
92 _p1 = keys[index + 1].second;
95 calcTangents(keys, index);
101 void CurveEvaluator::calcTangents(
const std::vector<std::pair<float, float>>& keys,
const size_t index)
103 std::pair<float, float> a;
104 const std::pair<float, float>& b = keys[index];
105 const std::pair<float, float>& c = keys[index + 1];
106 std::pair<float, float> d;
110 keys[0].first + (keys[0].first - keys[1].first),
111 keys[0].second + (keys[0].second - keys[1].second)
117 if (index == keys.size() - 2) {
119 keys[index + 1].first + (keys[index + 1].first - keys[index].first),
120 keys[index + 1].second + (keys[index + 1].second - keys[index].second)
126 const float s1_ = 2.0f * (c.first - b.first) / (c.first - a.first);
127 const float s2_ = 2.0f * (c.first - b.first) / (d.first - b.first);
129 _m0 = _curve->tension * (std::isfinite(s1_) ? s1_ : 0.0f) * (c.second - a.second);
130 _m1 = _curve->tension * (std::isfinite(s2_) ? s2_ : 0.0f) * (d.second - b.second);
133 float CurveEvaluator::evaluateHermite(
const float p0,
const float p1,
const float m0,
const float m1,
const float t)
135 const float t2 = t * t;
136 const float twot = t + t;
137 const float omt = 1.0f - t;
138 const float omt2 = omt * omt;
140 return p0 * ((1.0f + twot) * omt2) +
142 p1 * (t2 * (3.0f - twot)) +
143 m1 * (t2 * (t - 1.0f));
float evaluate(float time, bool forceReset=false)
CurveEvaluator(Curve *curve, float time=0.0f)
std::vector< std::pair< float, float > > keys