I am working on a plugin to use a motion capture system within Blender. The aim is to configure a human armature to work with the motion capture system in real time. At the moment I have some trouble on how to set the bones in a right pose.
I tried some different approaches but nothing worked until now. I am using the PoseBone to work on the bone position and tried the following:
PoseBone.location - some kinda works but seems to be the location within the armature, not the position i want to use
PoseBone.translate() - got this reported when I move a bone with the mouse but using it with python does'nt work, I get an error that head is read only
I am able to get matrices from the motion caputre system so I would try to use
PoseBone.matrix_local
on the Blender side but before I want to ask if someone can tell me what is the right way to set a bone in pose?
The trick is to use the rest matrix, which you get in edit mode, to transform between global space and bone space. Something like this should work, although I haven’t tested the code.
import bpy
def poseArmature(rig, locations, rotations):
bpy.context.scene.object.active = rig
bpy.ops.object.mode_set(mode='EDIT')
headRest = {}
matrixRest = {}
inverseRest = {}
for eb in rig.data.edit_bones[]
name = eb.name
headRest[name] = eb.head
matrixRest[name] = eb.matrix.rotation_part()
inverseRest[name] = matrixRest[name].copy().invert()
bpy.ops.object.mode_set(mode='POSE')
nFrames = len(locations)
for pb in rig.pose.bones:
name = pb.name
for frame in range(nFrames):
pb.location = inverseRest[name] * (locations[frame] - headRest[name])
for n in range(3):
pb.keyframe_insert('location', index=n, frame=frame, group=name)
mat = inverseRest[name] * rotations[frame] * matrixRest[name]
pb.rotation_quaternion = mat.to_quat()
for n in range(4):
pb.keyframe_insert('rotation_quaternion', index=n, frame=frame, group=name)