how to... occurrences?

Wonderful works! You have very nice use of color and the skin tones are really great I guess if I had one crit, it is that all your edges appear a tad blurred That is probably okay for stuff you
good point scott, everyone’s natural reaction is to try to pick off these fish up top but in most cases you would have to think that the school is larger than what we are seeing on the surface By go
All types of vegetables are great, however, preference should be given to green-leafed lobes of the ears, circling them the other ingredients and nutrients that help fight fat. When
braries of quenched fluorogenic substrates Binding to a single site in the human showed higher capacity for uptake and

You have to use actor.controlJoint() on the model whose joint you want to control. There are a few qualifications on controlJoint() that make its use confusing:

(1) You have to call controlJoint() at setup time, before you play any animations.

(2) You then have to have an animation playing, any animation.

(3) Finally, the transform that you apply to the joint in question via controlJoint() needs to be the joint’s local transform from its parent, but the transform that you extracted from the other actor via exposeJoint() is, by default, the net transform from the root. In order to get the joint’s local transform instead, use exposeJoint(localTransform = 1).


Thanks for this. This seems to clear up some things when working with this.

However - there is another issue. In the build that we are using, exposeJoint doesn’t have the keyword parameter “localTransform = 1”

I did however check in and the documentation for characterJoint and I do see the function “addLocalTransform”. I’ve never fiddled with but I am thinking that I could either update the exposeJoint function in actor myself or create a new function in my class that basically does the same thing but instead puts in addLocalTransform for the joint in place of addNetTransform.

Thanks again. I will try this and let you know.

You can also try taking the current (version 1.84) from the CVS repository and drop it over your direct/src/actor/ file. That should be all you need to do.


Okay - I have the latest file and update my code. I’m still having trouble doing this.

All the joints that are exposed are exposed with localTransform = 1. This seems to work fine. I’ve compared the transforms with this parameter set and not set. (The root joint still shows the same transform though.)

Now for the next step - i get the transforms from the exposed joints. I then apply this transform to the joints i want to control. This is still giving weird effect.

Is this correct? I do this with mutiple and single bones and they all give results i don’t expect. Is there some matrix transformations i’ll need to do? If get the transforms on the control joints after setting the animation and nothing else - i get identity for all the joints - Is this correct too?

Thanks again


That does sound like you’re doing the right thing, but I know this ought to work.

When you say “get the transform” and “apply the transform”, are you doing something like this?

This is the most robust way to copy the complete transformation from one node to another. Copying just, for instance, the getHpr() and/or the getPos() won’t get all of it.

When you say “get the transforms on the control joints”, well, of course those are initially identity because nothing sets them except you–as control joints, they are write-only, and whatever transform you assign to them is then applied to the corresponding joint’s transform. Unless you mean the exposed joints? You might need to call update() on your expose-joint actor to ensure that its joint values get fully recomputed this frame before you query them, unless you know the actor is going to be onscreen.


Yes I am doing this,


I’m pretty sure that the exposed joint actor is updated. I am getting the data a few frames after a pose is set on the exposed joint actor.

To me it seems the Hpr values are all off. I’m comparing values that are in Maya. The pos values seem accurate. The hpr values are weird large angle numbers. I am using degrees in Maya.

The transforms only consist of pos and hpr. There are no shear and scale values coming through the exposeJoint.getTransform()

And setting the transform on the root joint - in my case the ‘hip’ bone - causes the model to translate in space…

i’m continuing to experiment. Thanks for the advice - if you have any more ideas…please send them :slight_smile:

I found out one thing and i don’t know how much it effects the functions in panda that I am calling.

The joints in the model have their own axis. They are aligned in a way that is not the same a the world axis. They are different from each other.

The translations that the exposeJoint reports is based on the translations along those axis.

The rotations that are reported by exposeJoint are like i said before - totally off.

Is this something i shouldn’t or should have to worry about?


Hmm, you may be over-analyzing it. It is true that the rotations reported in Panda may be completely different from the rotations observed in your animation package, usually due to a coordinate-space translation.

This sample code seems to work fine for me. Every time I call copyJoints() it sets the panda2 model to the current pose showing on the panda1 model. You can try it with the sample panda model, as I have written it, or you can try substituting your own model.

from direct.directbase import DirectStart
from pandac.PandaModules import *
from import Actor

panda1 = Actor.Actor('panda.egg', { 'walk' : 'panda-walk.egg' })
panda2 = Actor.Actor('panda.egg', { 'walk' : 'panda-walk.egg' })

# This list of joint names was obtained via egg-optchar -ls.
jointList = [
    'root', 'chn1', 'TO_l_hip_hold', 'jnt1_1', 'jnt1_2', 'eff1',
    'chn2' , 'jnt2_1', 'jnt2_2', 'eff2', 'chn12', 'TO_l_should_hold1',
    'jnt12_1', 'jnt12_2', 'jnt12_3', 'eff12', 'chn13', 'jnt13_1',
    'jnt13_2', 'eff13', 'chn14', 'jnt14_1', 'jnt14_2', 'eff14', 'chn15',
    'jnt15_1', 'jnt15_2', 'eff15', 'chn1_1', 'TO_rhip_hold', 'jnt1_1_1',
    'jnt1_2_1', 'eff1_1', 'chn2_1', 'jnt2_1_1', 'jnt2_2_1', 'eff2_1',
    'chn22', 'jnt22_1', 'jnt22_2', 'eff22', 'chn23', 'jnt23_1',
    'jnt23_2', 'eff23', 'chn24', 'jnt24_1', 'jnt24_2', 'eff24', 'chn3',
    'jnt3_1', 'TO_fat_front', 'TO_fat_left', 'TO_fat_right', 'jnt3_2',
    'chn10', 'jnt10_1', 'eff10', 'chn4', 'jnt4_1', 'eff4', 'jnt3_3',
    'jnt3_4', 'eff3', 'l_hip_hold', 'r_hip_hold', 'chn7',
    'TO_l_should_hold', 'jnt7_1', 'jnt7_2', 'jnt7_3', 'eff7',
    'joint-head_parts', 'null1', 'null2', 'null3', 'null4', 'null8',
    'null9', 'null10', 'null11'

for j in jointList:
    panda1.exposeJoint(None, 'modelRoot', j, localTransform = 1)
    panda2.controlJoint(None, 'modelRoot', j)

panda1.setPos(-6, 0, 0)

panda2.setPos(6, 0, 0)
panda2.loop('walk')  # No visible effect (all joints are controlled).

def copyJoints():
    for j in jointList:
        n1 = panda1.find(j)
        n2 = panda2.find(j)


Wow - this works brilliantly - with no problem at all.

Thanks for this.


So it seems the only way to get all of the joints in an actor is to use egg-optchar -ls or inspect the development model with modeling software, and then hard-code the joints you want to control. Is this correct?

I ask because reading this made me wonder if there was a way to get the joints of some arbitrary actor that has been loaded. I was thinking a recursive function using getNumChildren(). Is there a much easier way of doing this? Is this even right? How does Panda (or egg converters if thats the case) handle the heirarchy of joints? Joints seem to be children of a partBundleNode. Do joints exist on the sceneGraph before exposed? I also noticed that effectors are in the jointList. Does Panda make no differentiation between skeletal structures?

I know its a lot of questions, but the more I think about it the more questions come up. So thanks in advance to anyone willing to answer. Even if its only to one of the questions.

It is also possible to traverse the list of joints at runtime; I just hardcoded the list into my above example to simplify the code. The joints are not nodes in the normal sense; to get to them, you start with bundle = partBundleNode.getBundle(), and then you can recursively walk through the children of the bundle using getNumChildren()/getChild().

The joints do not have a manifestation in the scene graph until they are exposed. To “expose” a joint means to create a node in the scene graph that is tied to the joint, so that when the joint animates, it moves the node as well.

Panda does not differentiate between different kinds of skeletal structures. None of that is important to Panda’s character animation code, which is simply playing back transforms (it doesn’t perform IK or apply constraints or do anything that requires different kinds of joint objects). This does mean that you tend to end up with more “joints” than are strictly required to replay an animation; that is why egg-optchar’s feature of removing unneeded joints is such a useful optimization.


wow. awesome. Everything answered before I could even turn around.

Thanks David