<< TOP



ICE を使ったコマ抜きアニメ
Making limitted animation with ICE
(アニメ向き)






 プロローグ
      続けて書く予定だった、ICE考察のアニメ編 が遅れてしまいました。
    Softimageにはまだまだ開拓すべきアニメーション加工方法がたくさんあり、
    アニメ的な表現にも生かせる事もいっぱいあるはずです。
     そこで、今回は コマ抜き的な動き について調べると共に、
    ICEを使ったコマ抜きアニメが出来ないか実験してみました。
    どれか1つでも参考になれば!! と考えます。

    > 通常アニメーション
      > AnimationMixer
    > ICE考察1
      > Modulo
    > ICE考察2
      > 値の代入
    > ICE考察3
      > Array化
    > ICE実践1
      > キャタピラ
    > ICE考察4
      > パーティクル;キャッシュ
    > ICE考察5
      > パーティクル;シミュレーション

パソコンのスペック WindowsXP SP3、 Intel Core2Duo 3G、 RAM; 3G、NVIDIA Quadro FX1700



通常アニメーション
 AnimationMixer
     まずは、通常のアニメーションからコマ抜きアニメーションを実現するには、どういった技法があるのか見てみました。
    プリミティブな球に適当な動きをキーフレームから作成すれば、滑らかな FCurve が作成できますね。



     で、FCurve に加工を施せば、コマが飛んだアニメーションになります。
    カーブの処理 にて 時間ステップを 3 とかにして 既存キーは保持 して リサンプル と スムーズ でも実行すれば
    階段状のFCurve になります。 うーん、とてもベタな方法で ベター(Better) じゃない。 



     そこで考えます。2コマ、3コマ 抜きにしたい時はそういう FCurve を全部作るの? って
    で、Exression が登場します。しかもClipに使うのです。下図を見てください。
    なんということでしょう!! コマ抜きの動きをしているのに FCurve はそのままですし、Clip にはWeight値しかありません、さて・・・。



    答えは ソースにあり。



    己の 各ローカルの軸移動の値に対して このような処理をさせています。

        at_frame( floor( Fc / 2 ) * 2, sphere1.kine.local.posx )

    つまり、ここの数値が  なら コマ抜き になります。
    ならば、Clipを並べて 無効/有効で 2コマClip、3コマClip と動きが選べるようになりますね。



    でもでも、まだ困ります。
    上の3項目で移動値だけだから、スケール値回転値があるとそれも書くだろうし、
    sphere1 って書かれているので、個別のものに対してすべてファイル名を付け直さないといけないだろうし。
     (また、Expression は毎フレーム計算するスクリプトみたいなものですので、大量にあった場合レスポンスが悪くなることが想定されます。)

    そこで、ICEを使ってなんとかならんの となる訳です。



ICE考察1
  Modulo
     さて、ICEの方なんですが、今までScriptやExpressionで動いていた関数をそのままICEで実現する 
    って考え方は案外あてはまらないと考えた方が良いです。
    ICEならではの作り方があり、発想の転換が良い方向にいきます。
     そこでまずは実験から始めましょう。
    以前の記事からも紹介しています通り、面白いICEノードとして Modulo を理解しましょう。
    この Modulo は、数値(Value)指定した数(Modulo by) 未満の剰余値を繰り返す結果を出します。
    例えば、入って来る数値を CurrentFrame にし、指定数に 3 と入れると、0.1.2 を繰り返します。



     上図は Modulo の結果が  だった場合、球から導いたグローバル値を Coneのグローバル値にする、
    って書いただけです。 (下のtestはModuloの結果値を見たいだけです)
    これだと、Modulo の結果が 0 と 1 だった場合が書いてないので、ワールドの中心値に戻ってしまう動きになります。

     もう少し考察します。では、ワールドの中心値に戻るんではなくて、前のフレームの値を代入できればいいのか、
    こんな風に作ったとします。



     今度は Round というICEノードが出て来ました。これはスカラー値を整数にします。便利です。
    Modulo の結果が 2だったら Sphere からのグローバル値を Sphere2 のグローバル値にし、
    それ以外は 以前のフレーム値(GetData At PreviousFrame)を、としました。
    2コマ抜きならOKです。ですが、3コマ抜きの時は、はい。困ります。
    元のSphereは毎フレーム動いている訳ですから、2フレーム前の値じゃないと動いてしまうフレームがありますよね。
    うーん、と。

ICE考察2
 値の代入
     で、こんな感じで対応を考えてみました。



     一旦、任意の名前(例では KomaTobiIchi ) に値を代入しておいて、その値から自分のグローバル位置を設定します。
    どうでしょうか?これなら 何コマ落ちでも平気です。コマ落ち数までアニメーションできます。
    注意は、この時の ICETree ノードの置き場所が Simulation コンストラクションモード以下に置いてあることです。

     これで対応が出来そうなことが解ったので、
    今度はもっと多くのもの、つまりキャラクターRigのように骨の数だけあるようなものにも対応すべく考えてみます。


ICE考察3
 Array化
      それは、いままででも紹介している高速化の為の Array(配列)を使った方法になります。(今回、もっとも単純な方法で・・・)
    すると2段設定の ICE になります。
    まずはデータをArray(配列)化 し、その後でオブジェクト個別毎にデータを引きだして位置データとする、という仕組みです。



     元のアニメーションがたくさんのオブジェクトがあることを想定して GetDataをGroup(Groupという名前)から得ます。
    Softimageは1からフレームが始まるので = 1 にしました。
    Array化した値の入る箱の名前は、良く使う BoneTransforms とし、その前計算として 代入値を PreBoneTransforms としました。
    個別のオブジェクトに付けるICEはコンパウンド化(BoneTransform2GL)しておきます。
    そして、このコンパウンド BoneTransform2GL の中身は


    となっています。
    最初のGetDataはReferenceとしてつないでおいて、
    コンパウンドをダブルクリックした時のPPG(プロパティーページ;設定画面)で、
    ICEのついているPointcloudを[ピック]出来る画面にしておきます。
    Indexの番号は Group から得たオブジェクトの上からの順番で、これは  から始まります。
    今は 1個 しか入ってないので 0 です。

     BoneTransform2GL というコンパウンドをたくさんのオブジェクトに一気に接続してしまうにはスクリプトが便利です。
    BoneTransform2GL コンパウンド は事前に ユーザーのワークグループにでも 書き出し を行っておきます。
    そして、こう書いたスクリプトを用意します。(違う名前のコンパウンドを同様に接続したい場合は、コンパウンド名前部分を変えるだけです)


      sub BoneTransforms2GL( oObj )
        set compound = Dictionary.GetObject( oObj & ".null.ICETree.BoneTransforms2GL", false )
        if typename(compound) = "Nothing" then
          set iceOp = ApplyOp("ICETree", oObj, siNode, null, null, 0)
          AddICECompoundNode "BoneTransforms2GL", iceOp
        ConnectICENodes iceOp & ".port1", iceOp & ".BoneTransforms2GL.Execute"
        end if
      end sub

      sub BoneTransforms2GLData( obj )
        if typename( obj ) <> "Group" then
          logmessage "You must select Group."
          exit sub
        end if

        set oGrp = obj
        for i=0 to oGrp.Members.Count - 1
          set oObj = oGrp.Members.Item( i )
          BoneTransforms2GL oObj
        next
      end sub

      sub BoneTransforms2GLData( )
        for i=0 to Selection.Count - 1
          set oObj = Selection.Item( i )
          BoneTransforms2GL oObj
        next
      end sub

      BoneTransforms2GLData


    を ツールバー のボタン (例; BoneTransform2GL )にしておけば、いつでも使えます。



    使い方は ICETree を付けたい複数のポリゴンオブジェクトを選択した状態で ボタン (例;BoneTransforms2GL) を押します。
    Pointcloud 名 と おのおののIndex番号を指定してあげます (例;ココでは1つなので 0 )。



    これでどんなにたくさんあっても、コマ抜きが 2コマ でも 3コマ でも自由にアニメーションをつけて
    設定した数のコマ抜き動きなってくれます。

    では、この方法で もっと複雑な動きのもので、コマ落ちアニメーションが出来るのか実践してみましょう。

ICE実践1
 キャタピラ
     戦車のキャラピラのICE版です。この動きを 2コマ落ちのアニメーション にしてみます。
    キャラピラの車輪の動き(回転と移動)からしてキーフレームアニメーションではなく、すべてICEで制御された動きです。
    唯一あるのは、矢印型のカーブが、ココからココへこの方向で行け、というのが Fcurveです。



     えらいこっちゃー のように見える 2つのICE、下のは回転と31個のキャタピラの動き計算、上のは計算された位置データをArray化しています。
    やったことは 上述の 考察2の値の代入 だけです。位置のデータを何コマ毎に更新するか、だけです。


    これさえ理解できれば、複雑なロボットの動きも、モーションキャプチャーの人体アニメーションも、すべてコマ落ちアニメーションに出来ます。



ICE考察4
 パーティクル;キャッシュ
     では、今度はパーティクルのようにICEのSimulationで発生するような動きも コマ抜けアニメが出来るのか実験してみます。
    まずは、無難にキャッシュしたものを考えてみました。
    するとどうでしょう、意外にも簡単にできます。



     通常発生するパーティクルは、キャッシュすると ミキサオペレータ に AnimationMixer として配置されます。
    そのデータを読むノードは CacheOnFileTake1 というノードになり、file Mode が Read Cache になってます。



    そのノードに入力する Frame 数が 値の代入 self.KomaFrame につなげて、
    受け取ったフレーム数のCacheだけを表示する ってなってます。
    ここでは 参考として Modulo が  なので、6 12 18 ・・・フレームの結果が表示されていきます。

ICE考察5
 パーティクル;シミュレーション
     では、今度はパーティクルでキャッシュしてない、シミュレーションのものはどう扱えるのか考察してみます。



     これは、そんな感じになった程度なんですが、SimulationRoot につながる Execute や Simulation に
    Moduloから来る値が = O で True の時だけ実行する ってしてみた結果です。
    この方法は 次の = O が来るまで実行しない、というものなので、フレーム数は伸びる感じになります。
    コマを抜いたのとは違う感じはするのですが、動かないフレームを用意できる方法として紹介しておきます。





     という訳で、どこか参考になるところありましたら幸いです。
    まだまだ ICE が続きますかね。

      乞う、ご期待!!