New Ardor3D Animation Features - Part 2

In the last post, we looked at how our new animation system adds animation states and a finite state machine to enable simpler handling of character animation.  This is good, but what if we need the character to be doing two things at once... say walking and pointing at something of interest.  We'd either need to have states for all possible combinations of behavior (yikes, and probably not possible), or we'd have to start modifying the solid states' blend trees, which is hairy and goes against what states were trying to accomplish anyhow.

Enter Ardor3D's AnimationLayer class.  Animation layering allows us to play multiple, unrelated animation states on the same skeleton by blending their outputs together.  In Ardor3D this blending is done through an AnimationBlender field in AnimationLayer.  The output of the layers is gathered by walking through the layers and blending each layer with the output of the layer (or layer's blender) immediately before it.  Right now we only have a lerp layer blender, but additive blending would be easy to implement as well.  Each layer implements the finite state machine talked about in the last post and is stored in a List in AnimationManager.

When putting the content and time line of your layers together you should pay special attention to the first or "base" animation layer.  To ensure your skeleton is properly posed, this layer should have an active state containing a complete skeletal pose for your character at all points in the time line.  (Note: You could split this responsibility across two or more layers, just make sure you are covered.)  Other layers in your manager may or may not have full pose information, or might only have an active state at certain points in the time line.  In our AnimationDemoExample we have a layer for walk/run, one for punch (which is only active when the punch button is pressed) and one for head turning (which may or may not be enabled.)


Now that we have our pieces laid out, how do we put them together in a way that is friendly to our development / art pipeline?  We could just go ahead and program our states in Java directly, but we might want to instead do it in a way that does not require recompiling classes and is perhaps even tool friendly.

To assist in this area, we've put together a JavaScript loading system.  Your layers, states, transitions and so forth are described using JSON and then converted to Java objects for populating an AnimationManager instance.  An example of this is displayed below:

// our base layer
var baseLayer = MANAGER.baseAnimationLayer;

// up and down movement state
var stateUD = {
    "name" : "up_down",
    "tree" : {
        "clip" : {
            "name" : "up_down_clip",
            "timeScale" : -1.5
        }
    },
    "transitions" : {
        "fade" : [
                 "-", "-", // start/end window
                 "fade", // type
                 "left_right", // target
                 0.5, // fade time
                 "SCurve5" // type
                 ],
        "cut" : [
                 "-", "-", // start/end window
                 "immediate", // type
                 "left_right" // target
                 ],
    },
    "endTransition" : [
                   "-", "-", // start/end window
                   "immediate", // type
                 "up_down" // target
                 ]
};

// add to layer
baseLayer.addSteadyState(_steadyState(stateUD));
In the above example, we grab the automatically provided base layer, create a JSON structure describing a state with a simple blend tree (with just one ClipSource node), two transitions ("fade" and "cut") and an endTransition (effectively a repeat).  We then add this state to our base layer.  The function _steadyState comes from functions.js, part of the ardor3d-animations project.  Note also that it is pretty easy to tweak fade times, time scales, and so forth.

In the next post, we'll look at how to set weights without knowing the exact structure of your layers/states. We'll also look at animation triggers and finally, we'll take a closer look at the demo.

0 comments: