MULTIPART ACTORS vs. HALF-BODY ANIMATION

Sometimes you want to be able to play two different animations on the
same Actor at once.  Panda does have support for blending two
animations on the whole Actor simultaneously, but what if you want to
play one animation (say, a walk cycle) on the legs while a completely
different animation (say, a shoot animation) is playing on the torso?

Although Panda doesn't currently have support for playing two
different animations on different parts of the same actor at once
(half-body animation), it does support loading up two completely
different models into one actor (multipart actors), which can be used
to achieve the same effect, albeit with a bit more setup effort.

Multipart actors are more powerful than half-body animations, since
you can completely mix-and-match the pieces with parts from other
characters: for instance, you can swap out short legs for long legs to
make your character taller.  On the other hand, multipart actors are
also more limited in that there cannot be any polygons that straddle
the connecting joint between the two parts.


BROAD OVERVIEW

What you have to do is split your character into two completely
different models: the legs and the torso.  You don't have to do this
in the modeling package; you should be able to do it in the conversion
process.  The converter needs to be told to get out the entire
skeleton, but just a subset of the geometry.  Maya2egg, for instance,
will do this with the -subset command-line parameter.

Then, in a nutshell, you load up a multipart actor with the legs and
the torso as separate parts, and you can play the same animation on
both parts, or you can use the per-part interface to play a different
animation on each part.


MORE DETAILS

That nutshell oversimplifies things only a little bit.  Unless your
different animations are very similar to each other, you will have
issues keeping the different parts from animating in different
directions.  To solve this, you need to parent them together properly,
so that the torso is parented to the hips.  This means exposing the
hip joint in the legs model, and subtracting the hip joint animation
from the torso model using egg-topstrip (because it will pick it up
again when it gets stacked up on the hips).  Also, you should strongly
consider egg-optchar to remove the unused joints from each part's
skeleton, although this step is just an optimization.

Unfortunately, all this only works if your character has no polygons
that straddle the connecting joint between the hips and the torso.  If
it does, you may have to find a clever place to draw the line between
them (under a shirt?) so that the pieces can animate in different
directions without visible artifacts.  If that can't be done, then the
only solution is to add true half-body animation support to Panda. :)


NUTS AND BOLTS

You need to parent the two parts together in Panda.  The complete
process is this (of course, you'll need to flesh out the details of
the maya2egg command line according to the needs of your model, and
insert your own filenames and joint names where appropriate):

(1) Extract out the model into two separate files, legs and torso.
    Extract the animation out twice too, even though both copies will
    be the same, just so it can conveniently exist in two different
    egg files, one for the legs and one for the torso.

   maya2egg -subset legs_group -a model -cn legs -o legs-model.egg myFile.mb
   maya2egg -a chan -cn legs -o legs-walk.egg myFile.mb
   maya2egg -subset torso_group -a model -cn torso -o torso-model.egg myFile.mb
   maya2egg -a chan -cn torso -o torso-walk.egg myFile.mb

    Note that I use the -cn option to give the legs and torso pieces
    different character names.  It helps out Panda to know which
    animations are intended to be played with which models, and the
    character name serves this purpose--this way I can now just type:

   pview legs-model.egg legs-walk.egg torso-model.egg torso-walk.egg

    Panda will bind up the appropriate animations to their associated
    models automatically, and I should see my character walking
    normally.  We could skip straight to step (5) now, but the
    character isn't stacked up yet, and he's only sticking together
    now because we're playing the walk animation on both parts at the
    same time--if we want to play different animations on different
    parts, we have to stack them.

(2) Expose the hip joint on the legs:

   egg-optchar -d opt -expose hip_joint legs-model.egg legs-walk.egg

(3) Strip out the hip joint animation from the torso and egg-optchar
    it to remove the leg joints:

   egg-topstrip -d strip -t hip_joint torso-model.egg torso-walk.egg
   egg-optchar -d opt strip/torso-model.egg strip/torso-walk.egg

(4) Bamify everything.

   egg2bam -o legs-model.bam opt/legs-model.egg
   egg2bam -o legs-walk.bam opt/legs-walk.egg
   egg2bam -o torso-model.bam opt/torso-model.egg
   egg2bam -o torso-walk.bam opt/torso-walk.egg

(5) Create a multipart character in Panda.  This means loading up the
    torso model and parenting it, in toto, to the hip joint of the
    legs.  But the Actor interface handles this for you:

   from direct.actor import Actor

   a = Actor.Actor(
     # part dictionary
     { 'torso' : 'torso-model.bam',
       'legs' : 'legs-model.bam',
     },

     # anim dictionary
     { 'torso' : {'walk' : 'torso-walk.bam'},
       'legs' : {'walk' : 'legs-walk.bam'},
     })

   # Tell the Actor how to stack the pieces.
   a.attach('torso', 'legs', 'hip_joint')

(6) You can now play animations on the whole actor, or on only part of it:

   a.loop('walk')

   a.stop()
   a.loop('walk', partName = 'legs')

