X-Git-Url: http://git.mutantstargoat.com?p=faros-demo;a=blobdiff_plain;f=src%2Ftrack.cc;fp=src%2Ftrack.cc;h=bc775baed0ba6a16b39f25e77fd89970b9d20c97;hp=0000000000000000000000000000000000000000;hb=d60954c471d6f446523bad8c4c4860aa2138da1e;hpb=6917510e2aff5fa6599065c684a344a24e42123d diff --git a/src/track.cc b/src/track.cc new file mode 100644 index 0000000..bc775ba --- /dev/null +++ b/src/track.cc @@ -0,0 +1,146 @@ +#include +#include +#include "track.h" + +static long remap_time(ExtrapMode mode, long t, long t0, long t1); +static float smoothstep(float a, float b, float x); + +Track::Track() +{ + interp = INTERP_SIGMOID; + extrap = EXTRAP_CLAMP; + keys_sorted = true; + defval = 0.0f; +} + +void Track::clear() +{ + keys.clear(); +} + +void Track::set_key(long tm, float val) +{ + int idx = find_key(tm); + if(idx >= 0) { + keys[idx].value = val; + return; + } + + TrackKey key = {tm, val}; + keys.push_back(key); + keys_sorted = false; +} + +float Track::get_key(long tm) const +{ + int idx = find_key(tm); + if(idx == -1) return 0.0f; + return keys[idx].value; +} + +int Track::find_key(long tm) const +{ + int sz = (int)keys.size(); + for(int i=0; ikeys.begin(), track->keys.end(), keycmp); + keys_sorted = true; + } + + long tstart = keys[0].time; + long tend = keys[nkeys - 1].time; + + tm = remap_time(extrap, tm, tstart, tend); + + int idx0 = get_interval(tm); + assert(idx0 >= 0 && idx0 < nkeys); + int idx1 = idx0 + 1; + + if(idx0 == nkeys - 1) { + return keys[idx0].value; + } + + float dt = (float)(keys[idx1].time - keys[idx0].time); + float t = (float)(tm - keys[idx0].time) / dt; + + switch(interp) { + case INTERP_STEP: + return keys[idx0].value; + + case INTERP_SIGMOID: + t = smoothstep(0, 1, t); + case INTERP_LINEAR: + return keys[idx0].value + (keys[idx1].value - keys[idx0].value) * t; + + default: + break; + } + return 0.0f; +} + +int Track::get_interval(long tm) const +{ + int nkeys = (int)keys.size(); + + for(int i=0; i= t1 ? t1 : t); + + case EXTRAP_REPEAT: + if(interval > 0) { + long x = (t - t0) % interval; + if(x < 0) x += interval; + return x + t0; + } + return t0; + + default: + break; + } + + assert(!"unreachable"); + return t; +} + +static float smoothstep(float a, float b, float x) +{ + if(x < a) return 0.0f; + if(x >= b) return 1.0f; + + x = (x - a) / (b - a); + return x * x * (3.0f - 2.0f * x); +}