12 template <
typename ValueT>
32 template <
typename ValueT>
70 ValueT
at(
float time)
const;
78 void update(
float time,
bool ignoreIfEmpty =
false);
92 void checkValueType(
const ValueT& value);
100 std::vector<Keyframe<ValueT>> keyframes;
109 operator ValueT()
const;
121 KeyframeProxy(Track& track,
float time);
131 template <
typename V>
135 return keyframes.
empty();
138 template <
typename V>
145 template <
typename V>
149 checkValueType(keyframe.
value);
150 keyframes.push_back(keyframe);
154 template <
typename V>
158 addKeyframe(Keyframe<V>(time, value));
161 template <
typename V>
168 template <
typename V>
170 Track<V>::sortKeyframes()
172 std::sort(keyframes.begin(),
175 { return lhs.time < rhs.time; });
179 template <
typename V>
181 Track<V>::checkValueType(
const V&)
192 void Track<VariantValue>::checkValueType(
const VariantValue& value);
194 template <
typename V>
203 if (keyframes.size() == 1)
205 return keyframes.front().value;
208 if (time <= keyframes.front().time)
210 return keyframes.front().value;
212 if (time >= keyframes.back().time)
214 return keyframes.back().value;
219 while (i + 1 <= keyframes.size() && keyframes[i + 1].time < time)
234 template <
typename V>
238 if (updateFunc && !(ignoreIfEmpty &&
empty()))
240 updateFunc(
at(time));
244 template <
typename V>
245 Track<V>::KeyframeProxy::KeyframeProxy(
Track& track,
float time) : track(track), time(time)
249 template <
typename V>
250 Track<V>::KeyframeProxy::operator V()
const
252 return track.
at(time);
255 template <
typename V>
262 template <
typename V>
266 track.addKeyframe(time, other.
value());
269 template <
typename V>
273 return track.at(time);
276 template <
typename ValueT>
280 os <<
"Track '" << track.id <<
"' with " << track.keyframes.size() <<
" keyframes: [";
283 os << kf.
time <<
", ";
A track represents the timeline of a single value, identified by a track ID.
ValueT at(float time) const
Get the interpolated value at the given time.
void addKeyframe(float time, const ValueT &value)
Add a keyframe to this track.
Track(const TrackID &id)
Construct a track with given ID (and no update function).
void update(float time, bool ignoreIfEmpty=false)
Call the update function with the interpolated value at the given time.
friend std::ostream & operator<<(std::ostream &os, const Track< V > &track)
bool empty() const
Indicate whether this track does not contain any keyframes.
std::function< void(ValueT)> UpdateFunc
The update function type.
void addKeyframe(const Keyframe< ValueT > &keyframe)
Add a keyframe to this track.
void clear()
Clear the track of all keyframes.
KeyframeProxy operator[](float time)
Add a keyframe by assignment: track[time] = value;
Track(const TrackID &id, UpdateFunc updateFunc)
Construct a track with given ID and update function.
ReturnT linear(float t, const VariantValue &lhs, const VariantValue &rhs)
std::variant< float, Eigen::MatrixXf, Eigen::Quaternionf > VariantValue
Variant for trajectory values.
Keyframe< VariantValue > VariantKeyframe
A keyframe with of type TValue.
Track< VariantValue > VariantTrack
A track with value type TValue.
std::string TrackID
ID of tracks.
A keyframe, representing a value at a given time.
Keyframe(float time, const ValueT &value)
Constructor.
A proxy allowing for adding keyframes by: track[time] = value;
void operator=(const ValueT &value)
Add a keyframe on assignment.
ValueT value() const
Get the value at time.