ON-BLOG

CGのこと、あれこれ書いてます。

XSIユーザーから観た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;
		}
}

ここはコードの説明した方がいいんで、そうします。

float $val =rand(0.5,2.0);

SIでもありますが、0.5から2.0までの間で乱数を作成してます。

string $poly[] = `polySphere -r $val`;
  • r $valで半径を変数で作成。作成した物を変数に代入。
float $x = rand( 0.8 , 1.5 );

乱数発生。

string $ver[] = `polyListComponentConversion -toVertex $poly[0]`;

「$poly[0]」で変数にある「polyListComponentConversion」で頂点、ポリゴンエッジなどのジオメトリを構成しているものを取得し
「-toVertex」頂点を選択し、変数に格納。

string $verE[] = `filterExpand -selectionMask 31 $ver`;

「$ver」にある配列を展開し、-selectionMask 31を選択する。
この「31」ってのは、頂点を表すみたい。
32エッジ 34ポリゴン 35 UVみたい。

for($obj in $verE)
	$x = rand( -0.1 , 0.1 );
	~(中略) 
	select -r $obj;
	move -r $x $y $z;

配列に入ってる頂点をobjに代入し、その頂点を選択。
XYZに乱数を入れ、その乱数を使って移動させる。
f:id:tommy_on:20130620002943p:plain

う~んイマイチわかんないですね。なんで訳してみます。
①0.5~2.0で乱数を作成、変数に格納。
②変数polyに半径(val)のスフィアを作成し格納
③XYZに乱数を発生させる(0.8から1.5)
④③で作った乱数を使って、スフィアにスケールをかける。
⑤変数verに変数polyの頂点を格納させる。
⑥頂点の各プロパティを取得する為、変数verEにselectionMask 31 である頂点を格納させる。
⑦Forで頂点数分回す
⑧XYZで乱数を発生させる。(-0.1から0.1)まで
⑨頂点を選択
⑩-rフラグがあるので、現時点のポジションから乱数を発生させたXYZを代入して移動させる。
こんな感じです。本文に置き換えるとわかりやすいかも。

あとそれの応用。

global proc makeRock1(int $num)
{
	int $i;
	for( $i = 0 ; $i < $num ; $i++ )
	{
		float $val =rand(0.5,2.0);
		string $poly[] = `polySphere -sx 5 -sy 3 -r $val`;
		float $x = rand( 0.5 , 2.0 );
		float $y = rand( 0.5 , 2.0 );
		float $z = rand( 0.5 , 2.0 );
		scale $x $y $z;
		float $Posx = rand( -5.0 , 5.0 );
		float $Posy = rand( -5.0 , 5.0 );
		float $Posz = rand( -5.0 , 5.0 );
		move $Posx $Posy $Posz;
		string $ver[] = `polyListComponentConversion -toVertex $poly[0]`;
		string $verE[] = `filterExpand -selectionMask 31 $ver`;
		for($obj in $verE)
			{
			$x = rand( -0.3 , 0.3 );
			$y = rand( -0.3 , 0.3 );
			$z = rand( -0.3 , 0.3 );
			select -r $obj;
			move -r $x $y $z;
			}
	}
}

f:id:tommy_on:20130620003109p:plain
石の数を引数で指定し、位置のランダム足しただけ。
岩がカクカクしてのはここで

string $poly[] = `polySphere -sx 5 -sy 3 -r $val`;

で値を入れているため。



ではSIではどうでしょうか?
※絶対やり方間違ってます。。
 かなり遅いんで。

MakeRock(10);
function MakeRock(num)
{
for( var i = 0 ; i < num ; i++ )
	{
	var Sphere = CreatePrim("Sphere", "MeshSurface");
	SetValue(Sphere+".sphere.radius", 1);
	var SclX = Math.random() * (2.0 - 0.5) +0.5;
	var SclY = Math.random() * (2.0 - 0.5) +0.5;
	var SclZ = Math.random() * (2.0 - 0.5) +0.5;
	Scale(Sphere, SclX, SclY, SclZ);
///////////////////////////////////////////////////
	var PosX = Math.random() * (5.0 - (-5.0)) +(-5.0);
	var PosY = Math.random() * (5.0 - (-5.0)) +(-5.0);
	var PosZ = Math.random() * (5.0 - (-5.0)) +(-5.0);
	Translate(Sphere, PosX, PosY, PosZ);
	var VerPos = Sphere.ActivePrimitive.Geometry.Points;
	for ( var j=0; j<VerPos.count; j++ )  
			{
			var VerX = Math.random() * (0.3 - (-0.3)) +(-0.3);
			var VerY = Math.random() * (0.3 - (-0.3)) +(-0.3);
			var VerZ = Math.random() * (0.3 - (-0.3)) +(-0.3);
			Translate(VerPos(j), VerX, VerY, VerZ);
			}
	}
}

f:id:tommy_on:20130620003434j:plain
頂点選んで、乱数の値を入れてるだけです。
内容的にはほとんど変わらないですね。

ではもういっちょMELで応用。
次はラティスを使った岩石作りです。

global proc makeRock5(int $num ,  float $xRange , float $yRange , float $zRange)
{
	int $i;
	for( $i = 0 ; $i < $num ; $i++ )
	{
			polySphere;
			string $lname[] = `lattice -divisions 2 5 2 -objectCentered true`;
			float $x = rand( 1.0 , 3.0 );
			float $y = rand( 1.0 , 3.0 );
			float $z = rand( 1.0 , 3.0 );
			scale $x $y $z;
			float $Posx = rand( -($xRange) , $xRange );
			float $Posy = rand( -($yRange) , $yRange );
			float $Posz = rand( -($zRange) , $zRange ); 
			move $Posx $Posy $Posz;
		string $points[] = `filterExpand -selectionMask 46 ($lname[1] + ".pt[0:1][0:4][0:1]")`;
			for($obj in $points)
				{
					$x = rand( -0.6 , 0.6 );
					$y = rand( -0.6 , 0.6 );
					$z = rand( -0.6 , 0.6 );
					select -r $obj;
					move -r $x $y $z;
				}
	}
}

f:id:tommy_on:20130620003758p:plain
いや~ハマりました。
どこが?

「;」とstring $points[] = `filterExpand -selectionMask 46 ($lname[1] + ".pt[0:1][0:4][0:1]")`;

ここです。
まず「;」の記載抜けが結構あり、え?え?え?ってなってました。
んで次、

string $points[] = `filterExpand -selectionMask 46 ($lname[1] + ".pt[0:1][0:4][0:1]")`;

46番がわからんかった。
filterExpand command
ここみてなんとかクリア。。
この辺不親切ですよね!


でこのSI版
これもかなり怪しいです。
ラティスの扱い方がわからんかった。。

MakeRock(10,5,5,5);
function MakeRock(num,X,Y,Z)
{
for( var i = 0 ; i < num ; i++ )
	{
	var Sphere = CreatePrim("Sphere", "MeshSurface");
	SetValue(Sphere+".sphere.radius", 1);
	var SclX = Math.random() * (2.0 - 0.5) +0.5;
	var SclY = Math.random() * (2.0 - 0.5) +0.5;
	var SclZ = Math.random() * (2.0 - 0.5) +0.5;
	Scale(Sphere, SclX, SclY, SclZ);
	var PosX = Math.random() * (X - (-X)) +(-X);
	var PosY = Math.random() * (Y - (-Y)) +(-Y);
	var PosZ = Math.random() * (Z - (-Z)) +(-Z);
	Translate(Sphere, PosX, PosY, PosZ);
	var Lati = GetPrimLattice(null, Sphere);
	var Ver = Lati.ActivePrimitive.Geometry.Points;
	for ( var j=0; j<Ver.count; j++ )
		{
			var VerX = Math.random() * (0.6 - (-0.6)) +(-0.6);
			var VerY = Math.random() * (0.6 - (-0.6)) +(-0.6);
			var VerZ = Math.random() * (0.6 - (-0.6)) +(-0.6);
			Translate(Ver(j), VerX, VerY, VerZ);
		}
	}
} 

f:id:tommy_on:20130620004239j:plain

こんな感じで岩の生成を行なってきました。
次からはパーティクルです。
あ、次回移行「SI版」がなくなります。
ってかSiだとできないことも多々あるんですわ。。



では…