A quick solution for equipment

The story so far

A few months back I wrote a simple export plugin for Blender. Unlike most export scripts, the plugin interprets blender files as asset libraries. The plugin supports basic material properties and animation.

When I wrote the export script, I didn’t want to spend time writing a bone animation module for the engine. Instead I decided to bake animation frames – bone deformations are applied from within blender, resulting in ‘mesh frames’.

While mesh frames are pretty heavy, there are advantages too:

  • Interpolating between frames is much faster than applying bone deformations.
  • Since the exporter generates frames by collapsing an object’s modifier stack, it is possible to export all kind of animations, not just bone animations.

Equipment

At that point, my setup didn’t provide a solution for equipment. So if I wanted an actor to hold an axe, or a sword, I had to clone the model and bake a separate animation. Needless to say such a system is hardly usable.

Equipping items consists in making them visible as part of a PC or NPC visual presentation, so an actor could hold a sword, a shield, or change dress (this requires more care).

The new setup is fairly simple:

  1. Bones are added to the actor’s armature – so we can add a bone to represent a sword, a gun, a hat… anything.
  2. The item we want to equip is placed at the correct location – so if it’s a sword, we just place it in the character’s hand.
  3. The item is renamed accordingly, e.g. sword@elven, indicates that the sword should animate along with an actor named ‘elven’.
  4. Parent the item to the armature (in the item’s modifier tab, I check ‘make real’ for the armature modifier, to ensure that this gets applied when the exporter collapses the modifier stack)

The notation item@actor is an arbitrary convention. Since actions are not bound to any particular actor, if we have…

  • an action named elven.strike
  • a piece of equipment named sword@elven

…then the exporter knows that elven.strike should be applied to sword@elven.

Animations are exported separately for various pieces of equipment. It’s a huge step forward compared to the previous system I used. When we want an actor to equip an item, all we have to do is load the matching ‘animated version’ of this item and synchronize animation playback.

This solution is still wasteful – but it wouldn’t be too hard to extend it to define equipment slots (so instead of exporting all animations over again for each item, we’d just have ‘dummies’ used to define transform matrices)

One Animation per File, really?

When I investigated Blender animation to create my exporter, I found about Blender actions. Blender actions provide a simple, easy way to define ‘several animations per actor’. More specifically, an action is a named sequence of key frames associated with an object (typically an armature, but also works with other object types). So at the moment I have ‘run’,'walk’,'hit’ actions etc… While actions are normally used in NLA (non linear animation – aka mixing part animations together, e.g. smile + run), they originally seemed well suited to building ‘animation libraries’ - All the exporter has to do is retrieve each action, bind it to the armature and export it.

Unfortunately, this approach breaks down when we combine several animated objects. For example, suppose you want to apply a floor constraint (e.g., as part of a walk animation), then…

  1. Consider the armature for the actor we’re animating.
  2. Define a ‘floor’ object
  3. Define 2 empties (used to move the actor’s feet)
  4. Apply the floor constraint to the empties using the ‘floor’ object as target
  5. Add IK solver constraints to the feet of the actor’s armature, so the feet now follow the empties.
  6. To animate, we move the empties, not just the bones.

How many objects are being animated here? Well, 3 really. We have the armature and the empties. To setup this animation correctly, then, we need to bind the following actions (assuming we associated the empties animations to actions) …

  • The armature action (e.g. elven.walk)
  • LeftFootEmpty action (elven.walk.leftFoot?)
  • RightFootEmpty action (elven.walk.rightFoot?)

At this point, I drop the towel altogether. Although there are disadvantages to keeping one file per animation, we have to choose: unless an animation is simple (1 action <=> 1 animation <=> 1 object), it should be kept in a separate file.

I guess if it was to do all over again, I’d simply try to avoid complex rigs. In the meantime I changed my export script (never mind some of my engine code) so that animations are always kept in separate files. I now have, for each object:

  • A model file. All models, whether animated or not, use the same format
  • For each model, zero, one or several animation files.