visualise Actor bones (skeleton)?

Im wondering if theres a function to show a visual representation of bones, like the ones for visualising collision geometry.
Im not very familiar in this field, so I dont know if egg even stores actual bone data, as I think ragdolls arent possible with this format.

You could simply iterate over the joints in the hierarchy and reparent a sphere to every one of them. I use that approach for visualising ragdolls.

If you want to draw the bones, I suppose you could draw a cylinder node for every parent<>child relationship.

I guess this means there isnt a built-in function for this.
Small problem, how can I set the visual ‘bone’s’ lenght and decided where they are conncted or not?

I’m not sure, I think that would be the distance between a child joint and a parent joint.

So a joints center point is its base? Is there even a tip data in egg?
Not all bones have parents or children.

Bones in Panda (and most other engines) do not have a length, it is just a transform. Often for visualization it is useful to draw a line from the parent bone to each child bone. You could do this using Panda’s LineSegs.

You mean Panda or the egg format. Because isnt the lenght required for ik stuff?
I guess I could just have a predefined lenght for bones without any parent/child.

So anyway, i dont really know how to access the bone data.

Panda doesn’t do IK. As rdb says, a bone is just a transform, no more, no less.

David

so… how can i access the bones and their pos/loc/scale to apply to the visualising nodes?

actor.exposeJoint() is the easiest way. It’s documented in the manual.

David

this doesnt work:

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

actor = Actor("panda")
actor.reparentTo(render)

for i in actor.getJoints():
	joint = actor.exposeJoint(None, 'modelRoot', i.getName())
	b = loader.loadModel('bone')
	b.reparentTo(joint)

Some of those nodes from actor.getJoints() are CharacterSlider types and can’t be exposed.

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

actor = Actor("panda") 
actor.reparentTo(render) 

for i in actor.getJoints():
   try:
      joint = actor.exposeJoint(None, 'modelRoot', i.getName())
   except AttributeError:
      print "Cannot expose", i.getName()
      continue
   b = loader.loadModel('bone') 
   b.reparentTo(joint)

run()

Not bad

but if there was a way to check if bone has parent and ‘connect’ those bones by scaling the child bone depending on their distance, then it would look better. I couldnt find a function for checking if joint has parent.
btw, what would be the best way to render bones in front of the mesh (x-ray)?

I quickly whipped this up for you:

from pandac.PandaModules import * 
loadPrcFileData("", "interpolate-frames #t")
import direct.directbase.DirectStart
from direct.actor.Actor import Actor
from random import random

actor = Actor("panda", {"walk" : "panda-walk.egg"})
actor.reparentTo(render)
actor.setBin('background', 1) 

def walkJointHierarchy(actor, part, parentNode = None, indent = ""):
    if isinstance(part, CharacterJoint):
        np = actor.exposeJoint(None, 'modelRoot', part.getName())

        if parentNode and parentNode.getName() != "root":
            lines = LineSegs()
            lines.setThickness(3.0)
            lines.setColor(random(), random(), random())
            lines.moveTo(0, 0, 0)
            lines.drawTo(np.getPos(parentNode))
            lnp = parentNode.attachNewNode(lines.create())
            lnp.setBin("fixed", 40)
            lnp.setDepthWrite(False)
            lnp.setDepthTest(False)

        parentNode = np

    for child in part.getChildren():
        walkJointHierarchy(actor, child, parentNode, indent + "  ")

walkJointHierarchy(actor, actor.getPartBundle('modelRoot'), None)

actor.loop("walk")
base.cam.setY(-50)

run()

The parentNode.getName() != “root” check is a hack, otherwise it draws lines from the root node, which is not desirable.

The setBin and setDepthTest/setDepthWrite calls make sure the bones are rendered last, and no depth testing is done, so that they show through everything.

Sweet. Ill try to use the bone shapes I made instead of linesegs, though.
If this was posted in the Code Snippets others would benefit from it too.

Feel free to. Public domain.