Blender で IK/FK 一致スクリプトを書く
カテゴリ:blender
ポーズボーンのアーマチュア座標は matrix クラス変数から取得できる。mathutils をインポートすれば matrix の decompose() で位置・回転・スケールをそれぞれ取得できる。これを使えば行列計算をせずに FK/FK 一致スクリプトを実装できる。この記事では腕を例として説明する。
解説
以下のスクリプトは IK ボーンと FK ボーンを持つリグで機能する。

ボーン構造
IK to FK
IK ターゲットを FK ボーンの先端へ移動し、ポールターゲットは肘ボーンの位置に移動する。ポールターゲットの位置が気に入らない場合は、上腕の子としてポールターゲットの移動先ボーンを配置するといい。
# IK ターゲットとポールを FK ボーンの位置へ移動させるスクリプト
import bpy
def set_translation(bone, loc):
mat = bone.matrix.copy()
mat[0][3] = loc[0]
mat[1][3] = loc[1]
mat[2][3] = loc[2]
bone.matrix = mat
def ik2fk(target, pole, upper_fk, fore_fk):
set_translation(target, fore_fk.tail)
set_translation(pole, upper_fk.tail)
pose_bones = bpy.context.active_object.pose.bones
upper_fk = pose_bones['upper_fk']
fore_fk = pose_bones['fore_fk']
target = pose_bones['target']
pole = pose_bones['pole']
ik2fk(target, pole, upper_fk, fore_fk)
FK to IK
親から子へ行列をコピーするだけだ。
# IK ボーンの情報を FK ボーンにコピーするスクリプト
import bpy
def fk2ik(fk_leaf, ik_leaf, num_bones):
fk = fk_leaf
ik = ik_leaf
stack = []
while num_bones > 0:
stack.append((fk, ik))
fk = fk.parent
ik = ik.parent
num_bones -= 1
for fk, ik in reversed(stack):
fk.matrix = ik.matrix
# update bone
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.mode_set(mode='POSE')
pose_bones = bpy.context.active_object.pose.bones
fore_fk = pose_bones['fore_fk']
fore_ik = pose_bones['fore_ik']
num_bones = 2
fk2ik(fore_fk, fore_ik, num_bones)
IK の影響力で IK/FK の切り替えをする場合
このスクリプトはIK の影響力を直接ドライバーで操作する方法のボーン構造で使える。
ボタンを表示させるには、テキストエディタの Run Script を押す必要がある。
IK 用のボーンと FK 用のボーンとデフォーム用のボーンを Copy Rotation で操作する場合
この項目はボーン構造がIK 用のボーンと FK 用のボーンとデフォーム用のボーンを Copy Rotation で操作する方法のボーン構造で使える。
スクリプト
使用する場合は、スクリプト中のボーン名を適宜変更する。
ボタンを表示させるには、テキストエディタの Run Script を押す必要がある。