FK/IK切り替え機能のあるリグにて、FK← →IKそれぞれの回転値にスナップする機能のソースコード。
これによって、ぴったりスナップするので、切り替え後の動きのブレをなくせる。
ソースコード
getting IK constrained rotations - Coding / Python Support - Blender Artists Community
ビジュアルトランスフォームの取得は上記参考。
使い方
- tgt_bnameに、対象のボーン名を複数設定する。
- prefix_nameに、FKまたはIKのプレフィックス名を追加する。
- IKをFKに沿わせる場合は、ik_prefix_nameにIKボーン名のプレフィックスを追加する。
- FKなら空にする。
- コンソール画面にコピペして実行する。
import bpy # スナップしたいデフォームボーン名を入力 tgt_bname = ["upperarm_l","lowerarm_l","hand_l"] # IK/FKのプレフィックス # ("REFIK_upperarm_l"のような形を想定。他の形の名前の場合はソースコードを編集すること) prefix_name = "REFIK_" # IKの場合、IKボーン名を設定する。 # ik_prefix_nameに値がある場合は、先にIKボーンの位置を手の位置に移動する処理が入る。 # ik_prefix_name = "" # ← FKなら空にする。行頭の「#」をつければ無効化されるので、それで切り替える。 ik_prefix_name = "MYIK_" def_ik_name = 'hand_l' # ポーズのビジュアルトランスフォーム(IKを考慮した最終的な位置)を得る # getting IK constrained rotations - Coding / Python Support - Blender Artists Community # https://blenderartists.org/t/getting-ik-constrained-rotations/494434/19 def visualmatrix(armature, bone_name): ''' return a local transformation matrix that captures the visual transformation including IK chain etc ''' pose_bone = armature.pose.bones[bone_name] data_bone = armature.data.bones[bone_name] # M_pose = pose_bone.matrix M_data = data_bone.matrix_local # # grab the parent's world pose and rest matrices if data_bone.parent: M_parent_data = data_bone.parent.matrix_local.copy() M_parent_pose = pose_bone.parent.matrix.copy() else: M_parent_data = mathutils.Matrix() M_parent_pose = mathutils.Matrix() # M1 = M_data.copy() M1.invert() # M2 = M_parent_pose.copy() M2.invert() # visual_matrix = M1 @ M_parent_data @ M2 @ M_pose # return visual_matrix ################################### ################################### # メイン処理 obj = bpy.context.object tgt_poseb = obj.pose.bones # IKボーンの位置を手の位置に移動 if ik_prefix_name: def_hand = obj.pose.bones[def_ik_name] tgt_ik = tgt_poseb[ik_prefix_name + def_ik_name] new_matrix = obj.convert_space(pose_bone=tgt_ik, matrix=def_hand.matrix, from_space='POSE', to_space='LOCAL') tgt_ik.location = new_matrix.to_translation() # デフォームボーンのビジュアルトランスフォームを取得し、クォータニオン回転に変換し、対象ボーンの回転値をそれに変更する。 for bn in tgt_bname: tgt_poseb[prefix_name+bn].rotation_quaternion = visualmatrix(obj, bn).to_quaternion()
リンク
IK/FK切り替え可能なリグを作る記事はこちら。