Stretch IK(伸びるIK)の解説です。 腕や脚で使われることを考慮して 今回紹介するのは伸びるIKなので縮みません。正確に言うと縮まないようにしています。
Stretch IKを作る場合、jointのtranslateXを使用する方法とscaleXを使う方法がありますが、今回はより一般的だと思われるscaleXバージョンを解説します。正直いって私のレベルではどちらのほうが良いかはわかりません(最近はtranslateXバージョンのほうが良さそうに思える今日このごろです)。スキニングすることを考えるとscaleX版のほうがベターです。
リグに関しては過去の記事も参考にしてください。
「ジンバルロックとRotate Orderについて」と「joint orientについて」は重要なことなので馴染みがない方はこちらをご覧になってください。この記事の内容を実践するにはjointのX軸が子の方向を向いている必要があります。
また、今回もNode EditorでノードをつなげるのでFKとIKのブレンドの記事を参考にしてください。
また、リグを組む上でスケールがからんでくるとなにかと不具合が多くなります。この不具合をパズルを解くように解決しなければなりません。よってスケールがからむと難易度がいっきに跳ね上がります。少なくとも「スケールがからむリグは難しい」ということだけは知っておいてください。
jointのスケール
親のjointでスケールで拡大しても子のjointは元の大きさ(元のスケール)を保っています。
Node Editorでみると親のjointの「Scale」が子のjointの「inverse Scale」に繋がれていることが確認できます。これでスケールを打ち消していることがわかります。
とにかくMayaのjointはこのようになっていることを理解してください。
なぜそのようになっているのか興味がある方は以前にも紹介した『マヤ道! ! : The Road of Maya (CG Pro Insights)』をぜひ読んでみてください。向学心のある方には非常におすすめです。
このようにスケールの仕様が普通のオブジェクトの親子関係とは違う点からもスケールを扱うリグはやっかいだということがわかったと思います。
stretch IKに挑戦
ここから本題に入ります。
まずは上の画像のように左腕をイメージしたシーンを作成します。
jointにIK(RPsolver)を引いてPoint Constraintで先端の小さなサークルでIKを動かせるようにします。
IKをjointの後ろのConeのコントローラーにPole Vector Constraintします。
中央の大きなサークルは全体の動きやスケーリングを制御するルートコントローラーになります。
Distance Tool( Create > Measure Tools > Distance Tool )を使って腕のjointの距離を測ります。
Persビューなどで適当な2点をクリックするとLocatorが2つ配置されます。その2つのLocatorをjointの始点と終点にそれぞれ配置(vを押しながらでjointにスナップします)します。
グループ分けは上のようにします。
「dnt_touch_Grp」に触ってはいけないものとしてdistanceDimensionを入れました。最終的には非表示にして隠します。アニメーターに触らせてはいけません。アニメーターは触ってはいけません。
「ctrl_Grp」にコントローラーを入れました。距離を測るためのLocatorはここに入れました。これでIKのコントローラーを動かしたときの距離が測れるようになります。
「joint_Grp」にはjointが入っています。
Node EditorのワークスペースでTABキーを押して「multiplyDivide」と入力する途中にリストが現れるのでそこから「multiplyDivide」を作成します。それを上の画像のようにdistanceDimensionShape1の「Distance」をmultiplyDivide1の「input 1X」に接続します。そしてその「Output X」をjoint1とjoint2の「Scale X」に接続します。
multipleDivideの設定は上の画像のようにしてください。
Operationには「Divide」を選択(今のIKの長さがデフォルトの長さの何倍なのかを割り算をして求めます)し、Input 2に6(デフォルト時の腕(joint)の長さ)を入れます。
Squash and Stretch IK?
すると結果は上の画像のようにアニメーターが大好きな(笑)Squash and Stretchのリグになってしまいました。
なぜこのようになってしまったのでしょうか。
少し考えればわかることですが、このリグでは距離が2倍になればスケールも2倍、1/2になればスケールも1/2のようにスケールの値が決まります。しかし、これでは腕が曲がらなくなってしまいました。距離が1倍以下の場合はスケールを1のままにするという条件を加えることにします。そうすればスケールが1のときには普通のIKとして動作します。
今度こそStretch IKの作成
正解から先に言ってしまうと上の画像のようにします。
「conditon」ノードを使って条件分岐を作ります。conditionノードは「if文」のようなものです。
First TermとSecond Termの値をOperationによる条件を満たせば「True」を満たさなければ「False」に設定された値をoutputします。
この「conditon」ノードで条件分岐した結果をjointのscaleXに接続します。つまり条件を満たした場合はstretchするようにして、満たしていない場合は普通のIKとして作動するようにすることが出来ます。
First TermにはIKの長さを繋げています。Second TermにはデフォルトのIKの長さ(6)を入れています。「Greater than」という条件はFirst TermがSecond Termより大きければTrueを返し、それ以外なら「False」を返します。つまり「現在のIKの長さがデフォルトよりも長ければ、multiplyDvideで計算したスケールの値(Trueの条件)を返し、それ以外では1(スケールの値)を返します(stretchしない)」ということです。
if (現在のIKの長さ > デフォルトのIKの長さ) {
joint1.scaleX = multiplyDivideで計算されたスケールの値;
joint2.scaleX = multiplyDivideで計算されたスケールの値;
} else {
joint1.scaleX = 1;
joint2.scaleX = 1;
}
スクリプトだとこんな感じでしょうか。こちらのほうがわかりやすいですが仕方ありません(笑)。
これで完成ですがまだ問題が‥
これでstretchIKは完成となりますが、実は問題があります。
それは大きなサークルのコントローラーをスケールすると問題が発生します。
縮小するとIKのコントローラーが移動していないにもかかわらずjointが折れ曲がってしまいます。
このようにスケールに関連したリグを構築しているとこのように次々と不具合が発生します。文章がそこそこ長くなったので今回はここまでにします。
次回は全体をスケールしても大丈夫な状態を目指します。
今回の記事が気に入っていただけた場合、ぜひとも他の記事もチェックしてみてください。Mayaのリギングに関する記事をまとめたページです。
コメント