SeminarThinkingParticles基礎レベル/対象者:中級/XPressoを少し使える人。Studioルールを使って賢く動かす。4Dに含まれる「パーティクル機能」の一つです。「パーティクル」というのは「粒子」という意味ですが、ここではもう少し広く「多数のオブジェクトを効率よく動かす方法」としておきます。4Dにおけるパーティクル機能の歴史をよく理解しておく必要があります。R4以前パーティクル機能はなく、多数のオブジェクトを効率よく動かすことはできませんでした。R5XLで標準のパーティクル機能が導入され、多数のオブジェクトを効率よく動かせるようになりました。複雑なことはできませんでした。標準パーティクルの機能はR11.5まで進化せず、現在でもあまり複雑なことはできません。R6〜R7COFFEEエクスプレッションが導入され、テキストベースでプログラムを書けばかなり複雑なことができるようになりました。現在でも複雑な表現にはXPressoの中に入っているCOFFEEノードを使います。標準のパーティクルにはCOFFEEと連動するための機能がなく、多数のオブジェクトを動かすために必要な機能を全てプログラムする必要がありました。そのため、作るのが非常に大変でした。R8〜R9XPressoとThinkingParticles(XLとStudio)が導入されました。XPressoはノードベースのプログラム環境で、COFFEEノードを使うとテキストベースのプログラムを混在させることもできます。ThinkingParticlesはXPressoの中でパーティクルを作るための拡張モジュール(拡張ライブラリ)です。R10〜R12多数のオブジェクトを効率よく動かすもう一つの機能として「MoGraph」が導入されました。MoGraphには二つの側面があります。一つは、初心者向けに「プログラムを書かずにXPressoとThinkingParticlesの機能を実現する」こと。一つは、上級者向けに「XPressoとThinkingParticlesの機能をさらに拡張すること」です。MoGraphは、一見初心者向けの機能に見えますが、至る所でXPressoやThinkingParticlesと連動するようにできています。MoGraphをThinkingParticlesに続く「第二の拡張モジュール」と考えることで、これまでのXPressoやThinkingParticlesを超える表現が可能になります。MoGraphが導入されたことにより、R12からThinkingParticlesはStudioだけに限定された機能になりました。R12で最も効率のいい方法は、「MoGraphで可能な表現はMoGraphで行い、MoGraphを超える表現についてはXPressoやThinkingParticlesを使う」ということになります。したがって、もしあなたがMoGraphに慣れていないのであれば、ThinkingParticlesを勉強する前に、まずMoGraphを勉強することをお勧めします。2ThinkingParticlesを作るThinkingParticlesは非常に強力な機能ですが、「難しい部分は各ユーザが勝手に作る」という構造になっているので、憶えることはそんなにありません。C言語を書いた経験があり、高校程度の数学と物理を理解している人であれば、1日で使えるようになります。4DやThinkingParticlesの機能に関係なく、「ユーザのアイディアとプログラミング能力次第」というわけです。それでは、早速ThinkingParticlesを作ってみましょう。ThinkingParticles(これ以降はTPと省略します)は、XPressoの拡張ライブラリですから、まずXPressoを作る必要があります。TPジェネレータ」からTPを生成するノードを選択します。ここでは標準のパーティクルに似た「PStorm」を選択します。図901-1これでとりあえずTPが生成されました。再生ボタンを押すとパーティクルが出る様子がわかります。パーティクルを生成するノードについて簡単に説明しておきます。PBlurp指定したオブジェクトに含まれるポリゴンを各々TP化します。別に指定したもう一つのオブジェクトに含まれるポリゴンに各々移動させます。言い換えると、オブジェクトをパーティクル化してモーフします。生成数や寿命はモーフにしたがって決まるので指定できません。特殊なパラメータとして、ポリゴンを断片化する方法や、断片化したポリゴンに厚みを付ける方法などを指定できます。PBornTPを生成します。指定できるパラメータは、「生成数」と「有効期間(寿命)」だけです。TPを生成するための一番簡単な機能で、一番よく使います。PDrawマウスでTPを直接描画します。背景パーティクルを適当に生成する場合などに便利です。生成数や生成フレームは描画時に決まります。その他に「有効期間(寿命)」を指定できます。PFragmentTP化されたオブジェクトに含まれるポリゴンを各々TP化します。パーティクルで飛ばした「石」が壁に当たって割れて「破片」が飛び散る、というような表現に使います。「有効期間(寿命)」と「速さ」を指定できます。特殊なパラメータとして、ポリゴンを断片化する方法や、断片化したポリゴンに厚みを付ける方法などを指定できます。PMatterWaves指定したオブジェクトの表面からTPを生成します。」、「大きさ」、「(オブジェクトから生成位置までの)距離」、「方向」などのパラメータをコントロールできます。PStorm基本的な働きは「PBorn」と同じですが、標準パーティクルの「エミッタ」と同じように、「エミッタの位置(及び、スケールや角度)」、「(TPの)速さ」、「(TPの)大きさ」、「(エミッタの)Fov(噴射範囲)」、「(エミッタの)大きさ」、「(エミッタから生成位置までの)距離」、「(TPの)回転」などのパラメータを最初に指定できます。3TPをグループに入れるTPを使う上で最も重要な概念は「グループ」です。TPに限らず、一般的にパーティクルというのは「ある操作をくり返し実行する機能」ですが、TPでは「パーティクル全体」ではなく、「パーティクルグループ」に対して操作を指定するのです。このグループに含まれるパーティクルは、条件によってどんどん変化していきます。グループを階層化することも可能です。このグループを適切に設定することで、非常に複雑なパーティクルの表現が可能になるのです。標準パーティクルやMoGraphには、このような「ダイナミックな(どんどん変化する)グループ」という発想がありません。この「グループ」が標準パーティクルやMoGraphに対するTPの最大の利点だと言えます。それでは、TPをグループ化してみましょう。設定」で必要なグループを作成しておく必要があります。グループを作成したら、すぐに適切な「名前」と「カラー」を指定しておきましょう。図901-2次に、「PStorm」ノードに「パーティクル生成」ポートを追加し、「PGroup」ノードを接続します。PGroupノードは、パーティクルを指定したグループに入れる働きをします。設定に表示されているグループ(ここでは「init」グループ)をドラッグアンドドロップすると、グループを指定できます。この時、一度でうまくグループを指定できず、元に戻ってしまう場合があります。そのような場合は、再度ドラッグアンドドロップして下さい。次に「PPass」ノードを作成します。PPassノードは、指定したグループからパーティクルを取り出す働きをします。設定に表示されているグループ(ここでは「init」グループ)をドラッグアンドドロップすると、グループを指定できます。次に、「PDeflector」ノードを追加します。PDeflectorノードは「オブジェクトに対する衝突」を表現するノードです。衝突するオブジェクト(ここでは「球体」オブジェクト)は、オブジェクトマネージャからPDeflectorノードにドラッグアンドドロップして指定します。衝突するオブジェクトはポリゴンに限ります。プリミティブやNURBSは衝突判定できません。この点に注意して下さい。これで、パーティクルが球体に衝突するようになりました。図901-3次に、パーティクルが球体に衝突した時にグループが切り替わるようにします。PGroupノードを複製し、「ON」ポートを追加します。ONポートを追加したノードは、ONポートの値が「真(TRUE)」の時(つまりスイッチが入っている時)だけ働くようになります。次に、PDeflectorノードに「イベント」ポートを追加します。イベントポートは、衝突が発生した時だけ「真」の値を出力し、それ以外の時は「偽」を出力します。このイベントポートをPGroupノードのONポートにつなぎます。難しい言葉で書きましたが、要はパーティクルが球体にぶつかった時だけPGroupノードを実行し、「after_collide」グループに移しているわけです。エディターを見ると、球体にぶつかったパーティクルの色が赤から緑に変わり、グループ分けが正しく実行されていることが判ったと思います。図901-4サンプル901aパーティクルをグループから取り出すノードには、PPass以外にも「PPassAB」というノードがあります。PPassABノードには、二つのグループに含まれるパーティクルを全て比較し、指定した距離より近いパーティクルだけを出力する、という機能があります。したがって、PPassABと「PRepulse&Bounce」ノードを組み合わせると、「パーティクル同士の衝突」を簡単に表現できます。4TPにオブジェクトを乗せるそれでは、グループ分けしたパーティクル「after_collide」に対していくつかの処理を追加してみましょう。最初はパーティクルに乗せるオブジェクトを替えてみます。TPでパーティクルにオブジェクトを乗せるには、まず「パーティクルジオメトリ」オブジェクトを追加する必要があります。これは一種の「おまじない」と考えて下さい。次に、立方体を2個作成し、それぞれに違った色のマテリアルを適用します。次に、「PShape」ノードを2個追加し、それぞれに立方体をリンクします。PShapeノードは、パーティクルにオブジェクトを乗せる働きを持っています。「init」をリンクしたPPassノードと、「after_collide」をリンクしたPPassノードにつなぎます。図901-6サンプル901cこれで、パーティクルグループごとに異なった立方体が乗りました。プログラム的には異なったオブジェクトを乗せているわけですが、見た目では「衝突によってパーティクルの色が変わった」ように感じられるはずです。TPではなぜかオブジェクトのサイズが1/10になるので、オリジナルのサイズに合わせたい場合は、PShapeノードの「境界半径」の値を「100」から「10」に変更して下さい。5TPを落とす次に、「PGravity」を使ってafter_collideグループを落としてみます。PGravityは、リンクしたオブジェクトのZ軸方向にオブジェクトを落とす働きを持っています。図901-7サンプル901dこの時、衝突する前のパーティクルグループ(init)はPGravityの影響を全く受けていないことに注意して下さい。PGravityは、「オブジェクト」や「領域(減衰)」や「選択範囲(MoGraph選択範囲)」ではなく、「グループ」に対して働いているのです。6TPを消す最後に、一般的なXPressoノードを使ってグループを切り替える方法について説明します。PGravityによって落下するafter_collideグループのパーティクルの位置が、「-500」よりも低くなったら消滅するように指定してみます。図901-8サンプル901eそのためには、まず「die」というグループを追加します。次に、PGroupとPPassノードを複製し、dieグループをリンクします。次に、「PGetData」ノードを作成します。PGetDataノードは、パーティクルの情報を取り出すためのノードです。実数」ノードにつなぎます。これはベクトルに含まれる「Y」成分だけを取り出すためです。次に、「比較」ノードを作成し、「比較演算子」を「<」に、「入力2」の値を「-500」に指定します。比較ノードの出力をPGroupノードのONポートにつなぎます。難しい言葉で書きましたが、要はパーティクルの位置が「-500」よりも低くなったら、PGroupノードを実行し、「die」グループに移しているわけです。最後に「PDie」ノードを作成します。PDieノードは、パーティクルを消すノードです。PDieノードは他のノードと違っていて、デフォルトでは「消さない」ようになっています。したがって、ただつないだだけでは働きません。ONポートを追加し、ここに明示的に「真(TRUE)」の値を指定する必要があります。そのために「定数」ノードを追加しています。定数ノードの「データタイプ」を「ブール」に切り替え、チェックボックスをチェックすると、値が「真(TRUE)」に切り替わります。TPならではの面倒な仕様ですが、よく間違うので注意して下さい。