dskjal
広告
広告

Blender で IK/FK 一致スクリプトを書く

カテゴリ:blender

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

解説

以下のスクリプトは IK ボーンと FK ボーンを持つリグで機能する。

bone hierarchy
ボーン構造

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 の影響力を直接ドライバーで操作する方法のボーン構造で使える。

.blend ファイルダウンロード

ボタンを表示させるには、テキストエディタの Run Script を押す必要がある。

IK 用のボーンと FK 用のボーンとデフォーム用のボーンを Copy Rotation で操作する場合

この項目はボーン構造がIK 用のボーンと FK 用のボーンとデフォーム用のボーンを Copy Rotation で操作する方法のボーン構造で使える。

スクリプト

使用する場合は、スクリプト中のボーン名を適宜変更する。

.blend ファイルダウンロード

ボタンを表示させるには、テキストエディタの Run Script を押す必要がある。

関連記事

IK-FK 切り替えスイッチ

Blender 記事の目次


広告
広告

カテゴリ