<< TOP



は・じ・め・て・の  ICE Kinematics その2
 (My First ICE Kinematics)
                

 プロローグ





データ構造について
 ICEの設定場所、this_model
     まずは、少し前知識。
    シーンを開くと、何処にICEが設定されているのか解りにくい!!
    実用的なシーンに設定したい場合はどうなるの??
    ・・・とかくサンプルのシーンは、その設定がそのまま使える構造になかったりして、がっかりしてしまいます。
     そこで、ここでのチュートリアル用のシーンは、以下のような構造になっていることをお伝えしておきます。

    • ICEは基本的に中央に置いてある "尖ったボックス" という表示にしてある Null に設定されています。
    • 実践的な使われ方を想定して、ICEに使われているものは全て Model以下に作成されています。
      その場合、通常 ICEノード内のデータ指定名にModel名も明記されますが (GetData/SetDataのデータ取得名)
      ここでのデータは、ユーザーツール>モデル名をthis_modelで置き換え が実行してあり、
      モデル名を変更したり、モデル単位で 書き出し/読み込み してもICEノードが使えるようにしてあります。



     少し名前の指定に手を加える事になる場合もあるのですが、
    ICEが設定されているデータ構造部分を Model単位で 書き出し/読み込み が出来ると、
    1つのシーンに色々なICE設定を表示しておいて、その内容を参照しながら別のICEノードを組む、といったワークフローが楽になります。
     
     ICEの各ノードを探す時は、検索の空欄に 名前の解っている一部分でも記入してみると検索機能が働いて、
    目的の ICEノードがすぐに見つけ出すことができます。
    途中の語句でもOK、関連性のありそうなノードを探すのにも、とっても便利です。
      (例えば、Curve といれるだけでその語句のあるノードが色々出てきます。)



      ICEノードをダブルクリックして表示される PPGの右側に [?] がある場合、それをクリックするとそのノードの説明が表示されます。
    [?] が無い場合でも、ユーザーガイドで検索をかけると説明が出てきます。



     各チュートリアルの内容には それぞれシーンが用意されています。
    ですが、正しいICEの習得の方法としては、自分で組んでみて、
    想定されているシーンと同様にちゃんと動作するのかをチェックするような方法でシーンを活用する・・・が一番良い使い方です。
    最初の簡単なものからちゃんと自分の手で組んでみてその仕組みを理解していかないと、あとの方のが追いつけなくなりますよ・・・♪

     それでは早速 スタートです。
     



オフセット
 グローバル値のオフセット
     サンプルシーン >> 01_Matrix_Offset_scn.zip  <シーンを見る前に自分で組んでみてください・・>

    内容は、
      Cubeのグローバル値を GetData で取得し、
      それを Conversion>Matrix to SRT で 拡縮/回転/移動値 に分解し、
      Math>Basic>Add を もう1つの Conversion>SRT to Matrix の間に挟み込み、
      そこから出た Matrix を SetData で Coneのグローバル値に接続しています。



     Add ノードをダブルクリックして表示されたPPGにY軸に値を入れると 
    その値がオフセット値として足されて Coneの位置が移動しますが、
    Cubeに回転値を付けてみると、Coneもその場で回転します。
    つまり、Cubeの中心として回転するようにはなっていない ということです。

     では、どのように組むと Cubeの位置を中心とする回転値が  Cone に与えられるか、です。  次へ>>


 ローカル値のオフセット
    サンプルシーン >> 02_Local_Offset_scn.zip

    内容は、
       Matrix to SRT Add と SRT to Matrix の接続はそのままに、、
      そこから出た Matrix を Cubeのグローバル値と Math>Basic>multiply を使って両方を接続し、
      その結果を SetDataで Cone のグローバル値 としています。



     どう変わりましたか?
    Add ノードをダブルクリックして表示されたPPGに値を入れると その値がオフセット値として足されて Coneの位置が移動します。
    そして、Cubeに回転値を付けてみると、今度はちゃんと Cubeを中心に Cone が回転します。

    では、次は 回転値のブレンドについてです・・・。  次へ>>


 ローテーションのブレンド
    サンプルシーン >> 03_Rotation_Blend_scn.zip

    内容は、
    GetDataで 2つのCubeのグローバルの回転値を用意します。
       ( この時、GetDataを2回使用していますが、この使い方が後で意味があること、便利な事が気が付いてきます。
      見かけは、全体を取って来ておいてその中から必要な細かいデータを取得するといった感じですが、
      オブジェクトを挿げ替えることが容易になる事とコンパウンドを作成しやすくなる事、という意味をも持っています。)

    Math>Basic>Blend を使って2つの回転値をブレンドし、 
    得た結果を回転値として Conversion>SRT to Matrix の回転値に接続し、
    その結果を SetDataで Cone のグローバル値 に設定しています。
    移動値は Math>Basic>Add で 5 Y軸に上げています。



    両側のCubeを回転すると、中央の Cone はその両方のブレンドした値で回転します。
    移動値は Add ノード でオフセットが付けられます。

    では、次は 移動値のブレンド と ポリゴン表面に沿って移動する設定についてです。  次へ>>


 ポリゴン表面に沿って移動
    サンプルシーン >> 04_Closest_Point_scn.zip  >> 少しのノードが増えてきましたよ。

    内容は、
    GetDataで 2つのCubeのグローバルの移動値を用意します。
    2個目の Math>Basic>Blend を使って、今度は 2つの移動値 をブレンドします。
    また、SetData で、ポリゴン (Land) 自身を用意します(つまり ジオメトリーとして取得します)。
    ここで、 GeometryQueries > Get Closest Locationノードを取り出し (取得方法は ClosestSurface になっている)
    ポリゴン (Land) を Geomerty に接続し、
    Blendノードから出た結果を Position に接続します。



    この Get Closest Location の Location から GetData で その PointPosition を取得します。
    そこから出る黄色の Value は移動値 として SRTtoMatrix を通じて Coneのグローバル値に設定します。
    間に Addノードが入っているのは オフセット値が入れられるようにしています。



    Cone は 両方のCubeの移動値と回転値にブレンドされながら、Landポリゴンの表面をすべって移動します。



     TIPS

      ICE は GetData で得たデータを 後で SetData を使って違うものに設定する、 というやり方でが多いです。
      GetData / SetData は良く使うノードですが、使い方にも色々工夫があります。

     あとでも登場しますが・・・、

    • GetDataは、2個使ってつないだ場合、その接続は リファレンス になります。
    • GetDataは、コンパウンドの外部接続に リファレンス として接続し、コンパウンドをダブルクリックした時のPPGに GetData内容をピック選択可能にします。
    • Locationという接続ノードから出力された先を GetData で得たいデータを特定するのですが、データタイプを変更する ということにも利用されます。
    • GetData/SetDataは、OutName と InName をつなぐことにより名前が継承され、記述名の省略ができるのですが、
      得るデータをきちんと特定する という役割の方が重要です。
    • SetDataは、通常にはない、新たに作成できる ”カスタムデータを格納するパラメータを作成する” という役割でも使われます。





積み重ねた値/線の表示
 移動値の積み重ね
    サンプルシーン>> 05_Transform_Stack_scn.zip 

    内容は、
    Conversion>SRT to Matrix  で Yに 1.5 を記入したものを 4つ用意し、
    Math>Basic>multiply を3つ使って 接続します。
    それらの値の結果 を Coneのグローバル値に SetDataで設定しています。
     間をつなぐ線上で 右マウスクリックして、"値の表示" を設定し、Axes を 表示にグローバル座標値使用 を有効にして表示します。


     
     各ノードのY軸の値が積み重ねられて表示されます。
    それらの最終的な値が Coneの値として位置付けられています。

    では、回転値は どうやって積み重ねられる でしょうか。  次へ>>


 回転値の積み重ね
    サンプルシーン>> 06_Rotate_Stack_scn.zip

    内容は、
    Conversion > Euler to Rotarion を取り出し、各4つの SRT to Matrix  の回転値に接続します。


      
    Euler to Rotarion に値を入れると、回転値が引き継がれて動きます。
    これだけでも、魚や尻尾のような動きになりそうで面白いですね。

    では、次は 積み重ねた値の間を 線 で表示します。  次へ>>


 ラインの表示
    サンプルシーン>> 07_Line_Through_Stack_scn.zip

    内容は、
    Conversion>Matrix to SRT で4箇所からの移動値を
    Array > BuildArray でつなぎ合わせ、得た Array値 を SetData につなぎます。
    ここでの注目点!! が SetData に 新しいペラメータとして self.custom と指定しているところです。
    Null-ICE に新しいデータ格納用のパラメータ "custom" が作成されたことになります。
    このつないでいる黄色の線を、"値の表示" で ライン を 表示にグローバル座標値使用 で表示するようにしています。



     "値の表示" は、そのデータの種類によって 数値 Null ライン を表示できます。
    作成途中のデバッグ として大変便利な機能なので、一時的に SetData でつないてみるなどして
    求めるデータが正しいのか確認する手段として利用出来ます。

     BuildArray で得た位置情報は 選択可能です。 次へ>>


 位置情報の選択
    サンプルシーン >> 08_Switch_Stack_Index_scn.zip

    内容は、
    Array > BuildArray から出ている Array値を  Array > Select In Array に接続してから
    出されるValueを移動値として SRT to Matrix  に接続して
    Coneのグローバル値として SetData しています。



     Select In Array の Index値 を変えると、Coneの位置が変わります。
    位置を変化させたい時のスイッチとして利用出来ます。

     ベジェ曲線としても表示が可能です。 次へ>>


 ベジエ曲線の表示
    サンプルシーン >> 09_Bezier_Through_Stack_scn.zip

    内容は、
     4つの位置データを Curves > Bezier4 につなぎます。
    その T 値 に Array > Build Linearly Interpolated Array ノードの結果をつなぎます。
    Bezier4 の結果を SetData で 新しいペラメータとして self.custom2 を作成して、そこにつなぎます。



     滑らかなカーブが表示されます。

     最後は 角度から円を表示します。 次へ>>


 角度から円の線の表示
    サンプルシーン >> 10_Draw_Circle_scn.zip

    内容は、
    Array > Build Linearly Interpolated Array ノードの結果を
    SetDataの カスタム値 Self.temp と Conversion > Axis and Angle to Rotation につなぎます。
    その回転値は 3DVectorで Zに 2 が入ったデータと Math > Vector > RotateVector で混合します。
    その結果も SetDataの カスタム値 Self.circ とつなぎます。



    値の表示 で ArrayRange が 1、10 となっています。

    Build Linearly Interpolated Array ノードのPPGの値を変えることで 半径を変えたり、360度に満たない円を表示したり出来、
    3D Vector ノードのPPGの値を変えることで 円の向きを 変更出来ます。
     



カーブを使った移動/変形
 カーブをパスとして移動設定
     任意のカーブをパスとして設定できる機能です。最後は、これを使いやすくした コンパウンド にまで作り上げてみましょう。

    サンプルシーン >> 11_Curve_Constraint_scn.zip

    内容は、
    まずは、Conversion > UV to Location ノードを取り出します。
    GetDataで カーブそのもの(ジオメトリー) を 用意して Geometry につなぎ、
    Conversion > Scalar to 2D Vector のVector値を UVという入力につなぎます。
     これで、カーブ U値の位置が取得できます。
    (カーブの長さ全体を1とした場合に ある値 例えば 0.5 の時の 位置がどこなのか ということです)

     で、その時の位置を得るために、GetData で PointPosition を得るようにし、
    その黄色のValue値を 移動値として SRT to Matrix  につないで、 
    SetDataで Coneのグローバル値に設定しています。


     
     意外と少ないノードで、カーブをパス設定するものが作れました。
    Scalar to 2D Vector のX値を変更すると、Coneがカーブ上を移動していきます。
     で、気が付きますよね。移動はしてくれますが、本当に移動だけで、回転はしてくれないと・・・。
    カーブに沿ってその向きも 変化させるには、どうしたらよいでしょう。
    考え方としては、Coneの回転値に その時居るUの位置の回転値と 混合させれば、、、ということで、
    それには、以下の手順で ノードを追加していきましょう。

     まず、GetDataで Coneのジオメトリー(全体)を取得します。
    そこから、もう1つGetDataで今度はグローバル値を、そしてそれを Matrix to SRT でSRT値に分解します。
     Conversion > UV to Location ノードから GetDataで PointTangent を取り出します。
    Rotation > Increment Rotation with 2 Vectors ノードで、
    前者をRotationに、後者を To Vector につなぎます。
    このノードが Coneの回転値を カーブの任意のU値(位置)での ベクトル値から計算して設定してくれます。
    その結果から出ている Execution > If は、コンパウンドにした時外部接続にして、
    カーブに沿って移動する時、回転値を考慮に入れるかどうかを選べるようにしておきます。
    • 考慮に入れる   =IfTrueの時は 計算した結果を Coneのグローバル値に設定します。
    • 考慮に入れない =IfFalseの時は、Cone自身が持っていた回転値をそのまま使います。
    最後に GetDataのConeの名前 OutName を SetDataの InNameに接続して、
    名前の継承と省略ができるようにしておきます。



     さーここまで来たら、コンパウンド化して、ワークグループを通じて皆で使えるようにも出来ます。
    右側の SetData以下を選択状態にして 右マウスクリック>コンパウンドの作成 です。
    2つのGetaDataの中の欄は空欄にしておきます。そのソースとレファレンスを外部接続にします。
    上の1つ目は [Curve]として、その下の2つ目は [Moving Object] としました。
    これで、コンパウンドをダブルクリックした時に表示されるPPGにて、[ピック] ボタンが用意されて便利に選べるようになります。
     0 から 100 までの値で パス%アニメーションが設定できるように、
    掛け算と Constant>Scalar を用意し、[0_100 Persentage]として外部接続しておきます。
    あとは、IFノードを [Condition]として 外部接続しておきます。



    ノード上を 右マウスクリック>コンパウンドのプロパティー を選択し、 
    カテゴリ に Kinematics を入れ、説明文や、バージョンを設定しておきます。
    右マウスクリック>コンパウンドの書き出し をして、ワークグループとして設定しているディレクトリーの
    /Data/Compounds 以下に保存します。



    記述したカテゴリに登録され、それを使ってちゃんと動作するかチェックします。



    これが完成したコンパウンドです。>> PassPercentageConstraint_xsicompound.zip

     次は、上記の応用で、カーブにポリゴン形状を乗せてみましょう。
    ちょうど、”カーブに沿って押し出し” みないな感じが ICEで 実現できます。 次へ>>


 カーブに沿ったポリゴン変形
    サンプルシーン>> 12_Bounding_Space_scn.zip

    内容は、
    GetData は 円柱の PointPosition を取得しています。下段の GetParticleというノードも中を見ると同じだと気が付きます。
    そこから 3DVectorを使ってスカラーの計算をしていますが、これはY軸で 一番下のを 0 (ゼロ)、 一番高い所を 1 とする値を得ています。
    そのままの組み合わせで使ってください。
    その結果を 円柱に新たに作った uVal というカスタムなパラメーターに格納しています。



     計算結果を SetDataとつないでいる所を ”値の表示” にすると、 0~1の値がシリンダー上の頂点に表示されます。
    この uVal 値を カーブ上に円柱を沿わせた時の Y軸の位置 とすることで変形をさせます。 


    サンプルシーン>> 13_Curve_In_Place_scn.zip

    上記 カーブをパスとして移動設定 の時のノードの使い方と同様です。

    内容は、
    Conversion > UV to Location ノードを使い、
    カーブのジオメトリーを Geometryに、
    GetDataで取り出した uVal というスカラ値をベクター情報に変換して UVにつなぎます。
    そのノードの結果から GetDataでPointPositionを得て、円柱のPointPositionに SetData しています。



     見えている上記図は、実は円柱が表示されている 結果なのです。
    ですが、Y軸方向のデータしか 頂点位置データとして 円柱に再設定しなかったので、
    線みたいになって表示され、カーブ上にくっついている状態なんです。
     そこで、あとの残りの軸、X軸とZ軸の頂点位置データ も カーブに沿った時の位置情報として追加してあげます。
     (その時、Y軸のデータは捨てるように工夫します。)


    サンプルシーン>> 14_Curve_Deform_scn.zip

    上記 カーブをパスとして移動設定 の時のノードの使い方と同様です。

    内容は、
    円柱から GetData で  PointPosition を得て 3D Vector to Scalar を通じて、
    X軸とZ軸だけのデータを用意して Rotation > RotateVector の Vectorにつなぎます。
    パスカーブを作る時にも使った方法で、 
    Conversion > UV to Location ノードから GetDataで PointTangent 経由で
    Rotation > Increment Rotation with 2 Vectors ノードの ToVector につなぎ、
    その結果をさっきの  Rotation > RotateVector の Rotation につなぎます。
    RotateVector の結果を 上述のY軸方向の位置データと Addノードで 追加します。
    それらすべての結果を SetData で 円柱のPointPosition として 再設定 しています。



     どうでしょうか、円柱がカーブ上に沿って変形していますか?
    カーブの頂点を移動させると、円柱ポリゴンも変形してついてきます。なんか出来そうでしょ。

     さて、これもここまで作ったなら、コンパウンド化して、便利に使えるようにしておきましょう。
    まず、これで動くことが解っているので、そこからもう少しノードを減らしてみましょう。
    円柱から得ている PointPosition を1つのノードでまかないます。
    uVal というカスタム値は、設定して取り出しているなら、そのままつないでしまえば良いでしょう。



    こんな感じにコンパウンドの中に格納しました。
    ダブルクリックすれば、カーブと変形させたいオブジェクトとピックできます。
    変形させるのが前提なので、パスカーブの時と違って、Ifノードは無い状態です。



    名前とバージョンを 2.0 として (SetDataが2つあるのが V1.0) 
    ワークグループにコンパウンドを書き出せば、カテゴリとして記述したところ、Kinematics に登録されます。



     立方体だってこの通り、変形!!
    あ、これ知っていますか? この状態で形として決定したい場合は、
    右下の Edit>フリーズ をかけると、ICEも消えてなくって この形状のまま固定されます。
    つまり、モデリングにもICEは使えるんですね。

    これが完成したコンパウンドです。>> ExtudeAlongCurve_xsicompound.zip


パフォーマンスの表示
 同じ機能のバージョン違い
     ICETree中央上部に パフォーマンスタイマーの開始 アイコンと
    表示>パフォーマンス ハイライト(時間 一番早いスレッド) があります (上部中央のプルダウンメニューも同じものです)。 
     バージョン違いによる正確な速度差というものは難しいのかも知れませんが、
    つなぎ方の違いにより、処理がかかる場所や時間が違うことが見て取れます。
     上述、ExtudeAlongCurve のV1.0 と V2.0 の違いは SetDateの数や、
    処理したノード数の違いなどがあり、変化がわかります。


    (頂点を動かすという同じ動きでの違い)



     という訳で、次回 こそ IK にいけるか?です。
      乞う、ご期待!!