ダイナミック・エクスプレッション

dynExpression() 関数

パーティクル は、 エミッターによって発生と動きのアニメーションを自動的に行なうことができますが、 同時に個々のパーティクルのアトリビュートを変化させることはできません。
そこで、 1 つ 1 つのパーティクルのアトリビュートを変化させながら、 アニメーションを実行させるには dynExpression() 関数を使用します。
アトリビュートを変化させるエクスプレッションの式には エクスプレッション で説明した frametime などのキーワードが使用できます。
1 つ1 つのパーティクルの番号を指定するためには particleId などのキーワードを使用します。 最初に作られたパーティクルの番号 particleId は 0 で、 以下発生した順に 1, 2, 3, ... と番号がついてゆきます。
ダイナミックエクスプレッションの式は MEL に似た文法になっています。 Python は使えません。

dynExpression 関数のフラグ

string=エクスプレッションの式
エクスプレッションの式を文字列で定義します。
creation=True
パーティクルの生成時に、エクスプレッションの式を実行します。
runtimeBeforeDynamics=True
パーティクルの生成後、ダイナミクスが実行される前にエクスプレッションの式を実行します。
runtimeAfterDynamics=True
パーティクルの生成後、ダイナミクスが実行された後でエクスプレッションの式を実行します。

パーティクルのアトリビュート

パーティクルの主なアトリビュートは以下の通りです。

長い名前 (短い名前) デフォールト値 説明
position (pos) vectorArray empty Runtime における個々のパーティクルの位置(ローカル座標)
worldPosition (wps) vectorArray empty Runtime における個々のパーティクルの位置(ワールド座標)
velocity (vel) vectorArray empty Runtime における個々のパーティクルの速度(ローカル座標)
worldVelocity (wvl) vectorArray empty Runtime における個々のパーティクルの速度(ワールド座標)
centroid (ctd) double3 empty パーティクルの平均位置(ローカル座標)
worldCentroid (wctn) double3 empty パーティクルの平均位置(ワールド座標)
acceleration (acc) vectorArray empty Runtime における個々のパーティクルの加速度
age (ag) doubleArray empty 個々のパーティクルの寿命
particleId (id) doubleArray empty 個々のパーティクルの番号
maxCount (mxc) long -1 パーティクルの最大個数
renderType (rt) enum 3 ハードウェアレンダリングの方法
ダイナミックアトリビュートについては dynExpression1.py の解説を参照してください。

dynExpression 関数の使用例1

エミッターから発生したパーティクルの色を、 赤から徐々に黒にしてゆくダイナミック・エクスプレッションを使った 関数を作ってみましょう。

  1. 以下の MEL スクリプトをPyMELスクリプトに書き換えて dynExpression1.py という名前で作ります。 global proc dynExpression1() { particle -p 0 0 0; string $ename[] = `emitter -type "direction" -dx 0.0 -dy 1.0 -dz 0.0 -spread 0.5 -rate 10`; string $pname[] = `particle`; addAttr -longName rgbPP -dataType vectorArray $pname[1]; dynExpression -creation -string "rgbPP = << 1.0, 0.0, 0.0 >>;" $pname[1]; dynExpression -runtimeAfterDynamics -string "rgbPP = rgbPP * 0.995;" $pname[1]; connectDynamic -emitters $ename $pname[0]; }
  2. 以下の Python スクリプトを dynExpression1.py という名前で作ります。
    import pymel.core
    
    def dynExpression1():
        pymel.core.particle(p=(0, 0, 0))
        ename = pymel.core.emitter(type='direction', dx=0.0, dy=1.0, dz=0.0, spread=0.5, rate=10)
        pname = pymel.core.particle()
        pymel.core.addAttr(pname[1], longName='rgbPP', dataType='vectorArray')
        pymel.core.dynExpression(pname[1], creation=True, string='rgbPP = << 1.0, 0.0, 0.0 >>;')
        pymel.core.dynExpression(pname[1], runtimeAfterDynamics=True, string='rgbPP = rgbPP * 0.995;')
        pymel.core.connectDynamic(pname[0], emitters=ename)
    
  3. スクリプト エディタ の ファイル → スクリプトのロード によって dynExpression1.py を読み込んで、テンキーの Enter キーなどで実行します。
  4. スクリプト エディタ のインプットウインドウにdynExpression1()と打ち込んで実行します。
  5. プレイバックを実行します。
    プレイバックさせる時はシェーディング(フラット または スムース)をかけておかないと色が見えない事に注意してください。
    [dynExpression1() の実行図]
    上図はわかりやすくするためにパーティクルの パーティクルのレンダータイプ アトリビュートを 球体 に変えて表示しています。

スクリプトの解説

import pymel.core
pymel.core モジュールをインポートします。
def dynExpression1():
dynExpression1() という関数の宣言です。
pymel.core.particle(p=(0, 0, 0))
パーティクルを (0, 0, 0) の位置に作ります。
ename = pymel.core.emitter(type='direction', dx=0.0, dy=1.0, dz=0.0, spread=0.5, rate=10)
そのパーティクルの位置に、 Y 方向にパーティクルが発生するエミッターを作ります。
ename[0] にエミッターの名前が入ります。
pname = pymel.core.particle()
エミッターによってパーティクルを追加されてゆくパーティクルオブジェクトを作ります。
pname[0] にパーティクルオブジェクトのトランスフォームノード、 pname[1] にパーティクルオブジェクトのシェープノードが代入されます。
pymel.core.addAttr(pname[1], longName='rgbPP', dataType='vectorArray')
パーティクルのシェープノード pname[1] にアトリビュートの型 dataType がベクトルの配列 vectorArray である rgbPP というアトリビュートを追加します。 rgbPP アトリビュートの PP は Per-Point の略です。
この rgbPP はダイナミックアトリビュートと呼ばれるもので、 パーティクルに追加されるまでは存在しません。
rgbPP は マルチポイント、マルチストリーク、ポイント、球体、スプライト、および ストリーク に有効です。
主なダイナミックアトリビュートには以下のようなものがあります。
goalPP
パーティクル単位でゴールに追従する度合を指定 (dataType は doubleArray)
lifespanPP
パーティクル単位でパーティクルが消える時間を指定 (dataType は doubleArray)
opacityPP
パーティクル単位の透明度を指定 (dataType は doubleArray)
数値、チューブ、および メタボール サーフェス 以外のパーティクルに有効。
radiusPP
パーティクル単位の半径を指定 (dataType は doubleArray)
メタボール サーフェス、クラウド、および 球体 のみに有効です。
使用例は 半径を変化させる MEL スクリプト を参照してください。
pymel.core.dynExpression(pname[1], creation=True, string='rgbPP = << 1.0, 0.0, 0.0 >>;')
creation フラグがついているので、 パーティクルが発生した時に string の後ろのエクスプレッションの式 "rgbPP = << 1.0, 0.0, 0.0 >>;" が実行されます。 この式によってパーティクルの色を最初、 赤( << 1.0, 0.0, 0.0 >> )にします。
ここで << 1.0, 0.0, 0.0 >> はベクトルとよばれるもので、 色の値のような 3 つの数値をひとつにして表したものです。 << と >> 間の 3 つの数値が、 それぞれ赤・緑・青を表します。 最小値 0.0、最大値 1.0 です。
pymel.core.dynExpression(pname[1], runtimeAfterDynamics=True, string='rgbPP = rgbPP * 0.995;')
-runtimeAfterDynamics フラグがついているので、 アニメーションが 1 フレーム進むごとにダイナミクスが実行された後に string に与えられるエクスプレッションの式 "rgbPP = rgbPP * 0.995;" が実行されます。
ベクトル rbgPP に 0.995 を乗算すると、 3 つの数値それぞれに 0.995 が乗算されます。 この場合、緑と青の数値は最初から 0.0 なので、 赤の値 1.0 が 1 フレームごとに 0.995 が乗算されて少しづつ小さい値になってゆきます。
1 フレーム目 << 1.0, 0.0, 0.0 >> * 0.995<< 0.995, 0.0, 0.0 >>
2 フレーム目 << 0.995, 0.0, 0.0 >> * 0.995<< 0.990, 0.0, 0.0 >>
3 フレーム目 << 0.990, 0.0, 0.0 >> * 0.995<< 0.985, 0.0, 0.0 >>
pymel.core.connectDynamic(pname[0], emitters=ename)
エミッター ename とパーティクル pname をコネクトしてパーティクルを発生させます。

練習

参考


Prev | Next
Home | Contents
Mail