## How do bones/armatures/curves work together numerically?

Blender documentation projects, tutorials, translation, learning & teaching Blender

Moderators: jesterKing, stiv

SteveBaker
Posts: 0
Joined: Thu Jun 03, 2010 5:39 am

### How do bones/armatures/curves work together numerically?

Background: I've been working in 3D graphics for 30 years, I've implemented skeletal mesh animation from scratch half a dozen times - so I have a clue. But I need help decyphering the armature information that blender provides so I can feed it to my own skeletal mesh rendering application.

I've written a Python exporter that saves out Armatures, Bones & IPO Curves - along with all of the data that blender lets you grab for those objects. Now I'm trying to make sense of what I see...and I'm having ZERO luck with it! I have the simplest test model imaginable - two bones with two cubes...one of which rotates 90 degrees around the Y axis and back again. You can grab it at http://sjbaker.org/tmp/kiss_animation.blend along with the XML file that my Python exporter produced from it (which basically just writes out all of the blender structures without doing anything to them...yet): http://sjbaker.org/tmp/kiss_animation.xml

I have the per-vertex blendweight and blendindex stuff all figured out and I've written a shader that I've carefully tested and I know works to transform the vertices correctly, given a set of bind-to-pose matrices, one per bone per time-step.

The problem is that I'm having a terrible time understanding what the numbers that my Python exporter extracts actually MEAN. On the BONE objects, I see 'armaturespace' and 'bonespace' with both head and tail positions for each, also a 4x4 armaturespace matrix and 3x3 bonespace matrix - also a bonespace roll angle and a length...plus curve data for the X,Y,Z,W components of a quaternion rotation and X,Y,Z location for each bone at each time step. I also understand how the bone hierarchy is organized.

However, turning that information into a bunch of bind-to-pose matrices that I can use in my shader to transform the skin vertices is turning into a nightmare! I simply can't fathom out what all of these numbers are telling me!

For example: My python dump says that the first bone goes vertically up from (0,0,0) to (0,0,1) and the second from (0,0,1) to (0,0,2) - which makes sense - that's what I see in blender. But the armaturespace and bonespace matrices for both bones mysteriously rotate through 90 degrees around the X axis?!?

WTF?

I didn't apply any rotations to the bones in the armature when I created it - and I can't think of any need for a 90 degree rotation - so what does this mean?

What I really need is a simple step-by-step explanation of the order of transform operations to get from a skin vertex in bind-pose to the animated position: given the data exposed to Python in the bone description and the quaternion for a particular timestep...exactly what math do I need?

-- Steve

an-toni
Posts: 0
Joined: Wed Mar 17, 2004 5:20 pm
Is this old doc of any help?
http://www.blender.org/development/rele ... ures-work/

Otherwise perhaps some of the existing armature export codes can help too.

~Toni

SteveBaker
Posts: 0
Joined: Thu Jun 03, 2010 5:39 am
Thank you! That definitely looks useful - I'll dive into it tonight and see if I can get something to work.
-- Steve

SteveBaker
Posts: 0
Joined: Thu Jun 03, 2010 5:39 am
I've worked through that document, and I thought I understood what it says - but the results don't work.

The second diagram seems to be telling me that I need to transform vertices by the "pose_mat" - which is basically:

...but for the uber-simple two bone animation in http://sjbaker.org/tmp/kiss_animation.blend, the first bone ends up with an identity matrix (which is good) - and the second bone gets:

pose_mat = I . tail [N-1] . I . I . curve[N]

(I is identity).

tail[N-1] is a one unit translation in +Z and for the first frame of the animation, the curve data is also identity.

So pose_mat ends up transforming the top cube +1 unit in Z...but it should be identity.

Hence, I'm either misunderstanding that document - or it's out of date for Blender 1.49.

HELP!
-- Steve