Help me understand armatures?

When we import a model with a rig, we get an Armature, which has Joints. Joints have children which are also joints, recursively. By inspection, the names of the joints appear to be the names of the bones in the model which was exported from (in my case) Blender.

The bones in Blender have a root and a tip, which are both said to be on the bone’s (local) y axis, so I’m assuming that the root has {:x 0, :y 0, :z 0} and the tip has {:x 0, :y ? :z 0} (where ? is some positive floating point number). A Joint has two instance variables which are Vector3f, but they’re called localScale and localTranslation, which doesn’t sound like what I’m looking for; and by inspection they don’t match the pattern I expect to see. Bones in Blender also have root and tip radius, and I’m not (yet) seeing those in the Armature API, either.

Can anyone elucidate?

1 Like

Fundamentally all the mesh vertexes are moved by a weighted average of how much a bone has moved from it’s rest position; the bones that affect a vertex are usually near the vertex but they don’t have to be.

Things like the bones radius etc are a way to set those weights automatically in blender but it is usually only a starting point. In blender you can hand paint how much each bone affects each vertex. So what ends up in jMonkey is the vertex weights; the bone radiuses are earlier in the process and no longer relevant

OK, but where do I find the length of the bone/joint?

What would the length of a bone mean in terms of how a bone affects a vertex. Really a bone extending in a direction really just means that vertexes in that direction are more influenced by that bone than its joint position would imply

Bones are kind of artificial concepts. The length of a bone is the distance between the “bone” and it’s parent. That’s why JME went with joints.

Bones look pretty in an editor but literally nothing actually deals with the “bone”… just the location of the joint.

OK, but if I can’t conveniently get the relative locations of the joints, I can’t mutate the armature, at which point the whole thing becomes useless. So at some point in the datastructure there has to be some proxy for the length of the bone. By inspection I’m guessing it’s the y axis of the localTranslation, since all the axis values for localScale for the joints in the models I’m looking at are approximately 1, and all the x and z axis values for localTranslation are approximately 0.

Why can’t you get the relative location of the joints?

Location relative to parent:
joint.getLocalTranslation()

Full transform relative to the model’s root:

…so location relative to the model’s root:
joint.getModelTransform().getTranslation()

The joint hierarchy is just like a scene graph hierarchy.

I think you may be thinking of the length of the bone as being the position of the next joint. That is indeed the way real bones work but surely doesnt matter from our perspective?

Well, exactly. So the value we need to modify to change the length of the bone is the y axis of the localTranslation.

It depends on how the bones are related relative to one another. It could be that typically it is the y axis… but I’ve seen it be the z axis for some models, too.