Often I find that I need to use the copy and paste pose buttons to get a smooth transition when animating a ChildOf constraint. Blender's built in copy and paste pose buttons ignore constraints so I coded my own. Basically select the bones you want, run the 'copy pose to buffer' script, then change frame to after your constraint influence has been changed and run the 'paste pose from buffer' script. This way you can get nice smooth transitions across those constraint changes...
'Copy Pose to Buffer'
import bpy
from mathutils import Matrix
def getmat(bone, active, context, ignoreparent):
'''Helper function for visual transform copy,
gets the active transform in bone space
'''
data_bone = context.active_object.data.bones[bone.name]
#all matrices are in armature space unless commented otherwise
otherloc = active.matrix # final 4x4 mat of target, location.
bonemat_local = Matrix(data_bone.matrix_local) # self rest matrix
if data_bone.parent:
parentposemat = Matrix(
context.active_object.pose.bones[data_bone.parent.name].matrix)
parentbonemat = Matrix(data_bone.parent.matrix_local)
else:
parentposemat = bonemat_local.copy()
parentbonemat = bonemat_local.copy()
parentposemat.identity()
parentbonemat.identity()
if parentbonemat == parentposemat or ignoreparent:
newmat = bonemat_local.inverted() * otherloc
else:
bonemat = parentbonemat.inverted() * bonemat_local
newmat = bonemat.inverted() * parentposemat.inverted() * otherloc
return newmat
for each_bone in bpy.context.selected_pose_bones:
ws_loc_matrix=getmat(each_bone, each_bone, bpy.context, False)
ws_rot_matrix=getmat(each_bone, each_bone,bpy.context,
not bpy.context.active_object.data.bones[each_bone.name].use_inherit_rotation)
ws_sc_matrix=getmat(each_bone, each_bone,bpy.context,
not bpy.context.active_object.data.bones[each_bone.name].use_inherit_scale)
each_bone['ws_loc_matrix']=ws_loc_matrix
each_bone['ws_rot_matrix']=ws_rot_matrix
each_bone['ws_sc_matrix']=ws_sc_matrix
'Paste Pose from Buffer'
import bpy
import mathutils
def rotcopy(item, mat):
'''copy rotation to item from matrix mat depending on item.rotation_mode'''
if item.rotation_mode == 'QUATERNION':
item.rotation_quaternion = mat.to_3x3().to_quaternion()
elif item.rotation_mode == 'AXIS_ANGLE':
quat = mat.to_3x3().to_quaternion()
item.rotation_axis_angle = mathutils.Vector([quat.axis[0],
quat.axis[1], quat.axis[2], quat.angle])
else:
item.rotation_euler = mat.to_3x3().to_euler(item.rotation_mode)
for each_bone in bpy.context.selected_pose_bones:
ws_loc_matrix=mathutils.Matrix(each_bone['ws_loc_matrix'])
ws_rot_matrix=mathutils.Matrix(each_bone['ws_rot_matrix'])
ws_sc_matrix=mathutils.Matrix(each_bone['ws_sc_matrix'])
each_bone.location=ws_loc_matrix.to_translation()
each_bone.scale=ws_sc_matrix.to_scale()
rotcopy(each_bone,ws_rot_matrix)
No comments:
Post a Comment