チュートリアル - 質量によるパーティクル フローのパーティクルへの影響

チュートリアル > 質量によるパーティクル フローのパーティクルへの影響

パーティクル フローを使用すれば、ユーザは、MAXScript によって生成されるパーティクル チャネルから、特定のフォース関連のオペレータの影響をコントロールできます。この機能はパーティクル ワイヤリングと呼ばれ、パーティクル フロー ユーザ インタフェースにおいて非表示のオプションです。

次のチュートリアルでは、軽いパーティクルは吹き飛ばされるが、重いパーティクルはほとんど影響を受けず動かないでいるという、現実感のある動作が得られるように、各パーティクルの質量を計算し、風のフォースの影響をコントロールする方法について説明します。

全体の流れ - 設定

速度や回転が一切なく位置だけの表面上でパーティクルを生成します。

パーティクルのサイズを変更する Scale オペレータを追加します。

Scale オペレータが生成したパーティクルのサイズを読み込む[スクリプト オペレータ](Script Operator)を追加します。

Force オペレータを追加します。

風スペース ワープを作成し、Force オペレータに追加します。

スクリプト ワイヤリングを有効にします(下記参照)。

Force オペレータで使用する影響値を計算するように、[スクリプト オペレータ](Script Operator)のスクリプトを編集します。

全体の流れ - スクリプト

スケール チャネルとフォース チャネルを有効にします。

パーティクルごとに、スケール値(パーティクルのサイズ)を取得します。

影響値を計算します。

この値をフォース チャネルに割り当てます。

パーティクル ビューの設定

パーティクル ビューの設定には、パーティクルの可変サイズを定める Scale オペレータが備えられています。

スクリプト ワイヤリングを有効にするには、次の手順を行う必要があります。

  • A: フォースの影響の制御に必要なパーティクルの浮動小数点のチャネル値を生成するため、Force オペレータの に、[スクリプト オペレータ](Script Operator)を追加します。

  • B: Force オペレータを右クリックし、[スクリプト ワイヤを使用](Use Script Wiring)オプションのチェックマークを付けます。

  • C: これにより、Force オペレータ内に新しく追加したロールアウトが有効になり、浮動小数点チャネルを通じて影響をコントロールできるようになります。

[スクリプト オペレータ](Script Operator)コード:

on ChannelsUsed pCont do
(
 pCont.useScale = true
 pCont.useFloat = true
)
on Init pCont do ()
on Proceed pCont do
(
 count = pCont.NumParticles()
 for i in 1 to count do
 (
  pCont.particleIndex = i
  pCont.particleFloat = 1.0/(pCont.particleScale^3)
 )
)
on Release pCont do ( )

結果:

ステップごとの解説

on ChannelsUsed pCont do
(

ChannelsUsed ハンドラは、[スクリプト オペレータ](Script Operator)が使用するチャネルを定義します。アクセスする必要のあるプロパティを指定せずに、パーティクル コンテナからパーティクル関連の値を取得したり、設定することはできません。このように、パーティクル フローは、[スクリプト オペレータ](Script Operator)にすべてのチャネルを与える必要はなく(パーティクル フローには任意の数のチャネルが存在します)、実際に必要となるチャネルだけを与えます。これによりメモリが節約されます。

パラメータ pCont には、パーティクル コンテナが含まれます。

pCont.useScale = true

質量を計算するためにパーティクルのサイズを読み取る必要があるので、スケール チャネルにアクセスする必要があります。

pCont.useFloat = true

また、浮動小数点値の格納に使用可能な汎用データ チャネルである浮動小数点チャネルも必要になります。 

 )

on Init pCont do
(

Init ハンドラは[スクリプト オペレータ](Script Operator)の初期化に使用します。通常は、Proceed ハンドラが使用できるように、変数を定義して初期値を取得するか、オブジェクトを作成します。ただし、ここではこのハンドラを使用しません。パラメータ pCont には、パーティクル コンテナが含まれます。

)

on Proceed pCont do
(

[スクリプト オペレータ](Script Operator)がパーティクル フローによって評価されるたびに、Proceed ハンドラが呼び出されます。ハンドラには、スクリプトの実際の本体が含まれています。パラメータ pContには、オペレータの適用先であるすべてのパーティクルを収めたパーティクル コンテナが含まれています。

count = pCont.NumParticles()

次に、パーティクル コンテナ内の現在のパーティクルの数を読み込みます。これに続くループで、パーティクル 1 つずつにアクセスします。変数に値を割り当てる理由は、これに続く for ループ内で、ループのサイクルが終わるごとに to 上限値を評価して、i 変数がこの上限値よりも大きいかどうかを判断するためです。for ループ内部で pCont.NumParticles() メソッド呼び出しを使用しているため、このメソッドは n 回呼び出されます。 ここで n はパーティクルの数になります。ただし、現在のコードを使用した場合、メソッドは 1 度しか呼び出されず、このためスクリプトがより高速に処理されます。

for i in 1 to count do
(

次に、1 からパーティクルの数までカウントする for ループを使用して、これに続くコード ブロックをパーティクルごとに繰り返します。変数 i には、現在のパーティクル インデックスが格納されます。

pCont.particleIndex = i

複数のパーティクルを処理するので、アクセスする現在のパーティクルを指定する必要があります。パーティクル コンテナの .particleIndex プロパティを i 変数に設定することにより、i 番目のパーティクルが現在のパーティクルになります。これ以降のパーティクル プロパティへのアクセス呼び出しはすべて、そのパーティクルに対して行われます。

pCont.particleFloat = 1.0/(pCont.particleScale^3)

これが、パーティクルの質量に反比例した影響値を計算する実際のコード行になります。この計算結果が、現在のパーティクルの particleFloat チャネルに割り当てられます。この計算結果は、particleFloat チャネルから浮動小数点値を受け取れるようにスクリプト ワイヤリングを有効にした Force オペレータからアクセスされます。

この行に関する追加説明

一般に、オブジェクトの質量はその体積と密度によって決まります。このシステムでは、パーティクルすべてが同じマテリアルで作られていると想定しているため、密度は必要になりません。バウンディング球のパーティクルだけを使用しています。この球の体積は、次の式を使用して計算されます。

4/3*Pi*R^3

ここでは R は球の半径です。4、3、および Pi は定数であるため、必要ありません。これらの定数を使用しても、最終的な値が少し大きくなるだけで、計算が遅くなってしまいます。ここで必要な数値は、半径の 3 乗です。体積(および質量)が増加すると、影響は減少します。したがって、R^3 の逆数を計算します。

これはまったく現実的とは言えません。風を使用した場合、風の影響は対象のオブジェクトの断面にも比例します。オブジェクトが小さくなるほど、断面も小さくなり、したがって影響も低くなります。球の断面は円(Pi*R^2)であるので、R^3/R^2 と計算し、さらにこれを R としています(これがここで使用する particleScale です)。

実際に使用すべき行

pCont.particleFloat = 1.0/pCont.particleScale

このような式を使用すると、より現実的になります。どちらの関数も適切な結果をもたらします。必要に応じて適切な方を使用してください。

)
)

これらは、i loop の末尾と Proceed... ハンドラの末尾です。

 on Release pCont do ( ) 

通常、クリーンアップを行うために Release ハンドラが必要になりますが、今回は必要ありません。

関連事項