Programming Manual Chap. 10

Animation Basics
In Wild Pockets, the word "Animation" is used to mean prerecorded movements. Animations are created in Max or Maya and exported to a file on the file server. There are three ways to generate movement: using the physics engine, using the lua script, and by recording movements in Max or Maya. Of these three, only the recorded ones are called "animations." The other two are just called "movement."

Animation is Bone-Based
Wild Pockets uses a bone-based animation system. This means that in addition to creating polygons, the artist creates "bone" objects. The polgyons are "rigged" to the bones, meaning that when the bone is moved, the polygons that are rigged to that bone follow along. In Max, you must use either Skin or Physique to rig your objects to the bones. In Maya you skin the model to the joints with a Smooth Bind.

When exporting an animation from Max or Maya, only bone-movements are recorded. That means that if you want to animate an object with Max or Maya, it must have a bone! Even if all you want to do is animate a cardboard box falling off a shelf, you must put one bone inside the box, rig the box to the bone, and manipulate the box by manipulating the bone.

In many models, bones are interconnected (ie, the forearm-bone is connected to the upperarm-bone), but they don't have to be. For example, if you wanted to create an animation of a car exploding, you would split the car mesh into a dozen or so chunks, and put a bone inside each chunk. By sending each bone hurtling in a different direction, the car will fragment. In this case, you would want the bones to be completely unconnected to each other.

Commands exist in the lua script to move the entire model, and also to move individual bones; see the documentation of class SceneObject for more information on bone manipulation commands.

Animation Files
An animation file specifies where bones should move. If you were to decode an animation file, you would see commands a little like this:
 * Time 0.0: Rotate right-elbow to 20 degree angle.
 * Time 0.1: Rotate left-knee to 2 degree angle.
 * Time 0.2: Rotate left-knee to 4 degree angle.

In this, the strings "right-elbow" and "left-knee" are the names of bones in the character’s skeleton. The animation file tells these bones where to go. There are a few technicalities, but generally, that’s the essence of what an animation file is.

An animation can affect all of a model’s bones, or only some of them – for example, a wave animation could be designed to affect only a model’s arm bones. A scene object can be commanded to play an animation resource. Multiple animations can play at once – for example, you could play a walk and a wave animation at the same time.

Using Animation Files
Once you have exported an animation file, you can import it into the scene with the following command: myAnimation = Animation.load(filename)

Once the animation is loaded, it can be applied to a scene object.

To play an animation on a scene object, use the following command: mySceneObject:playAnimation(myAnimation,options)

The animation will begin playing immediately after this command is run. The "options" argument is a table containing a set of fields that can modify the playback of the animation:
 * loop: A boolean flag. If true, the animation automatically repeats when it completes.
 * speed: The playback rate of the animation. 1.0 is the regular playback rate, while 2.0 doubles the rate (halves the duration) and 0.5 halves the rate (doubles the duration). the rate can be negative, which reverses the animation direction.
 * start: The time in the animation to begin playback, also known as the "key-in" time. Setting the start time to greater than 0 will skip parts of the animation from 0 seconds to the start time.
 * stop: The time in the animation to cease playback, also known as the "key-out" time. Setting the stop time to less than the length of the animation will skip parts of the animation from the stop time to the end of the animation.
 * time: The initialization time. For a looping animation, this is the start time for the first loop; otherwise, this is the same as the "start" option.
 * channel: A number or string specifying the channel for the animation. Two or more animations can be played simultaneously on the same model by putting them on different channels; each channel is separately controlled.
 * uniqueChannel: A boolean that, if set to true, will find the next free channel to use. (Overridden if channel is set)
 * callback: A function (taking no arguments) that is called when the animation completes one cycle.
 * callTime: A number in seconds of the amount of time before the end of the animation that the callback is called (default 0 seconds)
 * prePad: The time in seconds to stay on the first frame of the animation before starting to play (default 0)
 * postPad: The time in seconds to stay on the last frame of the animation after playing the full animation (default 0) (has no effect when loop = true)
 * fadeInTime: The time in seconds (including prePad) to fade the weight from 0 to the set weight. (default 0)
 * fadeOutTime: The time in seconds before the end, including postPad, to start fading from the set weight to 0 (default 0)
 * fadeAll: A boolean that if set to true fades all other animations out and then back in again at the end of this animation (default 0)
 * weight: A number between 0.0-1.0, defines the weight of the animation as compared to other animations currently playing on different channels. This will allow the system to blend two animations together. (default 1)

The properties of the animation that are controlled by the options table can also be modified while the animation is playing. See the documentation of class SceneObject for more information on the functions that modify the properties.

In addition to using an animation to move a model through time, a single frame of animation can be used to pose a model with the following command: mySceneObject:pose(myAnimation,desiredTime,boneNames)

This command positions the bones in the model based upon a specific snapshot of the specified animation. The desiredTime value is the time (in seconds) to snapshot within the animation. Additionally, boneNames is an array of strings that correspond to the names of the bones in the scene object; if boneNames is specified, only the bones with names matching the strings in the array will be moved, and all other bones will be left alone.

It should also be noted that animations only affect the visible geometry of a scene object. Collision geometry and physical properties aren't tied to the skeleton and so aren't modified by either posing or animation.

Animation Blending
Animation blending allows multiple animations to be played at the same time with different weights. This can be very useful when many animations will need to be played on the same object at either the same time, or with seamless transitions between them.

Animation blending centers around the weights on a given channel playing on a scene object. If a scene object only has one animation playing on it, it doesn't matter what weight it has, it will play the full animation as it has nothing to blend against (an exception is a weight of 0, which is special cased out to not playing). If two objects are weighted equally, they will both be blended equally against each other, so two animations playing with weights of 1.0 and 1.0 will act exactly the same as weights of 0.1, and 0.1. Animation weights can be changed fluidly mid animation by calling: mySceneObject:animationFade(weight, time, channel)

This command provides a way to linearly change weights from the current weight to a new weight over a period of time. For the best results blending from one animation to another, use this function in pair with itself, or playAnimation so that while one channel is fading in, another channel is fading out to 0.

As mentioned before, animation blending has to have something to blend against. Specifically for the case where there is no idle animation to blend all other animations against, this function returns a 0.1 second long looping animation of a scene objects default pose: mySceneObject:animationDefault

Animation Retargeting
While in general, animations and the models that will use them go hand-in-hand, the engine is flexible enough to apply an animation to any model. When doing this, bones in the animation that aren't in the model are ignored, and bones that aren't mentioned by the animation won't be manipulated by the animation. Whether it looks good depends on whether the model has a skeleton which is "sufficiently similar" to the one for which the animation was intended.