- GetValue() calculates the value at the given position now ondemand,
without caching values as previously. First, it uses binary search
to find the segment (start and end point) containing the given
position. Constant and linear interpolation are straightforward,
bezier curves are calculating by binary search between the end
points until a point on the curve is found with a X coordinate close
enough to the given position. That points Y coordinate is returned.
- IsIncreasing(), GetRepeatFraction(), GetDelta() use GetValue()
instead of accessing the (removed) Values vector.
- Removed now unused private functions, and the unused public
Process().
First test results show good performance improvements for the
"rendering case" (setting up the keyframe points at once, then getting
all values) and drastic performance improvements for the "preview
case" (changing keyframe points, mixed with getting values).
Returning a non constant reference is not possible; this allows
outside code to invalidate internal invariants (sorted order of
points) by modifying the returned point. To make updates the current
best approach is to remove the point by index, and then add it again.
The Values vector should only be accessed from the outside through the
GetValue() function. The Points vector should only be accessed using
the AddPoint(), RemovePoint(), .. functions.
This helps maintain internal invariants (e.g. keeping Points sorted)
and allows for future removal / lazy evaluation of Values.
The size() of the vectors had been accessed from various parts of the
code; the GetLength() (for Values) and GetCount() (for Points) member
functions provide access to this information and are already part of
the public API.
AddPoint() now searches (binary search) for the best place to insert a
new point, thus always maintaining the order of Points. Therefore,
ReorderPoints() is no longer needed.
CAVEAT: This breaks if some outside code changes (the public member)
Points!
With few points the performance doesn't differ that much; using
std::sort removes the possibility of introducing bugs into the
handmade sorting algorithm, though.
GetInt(), GetLong() are exactly the same as GetValue() except that
their result is rounded and converted to the repsective data type.
Thus avoid code duplication and use GetValue().
The previous values do not influence the return value of the function
nor does looping over them have any side effect.
The next_repeats value is not used in any way, thus it doesn't need to
be calculated.
Detecting PythonLibs before PythonInterp can cause a non-default Python
library to be picked up, which then won't match the PythonInterp version
(which always matches the version of the `python3` command).
- Switch to AUTOMOC for Qt classes
- Eliminate globbing of source subdirs
- Call `include_directories()` in top-level CMakeLists
- Make header files PUBLIC library sources
- Make other sources PRIVATE