Reading existing Animation data?

The “Advanced operations with Panda3D’s internal structures” manual page teaches how to read existing geometry and textures, but doesn’t mention animations.

How can I get the AnimChannelMatrixXfmTables of the bones? All I can get is the AnimBundle(Node), which only has methods for getting frame count and frame rate.

actor = Actor('pandaSmth')

animBundleNode = AnimBundleNode('animBundleNode', actor.getAnimControl(animationName).getAnim())

animBundle = animBundleNode.getBundle()

frameCount = animBundle.getNumFrames()
frameRate = animBundle.getBaseFrameRate()

The AnimBundle is the root node of the hierarchy of bones. Use get_child() or find_child() (inherited from AnimGroup) to walk through the list of children and find the particular bone you wish, then downcast it to the correct AnimChannel subtype.

David

get 0s

def scanAnimation(actor, animationName='anim'):
	oiginalAnimBundleNode = AnimBundleNode('animBundleNode', actor.getAnimControl(animationName).getAnim())
	originalAnimBundle = oiginalAnimBundleNode.getBundle()
	
	frameCount = originalAnimBundle.getNumFrames()
	frameRate = originalAnimBundle.getBaseFrameRate()
	
	# animTable -> animChannel -> animGroup -> animBundle -> animBundleNode -> animNodePath
	for animGroup in originalAnimBundle.getChildren():
		for animChannel in animGroup.getChildren():
			if type(animChannel) == AnimChannelMatrixXfmTable:
				print animChannel.getTable(ord('x')) # don't know why we need to pass the char code ( ord() ), not char
				print animChannel.getTable(ord('y'))
				print animChannel.getTable(ord('z'))
				
				print animChannel.getTable(ord('h'))
				print animChannel.getTable(ord('p'))
				print animChannel.getTable(ord('r'))
				
				print animChannel.getTable(ord('i'))
				print animChannel.getTable(ord('j'))
				print animChannel.getTable(ord('k'))

from panda3d.core import *
import direct.directbase.DirectStart
from direct.actor.Actor import *

actor = Actor('panda', {'anim':'panda-walk'})
actor.reparentTo(render)
actor.loop('anim')

scanAnimation(actor, 'anim')

run()

Why are you wrapping up the AnimBundle returned by getAnim() into a new AnimBundleNode? Then you walk through the children of this AnimBundleNode, and of course it has no children.

You should instead walk through the children of the original AnimBundle, not an empty AnimBundleNode that you created on-the-fly. Use AnimBundle.getChildren(), not AnimBundleNode.getChildren().

Edit: wait, my apologies–I see that you are using AnimBundle.getChildren(). You wrap your AnimBundle in a new AnimBundleNode, then immediately call getBundle() to retrieve that AnimBundle again. So the code is correct, if distractingly confusing.

I’m not sure I understand what problem you’re reporting, then. Can you be more specific?

Edit 2: Note that getChildren() only returns the children of the top node. If you want to walk the entire tree, you will need to call this recursively on each child.

David