MELの応用2 (岩石)
岩石を作る 2
前回の岩石を自動生成するスクリプトを少しだけ改良してみましょう。
岩石を作る方法 2
基本的な考え方は前回と同じですが、ポリゴンの分割数を変えて最後にスムースをかけることによって、全体がゆがんだ形になるようにしみます。
今回の作り方は以下の通りです。
- 分割数を少なめにしてポリゴンの球を作ります。
- 乱数を 3 つ発生させます。
- その乱数で X, Y, Z 方向にスケールをかけます。
- ポリゴンの各頂点に対して以下の処理を繰り返します。
	
	-  乱数を 3 つ発生させます。
	
-  その乱数で頂点を X, Y, Z 方向に移動させます。
	
 
- ポリゴンにスムースをかけます。
岩石を作るプログラム 2
まず、1 個だけ岩石を作るスクリプトを作ってみましょう。
- 以下のプロシージャを makeRock4.mel と言う名前でファイルに書き込みます。
global proc makeRock4()
{
	string $poly[] = `polySphere -subdivisionsX 5 -subdivisionsY 5`;
	float $x = rand(1.0, 2.0);
	float $y = rand(1.0, 2.0);
	float $z = rand(1.0, 2.0);
	scale $x $y $z;
	string $ver[] = `polyListComponentConversion -toVertex $poly[0]`;
	string $verE[] = `filterExpand -selectionMask 31 $ver`;
	for($obj in $verE)
	{
		$x = rand(-0.2, 0.2);
		$y = rand(-0.2, 0.2);
		$z = rand(-0.2, 0.2);
		select -r $obj;
		move -r $x $y $z;
	}
	string $polyS[] = `listRelatives -shapes $poly[0]`;
	polySmooth -divisions 2 -continuity 0.5 $polyS[0];
}
-  で makeRock4.mel を読み込みます。
-  で以下のコマンドを実行してみます。
	
 makeRock4();
 ![[makeRock4() の実行例]](../mel-ad00/makeRock4.jpg)  
スクリプトの解説
-  global proc makeRock4() 
- makeRock4 という名前のプロシージャーを宣言します。
-  string $poly[] = `polySphere -subdivisionsX 5 -subdivisionsY 5`; 
- ポリゴンの球を作ります。
	
 $poly には球の名前が代入されます。
	(poly[0] にトランスフォームノード、poly[1] にインプットノード)
	- -subdivisionsX 5
		
- 横方向の分割数を 5 にします。
	
- -subdivisionsY 5
		
- 縦方向の分割数を 5 にします。
	
 
- float $x = rand(1.0, 2.0);
- 1.0 から 2.0 の乱数の値を$xに代入します。
- float $y = rand(1.0, 2.0);
- 1.0 から 2.0 の乱数の値を$yに代入します。
- float $z = rand(1.0, 2.0);
- 1.0 から 2.0 の乱数の値を$zに代入します。
- scale $x $y $z;
- 3 つの乱数によってポリゴンの球にスケールをかけます。
- string $ver[] = `polyListComponentConversion -toVertex $poly[0]`;
- ポリゴンの球から頂点を取り出して $ver[] に代入します。
	
 polyListComponentConversionコマンドはポリゴンのオブジェクトから頂点・フェース・エッジ・UVなどを取り出すために使用します。
 $ver[] に入る返り値はコンポーネントなので以下の filterExpand コマンドで各頂点に展開する必要があります。
- string $verE[] = `filterExpand -selectionMask 31 $ver`;
- $ver の中から頂点(31 で表される)を配列に展開して $verE[] に代入します。
- for($obj in $verE)
- $verE[]から、1 つづつ頂点を取り出して $obj に代入してループの中の処理を行なう。
- $x = rand(-0.2, 0.2);
- -0.2 から 0.2 の乱数の値を $x に代入します。
- $y = rand(-0.2, 0.2);
- -0.2 から 0.2 の乱数の値を $y に代入します。
- $z = rand(-0.2, 0.2);
- -0.2 から 0.2 の乱数の値を $z に代入します。
- select -r $obj;
- ひとつの頂点 $obj だけをセレクトします。
- move -r $x $y $z;
- セレクトされている頂点を、その位置から$x, $y, $zだけ移動します。
-  string $polyS[] = `listRelatives -shapes $poly[0]`; 
- ポリゴンの球のトランスフォームノードからシェープノード(メッシュ)を得ます。
	
 listRelatives コマンドによってトランスフォームノード($poly[0])の子ノードになっているシェープノードの名前を得て、$polyS に代入しています。
 シェープノードの名前はポリゴンにスムースをかけるために必要です。
 なぜ、わざわざこのようなコマンドを実行する必要があるかというと、
	球の名前が入っている $poly にはトランスフォームノードとインプットノードの名前しか入っていないからです。
 例えば、以下の図であれば、トランスフォームノード pSphere1 からシェープノード pSphereShape1 を求めることになります。
 (polySphere1 はインプットノードです)
   
-  polySmooth -divisions 2 -continuity 0.5 $polyS[0]; 
- ポリゴンメッシュにスムースをかけます。
	
 スムースをかけるにはシェープノードが必要なので、
	上の listRelatives コマンドによって得られたシェープノードが入っている $polyS[0] を使っています。
	- -divisions 2
		
- 何回再帰的にスムースをかけるかを決めます。
		
 ここでは 2 回スムースをかけています。
		(デフォールトは 1 です)
- -continuity 0.5
		
- スムースの度合を表します。
		
 値が大きい程スムースになります。
 この値は 0.0 〜 1.0 の範囲で指定します。
 (デフォールトは 1.0 です)
 
練習
- 上の makeRock4.melを参考にしてmakeRock5.melを作り、
岩石の個数と岩石が作られる範囲を指定できるようにしてみましょう。
	
 (プロシージャの名前と引数)
 makeRock5(int $num, float $xRange, float $yRange, float $zRange)
	-  $num
		
- 岩石の個数
	
-  $xRange
		
- X 方向の範囲
		
 この値にマイナスを掛けた値から、この値までの範囲に岩石を作るようにします。
 例えば、この値が 5.0 なら -5.0 から 5.0 の範囲にしてください。
 以下の Y, Z も同じです。
-  $yRange
		
- Y 方向の範囲
	
-  $zRange
		
- Z 方向の範囲
	
 (使用例)
 makeRock5.melを読み込んで、makeRock5(5, 10.0, 12.0, 7.0)と実行すると5個の岩石が、
	X方向に-10.0から10.0まで、
	Y方向に-12.0から12.0まで、
	Z方向に-7.0から7.0までの範囲でランダムな位置に作られます。
 ![[makeRock5(5, 10.0, 12.0, 7.0) の実行例]](../mel-ad00/makeRock5.jpg)  
Tips (seed)
rand コマンドを使用すると、実行するたびに違う数値がかえってきますが、
常に同じ数値を返すようにしたい場合があります。
そのようなときには、以下のように seed コマンドを使用します。
seed 1;
rand 1 2;
// Result: 1.90019 //
rand 1 2;
// Result: 1.772618 //
seed 1;
rand 1 2;
// Result: 1.90019 //
rand 1 2;
// Result: 1.772618 //
 参考
 練習課題
Prev | Next
Home | Contents
Mail