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

当ページのリンクには広告が含まれています。

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

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

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

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

というわけで今回はきっちり合わせたい人向けというよりも、実戦編です。軍事では兵器の信頼性が重視されているように、古くから使われている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;
画像に alt 属性が指定されていません。ファイル名: matching_part2_upperArm_fk_to_ik.png

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

続いて左肘と左手首についても同様に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 )

今回の記事が気に入っていただけた場合、ぜひとも他の記事もチェックしてみてください。Mayaのリギングに関する記事をまとめたページです。

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

目次