I am currently creating an external Python script (for use with MatPlotLib library) that use the same maths and similar functions to the way Blender imports a .bvh and creates the rotation keyframes for each bone in the armature.
I have access to a database of .bvh mocap data that I must analyze using TensorFlow and am now eager to find a way to re-write some functionality into a custom application.
I have been examining the contents of import_bvh.py (file on GitHub: Link) and have come to the conclusion that my external application seems to be mostly correct except for the bone_rest_matrix (line 569) which I believe is in Blender’s bone space (or possibly Armature space)??
I do not know how to reproduce this value for a given armature (eg. the armature created in the MatPlotLib app).
When I look closely at import_bvh.py I see that it creates an armature and object (line 380) it then sets the bone.head and bone.tail (line 419) for each bone in the list of imported bvh nodes. But I do not understand how it sets the bone roll.
Also I notice that the left and right arms have different Up pointing orientations, so I assume the roll is local and not globally determined.Objective: I have been given some armature hierarchical data and I need to somehow compute the correct bone_rest_matrix so it can be used to extract the bone's Euler angles from the homogeneous coordinates:
euler = Euler(bvh_rot, bvh_node.rot_order_str[::-1]) #input Eulers bone_rotation_matrix = euler.to_matrix().to_4x4() bone_rotation_matrix = (bone_rest_matrix_inv * #NEED TO COMPUTE THIS (Inverse) bone_rotation_matrix * bone_rest_matrix) #NEED TO COMPUTE THIS rotate[frame_i] = bone_rotation_matrix.to_euler(pose_bone.rotation_mode, prev_euler)#output Eulers prev_euler = rotate[frame_i]
I was hoping someone could help me understand what the bone_rest_matrix is in this case. I think it is a child/parent hierarchy where each bone is in a local (aka “bone”) space and the orientation of the armature is as if it were resting in a tpose??
I am also not sure what “prev_euler” is doing or why it was required (I am not sure if it is part of the bvh decoding algorithm or just some Blender internal math stuff).
Any help here in understanding what this matrix represents or how to reproduce it would be amazing!!!