Transform Tracks
With our current setup, there exists tracks for scalars, vectors and quaternions. Next we need a higher order track, one that can encode the change of a Transform
object over time. In this context, a Transform
object is made up of three components: position, rotation and scale.
struct Transform { vec3 position; quat rotation; vec3 scale; }
If we where to template the Track
class to represent a Transform
it would look something like this typedef Track<Transform, 10> TransformTrack_BAD;
Not all transform tracks will animate every component of a transform object. Some animation might only animate the rotation for example. Because not all transform components need to be animated, making a frame that has 10 unique floats for every value and tangent is wasteful.
There is an additional piece of data that must be kept somewhere, a reference to the transform object that the transform track is animating. Typically, this type of reference is expressed as an index into the array that contains the scene hierarchy, or sometimes using a pointer. A transform track will always have a target object. Embedding this information in the transform track class would be very useful. The TransformTrack
covered in the book has the following member variables:
class TransformTrack { protected: unsigned int mId; VectorTrack mPosition; QuaternionTrack mRotation; VectorTrack mScale; float mStartTime; float mEndTime; protected: void RecalculateDuration(); pulic: Transform Sample(const Transform& t, float time, bool looping); // Rest of the class }
The TransformTrack
class does not need to be templated. It contains the following data:
- An id, that represents the index of the transform this track is affecting.
- A vector track for the position component.
- A quaternion track for the rotation component.
- A vector track for the scale component.
- Cached start and end times.
Any of the component tracks (position, rotation or scale) could be empty. When the Sample
function is called it must be provided a default Transform
. If a TransformTrack
has an empty component track, the missing value is taken from the passed in default Transform
object.
The TransformTrack
class caches start and end times. Any time one of the tracks changes, the cached times must be re-calculated. The start time is the lowest of the component track start times. The end time is the highest of the component track end times.
The TransformTrack
only animates the values of one Transform
object over time. Typically a character is made up of many transforms, not all of which are animated. Before exploring how to combine TransformTrack
objects into an animation clip, let's explore how the hierarchy that transform tracks animate works.