このチュートリアルは、「【初心者向けHoudiniトライアル006】Houdiniでガラスっぽく分割してみよう」の続きです。
使用するHoudiniバージョン
Houdini 18.0.460
とりあえずシミュレーションを追加してみよう
前回までの結果により1枚の板を分割することができました。
ここにシミュレーションを追加してみましょう。
今回はRBD Bullet SolverというSOPノードを使用します。そのため、Coreのライセンスでも粉砕シミュレーションを実行することが可能です!
- RBD Exploaded Viewは必要ないため削除します。
- RBD Bullet Solverを追加します。
RBD Bullet Solver SOPは、Bulletシミュレーションの実行を簡素化したDOPネットワークのラッパーです。 RBD Bullet Solver内にはいるとdopnetというネットワークが用意されていることがわかります。
DOPネットワークには、オブジェクトやフォースを作成したり読み込むためのダイナミクスノード(DOPs)を格納し、そこで接続を構築し、その相互作用をシミュレーションするためのソルバを設定します。
つまり、RBD Bullet Solverには粉砕シミュレーションを行うための必要な設定が一通りそろっており、SOP内でシミュレーションを行い、その結果、そのままSOPで使用することができます。
前回作成したRBD Material Fractureノードからは3つの情報を出力することができます。
1番目の出力はレンダージオメトリです。
2番目の出力はコンストレインジオメトリで、シミュレーションする破片間のダイナミックコンストレインを具現化するために使用します。コンストレインジオメトリは、RBD Material Fracture SOPを使ってジオメトリを粉砕させた時に作成されています。
3番目の出力はプロキシジオメトリで、レンダージオメトリを簡略化したジオメトリです。 プロキシジオメトリは、シミュレーションを高速化するのに非常に適しています。 ジオメトリがシミュレーションジオメトリとして使用されます。
Nullを作成し、1番目の出力と接続します。
ビューポートを確認するとレンダージオメトリが表示されます。特に今まで変わったところはありません。
2番目の出力とNullを接続します。
ビューポートを確認すると、ジオメトリではなくカーブような状態で表示されます。
右の出力とNullを接続します。
ビューポートを確認すると実際のジオメトリより簡素化されたプロキシが表示されます。シミュレーションにはこちらの出力ジオメトリを使用します。
この3つの出力を先ほど作成したRBD Bullet Solverに接続していきます。 - RBD Bullet Solverには5つの入力があります。ここでは今回使用する1-3番目の入力のみ説明します。
1番目の入力はレンダージオメトリです。この入力には赤い三角アイコンがついています。このアイコンがついている場合、ノードの計算に必須の入力となります。
2番目の入力はコンストレインジオメトリで、その上のRBD Material Fracture SOPを使ってジオメトリを粉砕させた時に作成されたものを使用します。
3番目の入力はプロキシジオメトリで、レンダージオメトリを簡略化したジオメトリです。 プロキシジオメトリは、シミュレーションを高速化するのに非常に適しています。 ここに接続したジオメトリがシミュレーションジオメトリとして使用されます。
RBD Material Fractureから出力されたレンダージオメトリ、コンストレインジオメトリ、プロキシジオメトリをRBD Bullet Solverに接続します。 - アニメーションを再生します。
ジオメトリ全体が下に落ちていくようになります。
これは、RBD Bullet SolverのForcesにてGravityがマイナス方向に設定されているからです。 - このままだと下に落ち続けてしまうため地面を追加します。
RBD Bullet SolverのGloundタブにて、Add Ground PlaneをGround Planeに設定します。
Ground Positionが地面の配置場所となるため、-1に設定します。
※一番最初のBoxをScale=2で作成しているため
ビューポートを確認するとBoxの下にGround Planeが設定されました。 -
アニメーションを再生しても落下することはなくなりました。
しかしこのままではガラスが粉砕シミュレーションになりません。
ガラスが割れる外的要因を追加
ガラスを割るために外的要因を追加していきます。シミュレーションジオメトリとして使用されのは3番目の入力であるプロキシジオメトリです。ここにガラスにぶつかる外的要因とガラスを設定していきます。
- RBD Bullet SolverのSolverタブ>CollisionsタブにてUse Collisionsをオフにします。
これは衝突用のジオメトリを生成するものになりますが、今回は使用しません。 - 外的要因をSphereで作成します。
- SphereにDisplayフラグを設定し、RBD Material FractureをTemplate表示にします。
- Sphereのパラメータを調整し下記のように設定します。
このSphereがDOP内でガラスに衝突しガラスが砕けます。 - このSphereをRBD Bullet Solverに持ち込む設定を追加していきます。
RBD Bullet Solverをダブルクリックしてネットワークに入ります。
dopnet内のforcesまで潜ってしまうのでdopnetをクリックして、ネットワークを上がります。
dopnetに入ると現在ガラスのプロキシジオメトリのみ存在することがわかります。
このdopnetにSphereをもってきます。 - Sphereのあるネットワークに戻り、Sphereの下にAssembleを追加します。
- Create Name Attributeをオフに設定し、Create Packed Geometryをオンにします。
Output prefixにcolliderと入力します。
Assembleノードを使い、SphereをPackオブジェクトに変更します。
Created Packed Geometryは、入力ジオメトリを受け取り、それを組み込みパックプリミティブにパック化します。
Packed Primitives(パックプリミティブ)は、 レンダリング時 にジオメトリを生成する手順です。パックプリミティブの内部には、ジオメトリに関する情報が埋め込まれて、必要な時にだけ情報を読み込むことで、Houdiniでのインタラクティブ操作時のメモリ使用量を減らすことができます。
この情報とは、メモリ内に格納されている実際のジオメトリ、他のジオメトリの一部の参照、ディスク上に保存されたジオメトリのファイルパスのことです。
Mantra, Houdiniビューポート, ソルバなどは、そのパックされた情報を解析する方法を知っており、効率的にジオメトリをレンダリング/表示/処理することができます。
ジオメトリをパックプリミティブに変換することで、 メモリ内 のパックプリミティブが得られます。 これは、メモリ内に、あなたの現在のバージョンのジオメトリの埋め込み参照を持ったPacked Geometry Primitiveを作成します。 "埋め込まれた"ジオメトリは、1個のトランスフォームを持った1個の編集不可な"プリミティブ"になります。
パックプリミティブは編集不可な、とても軽いリファレンスです。ジオメトリネットワークのメモリ内のパックプリミティブそれぞれのコピーを"アンパック"することで、参照されているジオメトリの実際のコピーを作成することができます。
Assebleにてパックジオメトリにした時点で、Sphereは単一のポイントデータとなります。
出力ジオメトリが組み込みパックプリミティブにパックされ、そして Output Prefix を使って、namePointアトリビュートを作成します。
Geometry Spreadsheetを確認するとPointsアトリビュートにnameが追加されていることがわかります。
- 次にRBD Configureにパックジオメトリ化したSphereを接続します。
RBD Configure ノードは、リジッドボディシミュレーションを行うために必要なプロパティをセットアップすることができます。 - RBD Configure のプロパティでBounding Type(境界ボリュームの形状)をBounding Boxに設定します。
- AttributesのGroupのドロップダウンリストから、作成したcolliderを設定します。
- Physical AttributesにてTypeをMetal、Ironに設定しました。
Typeではマテリアルベースの密度、跳ね返り係数、摩擦係数のプリセットを事前定義されたマテリアルタイプから選択します。
Typeを変更するとPointsアトリビュートに設定された摩擦係数や密度の値がかわります。 - 次にPointsアトリビュートとしてv(Velocity)アトリビュートを追加します。
SOPでアトリビュートを作成し、それをDOPに持ち込んで使用することができます。
Attribute Wrangleを追加します。
追加したAttribute Wrangleに下記のように設定します。
Wrangle ノードは、VEX を簡易なエクスプレッションで記述するためのノードです。VEX とは Vector EXpression の略で、 SIMD (Single Instruction Multiple Data) の一種でマルチスレッドで効率よく演算を行うことが出来るスクリプト言語です。実際にはランタイムでコンパイルされて実行されます。
Run OverはPointsに設定します。
VEXpressionには
v@v = {0, 0, -8};
と入力します。
VEXでは、@attribute_nameを使ってアトリビュートの値を読み/書きすることができます。@の前にデータタイプを設定します。Houdiniは、手動で別のタイプを指定しない限りは、他のすべての@参照を float だと想定します。 手動でアトリビュートのVEXデータタイプを指定するには、@記号の前にデータタイプを意味した文字を追加します。
今回はv@vとしたので、Vector型のvという名前のアトリビュートを設定します。
ノードのタイプによって、存在していれば(いくつかの場合では、そのアトリビュートが存在している必要がある)使用される特定のアトリビュートがあります。例えばPはポイントの位置をあらわすアトリビュート名です。そのほかにもNは法線になり、nameは、ボリュームやパックプリミティブなどのプリミティブを名前によってコードから検索できるようにするアトリビュートです。
同様にvは、Velocity(速度ベクトル)として使用されてるアトリビュートです。速度ベクトルですので、3つの値で定義しました。
これでSphereは-Z方向へと働く力が追加されました。
Geometry Spread Sheetを確認し、vが追加されていることを確認します。
- ここまででSphereをガラスに衝突させるための必要な設定を持たせることができました。ネットワークを認識しやすくするためにNullを追加し、区切りをつけます。
- このNullをRBD Bullet Solverの3番目の入力に接続します。
- RBD Bullet Solver内のDOPではどのように見えるか確認してみます。
RBD Bullet Solverのdopnetに入ります。
この時点で3番目の入力には、RBD Material Fractureからの入力がなく、Sphereからの入力となっているため、ビューポートにもSphereとグランドオブジェクトしか存在しません。
このSphereには速度ベクトル vアトリビュートを追加していたため、dopnetで再生するとSphereが -z 方向に移動することがわかります。
このままではSphereが衝突するべきガラスオブジェクトがありません。次のステップではガラスオブジェクトにdopnetに入力するための設定を追加しましょう。
ガラスにもシミュレーションの設定を追加
前のステップでdopnetにはSphereの入力しかありませんでした。そこで、ガラスオブジェクトのプロキシデータも一緒にdopnetに入力されるようにしましょう。
- Assembleを作成しRBD Material Fractureの3番目の出力を接続します。
- Aassembleにて以下のオプションを設定します。
ここでTransfer Groupsに*(アスタリスク)を入力しています。というのも、RBD Material Fractureを実行したときに各プリミティブが所属していた場所に従って、様々はプリミティブグループができていました。
例えばchipsグループなど割った際にどのような場所なのかを特定できるグループになっています。Assembleでパックプリミティブに際にそのままだとグループが削除されてしまうため、Transfer Groupに*を入力し、全てのグループを保持します。
- 現在グループはPrimiticesに設定されていますのでこれをPointsグループに変換します。
Group Promoteを追加します。
下記のようにプロパティを設定します。
Primitivesグループを全てPointsに変換しつつ、Primitivesグループも保持します。
現在、パックプリミティブなのでPointsになっているためPointsグループに変換しました。
Geometry Spread Sheetを確認します。
各ポイントがグループに所属しているか0か1の値で設定されています。
0はオフで、1はオンです。
ガラスと外的要因をまとめてRBD Bullet Solverに接続
- これでガラス側の準備もできました。
Sphereと情報を統合し、RBD Bullet Solverにわたします。
Mergeノードを追加し、NullとGroup Promoteを接続します。
- 最後にこのMergeノードをRBD Bullet Solverに接続します。
この状態で、RBD Bullet Solverのdopnetに入ると
Sphereとガラスが両方とも読み込まれています。 - 再生し、Sphereがガラスに衝突するか確認します。
RBD Bullet Solverのプロパティを調整
シミュレーションを再生するとタイムスライダが青くなります。
この青い部分はメモリにキャッシュされているので、マウスでドラッグすることができます。
- マウスをドラッグしガラスと衝突する場所を確認します。
すこしSphereが下に衝突してしまいました。
その場合、Sphereを少しガラスに近づけたり、上に移動したりして調整してください。
- RBD Bullet Solverを選択します。
Collision Paddingを0にします。
これは衝突形状を検出する距離で数値分ジオメトリを膨張します。
ここでは0に設定します。
- 次にForceを追加します。
Add Dragをオンにします。
Dragは加わる力に抵抗する力です。
Air Resistanceを0.002に設定します。
- Add Drag Spinも有効にします。
これは、スピンに対する抵抗する力です。
再生して確認します。
ここまでの設定でSphereが衝突し、破片を少し飛ばしてガラス全体が吹っ飛びます。
しかし、破片同士の結びつく力が強いので破片が思ったほど散らばりません。
- RBD Bullet SolverのConstrainsタブにて、Strengthを0.01に設定します。
- RBD Bullet Solverの中に入り、アニメーションを再生すると破片同士を拘束する力が弱くなったので、破片が細かく粉砕されます。
これでガラスに外的要因がくくわり、ガラスを下すことができました。しかし、このままではSphereが衝突したことでガラス全体が吹っ飛び、粉々に割れてしまっています。通常ガラスは枠によって固定されており、枠に近いほど割れにくくなります。
【初心者向けHoudiniトライアル008】ガラスの破片の情報を修正するへ続く