MELの応用1 (岩石)

岩石を作る

これから MEL の応用として、岩石を自動生成するスクリプトを作ってみましょう。
最初は簡単なスクリプトから始めて、すこしづつ違うバリエーションのものを作ってみます。
岩石のようなものを MEL によって自動生成するためには、様々な方法が考えられます。 ここでは、なるべくシンプルな方法で作ってみます。

岩石を作る方法 1

適当なプリミティブを作って、それをスケール・頂点の移動などで変形して、 岩石らしく見せる方法を試してみましょう。

ここでは以下の方法で作ってみます。

  1. 乱数を 1 つ発生させます。
  2. その乱数が半径になる、ポリゴンの球体を作ります。
  3. 乱数を 3 つ発生させます。
  4. その乱数で X, Y, Z 方向にスケールをかけます。
  5. ポリゴンの各頂点に対して、以下の処理を繰り返します。
    1. 乱数を 3 つ発生させます。
    2. その 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 個だけ岩石を作るスクリプトを作ってみましょう。

  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;
    	}
    }
    
  2. ファイル → ソーススクリプト で makeRock1.mel を読み込みます。
  3. スクリプト エディタ で以下のコマンドを実行します。
    makeRock1();
    [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 が球体の名前だとして、以下のように実行が進みます。
  1. $obj = $verE[0]; が実行されて、 $obj に "pSphere1.vtx[0]" が代入され、 for 文を 1 回実行します。
  2. $obj = $verE[1]; が実行されて、 $obj に "pSphere1.vtx[1]" が代入され、 for 文を 1 回実行します。
  3. 以下、同様に頂点の個数だけ繰り返します。
以下は 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 を以下のように変更すると、 出来上がりの形を変更することができます。

練習

まとめ

参考

練習課題


Prev | Next
Home | Contents
Mail