Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Read this forum topic for more info: http://blenderartists.org/forum/showthread.php?260602-transform-matrix-to-bone-%28head-tail-roll%29-bug

I'm trying to get my Blender3d modeller importer to create correct bones from my file's transform matrices.

The Blender Python API doesn't have a way to do this (anymore!), so people had to dig the Blender C source to find out how Blender does it and port that. Here's a Python port of the needed functions, not by me (I don't know C):

def vec_roll_to_mat3(vec, roll):
    target = mathutils.Vector((0,1,0))
    nor = vec.normalized()
    axis = target.cross(nor)
    if axis.dot(axis) > 0.0000000001: # this seems to be the problem for some bones, no idea how to fix
        axis.normalize()
        theta = target.angle(nor)
        bMatrix = mathutils.Matrix.Rotation(theta, 3, axis)
    else:
        updown = 1 if target.dot(nor) > 0 else -1
        bMatrix = mathutils.Matrix.Scale(updown, 3)
    rMatrix = mathutils.Matrix.Rotation(roll, 3, nor)
    mat = rMatrix * bMatrix
    return mat

def mat3_to_vec_roll(mat):
    vec = mat.col[1]
    vecmat = vec_roll_to_mat3(mat.col[1], 0)
    vecmatinv = vecmat.inverted()
    rollmat = vecmatinv * mat
    roll = math.atan2(rollmat[0][2], rollmat[2][2])
    return vec, roll

How to use them:

pos = mymatrix.to_translation()
axis, roll = mat3_to_vec_roll(mymatrix.to_3x3())

bone = armature.edit_bones.new('name')
bone.head = pos
bone.tail = pos + axis
bone.roll = roll

Sadly, it seems even the Blender C code is buggy and doesn't take into account cases when the bone is parallel to (0,1,0). So such bones can get assigned wrong (by 180 degrees) rolls and mess up animations.

Does anyone have better code for generating roll which takes into account such cases?

The old Blender 2.4 API generated correct ones. Its C code can be found here: http://svn.blender.org/svnroot/bf-blender/branches/blender-2.47/source/blender/blenkernel/intern/armature.c I'm no C coder myself, again.

share|improve this question
    
So you're asking that someone who knows C and Python to convert the C code to Python? –  Byte56 Jul 18 '12 at 14:45
1  
No, that would be one of the few ways to answer this (but only if the C functions in 2.4 are different from the C functions in 2.6 which were ported, which seems to be so since my Blender 2.4 importer works fine). Other ways to answer would be to explain in words what needs to be done, or put together some pseudocde, or modify the existing Pythin functions to work for this scenario. –  user17402 Jul 18 '12 at 16:59

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.