|
Designer's
Notebook

Animation
Blending: Achieving Inverse Kinematics and More
Putting It
All Together
Large
selections of blending methods have been defined and are almost
ready for use. When using a blending system, the level of required
animation is significant. It is critical to plan out the entire
blend tree from the start. When planning the 'Mech animation system,
our team was surprised by the amount of animations it took to fulfill
the design. MechWarrior required 152 animations per 'Mech,
and there were over 20 'Mechs. During scheduling, it became evident
that generating this amount of animations was not obtainable. Because
of this, the team was forced to modify the animators' tools to minimize
the amount of animations. Ultimately, the list was reduced to 30
animations that the animators created from scratch. At that point,
tool processes would take those 30 animations and alter them in
various ways to create the final 152. The animators then performed
a final review of all 152 animations before they were added to the
system.
Testing
and finalizing each blender is crucial. In developing MechWarrior,
the team failed to test a few blocks, such as 'Mech jumping. There
was a general plan, but nothing concrete. Unfortunately this became
a bigger problem later in the project. By the time it was obvious
that there was a real problem, half the 'Mechs were already animated
and there was not enough time to redo the animations or reschedule
the remaining 'Mechs. The final result was that the game was shipped
with unsatisfactory landing animations. This would have been solved
if time were taken upfront to make sure all the animation blocks
worked as planned.
Figure
12 represents the basic blenders used for MechWarrior. 'Mechs
are animated with a state engine which is also serves as the transition
FIFO. Each state represents a cycling animation like walking, standing
or fallen down and is built off of other blender nodes. Each transition
is a one-time animation. The transition FIFO is extended to have
knowledge of each state and is responsible for pushing new animations
into the queue based on input from the 'Mech simulation. As it pushes
new states, it also handles pushing the transition blender nodes
as well. The FIFO carefully monitors positions of all states to
handle the addition and removal as well as the transition points.
Some
of the states represented in 'Mech are simple poses, while some
are multi-axis IK blender nodes, like crouching or standing. Other
states are built up of single axis speed blenders and multi-axis
IK blenders. Forward motion, for instance, is a speed blender with
a walk input and a run input. Both the walk and run inputs are multi-axis
IK blenders with up, down, left, right and flat animations feeding
into them.
The
transition FIFO is also the state engine for the 'Mech animations.
The states are code driven. The 'Mech simulation code requests different
motions states depending on need. The contents of the states and
transitions are data driven from a file. It is not the responsibility
of the simulation to determine what is in a state. The simulation
simply requests states and waits for them to happen, but must also
be aware that the state change will not be automatic. Each state
and transition is represented by some unknown blender nodes. The
blender nodes could be as simple as poses or as complex as full
trees. In this case, the FIFO is relying on states to be cyclic
and on transitions to be non-cyclic. When the simulation requests
a state, the FIFO finds the state and the associated transition.
The transitions could be specific, such as a specific forward state
to stand state, or they could be generic, like any state to fallen
state (see Figure 13). The transition is associated with transition
points for the old and new states. The FIFO waits for the old movement
state to be in the correct position and then starts the transition
blends. When the old state no longer has any influence, the FIFO
removes it from the queue. When the transition has no more influence,
it is also removed from the queue, leaving just the new movement
state. At this point, the simulation is ready to transition to another
node. Theoretically, these nodes can be stacked in multiples and
processed one at a time, but that could grow out of control and
take an inordinate amount of time. The MechWarrior engine
is careful to request only one state at a time. In the rare case
that a state change really needs to happen instantly, the simulation
does a special request which puts a new priority blender node on
top of the transition FIFO. When the new animation gains full weight,
all others are removed and that animation becomes the current movement
state.
Figure
14 is a tree of an action-sport title currently being developed.
The tree is much more complicated than the 'Mech tree, and this
tree relies much less on states. In this tree, there is a top-level
priority system to determine what general blender branch will be
shown. The character in this example can do tricks, ride his vehicle
and crash. Crashing is the most important and should always be visible.
There are numerous ways the rider can crash but only one should
play at a time. As such, this branch is a simple FIFO queue. The
next branch is the trick branch. Like the crashes, only one animation
is played at a time, but the transitions are a little more important
and defined. Tricks have a transition state engine that is also
a FIFO queue similar to the 'Mech state engine. The last layer of
the priority FIFO is the movement layer. The movement layer is again
another priority layer. However, blending too many animations is
expensive and can make the animations look muddled. The priority
systems assist the simulation in culling down the list of animations
that are actually going to be played.
The
priority layer illustrated in Figure 15 is choosing between the
rider ground IK movements, G-forces on the rider and the rider's
steering control. While it could conceivably build a large multi-axis
blender for all of these animations, the amount of source data would
multiply. Combining G-Forces and steering forces into a multi-axis
blender node, for example, would likely require each G-Force animation
to be represented with each steering animation. This would total
out at about 56 animations as opposed to the current 15. The initial
concept of this tree included a fully blended system, but simply
diagramming during the planning phase pointed out that the large
number of animations would be a problem.
Memory Performance
The
number of animations really snuck up on the team. The fidelity of
this system comes at a cost. Each 'Mech has 152 animations which
totals out to 3,600 animations in MechWarrior4 alone. This
does not include all the expansion packs and Mercenaries,
which double that number. The working set of actual blended animations
comes out to about 360 animations per frame or 7,200 animated channels.
Each IK animation requires five animations; flat, up, down, left
and right. Just 30 animation states that have ground IK would equal
a surprising 150 animations.
The
memory required to hold that much data is significant, but fortunately,
there is a solution for this. Each animation needs to be aggressively
optimized, and each channel in the animation must have its own optimization
as well. By doing this, the channels in the hierarchy that must
be absolutely accurate can be optimized with tighter thresholds.
The remaining channels can be optimized at a lower fidelity. Care
needs to be taken to not over-optimize, as well. At least one key
frame for each channel is needed for successful blending. Just because
a channel is not animating does not mean it does not have a position.
If this key frame is not available, the blender will not be able
to blend the channel with other channels.
It
is critical to have a tool that can data-mine animation size. The
MechWarrior engine provides an animation viewer that can
open up lists of animations. This tool reports the total size of
the animation set and can dig down into each animation. Inside each
animation, the tool reports exact details of the animation, including
key frame sizes, header sizes and the key frame data. It serves
as an invaluable tool for finding optimization problems as well
as for diagnosing exporter errors in the animation. Using optimization
alone, we cut the size of animations per 'Mech are minimized from
a few megs to about 700k. This 700k includes all 152 animations.
CPU Performance
Cache
performance issues are, by far, the number one performance issue
in the animation system. In order to minimize cache issues, do not
iterate and interpolate animation that is insignificant. Calculating
the blend tree and weights before iteration allows the user to completely
skip unused branches. Secondly, keep the data small. The smaller
the data, the faster it will load and process. Finally, keep key
frame times separate from key frame data in the animation format.
Iteration of the key frames can very often go through large sections
of the animation. If the key frame format includes the key frame
time and key frame data, all the key frame data is being loaded
into the cache before necessary and likely throwing it away again
before it is used. Keeping key frame time separate from channel
data produces less cache misses and makes pre-fetching a little
easier.
Blending
systems can take a toll on the CPU processing as well. Large amounts
of interpolation happen every frame, and if standard quaternion
slerp is being used, with four sin's, an arcos and a square root
normalize, performance will suffer. An optimized interpolator and
normalize function are essential. "Hacking Quaternions"
(see the "References" section at the end of this article)
is a good source for information on this issue. As each animation
system is going to behave differently, someone familiar with assembly
optimization should review the animation code to suggest processor
and cache improvements. Lots of little improvments can be preformed
to speed-up this type of code.
Helping the
Animator
There
has been much discussion from a technical standpoint about establishing
this type of system. But the most important part of the process
is the animators. Blended IK is wholly dependant on animators. Programming
teams must fully support the artists, rather than just leave them
to "create their art". The MechWarrior programming
staff wrote several plugins for the animators' art package. These
tools range from exporters to fully integrated animation plug-ins
that have very little game technology.
All
of the animations are exported from the art package, and very little
is done procedurally to the 'Mechs during run-time. Some of the
animation is possible to create procedurally, but this is performed
within the art package instead of during runtime. BY not performing
runtime procedural alterations of the animation, the artist is able
to fix errors in the procedural algorithms. If the position of a
leg is procedurally calculated based on an IK chain, that chain
might reach the target position in a strange and undesirable way.
When these errors occur, the artist can adjust the animation to
look correct. These modifications proved to be invaluable as more
'Mechs were designed with complex leg structures and as the art
package was not always able to satisfactorily solve those IK. It
takes much less time and effort for the artist to correct the errors
than to fix the algorithm that produced the error. Allowing the
artists to adjust things also allows them to modify an animation
to be more aesthetically pleasing and further modify the procedural
animation. The artist can put in subtle differences in the motion
to make it look less procedural, or he can completely abandon the
procedural animation all together and add something created from
scratch. The artist can also choose to not modify the animation
further.
Three
main content generation tools were created for MechWarrior.
The Mirror Tool, Reverse Tool and Hill Tool.
The Mirror Tool can take any animation and mirror it on an
axis. This allows the animators to quickly take a step forward
left leg animation and turn it into a step forward
right leg animation. The Reverse Tool allows animators
to completely reverse an animation in time. Forward walks become
backward walks. With a little modification, they alter the weight
and timing of the animation and it looks convincingly different.
The Hill Tool was by far the most complicated animation generation
tool we produced. For the Hill Tool, a plug-in was created
that took an animation designed for flat ground and replicated it
to uphill, downhill, lefthill and righthill animations. The artists
had an array of inputs for the tool that would scale and adjust
specific joints in the hierarchy to help them create a smooth animation.
When run, the tool will re-adjust the IK handles of the feet to
match the ground angles and adjust other joints with the data in
the input arrays. The artists work first with a simple walk animation
to determine the appropriate inputs needed, and once they have those
inputs, they run the entire suite of flat ground animations through
it to get the full list of hill animations.
Animation
count was also reduced by sharing animations between 'Mechs at runtime.
As 'Mechs are varied in size, shape and joint count, this can be
relatively challenging and is not always possible. Where available,
the artists are allowed to specify animations from another 'Mech
to be used for the current 'Mech. Many commercially available packages
also exist to facilitate off-line sharing of motion data between
characters. Due to memory concerns this is the one exception of
run time alteration.
Conclusion
Blended IK
and More
Generic
IK systems have a hard time imparting the sense of timing and motion
that an animator can produce, even when combined with complicated
physics. Many times, looking real is not actually being real. Because
of this, blending IK is a great method of having a character act
and react to its environment. Punching, getting punched, kicking
objects and picking up objects are all problems that are very hard
to solve with math. Math has a hard time determining how a character
distributes his weight when he picks up an object on a table. Maybe
the character uses his other arm to hold his balance or maybe he
bends at the knees. Granting the responsibility of this process
to the animators can greatly increase the fidelity. Whether a sports
game, fighting game, platform game or FPS, any game with animation
can apply these methods. A blending system can breathe life into
characters. Simply allowing animators to do their jobs makes our
games infinitely better.
What
I have presented here is what I believe is a solution to allowing
animators to stay in control while maintaining a believability in
game characters actions and reactions. If you have any questions
or comments, I encourage you to email me at jerryeds@microsoft.com.
References:
Ken
Shoemake, Animating Rotations with Quaternion Curves, SIGGRAPH
'85, pp. 245-254.
Jonathon
Blow, Hacking Quaternions, Game Developer Magazine, March
2002.
______________________________________________________
|