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 void Track::set_key(long tm, float val)
23 int idx = find_key(tm);
25 keys[idx].value = val;
29 TrackKey key = {tm, val};
34 float Track::get_key(long tm) const
36 int idx = find_key(tm);
37 if(idx == -1) return 0.0f;
38 return keys[idx].value;
41 int Track::find_key(long tm) const
43 int sz = (int)keys.size();
44 for(int i=0; i<sz; i++) {
45 if(keys[i].time == tm) return i;
50 static bool keycmp(const TrackKey &a, const TrackKey &b)
52 return a.time < b.time;
55 float Track::operator ()(long tm) const
61 int nkeys = keys.size();
66 Track *track = (Track*)this;
67 std::sort(track->keys.begin(), track->keys.end(), keycmp);
71 long tstart = keys[0].time;
72 long tend = keys[nkeys - 1].time;
74 tm = remap_time(extrap, tm, tstart, tend);
76 int idx0 = get_interval(tm);
77 assert(idx0 >= 0 && idx0 < nkeys);
80 if(idx0 == nkeys - 1) {
81 return keys[idx0].value;
84 float dt = (float)(keys[idx1].time - keys[idx0].time);
85 float t = (float)(tm - keys[idx0].time) / dt;
89 return keys[idx0].value;
92 t = smoothstep(0, 1, t);
94 return keys[idx0].value + (keys[idx1].value - keys[idx0].value) * t;
102 int Track::get_interval(long tm) const
104 int nkeys = (int)keys.size();
106 for(int i=0; i<nkeys-1; i++) {
107 if(tm < keys[i + 1].time) {
114 static long remap_time(ExtrapMode mode, long t, long t0, long t1)
116 long interval = t1 - t0;
120 if(interval <= 0) return t0;
121 return t < t0 ? t0 : (t >= t1 ? t1 : t);
125 long x = (t - t0) % interval;
126 if(x < 0) x += interval;
135 assert(!"unreachable");
139 static float smoothstep(float a, float b, float x)
141 if(x < a) return 0.0f;
142 if(x >= b) return 1.0f;
144 x = (x - a) / (b - a);
145 return x * x * (3.0f - 2.0f * x);