CG・コンテンツ制作
  1. CG・コンテンツ制作トップ
  2. DAIKIN CG Channel
  3. UsersNotes
  4. ICE
  5. は・じ・め・て・の  ICE Kinematics その3 ICE IK (逆運動学) 編
SUITE USERS NOTES
は・じ・め・て・の ICE Kinematics その3
ICE IK(逆運動学)編
(My First ICE Kinematics ; ICE Inverse Kinematics)
ICE_kine_01ritaro_ml

プロローグ

今回は、Softimage 2011 から正式サポートしました ICEの Kinematics機能について その3 です。
ここからは、更に発展して、ICEで動くインバース・キネマティクス(K)の設定をしてみたいと思います。
だんだん複雑なものになって行きますが、すでに多くのサンプルや情報があるので、それらを参考にしつつご紹介します。
Rigを組むような人であれば関心は非常に高いのではないでしょうか。
リガーがアニメーターやモーキャプスタッフと相談して、従来よりも優れたRigを作成できる可能性を・・・秘めていますよ。
ここでは、その基礎になるようなことが伝えられたら・・・と思っております、ハイ。

ではでは、ICE で作る IK をつくりはじめしょう♪♪

1)ボーンの用意
 >事前情報と便利ツール
2)2ボーンIK
 >2ボーンIKの設定方法
 >2ボーンIKの高速化
 >オフセットの考察
 >UpVectorの考察
3)ICE の エンベロープ
 >Dual Quaternion Deformation の設定方法
 >Nullボーン時の対応方法
パソコンのスペック WindowsXP SP3、Intel Core2Duo 3G、RAM; 3G、NVIDIA Quadro FX1700



ボーンの用意
事前情報と便利ツール
まずは、少し前 TIPS
キャラクター・セットアップ、つまりボーンの設定ですが、Softimageで便利な機能の1つに、エンベロープ > リファレンスポーズの設定があります。
骨構造体(Rig)に対してエンベロープを設定した後に骨構造位置を変更させたり、エンベロープを骨に付け直したりする時に重宝する便利な機能です。
 >> ヘルプで [リファレンスポーズの変更] を参照

!!作成 > スケルトンから作った、ボーンを選択した状態で
プロパティー > 静止キネマティクス状態を実行すると Static_KineState というノードが出来、
ダブルクリックしてPPGを表示すると値がまだの状態です。
この状態で、エンベロープ > リファレンスポーズの設定を実行すると、この PPG にグローバルの値が代入されることが解ります。
つまり、ボーンにその”デフォルトの位置”としてグローパル値が設定されたことを意味しています。
ICE の IK設定時にこの Static_KineState をボーン位置として利用しています。!!
ICE_kine_100


既存の骨を ICE用に使うインプリシットのボーンに置き換えてくれる便利ツールを用意することが出来ました。

スクリプトの提供です。(VBS)ありがたや!! >>  Chain2Bones.vbs

スケルトン構造の骨を選択してを実行します。
自己インストール型になっていますので、自分の Workgroup として設定しているディレクトリーなどの Plugins ディレクトリー以下に保存して利用します。
実行すると、元のボーンの位置でインプリシットの単独ボーンに置き換えてくれます。(名前も継承して欲しかった・・・)
<注意>本当に置き換えちゃうので、元の骨が無くなってしまいます。
必ずコピーを作って、それにこのツールを使ってください。

少しでも本番っぽさを考え、既存キャラの足ボーンをからインプリシットのボーンを用意してみます。
ICE_kine_101
ボーン部分だけを選択した状態にして、Chain2Bonesを実行すると
その位置と角度を保ったインプリシットのボーンが抽出できます。
ICE_kine_102
各ボーンに名前を付け、エフェクターの位置にNullを作成しておきます。
これらすべて並列で置いてあり、階層構造的に親子ではありません。
ICE_kine_103

ICE_kine_103b



2ボーンIK
2ボーンIKの設定方法
2つのボーンを選択し、プロパティー > 静止キネマティクスの状態 Static_KineState というノードを付けて
エンベロープ > リファレンスポーズの設定をしておきます。

ワールドのセンターの尖ったボックス形状の NULL ICETree を設定します。
ここではそのICEの設定されている Nul lを ICERig と命名しています。

名前とかはサンプルなどと同じにしておくと、そこで使われているツールとかがそのまま利用出来るケースが多いので、真似ッコがいいです ^_^;;

前頁にて記述したICEKinematicsをWorkgroup設定していれば、
タスクを ICEKimematics にするとIK Solvers > 2 BoneIK ノードがあるのでそれを取り出します。
上記で用意した、2つのボーン(LThigh , Shin )とエフェクターの位置にした Null1(LlegEff) を Exporer から D&D して ICEノードを作成します。
ICE_kine_104
IK Solvers > 2 BoneIKノードを良く見ると、Target Position とは Eff の位置情報、Bone1と2は移動値と長さと解ります。

1) GetData ノードを取り出して、エフェクターからつないで、[Explorer]ボタンから、GlobalTransform のPos をクリックしてグローバルの位置データを設定します。
そしたらそれを 2BoneIK TargetPosition に接続します。
ICE_kine_105
2) GetData ノードを取り出して、LThigh からつないで、 [Explorer] ボタンから、
Static_KineState というノードをクリックしてグローバルの位置データを設定します。
そしたらそれを 2BoneIK Bone1Transform に接続します。
ICE_kine_106
3)GetData ノードを取り出して、LThigh からつないで、 [Explorer] ボタンから、 Length というノードをクリックして長さのデータを設定します。
そしたらそれを 2BoneIK Bone1Length に接続します。
ICE_kine_107
4)5)2)3)と同じ事を2個目の骨(Shin)にも設定して、 Bone2Transform Bone2Length に接続します。
そしたら、2つの骨位置が動き毎に計算された結果をグローバルの位置として設定するので SetDataノードを取り出し、Kine.global が設定している状態で
各骨からの入力と2BoneIK からの計算結果をつなぎ合わせます。
ICE_kine_108
後は、出力側に Execute が2つあるので、1つにまとめることができる Executeノードを利用して、1つの出力を ICETree の Port1 に接続して完成です。
ICE_kine_109
ちゃんと動作するかエフェクターを動かして遊んでみてください。
ICE_kine_110



2ボーンIKの高速化
さて、上記で動いているので完成・・・・とも思えるのですが・・・・、
実はキャラクター一体分、それぞれの全部の骨に SetData で Global 値を設定すると・・・良いパフォーマンスが得られません。
ICE で期待される高速化を目指すのであれば、ちょっとした工夫を施します。
それは、一旦バッファーのように位置データ(例は良く self.BoneTransforms という値名)を格納しておいて、
そのデータを元に Array ノードを使って配置する方法が取られます。
この方法を設定するには、またかなりの改造が必要です。それではいきますよ・・・・。

まずは、データ格納の箱を作成します。
Math > Matrix >  4x4Matrix と Array> BuildArrayfromConstant を用意してつなぎ、
それを SetData self.BoneTransforms と新しいパラメータを作成して ICETree の最初のPort1に接続します。
BuildArrayfromConstant のSizeには、確保する配列のサイズを指定しますが、ここでは最低でも骨の数(つまり、2)を設定しておく必要があります。
実際には、今後の拡張に備え、人体全体に使われているであろう骨の数、例えば150とか設定しておくと良いでしょう。
ICE_kine_121
ここで最初に宣言していますので、後はこのパラメータにそれ以下で計算される結果がどんどん代入されていきます。

<追加情報>
どんどんと複雑になっていってしまう場合、
・見た目の簡素化、修正のし易さ、
・計算部分とシミュレーション部分との分離
・計算/処理の順番を決めておく、
などの為、別々の ICETree ノードに分けて設定していくようになります。
例のとしては、こんな具合になります。
ICE_kine_122ICE_kine_123
当然ですが、Softimage の処理順番に従い、コンストラクションモードの下から順番に処理されます。↑

さて、お次、 Array で位置を特定させるには ID値が必要です。
この部分の説明はは・じ・め・て・の ICE Kinematics その2の位置情報の選択で既に紹介しています。
そこでは、Index値(ID値)を変えると、コーンが置かれる Array上の位置が変化したあれです。
なので、ここでは各ボーンにユニークな ID番号を設定する為に、カスタムのプロパティーセットを利用します。

第1ボーン LThigh を選択して作成6 > パラメーター > 新規カスタムパラメーターセットを実行します。
その名前を ICEBoneParams とし、 BoneID ParentID は整数として-1~999範囲にし
Length は浮動小数値として0~999とします。
ICE_kine_124
一度作成してしまえば、コピぺが出来るので、各骨に異なる BoneID値を入れておきます。
今はあとの2つの値はここでの説明に使用していません。

<追加情報>これは、何かグループ単位で一括でカスタムのプロパティーを設定したい場合の参考になります。

で、スクリプトの提供です。(VBS)ありがたや!! >> ConfigureICEBoneParamsProperty.vbs
グループを作成して選択状態にしてからこのスクリプトを実行してください。
ICEBoneParams というカスタムプロパティーが自動的に作成されます!!!
個々に異なる BoneID値にはしてくれるようですが、他の部分と合わせて自分で再度数値を記入していってください。
ICE_kine_125
次は、一括でデータを取得しやすいようにグループを作成します。
足2つ(LThigh, LShin)を LegBone1 というグループを作成して入れ、それを Array に渡すようにします。

<追加情報>
キャラ全体のグループ、例えば ENV_MainBody というグループがあるのであれば、
初期設定用の別 ICETree ノード( Init_ICE_Rig と命名)にて、 ENV_MainBody グループから ID値を取得して、
全体のID(BonesIDs)を最初に設定しておくと良いでしょう。下図;一括初期設定例
ICE_kine_140

さて、最大の山場です。
このようにノードを組み上げて行きます。(ただし、これだけでは動きまんよ。)
ICE_kine_126
では始めます。(この作業中、Boneは下図のようにきちんとした位置に表示されません)
LegBone1 Groupノードを D&D し、新しいGetDataノードつないで、 ICEBoneParams 内の BoneID を取得します。
その値(Value)を Array > Set in Arrayの Index につなぎ、結果(Result)をSetData self.BoneTransforms に接続します。
それを IceTree の Port2 に接続します。この時点で、 Set in Array の前の部分を「値の表示」にて数値にすると、
BoneID の値がちゃんと取れてることを表示してくれます。
ICE_kine_127
Array > Build Array Set in Arrayの前に配置し、その Value に接続します。
前述の試し動きの時にあった SetData を削除して
Bone1 の結果を Value1 に、
Bone2 の結果を Value2 に接続し、
3個目の Value3 にはエフェクトの位置情報を 2BoneIK を挟んで Matrix to SRT →SRT to Matrix から得た Matrix の結果を接続します。
そして、GetData で self.BoneTransforms Set in Array Array に接続します。
ICE_kine_128
Build Array から Array 出力を「値の表示」にて Axes にするとその位置と方向が見れます。
ICE_kine_129
そして最後の仕上げです。
実は最後に各ボーン毎にも ICE を設定が存在します。どのボーンにも ICETree の内容は同じです。
己にカスタムパラメータで設定していたID値と格納した BoneTransformsから自分の位置を SelectArray で導き出し、
それを自分のグローバルの位置として SetData で設定しています。
ICE_kine_130
全部のボーンに付けるものなので、簡単なコンパウンド化しておきます。(名前を統一しておきます。)
Bind Deformer to ICE Rig と名前を付け、タスクを ICE Kinematics/Rig Binding にします。バージョンは 1.3 にしておいてください。
出来たら、コンパウンドの書き出しで保存しておきます。
ICE_kine_142
<追加情報>これは、一括でコンパウンドなどICEノードをICETree作成含めて接続したい場合の参考になります。

で、スクリプトの提供です。(VBS)ありがたや!! >> BindRigToICEData.vbs  

グループを作成して選択状態にしてから > メンバの選択にしておきます。(全部が白色選択状態)
そして、このスクリプトを実行します。
全部の選択ボーンに自動的にBind Deformer to ICE Rigが ICETree に接続されています。

良く使うスクリプトはツールバーにまとめて、ワークグループに保存すれば直ぐにみんなの共有ツールに出来ますね。
ICE_kine_143

はい、全ての設定が終了しました。きちんと動くか遊んでみてください。
ICE_kine_131
うまく動作しましたら、お疲れ様でした!! OKです。

最初はなんでこんなに・・、と思うところなんですが、
一回動いてしまい、事情が解ってしまうと、おお♪、となるといいな・・と言ったところでしょうか・・・。



オフセットの考察
どこかの付属物としての骨構造体をくっつける場合の考察です。

は・じ・め・て・の ICE Kinematics その1の オフセットを付けるMatrix Offset use を利用すると簡単です。
オフセットの値を知る為に仮に作成したNullを HipPlate1の子供にして値を知ります。
ICETree 上に HipPlate のグローバルトランスレーションを持って来て、Matrix Offset use の InputMatrix につなぎます。
オフセットを付ける第1ボーンの LThigh のStaric_KineStateからのMatrixを MatrixtSRTで回転とスケール値 を Matrix Offset use にそれぞれつなぎます。
オフセット値仮Nullから得た値を記入します。
最後に、出た結果の Matrix を 2BoneIKの Bone1Trasform に接続します。
ICE_kine_132
これで腰骨を動かすと第1ボーンの LThigh が動くのを試してみてください。
ICE_kine_133



UpVector の考察
これも骨の方向を制御するもの、としての考察です。(中級レベルに”もってこい”のサンプルです。)

第1ボーンのオフセット値の後に差し込む形でボーンの方向を変えてみました。
UpVector用のピラミッド表示のNullはやはり並列に置いてあります。
ICE_kine_141
サンプルとしているのは Kinematics > LookAt というコンパウンドを展開して中にある Point Pose at Position を編集したものです。
ICE_kine_150
更にPoint Pose at Positionを展開すると、下図のようになっています。
入って来るUpVectorの位置から方向を導き、それを回転値として計算して第1ボーンのグローバル値にするということが想定できます。
ICE_kine_151
ちょっとした改善が使い易すさと、ICE の機能の理解を深めることになります。
ICE_kine_152
変更点は、入って来る UpVector の位置が骨の前か後ろかを If でつなぎ、Flipにチェックを入れると後ろになるようにしています。
これだけなのに、UpVectorのX軸移動方向とは逆方向に骨の向きがちゃんと回転します。前にある場合は位置を追従して回転します。

その下の BuildArray は、第1ボーン → UpVector → Effector の位置順にオレンジ色の線を描画しているだけのものです。
If ではなく Andですが、チェックを入れると線が描かれ、外すと消えます。
こうしたちょっとしたことがアニメーターに使いやすいツールになるでしょう。

思うような動きになっているかは、試してみてください。
もし、UpVectorの動きが他のオブジェクトと追従して動いて欲しいなら、HipPlate1 の子供にしてみたはいかがでしょうか。
ICE_kine_153
完成されたものではありませんが、試してもらって良いです。
少量の変更なので、V1.2としてコンパウンドを書き出しました。 > Point Pose at Position.1.2.xsicompound



ICE のエンベロープ
Dual Quaternion Deformation の設定方法
さて、ボーン構造まで出来たとして、パフォーマンスを調べると次に重いのは、エンベロープだったりするのです。
そこで、エンベロープの計算もICEにしてみるというのは興味ありませんか?
しかも従来とは違って、色々と工夫の余地があり、どのようにエンベロープの処理するかをも設定できるのです。

ここでも2個の ICE_Tree を設定します。ウェイト値の処理とエンベロープの処理です。
ICE_kine_160


脚用のポリゴンを用意し、サブディビジョンサーフェイス(+キーが2回とか)がかかってる場合は元のポリゴン形状に戻しておきます。
脚の骨のグループ LegBone1 が用意してあります。これを使って通常のようにエンベロープを脚ポリゴンに設定します。
エンベロープ > エンベロープの設定 > グループのピック、右マウスボタンで決定。

今回は脚しかないので LegBone1 をボーンのグループとして D&D して来て、
Skinning >  CalucateDeformerWeight につないで ICE_Tree に接続します、 
以上ですなんて簡単な・・・・
ICE_kine_161
いや、ちゃんと解説します。
この処理で、Self.EnvelopeDeformerIndices と Self. EnvelopeWeights というパラメータを用意しています。
EnvelopeDeformerIndices はウェイトの種類を数字化しています。 EnvelopeWeights は文字通りウェイト値ですね。
ICE_kine_162
CalucateDeformerWeight の中を見てみると、最後に SetDataでそれぞれの値を代入しています。
「値の表示」してみると各値がちゃんと取れているのか見ることができます。



2個目の ICE_Tree を作成して、名前を Envelope_ICETree としてみました。
今回は脚しかないので LegBone1 をボーンのグループとしてD&Dして来て、
Skinning > Dual Quaternion Deformationの Deformer Group In Name につないで Envelope_ICETree に接続します。
通常のEnvelopeOperatorを無効にして、エフェクターを動かしてちゃんと動くか確認します。
以上です。なんて簡単な・・・・
ICE_kine_164
いや、ちゃんと解説します。
Dual Quaternion Deformation は他サイトで現在は V2.0 が公開されていますので取得してください。
中を見ると結構なノードがありますが、 EnvelopeDeformerIndices EnvelopeWeights を使って、PointPositionのデータを計算しています。
変形方法が選択になっていて Dual Quaternion Skinning でないと曲がった時の形状が細くなったりしてしまいます。
もちろんサブディビジョンサーフェイスにも対応していますので、+キーを2回押して滑らかにしてもきちんと変形しています。
複数のエンベロープ・ウェイトがある場合はどれかを選択できるようになっています。
ICE_kine_165


Nullボーン時の対応方法
さて、最後に Null を Rig に使っていて、ボーン構造となっている場合、
上記 CalucateDeformerWeight の中では Length の値を取得しているので、Null に無い Length値が取得出来ず、
そのままでは動かないことが解ります。
ならば、このページで紹介していますカスタムパラメーターに Length の値をちゃんと記入してあげて、それを取得すれば良いと気がつきます。
Nullボーンのグループを D&D し、そこからカスタムパラメーターの LengthをGetDataし、それを Self.Length に SetData します。
その間を「値の表示」にしていみると、ちゃんと得ていることが確認できます。
そしたら、その値を CalucateDeformerWeight の Length の値に代入すれば OK です。
え?そんな接続部が無い?いやいや・・・作ったまでです。
ICE_kine_166
中を見ると、内部で Get .Length となっているので、そこだけ外部接続にして、その名前を Length と変えただけです。
ICE_kine_167
Null の骨であっても、その表示がボーンらしいみたいな一工夫として
X軸方向の Null なら、X軸スケール値の半分がX軸のオフセット位置なんて使われ方もあるようです。
ICE_kine_168

という訳で、正しく動いた場合のサンプル画像です。



すでに多くのサンプルやコンパウンド、スクリプトが存在しますので、
先人達の知恵をうまく活用して自分の目的の動きになるように組み合わせる ・・・ というのが ICE のうまい使い方ではないでしょうか。
つまり、”うまく組み合わせられるように何をしているのかを理解すること”が ICE の使い方のくせとかこつになるのかも知れません。

という訳で、次回は ICE のスプリングとかコリジョンとか予定してるんですが・・・。
乞う、ご期待!!
戻る 次へ

お気軽にお問い合わせください

Daikin CG News お申し込み

CGクリエイター向けのセミナー・イベントやキャンペーン、製品情報をメールマガジンでお届けします。(登録無料)

Twitter

ページの先頭へ