_581x100.png CGsyomei_583x102.gif 訪問者 無料カウンター ページビュー 無料カウンター

2011年12月18日

(TP Basic) ダイナミックセットツリー内のオペレーターの順序の重要性

 今回はTPのセッティングをする際に非常に重要な、ダイナミックセットツリー内のオペレーターの順序について説明します。これは以前掲載した「(TP Basic) Memory Operatorの基本」の記事で、同じように設定したのにうまくTeapotが発生してくれないという人が何人かいたので恐らくこうであろうという理由とそのロジックを説明しておきたいと思います。

 それでは以前のシーンの設定をもう一度見てみたいと思います。born_bulletダイナミクスは単に弾を発射する為のものなのでここは殆ど関係ないです。問題は次のborn_Teapotにあります。今回は理解しやすくする為にいくつかオペレーターを削除してより簡素にしています。最初の着弾の位置もやや変えています。この状態で結果を見てみると、自分の元のデータでは以下の図のように問題なくTeapotが発生しています。

DynamicsTreeOrderBasic_PDNext.jpg

ではほんの少しだけセッティングを変更してみます。ノードの構成は全く一緒です。今度はTeapotが発生していませんね。

DynamicsTreeOrderBasic_PDFirst.jpg

 では違いがどこにあるのかというと、それはダイナミクスツリー内のオペレーターの順序にあります。自分が変更を加えたborn_TeapotダイナミクスツリーではPosition Born_Teapotの上にParticle Dieが来ています。実はこれが原因なんですね。

 何故これがうまく機能しない原因なのかを説明したいと思います。まずTPの計算の順序はダイナミクスツリーの上から下へという順序でオペレーターの計算がされています。上から下まで1フレーム内(SubSamplingが細かければ1フレの間に数回繰り返します。)の処理をし終わると再び一番上のダイナミクスから計算を始めまた下に下りていくという繰り返しになります。

DynamicsTreeOrderBasic_Order.jpg


 では実際にはどう計算が処理されているのでしょうか。処理の流れを確認する為にはやはりDebugをしてみるのが一番です。自分のborn_Teapotダイナミクスのセッティングで、着弾してTeapotが発生した瞬間の処理を追ってみたいと思います。

 が、Debugの結果の意味を説明する前に少しだけパーティクルグループノードについて説明しておかないといけないことがあります。それは、このノードは単にパーティクルにオペレーターを適用させる指示を出すものだけではなく、それ自体がパーティクルの持つAge,Velocity,size,mass,などなどのパーティクルが持ちうる全ての情報を詰め込んだバッグのようなものだということです。TP4から以下の図のようにパーティクルグループノードのParticleアウトプットから直にパーティクルが持つ各パラメーターの情報を取り出すことができるようになっています。まずこういうオペレーションができるという前提を知っておいてください。

DynamicsTreeOrderBasic_Memory.jpg


 さてそれではDebugの検証に戻ります。データの流れに直接関わっているインプット、アウトプットをデバッグ可能な状態にします。Nodeヘルパーは今回無視して構いません。結果は以下の図のようになります。Debugウインドウ内の枠で囲っている部分が着弾したときの各ノードの処理の経過を表しています。

DynamicsTreeOrderBasic_ResultOk.jpg

 さらに、ダイナミクスツリーは上から下の方向に計算をしていくという前提を踏まえ、これを細かく見ていきます。今回は各ノードの計算の順序はbulletパーティクルグループ、Udeflectorノード、PositionBorn_Teapotノード、Particle Dieノード、Geom Instanceノードの順になっています。まずは赤い囲みの部分を見てみます。最初にbulletグループノードが最初のパーティクルのIDを用意しています。particle=0とはパーティクルが無いという意味ではなくIDのナンバーが0のパーティクルだという意味です。次にUdeflectorのParticleインプットがID0のパーティクルを認識します。認識したらCollisionがOnになったという意味のBool値の1の値をアウトプットします。その1の値を受けて、PositionBorn_TeapotのOnインプットにOnの命令が出されます。注意したいのは、この時点ではまだPositionBorn_Teapotはパーティクルを発生させてないということですね。ここで一旦処理は終了し、別の流れへと移ります。

DynamicsTreeOrderBasic_ResultOkRed.jpg

 次は緑の囲みの部分です。ここでもbulletグループノードがID0のパーティクルを用意するところから始まります。次にPositionBorn_TeapotのPositionインプットがbulletパーティクルグループからダイレクトにPosition情報を受け取っています。パーティクルグループノードは全てのパーティクルの情報を入れ込んだバッグで、それを取り出しているという感覚がわかるでしょうか?そしてこの時点で初めて、先ほどのUdeflectorの処理でOnになったことでIDが1のパーティクルが発生し、Born Particleアウトプットに用意されます。で、次にちょっと面白いのが、そのID1のパーティクルが、ツリーの並びでは一番下のGeom InstanceのParticleインプットにこの時点で命令を出しているということです。一続きのノードの並びであれば処理が優先されるということみたいです。この時点でTeapotオブジェクトが発生していることになります。

DynamicsTreeOrderBasic_ResultOkGreen.jpg

 次に紫の囲みの部分の処理を見てみます。UdeflectorがParticle Dieに命令を送る部分ですが、以前にbulletパーティクルを受け取っているという処理は省かれているようです。ここではCollisionのBool値の1がParticle DieのOnインプットに送られています。

DynamicsTreeOrderBasic_ResultOkPurple.jpg



 そして最後に青の囲みの部分です。bulletパーティクルのID0のパーティクルが用意されたらParticle DieのParticleインプットに送られ、結果bulletパーティクルは消えるということになります。以上がTeapotがきちんと発生する場合の処理の流れです。

 DynamicsTreeOrderBasic_ResultOkBlue.jpg

 ではParticle DieがPositionBorn_Teapotの上に来ている場合をみて見ましょう。分かりやすくするためにノードの見た目の並びも変えてみました。結果は以下のようになります。

DynamicsTreeOrderBasic_ResultNo.jpg

 ではまた同じく各データの流れを分けて検証していきます。まずは赤い囲みの部分からです。ここは前回と殆ど同じです。違いはCollisionのOnの命令がParticle DieのOnに行っていることです。

DynamicsTreeOrderBasic_ResultNoRed.jpg

 次は緑の囲みの部分です。ID0のbulletパーティクルがParticle Dieに渡されます。この時点でParticle DieはOnになっているのでID0のbulletパーティクルは消滅するということに注意してください。

DynamicsTreeOrderBasic_ResultNoGreen.jpg

 次に紫の囲みの部分です。UdeflectorがPositionBorn_TeapotのOnにBool値の1を送っています。しかしこの時点ではID1のパーティクルは発生していません。

DynamicsTreeOrderBasic_ResultNoPurple.jpg

 次に青の囲みを見ると、ID0のパーティクルが一旦用意されようとしていますが、もう緑の囲みの部分でパーティクルが消えていることになっているので消えたパーティクルからPosition情報を取り出せないことになります。よってPositionBorn_TeapotのPositionインプットにはbulletパーティクルのPositionが渡せない為にこのダイナミクスツリー内のロジックが破綻していることになります。これが原因でTeapotのインスタンスオブジェクトが発生しないんですね。このように、PositionBornノードでパーティクルが発生する為の条件はOnになっていることと発生するパーティクルのPositionが確定していることであるということが分かります。

DynamicsTreeOrderBasic_ResultNoBlue.jpg

 とは言えPositionBornのオペレーターをデフォルトの状態で出した時はシーンの原点からパーティクルが発生するんですよね^^;多分ですが、Position情報を送るノードの構成になっているにも関わらず情報が送られない場合はロジックが破綻すると自分は認識しています。

 また色々試したところ、Particle Dieが先に来ている状態でも、bulletパーティクルグループからPositionアウトプットを出してそこからPositionBorn_TeapotのPositionに繋いだ場合はパーティクルが消えているにも関わらずきちんとPositionが渡るようです。よってTeapotがきちんと発生しています。これはすでにbulletパーティクルグループのバッグの中からPositionが取り出されている状態なのでパーティクルが消えてもPositionは渡せるということなのかもです。ここは自分の考え方が間違っているかもしれないので、また後日はっきりしたことが分かったら追記します。

DynamicsTreeOrderBasic_ResultOkPos.jpg

 とりあえずかなり長くなってしまいましたが、ダイナミックセットツリー内のオペレーターの順序がいかに大事かが分かって貰えたと思います。きちんとノードを繋げているにも関わらず思ったような結果が出ない場合はまずここを疑ってみましょう。そしてDebugをしてデータの流れを確認してみてください。この癖をつけておけばある程度のミスは自力で洗い出すことが出来るようになります。
posted by けゑ at 11:42| Comment(0) | TrackBack(0) | Thinking Particles
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

この記事へのトラックバックURL
http://blog.sakura.ne.jp/tb/52086022

この記事へのトラックバック