5 static long remap_time(ExtrapMode mode, long t, long t0, long t1);
6 static float smoothstep(float a, float b, float x);
10 interp = INTERP_SIGMOID;
11 extrap = EXTRAP_CLAMP;
21 bool Track::empty() const
26 int Track::get_num_keys() const
28 return (int)keys.size();
31 const TrackKey &Track::operator [](int idx) const
36 TrackKey &Track::operator [](int idx)
41 void Track::set_value(long tm, float val)
43 int idx = find_key(tm);
45 keys[idx].value = val;
49 TrackKey key = {tm, val};
54 float Track::get_value(long tm) const
56 int idx = find_key(tm);
57 if(idx == -1) return 0.0f;
58 return keys[idx].value;
61 int Track::find_key(long tm) const
63 int sz = (int)keys.size();
64 for(int i=0; i<sz; i++) {
65 if(keys[i].time == tm) return i;
70 static bool keycmp(const TrackKey &a, const TrackKey &b)
72 return a.time < b.time;
75 float Track::operator ()(long tm) const
81 int nkeys = keys.size();
86 Track *track = (Track*)this;
87 std::sort(track->keys.begin(), track->keys.end(), keycmp);
91 long tstart = keys[0].time;
92 long tend = keys[nkeys - 1].time;
94 tm = remap_time(extrap, tm, tstart, tend);
96 int idx0 = get_interval(tm);
97 assert(idx0 >= 0 && idx0 < nkeys);
100 if(idx0 == nkeys - 1) {
101 return keys[idx0].value;
104 float dt = (float)(keys[idx1].time - keys[idx0].time);
105 float t = (float)(tm - keys[idx0].time) / dt;
109 return keys[idx0].value;
112 t = smoothstep(0, 1, t);
114 return keys[idx0].value + (keys[idx1].value - keys[idx0].value) * t;
122 int Track::get_interval(long tm) const
124 int nkeys = (int)keys.size();
126 for(int i=0; i<nkeys-1; i++) {
127 if(tm < keys[i + 1].time) {
134 static long remap_time(ExtrapMode mode, long t, long t0, long t1)
136 long interval = t1 - t0;
140 if(interval <= 0) return t0;
141 return t < t0 ? t0 : (t >= t1 ? t1 : t);
145 long x = (t - t0) % interval;
146 if(x < 0) x += interval;
155 assert(!"unreachable");
159 static float smoothstep(float a, float b, float x)
161 if(x < a) return 0.0f;
162 if(x >= b) return 1.0f;
164 x = (x - a) / (b - a);
165 return x * x * (3.0f - 2.0f * x);