パーティクルのインスタンス 2
インスタンスにブラシを使う
前回のインスタンス化のスクリプトを、ペイントエフェクトのブラシを使ったものにしてみましょう。
インスタンスの使用例 2
羽をブラシにし、インスタンス化して、
アニメーションさせてみましょう。
- 以下の MEL スクリプトを makeInstance4.mel という名前で作ります。
proc string makeFeather()
{
string $cname = `curve -d 3 -p -0 -0 0 -p 0.2 0.2 0 -p 0.4 0.6 0 -p 0.6 0.4 0 -k 0 -k 0 -k 0 -k 1 -k 1 -k 1`;
source "/usr/aw/maya6.0/brushes/feathers/featherWhite.mel";
string $fname = `getDefaultBrush`;
setAttr ($fname + ".globalScale") 5;
string $tname = `createNode transform`;
string $sname = `createNode stroke -p $tname`;
connectAttr ($fname + ".obr") ($sname + ".brs");
connectAttr ($cname + ".ws") ($sname + ".pcv[0].crv");
return $tname;
}
global proc makeInstance4()
{
string $pname[] = `particle -p 4.6 0 9.0 -p -2. 0 4.1 -p -5.9 0 -5.5 -p 3.7 0 4.5 -p 2.5 0 3.1`;
string $oname = makeFeather();
select -tgl $pname[0] ;
string $iname = `particleInstancer -addObject -object $oname $pname[1]`;
addAttr -ln myRotate -dt vectorArray $pname[1];
dynExpression
-s ("if(frame == 1)"
+ "{"
+ " $rand = rand(0,180);"
+ " myRotate = <<$rand, $rand, $rand>>;"
+ "}") -creation $pname[1];
dynExpression
-s ("if(frame > 1)"
+ "{"
+ " float $val = particleId % 5.0 / 5000.0 + 0.0002;"
+ " myRotate += <<$val, ($val * 2),($val * 3)>>;"
+ "}") -rbd $pname[1];
particleInstancer -e -name $iname -rotation myRotate $pname[1];
}
- の によって makeInstance4.mel を読み込みます。
- Script Editor のインプットウインドウで、makeInstance4() を実行します。
すると、以下のようにインスタンス化されたブラシが現れます。
- アニメーションを実行します。
アニメーション実行結果
スクリプトの解説
proc string makeFeather()
- makeFeather というプロシージャーの宣言です。
このプロシージャーでペイントエフェクトによる羽を作ります。
string $cname = `curve -d 3 -p -0 -0 0 -p 0.2 0.2 0 -p 0.4 0.6 0 -p 0.6 0.4 0 -k 0 -k 0 -k 0 -k 1 -k 1 -k 1`;
- ペイントエフェクトのストロークのために NURBS カーブを作ります。
source "/usr/aw/maya6.0/brushes/feathers/featherWhite.mel";
- 羽のブラシを作る MEL スクリプトを読み込んで実行させます。
/usr/aw/maya6.0/brushes ディレクトリの下には、
feathers 以外にも様々なディレクトリがあります。
そして、それらのディレクトリの中に
featherWhite.mel 以外の多くのブラシを作る MEL スクリプトが存在します。
string $fname = `getDefaultBrush`;
- getDefaultBrush コマンドによって現在、有効になっているブラシの名前を得ます。
この場合は、source で読み込んだ羽のブラシになります。
setAttr ($fname + ".globalScale") 5;
- ブラシの .globalScale アトリビュートに 5 を設定して、
見やすいように羽の大きさを大きくしておきます。
string $tname = `createNode transform`;
- ストロークの親になるトランスフォームノードを作ります。
string $sname = `createNode stroke -p $tname`;
- ブラシのためにストロークを作ります。
トランスフォームノード($tname)を DAG の親ノードにしておきます。
connectAttr ($fname + ".obr") ($sname + ".brs");
- ブラシのデータ出力アトリビュート(obr)を、ストロークのアトリビュート(brs)にコネクトします。
これによって、ブラシがストロークに使われるようになります。
connectAttr ($cname + ".ws") ($sname + ".pcv[0].crv");
- カーブ($cname)のアトリビュート(ws)を、ストローク($sname)のアトリビュート(pcv[0].crv)にコネクトします。
これによってカーブ($cname)がストロークに使われるようになります。
return $tname;
- ストロークのトランスフォームノードの名前を、
プロシージャーの返り値として返します。
global proc makeInstance4()
- makeInstance4 というプロシージャーの宣言です。
このプロシージャーでパーティクルのインスタンスを作ります。
string $pname[] = `particle -p 4.6 0 9.0 -p -2. 0 4.1 -p -5.9 0 -5.5 -p 3.7 0 4.5 -p 2.5 0 3.1`;
- 5 個の点をもつパーティクルを作ります。
このパーティクルの各点にインスタンスが作られます。
string $oname = makeFeather();
- makeFeather プロシージャーによって羽のブラシを作ります。
$oname にはストロークの名前が入っています。
select -tgl $pname[0] ;
- パーティクルを追加してセレクトしておきます。
この時、ストローク($oname)もセレクトされています。
string $iname = `particleInstancer -addObject -object $oname $pname[1]`;
- インスタンサーノードを作成して、パーティクルの点の位置にコーンを配置します。
このコマンドによってパーティクルインスタンサ−ノードが作られて、
その名前が文字列変数 $iname に代入されます。
各フラグの意味は以下のとおりです。
- -addObject
- インスタンスとしてオブジェクトを追加
- -object $oname
- 追加するオブジェクトの指定
ここでは羽のブラシが付いたストローク($oname)
addAttr -ln myRotate -dt vectorArray $pname[1];
- パーティクルに myRotate という名前のアトリビュートを追加します。
myRotate の型は vectorArray というベクトルの配列で、
一つ一つのベクトルがインスタンスの回転をコントロールします。
dynExpression
-s ("if(frame == 1)"
+ "{"
+ " $rand = rand(0,180);"
+ " myRotate = <<$rand, $rand, $rand>>;"
+ "}") -creation $pname[1];
- パーティクル作成時(-creation)のダイナミックエクスプレッションを設定します。
エクスプレッションの式は文字列の結合によって作られているので、
見やすくするために式の部分だけにしてみましょう。
if(frame == 1)
{
float $rand = rand(0,180);
myRotate = <<$rand, $rand, $rand>>;
}
if(frame == 1)
- 1 フレーム目に以下のコマンドを実行します。
frame は現在のフレーム番号を表す特別な変数です。
float $rand = rand(0,180);
- 0 から 180 までの乱数を作成して $rand に代入します。
myRotate = <<$rand, $rand, $rand>>;
- 先に追加されたアトリビュート myRotate に乱数の値を使ったベクトルの値を代入します。
このベクトルがコーンの X, Y, Z 方向の回転角度になります。
dynExpression
-s ("if(frame > 1)"
+ "{"
+ " float $val = particleId % 5.0 / 5000.0 + 0.0002;"
+ " myRotate += <<$val, ($val * 2),($val * 3)>>;"
+ "}") -rbd $pname[1];
- アニメーション実行時のダイナミックエクスプレッションを設定します。
-rbd フラグによって、ダイナミクスの実行前にダイナミックエクスプレッションが実行されます。
見やすいように式の部分だけにしてみます。
if(frame > 1)"
{
float $val = particleId % 5.0 / 5000.0 + 0.0002;
myRotate += <<$val, ($val * 2),($val * 3)>>;
}
if(frame > 1)
- 1 フレーム目よりアニメーションが進んでいるときに、
以下のコマンドを実行します。
float $val = particleId % 5.0 / 5000.0 + 0.0002;
- 個々のパーティクルごとに、違う速度で回転させるために、
個々のパーティクルの番号 particleId を使用して $val の計算をしています。
- 5.0
- 5 個ごとに違う速度で回転するようになります。
- 5000.0
- この数値を大きくすると、回転速度が遅くなり、
小さくすると速くなります。
- 0.0002
- すべてのパーティクルが、このスピードより速いスピードで回転します。
この値を 0.0 にすると回転しない羽根がでてきます。
$val の計算方法は、これ以外にもいろいろ考えられます。
myRotate += <<$val, ($val * 2),($val * 3)>>;
- アトリビュート myRotate にベクトル <<$val, ($val * 2),($val * 3)>> を加算します。
これによって 1 フレーム毎にインスタンスであるコーンの回転角度が
X 方向に $val、
Y 方向に ($val * 2)、
Z 方向に ($val * 3)、
づつ増加します。
particleInstancer -e -name $iname -rotation myRotate $pname[1];
- インスタンサ−ノード $iname に、
インスタンスの回転をコントロールするアトリビュートとして myRotate を使用するように設定します。
各フラグの意味は以下のとおりです。
- -e
- エディットモード
- -name $iname
- 設定を変更するインスタンサ−ノードの指定
- -rotation myRotate
- 回転をコントロールするアトリビュートの指定
Tips (source)
source によって、MEL スクリプトを読み込んで実行させることができます。
の によって読み込むのと同じです。
スクリプトパスにある MEL スクリプトはファイル名だけで、
それ以外はフルパスで指定する必要があります。
例えば、makeInstance4.mel を source によって読み込むためには、
以下のように実行します。
- makeInstance4.mel のあるディレクトリ(ホルダー)を調べます。
Linux の場合、コンソールで以下のコマンドを実行
% cd mel
% pwd
/home/ad000000/mel ← MEL スクリプトのあるディレクトリ
- 調べたディレクトリ名を付けて
source を実行します。
source "/home/ad000000/mel/makeInstance4.mel";
なお、source は通常の MEL コマンドではないので注意が必要です。
(以下の練習を参照してください)
Tips (ブラシの位置 - Windows)
makeInstance4.mel と同じブラシは、
Windows においては以下のホルダーに存在します。
C:/Program Files/AliasWavefront/Maya6.0/brushes/feathers/featherWhite.mel
練習
- 使用例の makeInstance4.mel を参考にして、makeInstance5.mel を作り、
ディレクトリ名と MEL スクリプトファイル名を使って任意のブラシをインスタンス化できるようにしてみましょう。
(引数)
makeInstance5(string ディレクトリ名, string ファイル名)
(使用例)
- の によって makeInstance5.mel を読み込みます。
- でコマンドを実行します。
makeInstance5("flowers", "daisyLarge");
- 以下のようなブラシのインスタンスが作成されます。
- アニメーションを実行します。
アニメーション実行結果
(ヒント 1)
ブラシのディレクトリ名には以下のようなものがあります。
airbrush, animal, cityMesh, clouds, electrical, feathers, fibers, fire, flesh, flowers, flowersMesh, food, foodMesh, fun, funMesh, galactic, glass, glows, grasses, hair, liquid, markers, metal, objectsMesh, oils, paper, pastels, pencils, pens, plants, plantsMesh, trees, treesMesh, underwater, waterMesh, watercolor, weather, wetInWet
例えば、この中の flowers ディレクトリにある、ブラシのファイル名には以下のようなものがあります。
africanLily.mel buttercup.mel, clover.mel, dahliaPink.mel, dahliaRed.mel, daisyLarge.mel, daisySmall.mel, dandelion.mel, dandelionYellow.mel, delphinium.mel, flowerTallRed.mel, hyacinth.mel, lilyOrange.mel, lilyRed.mel, paintedDaisy.mel, roses.mel, sunflower.mel, violet.mel,
これらは、Visor に表示されるブラシのリストと同じものです。
(ヒント 2)
MEL スクリプトを source で読み込む場合に、
変数を使うときは特別な方法が必要です。
例えば、ディレクトリ名が $dname という変数に入っていて、ファイル名が test.mel の場合は、
以下のコマンドではエラーになります。
source ($dname + "test.mel");
この場合は eval を使用して以下のように実行します。
eval ("source \"" + $dname + "test.mel\"");
source の後の \" と、test.mel の後の \" に注意してください。
(ヒント 3)
引数によってブラシの種類を選ぶためには、
makeInstance3.mel の source に与えているパスの中で、
ブラシのディレクトリと MEL スクリプトファイルの名前の部分を、
引数によって変更できるようにすればよいでしょう。
"/usr/aw/maya6.0/brushes/" + ディレクトリ + "/" + ファイル名 + ".mel"
練習課題
参考
Prev | Next
Home | Contents
Mail