I am wondering whether I have discovered a bug in io_anim_bvh/import_bvh.py, or whether my problem is related to my BVH setup. What I am doing is importing a number of BVH animations exported from another app onto a small crowd of Manuel Bastioni Lab characters in Blender. To minimize the scripting I have set up these BVH files in such a way that all of the characters can be placed in the world at the origin, and all of their movement around the world is contained in their BVH animations.
This system has generally been working fine; I can load my BVH files into other applications and they perform as expected. However, but I am experiencing a fairly dramatic problem bringing them into Blender (v. 2.79 with MBLabs 1.6). Where the actors should all be standing on a flat ground plane at elevation zero meters, they are instead located on a slightly rotated plane of their own, such that the actors in the back are floating above the ground and those in front are buried. It appears that this plane is rotated slightly about the X axis.
I believe I have tracked the problem down to import_bvh.py in the io_anim_bvh addon, but this is where I got stuck. The following bit of code (import_bvh.py line 536) is where my global position gets rotated by a matrix, which I guess came from the hip bone in the armature:
for frame_i in range(num_frame): bvh_loc = bvh_node.anim_data[frame_i + skip_frame][:3] bone_translate_matrix = Matrix.Translation(Vector(bvh_loc) - bvh_node.rest_head_local) location[frame_i] = (bone_rest_matrix_inv * bone_translate_matrix).to_translation()
I have verified that bone_translate_matrix contains the proper global position from the BVH. However, bone_rest_matrix_inv is not identity. It makes sense that we would multiply translations by the base orientation of the node (for instance, if our BVH has us walking forward, we would want that oriented to the direction we’re facing.) However, it appears that there is a slightly forward pitch to the hip node (if that’s what is going on) which in my case wrecks all of my global positions.
Since for my case my characters are starting in default pose at the origin, I thought I might temporarily just remove the matrix multiplication, but that did not work (characters disappeared entirely). On closer analysis, I see that the bone_rest_matrix_inv is not even close to identity, it is more like a major ninety degree flip:
<Matrix 4x4 ( 1.0000, 0.0000, -0.0000, 0.0000) (-0.0000, 0.0499, 0.9988, 0.0000) ( 0.0000, -0.9988, 0.0499, 0.0000) ( 0.0000, 0.0000, 0.0000, 1.0000)>
So my next try was to smooth that out to this:
<Matrix 4x4 ( 1.0000, 0.0000, -0.0000, 0.0000) (-0.0000, 0.0000, 1.0000, 0.0000) ( 0.0000, -1.0000, 0.0000, 0.0000) ( 0.0000, 0.0000, 0.0000, 1.0000)>
This brought me a lot closer, which is why I feel like I might be on the right track, but it didn’t take me all the way there. Apologies for having trouble with the image attachment system in these forums but I couldn’t get things to work out right, instead I’m going to provide old fashioned links.
Situation before my fix: http://megamotionsoftware.com/files/ActorBlock_2x2_01a.jpg
Situation after my fix: http://megamotionsoftware.com/files/ActorBlock_2x2_01b.jpg
You may be able to notice it got quite a bit better, but is still not right.
A sample BVH file that demonstrates the problem is here: http://megamotionsoftware.com/files/930.bvh
If you load that onto a MBLabs character in Blender, you will note that he is buried up to his knees in the ground plane. If you load it into BVHacker you should notice him standing with his feet on the ground plane.
If anyone has any input as to what might be going on here, or how best I might go about working around or fixing this problem, I would be most grateful to hear it!