MayaでFKとIKのマッチング(位置合わせ)方法 part2 (xformコマンド版)

MayaでRigging

MayaでFKとIKのマッチング(位置合わせ)方法のpart2です。

FKとIKのマッチングの前にFKとIKのブレンド(切り替え)の記事を読んでいることを前提としています。まだ読まれていない方は最初にそちらをお読みください。

MayaでFKとIKブレンド(切り替え)方法
MayaでFKとIKのブレンド(切り替え)方法を解説します。ブレンドと切り替えについては人それぞれ好みがあると思います。私は補間してくれるブレンドは嫌いではありませんが、キーを沢山打たなくてはならないアニメーターとしては数値をいれてキーを...

前回のpart1ではmatch Transformationsを使う方法を解説しましたが、今回はxformコマンドを使う方法を解説します。まだ前回の記事を読まれていない方はそちらを先にお読みください。

MayaでFKとIKのマッチング(位置合わせ)方法 part1)
前回の記事(MayaでFKとIKブレンド(切り替え)方法)の続きとして、FKとIKのマッチング(位置合わせ)について解説します。前回の記事で作成したシーンを使用します。よって前回の記事をご覧になっていない方はまずはそちらを御覧ください。...

前回の方法で基本的には問題ないとは思います。しかし、その方法では上腕を一致させたときにjointのrotateの数値が全く同じにはならずに小数点以下の第三位の数値が微妙に違っていたりします。ということで制度があまり高くないようです。アニメーションをつけるうえでは問題ないとは思いますが、この精度の低さが積み重なるとなにか大きな不具合につながらないともかぎりません。このぼんやりとした不安を解消したいと思います。

というわけで今回はきっちり合わせたい人向けというよりも、実戦編です。軍事では兵器の信頼性が重視されているように、古くから使われているxformコマンドを使用したほうが良いでしょう。

スポンサーリンク

xfomコマンド

MELにもPythonのmaya.cmdsにもxformコマンドはありますが、わかりやすいMEL版で説明します。

FKをIKにマッチング

まずはFKをIKにマッチングします。上の画像では黄色のjointを赤のjointにあわせます。

$l_uArm_ik_rot = `xform -query -objectSpace -rotation L_upperArm_ik_Jnt`;
print $l_uArm_ik_rot;

MELのxformコマンドで左腕の上腕「L_upperArm_ik_Jnt」の回転を取得します。

そして上に回転の値がXYZの順番に表示されます。

実際の 「L_upperArm_ik_Jnt」 の値と合っているはずです。確認してみてください。

次にここで入手した回転の値をFKの左腕の上腕「L_upperArm_ik_Jnt」に入れます。

もちろん手作業で数値を入れても良いですが、MELを使います。

$l_uArm_ik_rot = `xform -query -rotation L_upperArm_ik_Jnt`;

xform -rotation $l_uArm_ik_rot[0] $l_uArm_ik_rot[1] $l_uArm_ik_rot[2] L_upperArm_fk_Jnt;

左腕の上腕がマッチングされました。

続いて左肘と左手首についても同様にxformコマンドを実行します。

//FKをIKにマッチング MELバージョン
$l_uArm_ik_rot = `xform -query -rotation L_upperArm_ik_Jnt`;

xform -rotation $l_uArm_ik_rot[0] $l_uArm_ik_rot[1] $l_uArm_ik_rot[2] L_upperArm_fk_Jnt;

$l_elbow_ik_rot = `xform -query -rotation L_elbow_ik_Jnt`;

xform -rotation $l_elbow_ik_rot[0] $l_elbow_ik_rot[1] $l_elbow_ik_rot[2] L_elbow_fk_Jnt;

$l_hand_ik_rot = `xform -query -rotation L_hand_ik_Jnt`;

xform -rotation $l_hand_ik_rot[0] $l_hand_ik_rot[1] $l_hand_ik_rot[2] L_hand_fk_Jnt;

すべて動作をまとめると上のようになります。

これでマッチングできました。

rotateの数値はすべて合っているはずです。

素晴らしい!

IKをFKにマッチング

次はIKをFKにマッチングします。

上と同じように今度は左手のIKコントローラー「L_hand_ik_Ctrl」のtranslateとベクターコントローラー「L_arm_vector」のTranslateをあわせます。

問題発生

なんと左腕のIKが伸び切ってしまい変な形になってしまいました。

Script Editorで数値を確認すると

3 0 0 0 0 0

「L_hand_fk_Jnt」のtranslateXが3、 translateYが0、 translateZが0。

「fk_vector_loc」のtranslateXが0、 translateYが0、 translateZが0。

になっていました。

つまり、ローカル(オブジェクト)座標のtranslateをワールド座標のtranslateに変換しなければなりません。

こんな感じでworldSpaceに変換してみると

このようにまた変な感じになってしまいました。

問題解決

この原因は左手のIKコントローラーは手の初期位置でfreeze Transformationしてしまったのでpivotが違うためです。

// IKをFKにマッチング MELバージョン
$l_hand_fk_trans = `xform -query -worldSpace -translation L_hand_fk_Jnt`;
$l_hand_fk_rot = `xform -query -worldSpace -rotation L_hand_fk_Jnt`;

move -rotatePivotRelative -worldSpace $l_hand_fk_trans[0] $l_hand_fk_trans[1] $l_hand_fk_trans[2] L_hand_ik_Ctrl;
rotate -worldSpace $l_hand_fk_rot[0] $l_hand_fk_rot[1] $l_hand_fk_rot[2] L_hand_ik_Ctrl;

$vector_fk_trans = `xform -query -worldSpace -translation fk_vector_Loc`;

move -rotatePivotRelative -worldSpace $vector_fk_trans[0] $vector_fk_trans[1] $vector_fk_trans[2] L_arm_vector;

このように「-rotatePivotRelative」を使って、rotate pivotから移動することで解決です。

まとめ

xformコマンドを使ってのFKとIKのマッチングはrotate pivotを考慮しないといけないなど面倒な部分があります。

結局はmatch Transformationsがどの程度信用できるかの問題になると思います。

match TransrationはMaya2016からという比較的新しい機能(softImage(XSI)にあった機能の移植でしょうか?)なので信頼性がまだ低いのでしょう。ちなみにこの記事はMaya2019で制作しながら書きました。今後match Translationの精度があがることを祈りましょう(笑)。

よってしばらくはxformコマンドを使うのがよさそうです。

ただ前にも述べましたが、個人で使うだけならばmatch Transformationsで十分だと思います。

おまけ

最後にPython(maya.cmds)版を貼っておきます。

// FKからIKへマッチング pythonバージョン
import maya.cmds as cmds

l_upperArm_ik_rot = cmds.xform( 'L_upperArm_ik_Jnt', objectSpace = True, rotation = True, q = True )
cmds.xform( 'L_upperArm_fk_Jnt', objectSpace = True, rotation = l_upperArm_ik_rot )

l_elbow_ik_rot = cmds.xform( 'L_elbow_ik_Jnt', objectSpace = True, rotation = True, q = True )
cmds.xform( 'L_elbow_fk_Jnt', objectSpace = True, rotation = l_elbow_ik_rot )

l_hand_ik_rot = cmds.xform( 'L_hand_ik_Jnt', objectSpace = True, rotation = True, q = True )
cmds.xform( 'L_hand_fk_Jnt', objectSpace = True, rotation = l_hand_ik_rot )
// IKからFKへマッチング pythonバージョン
import maya.cmds as cmds

l_hand_fk_trans = cmds.xform( 'L_hand_fk_Jnt', worldSpace = True, translation = True, q = True )
l_hand_fk_rot = cmds.xform( 'L_hand_fk_Jnt', worldSpace = True, rotation = True, q = True )

cmds.move( l_hand_fk_trans[0], l_hand_fk_trans[1], l_hand_fk_trans[2], 'L_hand_ik_Ctrl', rotatePivotRelative = True, worldSpace = True )
cmds.rotate( l_hand_fk_rot[0], l_hand_fk_rot[1], l_hand_fk_rot[2], 'L_hand_ik_Ctrl', worldSpace = True )

vector_fk_trans = cmds.xform( 'fk_vector_Loc', worldSpace = True, translation = True, q = True )
cmds.move( vector_fk_trans[0], vector_fk_trans[1], vector_fk_trans[2], 'L_arm_vector', rotatePivotRelative = True, worldSpace = True )

Follow me!

コメント

PAGE TOP
タイトルとURLをコピーしました