すあまの備忘録

誰得内容の自分のための非営利目的備忘録ブログ(筆者がわかっても内緒にしてください)

RBD Guide Simulation

忙しくて書きかけの記事を放置していたらインディゾーンさんのブログに記事が追加されていました。

Houdini 18.5でのガイドシミュレーション | インディゾーンHoudini情報日本語ブログ

ここは自分への備忘録でやり方も若干違うため記事を投稿します。

hipはこちら(Houdiniは18.5.408)

Houdini18.5からRBD Bullet Solver(SOP)を使用せずにRBD Guide機能が使えるようになりました。

待望の更新なのでかなり嬉しいです。

最初に

この件はインディゾーンさんのブロクにも記載されていますが、Guide Geometryが単一のメッシュの場合、正確に認識できないようです。

nameがなければAsembleでnameを作成しているようなので単一ピースの場合1つのnameしか作成されない〜からの処理の流れでなっていると思います。

f:id:godofsuama:20201220232033p:plain

なのでインディゾーンさんの記事のようにBooleanで複数のピースが作成できるようにするか、分割数の少ないVoronoi等でざっくりピースを割ってあげる必要があります。

RBD用メッシュ

f:id:godofsuama:20201220232508p:plain
使用するRBD用メッシュ

f:id:godofsuama:20201220232533p:plain
簡単なネットワークから作成

あとで使用するためにConstraintも作成しています。

下部をactive==0で壊れないように設定しています。

f:id:godofsuama:20201220232752p:plain

Guide用メッシュ

f:id:godofsuama:20201220232857p:plain
Voronoiで少ないピースに割ったもの

f:id:godofsuama:20201220232937p:plain
同じメッシュからピース数の少ないものを作成

GuideのDeform

f:id:godofsuama:20201220233051g:plain
Bendでねじってみた

RBD Guide Setup

f:id:godofsuama:20201220233537p:plain

第一入力にnameを持たせてPackしたRBD用メッシュを接続します。

第二入力にConstriantを接続します。

第三入力は必要であればProxy Geometryを接続します。(個人的にはほぼ繋がないです)

第四入力にGuide Geometryを接続します。

Setupタブ

f:id:godofsuama:20201220234015p:plain

Start / End Frame : Guideアニメーションの開始終了フレーム。この範囲内でGuideに追従する。適切に設定しておいたほうが良い。

Mode : 追従させるGuide Geometryを探す基準、Near PointはGuideの中心までの距離ベース。Near SurfaceはGuideの面ベース。Volumeはよくわからない。

Max Distance : Guideを探す距離の最大値。この値を超えるとGuideを探さない。-1はこの設定を無視するということなので、どんなに遠くても必ず1つは見つける。

Strength : 距離に応じて強さを乗算する。これはひとつ下のDistance to Strengthと一緒に使う。

Distance to Strength -Distance : 強さを乗算する距離の最大最小値

Distance to Strength -Strength Mutiplier : 最大最小間での乗算する値

Blend : Guideに追従する具合を設定。(各ピースごとに設定したい場合は、Use VEXpressionsで設定する。)

Neighboprsタブ

Guideの精度とエラー回避のものっぽいが効果がよくわからない...

適切に設定すると各Guide Geometryごとに最小の接続数が設定できたりするので、Guide追従しないで動かないor追従しすぎるピースを回避できるらしい。

Constraintタブ

後述に若干追記あります。

Remove Intra-Guide Constrains : チェックを入れると同じGuide Geometry内のConstraintを削除する。

f:id:godofsuama:20201221003423p:plain
例:オフの場合

f:id:godofsuama:20201221003452p:plain
例:オンの場合

Constraint Group : ↑を適応するグループ名

このConstraintはうまく使わないと事故が起きそうだった。

Glue-Softの切り替え設定しているConstraintも削除されてしまうため、下手に設定するとConstraintを一切しないピースになる。

Sim

f:id:godofsuama:20201220235611p:plain
DOP

Pre-SolveとPost-Solveに違う設定の「RBD Guide」ノードを接続する。

Pre-Solveのほうは、Guideタブを使用し、Un-Guideはオフにして使用しない。

Post-Solveのほうは、Guideタブはオフにして使用せず、Un-Guideはオンで使用する。

どちらもInputタブはGuide SourceにGuide Geometry(RBD Guide Setupの第四出力)を指定し、Post-Solveの方はGeometry SouceにRBD用メッシュも指定する。

f:id:godofsuama:20201221001154g:plain
Pre-Solveのほう

f:id:godofsuama:20201221001217g:plain
Post-Solveのほう

インディゾーンさんのブログではPre-Solveだけに接続していました。

PreSolveに「RBD Guide」を接続して、Guide,Un-Guide,Inputの全タブを設定してもRBD Guide処理は動作します。

しかし、Exampleのシーンでは、Guideへの追従はVelocity とTarget Velocityに影響を与えるためPre-Solveで行うこと。

Un-Guide処理はPre-Solveでも実行できるが、Post-Solveで実行する方をおすすめする。と書いてあるのでこちらの手法で記事を書いています。

コリジョン等の処理(Solverが行う)を挟んでからガイドへの追従を切るほうが結果が良いという感じです。

ちなみに、コリジョンなどの処理をしていない場合はPreのみ、PrePost両方に分けるのどちらでもほぼ結果は変わりません。

Simがもし動かない場合

原因がよくわかってないですが、さっきまで動いていたのに突如動かない場合やそもそも動かない場合があります。

自分の場合はGuide Geometryにrestを作成すると回避できました。

f:id:godofsuama:20201221022745p:plain
rest

timeshiftを使用しRBD Guide SetupのStartframeで止め、restを作成し、

Attribute CopyのMatch by Attributeでnameを使用しnameごとにrestを作成します。

RBD Guideの変更箇所

詳しくはヘルプを見よう。

Guiding

Method : Target Velocityに設定。Velocityのほうが正確だがコリジョンした際にジッターが出る可能性があるらしい。

Blend : Guideへの追従具合。下げるとジッターが減るらしい。1の完全追従だと後述のGuideが動く前にずれる問題が回避はできる。

Un-Guiding

Instantaneousは即時(そのフレームの話)

Accumulatedは累積(過去の量)

Linear : Threshold : 各ピースの計算後のガイドとの位置の差

Angular Threshold : 各ピースの計算後のガイドとの角度の差

Distance Threshold : 各ピースのガイドへの距離と静止時の距離の差

Sim -Constraintの追加

f:id:godofsuama:20201221004411p:plain f:id:godofsuama:20201221003753p:plain

ConstraintにGlue-Softの切り替えを設定し、DOP内でConstrfaintを使用した状態で、「RBD Guide Setup」のConstraintタブ、Remove Intra-Guide Constraintsがオフだと

ピースは一切動きません。Constraint Geometryを見てみると、Glueの解除ができていないようです。

Remove Intra-Guide Constraintsをオンにしてみます。

f:id:godofsuama:20201221015128g:plain

うまくいっているように見えますが、後一歩調整したいです。

Wire frame表示をやめるとわかりやすいです。

f:id:godofsuama:20201221021538g:plain

ピース間のConstraintがない部分で自己衝突が発生してGlueが全てSoftになってしまってしまい、Guideに追従する前から動いてしまっています。

f:id:godofsuama:20201221021723p:plain
Guide追従前に動いている

これはRBD Guide SetupのConstraintを削除するグループを指定しても回避は難しいですし、

そもそもの話、Guide Simulationしている時点でConstraintを使う意味があるのか?という問題もあります。

それでも併用したい場合もありますし、RBD Guide(DOP)のGuidingにあるBlendパラメーターを下げると同じように事前に動いてしまうため

Blendを1から下げることができない=完全にGuideに追従しかない。という状況です。

ついでにいうと全てSoftになってしまうと計算が重いです。

回避を考えてみたので一例としてのせます。

Constraintエラーの回避

restが必要なので、Simがもし動かない場合、のセットアップを済ませてください。

RBD Guide SetupのConstraintsにAtribute Copyを作成し、画像のようにつなぎます。

Copy Attributes fromがGeometryで、Copy Attributes toがConstraint Geometryです。

f:id:godofsuama:20201221023017p:plain

f:id:godofsuama:20201221023104p:plain

DOP内でSOP Solverを作成し、Constraint Networkにつなぎます。

f:id:godofsuama:20201221023140p:plain

SOP Solver内で以下のように組みます。

f:id:godofsuama:20201221023415p:plain

Object MergeでGuide GeoemtryをSOPから読み込み、

check_moveに以下のように記述し、restPが違うかどうかをチェックします。Vectorなので精度が心配ですがまあいいでしょう。

//run over Points
i@move = 0;
if(@P != @rest) {
    i@move = 1;
}

check_guideNameに以下のように記述します。__guide_nameがあるかどうかをチェックし、なければnameを使用します。

//run over Points
int check = findattribval(0, "point", "__guide_name",0);

if(check == -1) {
    s@__guide_name = point(0,"name",@ptnum);
}

copy_moveは以下の設定です。

f:id:godofsuama:20201221024056p:plain

broke_glueは以下です。各Constraint Geometryで動いたかどうかをチェックし、

動いた場合に__guide_nameが異なれば違うGuideを参照しているのでGlueを削除(Remove Intra-Guide Constraintsをオンと同じ)

それ以外の動いた部分はSoft(Next Constraint)に変更という処理です。Next Constraintが設定されていない場合の回避処理は入れてません。

//run over Primitives
if(s@constraint_name == "Glue") {
    int pts[] = primpoints(0, @primnum);
    
    string name1 = point(0, "__guide_name", pts[0]);
    string name2 = point(0, "__guide_name", pts[1]);
    
    int move1 = point(0, "move", pts[0]);
    int move2 = point(0, "move", pts[1]);
    
    if(move1 + move2 == 2) {
        if(name1 != name2) {
            i@group_broken = 1;
        }else{
            i@group_soft = 1;
            s@constraint_name = s@next_constraint_name;
            s@constraint_type = s@next_constraint_type;
        }
    }
}

broke_softは以下ですが、Soft Constraintを切る条件なので好きに設定する部分です。グループの指定だけは忘れないようにします。

f:id:godofsuama:20201221024934p:plain

//run over Primitives
if(@force >= 70) {
    i@group_broken = 1;
}

これでコリジョンや自分でGlueを削除しない限りはGuideが動くまではGlueが切れないため動かないように設定できます。

f:id:godofsuama:20201221025450g:plain