Motive Animation System
An open source project by FPL.
 All Classes Functions Variables Typedefs Friends Pages
motive::BulkSplineEvaluator Class Reference

Traverse through a set of splines in a performant way. More...

#include <bulk_spline_evaluator.h>

Detailed Description

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 CompactSplineSourceSpline (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 CubicCurveCubic (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 RangeModularRange (const Index index) const
 

Member Function Documentation

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.

const CubicCurve& motive::BulkSplineEvaluator::Cubic ( const Index  index) const
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.

float motive::BulkSplineEvaluator::CubicX ( const Index  index) const
inline

Return the current x value for the current cubic. Each spline segment is evaluated as a cubic that starts at x=0.

void motive::BulkSplineEvaluator::Derivatives ( const Index  index,
const Index  count,
float *  out 
) const
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.

void motive::BulkSplineEvaluator::DerivativesWithoutPlayback ( const Index  index,
Index  count,
float *  out 
) const
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.

float motive::BulkSplineEvaluator::DerivativeWithoutPlayback ( const Index  index) const
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.

float motive::BulkSplineEvaluator::EndDerivativeWithoutPlayback ( const Index  index) const
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.

bool motive::BulkSplineEvaluator::ModularArithmetic ( const Index  index) const
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).

const Range& motive::BulkSplineEvaluator::ModularRange ( const Index  index) const
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.

float motive::BulkSplineEvaluator::NextY ( const Index  index,
const float  current_y,
const float  target_y,
const ModularDirection  direction 
) const
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.

float motive::BulkSplineEvaluator::NormalizedY ( const Index  index) const
inline

Return the current y value for the spline at index, normalized to be within the valid y_range.

Index motive::BulkSplineEvaluator::NumIndices ( ) const
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().

  • splines are allocated or removed at the highest indices
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.

float motive::BulkSplineEvaluator::YDifferenceToEnd ( const Index  index) const
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.

const float* motive::BulkSplineEvaluator::Ys ( const Index  index) const
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.


The documentation for this class was generated from the following file: