2016年12月12日月曜日

触ったものから動きだすキッカケを作る2つの方法。

この記事はHoudiniアドベントカレンダーの記事です。

全体の仕組みは、グリッドにコピーされたオブジェクトが別ジオメトリによって触れられた順に動きだすというものです。
判定にはグリッドのポイントを使います。そのデータをコピーされるAという形のアニメーションに反映する事でタイミングをずらすことができます。

基本的にsopは現在のフレームのみの計算なので、過去の値を記憶したり積分したりするにはsolver sopやchop、pop、dopを使う必要があります。
ここではsolver sop と chopを使った2つの方法を解説します。

hipファイルはこちらです。

まずは左側のsolver sopを使用する方法からです。

では、触わる為のVolumeジオメトリを用意します。なぜVolumeにデータにしているのかというとGroup sop などでも別オブジェクトでグループ指定できますが、精度が怪しい為確実に判定ができる様Volumeデータにしています。
これはSphereを単にvdb from volumeでタイプをFog VDBにするだけです。

transformでアニメーションを適当につけます。

Grid にpoint wrangleを繋いで2番目のインプットにこのボリュームを指します。

i@in= volumesample(1,0,@P)>0; 
i@in_frame = 0;

##volume sampleでグリッドのポイントがボリュームの中にあるのか外にあるのか判定できます。volume sampleは参照しているポイントのポジションがボリューム中にあるならプラスの値を、外にあるならマイナスの値を返します。

##もう一つこの先使用するボリュームに入った瞬間のフレーム番号を記憶させる為のin_frameというアトリビュートを作っておきます。

次にsolver sopを作ります。中のネットワークはこんな感じです。

point wrangle の式はこのような感じで
if (i@in == 1 && @in_frame== 0)
{
    i@in_frame = @Frame;
}
i@in = max(@in, @opinput1_in);
 
##ボリュームの中にあり(@in==1) かつ、まだ触れられていなければ(@in_frame==0)in_frameに現在のフレーム番号を渡します。これで入った瞬間のフレーム番号が記憶できました。
## 現在と過去を比べて常に大きい値がinに入る様にする事で、過去から現在に渡って触れられたポイントを記憶する事ができます。

solver sopを抜けて上の階層に戻りtime shiftで使用する為の shiftというアトリビュートを作point wrangleで作ります。
if (@in_frame != 0) i@shift = max(0,@Frame - @in_frame);

触れられたフレーム番号(@in_frame)を現在のフレーム番号(@Frame)から引き算する事で
ボリュームに入った瞬間からアニメーションするアトリビュートが出来ます。マイナス値は不要なのでmaxで0以上の値を取得する様にします。
ボリュームに入ったポイントのみにアトリビュートを作りたいので @in_frame != 0 としてフィルタリングしておきます。

22f目の状態のspread sheetです。shiftアトリビュートがin_frame分ずれたフレーム番号になっているのが確認できます。

これで下地が完成です。

あとはアニメーションしたAという形のオブジェクトをcopy sopします。
(Aの形をしたオブジェクトにはくねくね動いて徐々に収まる70fくらいのbendのアニメーションがついています。)

stampにチェックを入れ Attribute Stampsに先ほど作ったshift アトリビュートをいれます。
Aのオブジェクトにtime shiftを繋ぎstampでshift アトリビュートを参照します。
stamp("../copy1","shift",0)

これで一つ目の方法は完成です。

-----------------------------------------------------------------------------------------------------------------------

次にchopを使用するやり方です。


solver sop以前は同様で今度はinアトリビュートをchopで引っ張ります。
chopの中身はこんな感じです。


geometry chopはジオメトリのpoint アトリビュートをインポートする事ができます。
in アトリビュートを持ってきて、methodをAnimatedにする事で全フレームの値を参照できる様になります。


見やすいように1つのポイントのグラフのみ表示しています。

次にtrigger chop。デフォルトでTrigger Threshold が0になっているので値が0以上になったときにtriggerのアクションを入れることができます。AttackタブでAttack Length を0
Peak Lengthをにシーンの最終フレーム番号を入れることで値が0以上になった以降最後まで常に1になるグラフが出来ました。


全てのポイントのグラフを表示するとこんな感じです。


これにリニアにアニメーションするFrame番号のチャンネルをコピーする事で以下の様になります。


これでchopでの下地が出来ました。
先ほどはshiftというアトリビュートを作りましたが、今回はchopでinアトリビュートを
直に編集したのでstampではinアトリビュートを参照して終了です。
stamp("../copy2","in",0)

今回の何かをきっかけに何かが始まるというのは、様々な場面で使え応用がききます。
自分はsopが好きなのでsolver sopの方をよく使用しますが、グラフで視覚的に把握したい場合はchopが分かり易いかと思います。


他にも記事を投稿できたらと思ったのですが、ちょうど来月号のCGWORLDにHoudini Tipsの記事を3つ書いたところだったのでネタがちょっと思い浮かびませんでした。
そちらは他のソフトでは苦労するような表現をHoudiniならシンプルな方法で解決できる方法を紹介しています。別ソフトから移行を考えている方に是非読んでいただけたらと嬉しいです。

ではでは。