|
Motive Animation System
An open source project by
FPL.
|
Traverse through a set of splines in a performant way. More...
#include <bulk_spline_evaluator.h>
Traverse through a set of splines in a performant way.
This class should be used if you have hundreds or more splines that you need to traverse in a uniform manner. It stores the spline data so that this traversal is very fast, when done in bulk, and so we can take advantage of SIMD on supported processors.
This class maintains a current x value for each spline, and a current cubic-curve for the segment of the spline corresponding to that x. In AdvanceFrame, the xs are incremented. If this increment pushes us to the next segment of a spline, the cubic-curve is reinitialized to the next segment of the spline. The splines are evaluated at the current x in bulk.
Public Types | |
| typedef int | Index |
Public Member Functions | |
| Index | NumIndices () const |
| void | SetNumIndices (const Index num_indices) |
| void | MoveIndices (const Index old_index, const Index new_index, const Index count) |
| void | SetYRanges (const Index index, const Index count, const Range &modular_range) |
| void | SetSplines (const Index index, const Index count, const CompactSpline *splines, const SplinePlayback &playback) |
| void | ClearSplines (const Index index, const Index count) |
| Mark spline range as invalid. | |
| void | SetXs (const Index index, const Index count, const float x) |
| void | SetPlaybackRates (const Index index, const Index count, float playback_rate) |
| void | AdvanceFrame (const float delta_x) |
| bool | Valid (const Index index) const |
Return true if the spline for index has valid spline data. | |
| float | X (const Index index) const |
Return the current x value for the spline at index. | |
| float | Y (const Index index) const |
Return the current y value for the spline at index. | |
| float | NormalizedY (const Index index) const |
| const float * | Ys (const Index index) const |
| float | Derivative (const Index index) const |
Return the current slope for the spline at index. | |
| void | Derivatives (const Index index, const Index count, float *out) const |
| float | DerivativeWithoutPlayback (const Index index) const |
| void | DerivativesWithoutPlayback (const Index index, Index count, float *out) const |
| float | PlaybackRate (const Index index) const |
Return the current playback rate of the spline at index. | |
| const CompactSpline * | SourceSpline (const Index index) const |
Return the spline that is currently being traversed at index. | |
| void | Splines (const Index index, const Index count, const CompactSpline **splines) const |
| const CubicCurve & | Cubic (const Index index) const |
| float | CubicX (const Index index) const |
| float | EndX (const Index index) const |
| Return x-value at the end of the spline. | |
| float | EndY (const Index index) const |
| Return y-value at the end of the spline. | |
| void | EndYs (const Index index, const Index count, float *out) const |
| TODO OPT: Write assembly versions of this function. | |
| float | EndDerivative (const Index index) const |
| Return slope at the end of the spline. | |
| void | EndDerivatives (const Index index, const Index count, float *out) const |
| TODO OPT: Write assembly versions of this function. | |
| float | EndDerivativeWithoutPlayback (const Index index) const |
| float | YDifferenceToEnd (const Index index) const |
| void | YDifferencesToEnd (const Index index, const Index count, float *out) const |
| TODO OPT: Write assembly versions of this function. | |
| float | NormalizeY (const Index index, const float y) const |
Apply modular arithmetic to ensure that y is within the valid y_range. | |
| float | NextY (const Index index, const float current_y, const float target_y, const ModularDirection direction) const |
| bool | ModularArithmetic (const Index index) const |
| const Range & | ModularRange (const Index index) const |
| void motive::BulkSplineEvaluator::AdvanceFrame | ( | const float | delta_x | ) |
Increment x and update the Y() and Derivative() values for all indices. Process all indices in bulk to efficiently traverse memory and allow SIMD instructions to be effective.
|
inline |
Return the raw cubic curve for index. Useful if you need to calculate the second or third derivatives (which are not calculated in AdvanceFrame), or plot the curve for debug reasons.
|
inline |
Return the current x value for the current cubic. Each spline segment is evaluated as a cubic that starts at x=0.
|
inline |
Return the slopes for the count splines starting at index. out is an array of length count. TODO OPT: Write assembly versions of this function.
|
inline |
Return the slopes for the count splines starting at index, ignoring the playback rate. out is an array of length count. TODO OPT: Write assembly versions of this function.
|
inline |
Return the current slope for the spline at index. Ignore the playback rate. This is useful for times when the playback rate is 0, but you still want to get information about the underlying spline.
|
inline |
Return slope at the end of the spline, at index. Ignore the playback rate. This is useful for times when the playback rate is 0, but you still want to get information about the underlying spline.
|
inline |
True if using modular arithmetic on this index. Modular arithmetic is used for types such as angles, which are equivalent modulo 2pi (e.g. -pi and +pi represent the same angle).
|
inline |
The modular range for values that use ModularArithmetic(). Note that Y() can be outside of this range. However, we always normalize to this range before blending to a new spline.
| void motive::BulkSplineEvaluator::MoveIndices | ( | const Index | old_index, |
| const Index | new_index, | ||
| const Index | count | ||
| ) |
Move the data at old_index into new_index. Move count indices total.
Unused indices are still processed every frame. You can fill these index holes with MoveIndex(), to move items from the last index into the hole. Once all holes have been moved to the highest indices, you can call SetNumIndices() to stop processing these highest indices. Note that this is exactly what fplutil::IndexAllocator does. You should use that class to keep your indices contiguous.
|
inline |
Helper function to calculate the next y-value in a series of y-values that are restricted by direction. There are always two paths that a y value can take, in modular arithmetic. This function chooses the correct one.
Calculate the difference from the current-y value for direction.
|
inline |
Return the current y value for the spline at index, normalized to be within the valid y_range.
|
inline |
Return the number of indices currently allocated. Each index is one spline that's being evaluated.
| void motive::BulkSplineEvaluator::SetNumIndices | ( | const Index | num_indices | ) |
Increase or decrease the total number of indices processed.
This class holds a set of splines, each is given an index from 0 to size - 1.
The number of splines can be increased or decreased with SetNumIndices().
| void motive::BulkSplineEvaluator::SetPlaybackRates | ( | const Index | index, |
| const Index | count, | ||
| float | playback_rate | ||
| ) |
Set conversion rate from AdvanceFrame's delta_x to the speed at which we traverse the spline. 0 ==> paused 0.5 ==> half speed (slow motion) 1 ==> authored speed 2 ==> double speed (fast forward)
| void motive::BulkSplineEvaluator::SetSplines | ( | const Index | index, |
| const Index | count, | ||
| const CompactSpline * | splines, | ||
| const SplinePlayback & | playback | ||
| ) |
Initialize index to process s.spline starting from s.start_x. The Y() and Derivative() values are immediately available.
| void motive::BulkSplineEvaluator::SetXs | ( | const Index | index, |
| const Index | count, | ||
| const float | x | ||
| ) |
Reposition the spline at index evaluate from x. Same as calling SetSpline() with the same spline and playback.start_x = x.
| void motive::BulkSplineEvaluator::SetYRanges | ( | const Index | index, |
| const Index | count, | ||
| const Range & | modular_range | ||
| ) |
Initialize index to normalize into the modular_range range, whenever the spline segment is initialized. While travelling along a segment, note that the value may exit the modular_range range. For example, you can ensure an angle stays near the [-pi, pi) range by passing that range as the modular_range for this index. If !modular_range.Valid(), then modular arithmetic is not used.
| void motive::BulkSplineEvaluator::Splines | ( | const Index | index, |
| const Index | count, | ||
| const CompactSpline ** | splines | ||
| ) | const |
Return the splines currently playing back from index to index + count. splines is an output array of length count.
|
inline |
Return y-distance between current-y and end-y. If using modular arithmetic, consider both paths to the target (directly and wrapping around), and return the length of the shorter path.
|
inline |
Return the current y value for splines, from index onward. Since this is the most commonly called function, we keep it fast by returning a pointer to the pre-calculated array. Note that we don't recalculate the derivatives, etc., so that is why the interface is different.