日本でハリウッドVFXを制作! 「経産省アイディアボックス」 結果:  
●まとめエントリはこちら ●FAQ ●お問い合わせは左のメールフォームから

2012年2月24日金曜日

パーティクル101 その1:パーティクルの作成

パーティクル101の「101」は入門者向けであることを示しています。
詳しくはWikiの説明を読んでみて下さい。
Wikipedia:
「アメリカ合衆国の大学では、101は基礎あるいは入門科目の番号になっていることがある。転じて、あるものが入門者向けであることを示す。この用法はアメリカ合衆国以外では一般的でない。」

最近は転職のために、Houdiniの勉強を中心にしているのですが、MayaのParticleを仕事で使う機会も増え、またTwitterで経験者の話を聞いてみるとMayaのParticleをMelで操作するのは基礎を習うには良いとのアドバイスもあったので、少しづつやってみようかと思いました。

この「パーティクル101」はそうした中でわかったことなどを記録していくシリーズです。
(どこまで継続するかは不明です)

基本的にはパーティクルを数値と計算で操作する(ようするにエクスプレッション)部分をメインに学習することをかんがえています。


<パーティクルの作成>
パーティクルの操作においてはまずパーティクルをシーン内に持つ必要があります。
コントロールするためにはその対象がないとなにもできません。

メニューからやると簡単なんですが、それではMelの勉強にならないのでMelだけでやってみます。
またEmitterを使うと簡単に大量発生させられますが、
自分の意図で厳格に個数と位置を決めてパーティクルを発生させる方法をまずとります。
目指すは完全なコントロールです。



まずスクリプト・エディターで以下のように入力してEnterを押し実行します。
particle;

Particle1(トランスフォーム)ノードとparticleShape1ノードが作成されます。
particleShape1ノードのGeneral Control Attributesを開くと
Count: 0
すなわちパーティクルの数はゼロであることがわかります。
ParticleShapeノードはあれど実際のパーティクルはゼロです。


Particleのノードだけでなくシーン内に実際のパーティクルを作るには、Emitterと接続するかその位置を指定する必要があります。

位置を指定するには-positionフラグを使います。(短縮形 -p)
使い方は下記のようにxyzの座標値をスペースをはさんで指定してやります。
-p x y z
例1)-p 0 0 0
例2)-p 1 1 1

では原点からY軸方向へ1つ移動した位置へパーティクルを一つ作ってみます。
particle -p 0 1 0;

これにより図のようにパーティクルが作成されます。




先ほどのようにParticleShapeノードのGeneral Control Attributesを見ると
Count: 1となり
パーティクルが一つ作成されたことがわかります。

複数のパーティクルを作成するには、それぞれのポイントを指定してやります。
particle -p 0 1 0 -p 1 1 0;

この辺りの詳しいことはHP:Digital Matrixの「Particle」に書かれています。


ではこれを応用して複数のパーティクルをX軸上に並べるスクリプトを作ってみます。

原点0 0 0 から初めて1づつX軸上のプラス方向へずらして配置します。
0 0 0
1 0 0
2 0 0

・・・・
という具合です。


まずはDigital Matrix の説明を参考にやってみましょう。

このやり方は基本はループ処理で、particleコマンドの -pにいれる座標値を作ってやるものです。

{
int $i;
float $x, $y, $z;
string $points ="";

    for ($i =0; $i < 3; $i++)
    {
        $x =$i;
        $y=0;
        $z=0;
        $points =$points + "-p" + " "+ $x + " " + $y + " " + $z +" " ;
    }
print $points;
eval ("particle" + $points);
}

print コマンドでスクリプトエディターに$points変数の値が表示され
-p 0 0 0 -p 1 0 0 -p 2 0 0
画面には3つのパーティクルが表示されます。




<後からパーティクルを追加するには>
 今回はparticleコマンドでパーティクルを作り、将来的にはそれにインスタンサーをつけたりその場で回転させたり、別々に移動したりと言うことを考えています。
その為にはパーティクルID毎に別々の制御をすることを考えていますが、場合によってはパーティクル数が足りないことに途中で気がつくかも知れません。
particleコマンドでは、パーティクルの数は最初から決めておく必要があり、後から追加するわけにはいきません。
パーティクル数を増やした、particleコマンドをもう一度実行すると、 新しparticleShapeが作成され、追加されることはありません。

パーティクルを追加するには、emitコマンドを使います
オンラインヘルプ:emitコマンド


まず新しいシーンファイルで以下のようにテストしてみます。   
1)以下のコマンドを実行してParticleShapeノードを作成
particle;
ここではパーティクルの数はゼロです。

2)以下のコマンドを実行します。
emit -o particle1 -pos 0 0 0;
これでパーティクルが一つ作成されました。
先ほどのようにParticleShapeノードのGeneral Control Attributesを見ると
Count: 1
となっています。


3)しかしこの方法には実は落とし穴があります。
emitコマンドは実行されるとパーティクルを発生させます。
しかしアニメーションが再生された後、初期フレームに戻ったとき、それはparticleShape1の初期状態に戻ります。すなわちここではパーティクル数ゼロになります。




<後から追加したパーティクルを保持する>
emitコマンドで追加したパーティクルを初期状態で保存しておくにはDynamicsメニューから
solver > InitialStates
でパーティクルの初期状態を保存します。

同じ事を実行するコマンドは以下の通りです。
saveInitialState particle1 ;

初期状態を解除するには、以下を利用する事が出来ます。
clearParticleStartState particle1;
(ただしこれはすべてにおいて、パーティクル数をゼロにします。)

情報元



では初期状態を保存するコマンドを組み込んだMelを作ってみます。

すでにparticleShapeは作られているという前提なので、先に
particle;
を使いparticleShape1を作った後に以下を実行します。


{
int $i;
float $x, $y, $z;
string $points ="";

    for ($i =0; $i < 3; $i++)
    {
        $x =$i;
        $y=0;
        $z=0;
        $points = "-pos" + " "+ $x + " " + $y + " " + $z +" " ;
        print $points;
        eval ("emit" + "-o particle1" +  $points);
    }
saveInitialState particle1;
}

0 件のコメント:

コメントを投稿