How do you export bones relative to parent? I'm currently writing an exporter script. So far, I can export meshes just fine, but I've got some problems with exporting the armature.

According to the python api, there are three different types of bones:


editbones: Are used to create/modify the armature/skeleton and are only available in edit mode. See http://www.blender.org/documentation/blender_python_api_2_67_1/bpy.types.EditBone.html (which, obviously, aren't needed for exporting animation. I just list them for completeness.)
bones: Define the armature structure. See http://www.blender.org/documentation/blender_python_api_2_67_1/bpy.types.Bone.html
posebones: Are used for animation. The posebones are structured like the bones of the armature, but transformed according to the current frame of the active action/pose. See http://www.blender.org/documentation/blender_python_api_2_67_1/bpy.types.PoseBone.html


There's also this old (or rather: ancient) guide on how armatures work: http://www.blender.org/development/release-logs/blender-240/how-armatures-work , but I can't find a proper mapping between that document and the current api.

I know I can get the restpose of the armature by grabbing the bone.matrix_local, but this matrix is relative to the armature.

So...
How do you grab the bones matrices so that the transform is relative to the parent instead of relative to the armature?

I tried exporting the bones relative to their parent by multiplying the inverse of the parents matrix_local by the bones matrix_local, but that does seem to result in incorrect translation values.

This is how I currently grab the parent-relative matrices:

        #I'm interested in the rest pose here, so I iterate over the bones
        for bone in armature.data.bones:                
            #make matrix of this bone relative
            boneMat = mathutils.Matrix.Identity(4)
            if bone.parent == None:
                boneMat = bone.matrix_local
            else:
                boneMat = bone.parent.matrix_local.inverted() * bone.matrix_local

            #decompose
            loc, quat, sca = boneMat.decompose()


By the way: I'm using blender 2.66.1 w/the included python
The code snippet you give seems to be correct if you want the transform from the head of the parent bone to the head of the child bone.

How is the translation incorrect? There are supposed to be two translations between these bones, one from the head of the parent to its tail, and (if the child is not connected to the parent) one from the tail of the parent to the head of the child.

In the 2.40 armatures guide, bone.matrix is bone_mat and bone.matrix_local is arm_mat. This is how they relate in python:

# parent head to tail, and parent tail to child head
bone_translation = Matrix.Translation(Vector((0, bone.parent.length, 0)) + bone.head)
# parent armature space matrix, translation, child bone rotation
bone.matrix_local == bone.parent.matrix_local * bone_translation * bone.matrix.to_4x4()