Specifically, this function :
Code: Select all
def blender_bone2matrix(head, tail, roll):
# Convert bone rest state (defined by bone.head, bone.tail and bone.roll)
# to a matrix (the more standard notation).
# Taken from blenkernel/intern/armature.c in Blender source.
# See also DNA_armature_types.h:47.
target = [0.0, 1.0, 0.0]
delta = [tail[0] - head[0], tail[1] - head[1], tail[2] - head[2]]
nor = vector_normalize(delta)
axis = vector_crossproduct(target, nor)
if vector_dotproduct(axis, axis) > 0.0000000000001:
axis = vector_normalize(axis)
theta = math.acos(vector_dotproduct(target, nor))
bMatrix = matrix_rotate(axis, theta)
else:
if vector_crossproduct(target, nor) > 0.0: updown = 1.0
else: updown = -1.0
# Quoted from Blender source : "I think this should work ..."
bMatrix = [
[updown, 0.0, 0.0, 0.0],
[0.0, updown, 0.0, 0.0],
[0.0, 0.0, 1.0, 0.0],
[0.0, 0.0, 0.0, 1.0],
]
rMatrix = matrix_rotate(nor, roll)
return matrix_multiply(rMatrix, bMatrix)
Really, it should be calling "vector_dotproduct". This is also what happens in the original code.
For comparison, here is the original function in the blender code :
Code: Select all
void make_boneMatrixvr (float outmatrix[][4],float delta[3], float roll)
/* Calculates the rest matrix of a bone based
On its vector and a roll around that vector */
{
float nor[3],axis[3],target[3]={0,1,0};
float theta;
float rMatrix[3][3], bMatrix[3][3], fMatrix[3][3];
VECCOPY (nor,delta);
Normalise (nor);
/* Find Axis & Amount for bone matrix*/
Crossf (axis,target,nor);
if (Inpf(axis,axis) > 0.0000000000001) {
/* if nor is *not* a multiple of target ... */
Normalise (axis);
theta=(float) acos (Inpf (target,nor));
/* Make Bone matrix*/
VecRotToMat3(axis, theta, bMatrix);
}
else {
/* if nor is a multiple of target ... */
float updown;
/* point same direction, or opposite? */
updown = ( Inpf (target,nor) > 0 ) ? 1.0 : -1.0;
/* I think this should work ... */
bMatrix[0][0]=updown; bMatrix[0][1]=0.0; bMatrix[0][2]=0.0;
bMatrix[1][0]=0.0; bMatrix[1][1]=updown; bMatrix[1][2]=0.0;
bMatrix[2][0]=0.0; bMatrix[2][1]=0.0; bMatrix[2][2]=1.0;
}
/* Make Roll matrix*/
VecRotToMat3(nor, roll, rMatrix);
/* Combine and output result*/
Mat3MulMat3 (fMatrix,rMatrix,bMatrix);
Mat4CpyMat3 (outmatrix,fMatrix);
}