MELの応用1 (岩石)
岩石を作る
これから MEL の応用として、岩石を自動生成するスクリプトを作ってみましょう。
最初は簡単なスクリプトから始めて、すこしづつ違うバリエーションのものを作ってみます。
岩石のようなものを MEL によって自動生成するためには、様々な方法が考えられます。
ここでは、なるべくシンプルな方法で作ってみます。
岩石を作る方法 1
適当なプリミティブを作って、それをスケール・頂点の移動などで変形して、
岩石らしく見せる方法を試してみましょう。
ここでは以下の方法で作ってみます。
- 乱数を 1 つ発生させます。
- その乱数が半径になる、ポリゴンの球体を作ります。
- 乱数を 3 つ発生させます。
- その乱数で X, Y, Z 方向にスケールをかけます。
- ポリゴンの各頂点に対して、以下の処理を繰り返します。
- 乱数を 3 つ発生させます。
- その 3 つの乱数で、頂点を X, Y, Z 方向に移動させます。
Tips
上の説明にでている乱数とは、ある範囲内のでたらめな数値のことです。
MEL では rand コマンドを使用して乱数を得ることができます。
rand コマンドは、下の使用例のように実行するたびにランダムな違う数値を返してくれるので、
岩石のように不規則な形を作る場合によく使用されます。
rand(1.0, 5.0); ← 1.0 から 5.0 までの乱数を返します
// 結果: 3.307047 //
rand(1.0, 5.0); ← 同じコマンドを実行すると、違う数値を返します
// 結果: 4.70314 //
rand(1.0, 5.0);
// 結果: 1.529152 //
岩石を作るプログラム 1
まず、1 個だけ岩石を作るスクリプトを作ってみましょう。
- 以下のプロシージャを makeRock1.mel と言う名前でファイルに書き込みます。
global proc makeRock1()
{
float $val = rand(0.5, 2.0);
string $poly[] = `polySphere -r $val`;
float $x = rand(0.8, 1.5);
float $y = rand(0.8, 1.5);
float $z = rand(0.8, 1.5);
scale $x $y $z;
string $ver[] = `polyListComponentConversion -toVertex $poly[0]`;
string $verE[] = `filterExpand -selectionMask 31 $ver`;
for($obj in $verE)
{
$x = rand(-0.1, 0.1);
$y = rand(-0.1, 0.1);
$z = rand(-0.1, 0.1);
select -r $obj;
move -r $x $y $z;
}
}
- で makeRock1.mel を読み込みます。
- で以下のコマンドを実行します。
makeRock1();
スクリプトの解説
global proc makeRock1()
- makeRock1 という名前のプロシージャを宣言します。
float $val = rand (0.5, 2.0);
- 乱数を作るコマンド rand(0.5, 2.0) によって、
0.5 から 2.0 までのランダムな値を $val に代入します。
string $poly[] = `polySphere -r $val`;
- 半径 $val のポリゴンの球体を作ります。
-r フラグは球体の半径を指定するものです。
ここでは $val が半径になります。
配列 $poly には、
$poly[0]に球体のトランスフォームノード、
$poly[1]に球体のインプットノードの名前が入ります。
たとえば、pSphere1 (トランスフォームノード)、polySphere1 (インプットノード)などです。
float $x = rand(0.8, 1.5);
- 0.8 から 1.5 の間の乱数の値を $x に代入します。
float $y = rand(0.8, 1.5);
- 0.8 から 1.5 の間の乱数の値を $y に代入します。
float $z = rand(0.8, 1.5);
- 0.8 から 1.5 の間の乱数の値を $z に代入します。
scale $x $y $z;
- 乱数の値でポリゴンの球体にスケールをかけます。
string $ver[] = `polyListComponentConversion -toVertex $poly[0]`;
- ポリゴンの球体から、頂点を取り出して配列 $ver[]に代入します。
polyListComponentConversion コマンドは、
ポリゴンのオブジェクトから頂点・フェース・エッジ・UVなどの、
コンポーネント名を取り出すために使用します。
フラグ -toVertex によって頂点が取り出されますが、
これを以下のフラグに変えることによって、他の種類のコンポーネントを取り出すことができます。
- -toEdge
- エッジを取り出す
- -toFace
- フェースを取り出す
- -toUV
- UV を取り出す
返り値($ver[] に入る)は、
pSphere1.vtx[*] などという形のコンポーネントなので、
以下の filterExpand コマンドで各頂点の名前に展開する必要があります。
string $verE[] = `filterExpand -selectionMask 31 $ver`;
- コンポーネント $ver を頂点の配列に展開して、$verE[]に代入します。
-selectionMask フラグについている 31 が頂点を表します。
たとえば、$ver に "pSphere1.vtx[*]" が入っているとすると、
このコマンドの実行によって、
"pSphere1.vtx[0]", "pSphere1.vtx[1]", ... という名前に展開されて、
以下のように $verE[] に代入されます。
$verE[0] = "pSphere1.vtx[0]";
$verE[1] = "pSphere1.vtx[1]";
$verE[2] = "pSphere1.vtx[2]";
.
.
.
-selectionMask の数字(31)は、コンポーネントの種類によって、以下のものが使用できます。
- 32
- エッジ
- 34
- フェース
- 35
- UV
for($obj in $verE)
- $verE[] から、1 つづつ頂点の名前を取り出し
$obj に代入してループの中の処理を行ないます。
実際には、pSphere1 が球体の名前だとして、以下のように実行が進みます。
- $obj = $verE[0]; が実行されて、
$obj に "pSphere1.vtx[0]" が代入され、
for 文を 1 回実行します。
- $obj = $verE[1]; が実行されて、
$obj に "pSphere1.vtx[1]" が代入され、
for 文を 1 回実行します。
- 以下、同様に頂点の個数だけ繰り返します。
以下は for 文の中のコマンドです。
$x = rand(-0.1, 0.1);
- -0.1 から 0.1 の乱数の値を $x に代入します。
$y = rand(-0.1, 0.1);
- -0.1 から 0.1 の乱数の値を $y に代入します。
$z = rand(-0.1, 0.1);
- -0.1 から 0.1 の乱数の値を $z に代入します。
ここの、-0.1 と 0.1 という数値は、
球体の大きさを考えて、形が崩れすぎない程度の適当な値を選んでいます。
でこぼこの形を変えたければ、違う数値にしてもかまいません。
select -r $obj;
- $obj だけをセレクトします。
move -r $x $y $z;
- セレクトされている頂点を移動します。
-r フラグがあるので、
現在、頂点のある位置から $x, $y, $z だけ移動します。
形の変更方法
makeRock1.mel を以下のように変更すると、
出来上がりの形を変更することができます。
- ポリゴン球体の分割数を変えてみます。
X 方向の分割数を 5、Y 方向の分割数を 3 にするには、
polySphere
コマンドを以下のように変更します。
string $poly[] = `polySphere -sx 5 -sy 3 -r $val`;
- 頂点の移動距離も変えてみます。
for 文の中の rand コマンドの引数を変更します。
$x = rand(-0.3, 0.3);
$y = rand(-0.3, 0.3);
$z = rand(-0.3, 0.3);
- ポリゴン球体のスケール値を変えるのもよいでしょう。
float $x = rand(0.5, 2.0);
float $y = rand(0.5, 2.0);
float $z = rand(0.5, 2.0);
練習
- 上の makeRock1.melを参考にしてmakeRock2.melを作り、複数の岩石を作ることができるようにしてみましょう。
岩石の現れる位置は X、Y、Z 方向に -10.0 から 10.0 までの範囲にしてください。
位置も乱数(randコマンド) によって決めてください。
(プロシージャの名前と引数)
makeRock2(int $num)
引数 $num は作られる岩石の個数です。
(使用例)
makeRock2.melを読み込んで、makeRock2(5); と実行すると5個の岩石が適当な位置に作られます。
実行を繰り返すたびに違う位置に岩石が作られるはずです。
まとめ
- 乱数を得るには rand コマンドを使用します。
- ポリゴンの各頂点に何らかの処理を行なう場合には、以下のコマンドを使用します。
- polyListComponentConversion
- ポリゴンからコンポーネントを取り出します。
- filterExpand
- コンポーネントを展開します。
参考
練習課題
Prev | Next
Home | Contents
Mail