日本でハリウッドVFXを制作! 「経産省アイディアボックス」 結果:  
●まとめエントリはこちら ●FAQ ●お問い合わせは左のメールフォームから

2009年5月14日木曜日

magコマンド応用編 (2):近づいたら色が変わる

次に動作を逆にして最初の予定通り、近づくと赤くなるようにする。

このとき、オブジェクト同士がオーバーラップしなくても最大限近づいた時に赤くなるようにする。

必要な条件を整理すると。

1)離れるに従って$distの値は大きくなる。
2)それとは逆にcolorRの値は小さくなる。
3)オブジェクトに近づくとcolorRは1に近づいていく。
4)オブジェクトが離れたとき、colorR=0.5が最小値でそれ以下はない。


前回は、$distがゼロのときにcolorR=0.5でそれ以外は特に決めていなかったので簡単だったが今回は少し複雑そうだ。。

上記の条件から具体的な数字を割り出していく。
前回と違い、今度は色が変化して行く際の閾値を決める必要がある。
画面でみながらオブジェクトを移動し、その距離をスクリプトで計測しながら最大値を1.5に設定することにした。

$distが0.5(接触する直前の距離)の時colorR=1。$distがそれ以下でもcolorR=1を保つ。
$distが1.5(離れたときの最大値)の時colorR=0.5。$distがそれ以上でもcolorR=0.5を保つ

簡単に書くと
$dist 0.5より小さい  --- 0.5 <---> 1.5 --- 1.5より大きい
colorR  1      --- 1.0 <---> 0.5 --- 0.5

二つのオブジェクト間の距離が開くとき、
$dist:0.5から1.5へ変化する(差は1.0)
colorR:1.0から0.5へ変化する(差は0.5)
$distが増加するとcolorRは減少する。

例:
$distが0.5から0.1増加し、0.6になる時、
$colorは1.0から0.05減少し、0.95になる。


--------------------
こういった制限、もしくはcolorRの変化が起こるために「必要な事柄」というのは「条件」の定義に当てはまる。 (当ブログ:If文の重要性

<条件>の定義
(1)物事を決定したり約束したりするときに、前提あるいは制約となる事柄。
(2)物事の成立あるいは実現に必要な事柄。ある事態を引き起こす原因。


これはif文の出番ということだ。

上記をスクリプトとに直すと以下のようになる。


if ($dist<0.5)
$color = 1;

else if ($dist>1.5)
$color = 0.5;

else
$color = 1-$dist*0.5;


これをmagコマンドまでの部分と一緒にすると以下のようになる。
--------------------
string $name[] = { "nurbsSphere1","nurbsCone1"};

vector $obj1Vec = `xform -q -t -ws $name[0]`;
vector $obj2Vec = `xform -q -t -ws $name[1]`;

vector $distVec = $obj1Vec - $obj2Vec;
float $dist = `mag $distVec`;

if($dist<0.5)
$color = 1;

else if($dist>1.5)
$color = 0.5;

else
$color = 1-$dist*0.5;
lambert2.colorR=$color;

print ($dist + "\n");

--------------------


とりあえず動いてくれたが距離が1.5を超えているとき、Rの値がゼロになり色が青緑になっている。
しかも、近づいても色が変化せず、0.5を超えるとき、突然、赤に切り替わる。

if文の箇所がうまく機能していないようだ。
また距離が小さすぎてよくわからない可能性もあるので$distの最小値を1に最大値を11に変えた。

いろいろと順番を変えたりして、試してみたが$distの値が最大値を超えたときの値が正常に反映しなかったり、$distの値でRの値を段階的にかえていくところがうまく機能しなかった。

たまたまBlueの値に$colorの初期値0.5を入れてみたら、すべてがうまく動作するようになった。

float $color =0.5;

if($dist<1)
$color = 1;

else if(11<$dist)
lambert2.colorB=$color;

else if(1<$dist)
$color = (1-$dist*0.05);

lambert2.colorR=$color;

ただこのif文の順番を変えるととたんに機能しなくなる。
とくに色がグレイになるときに青緑になってしまう。
赤の値が以上に大きくなり-5以上の数字になったりする。


とりあえず機能してはいるがどうもすっきりしない。
なぜBに値をいれてやることでRの値がリセットされるのか??
もしかしたら、learningMayaでやっているようにsetAttrを使うべきなのかもしれない。


将来のためにも両方を試してみることにした。


--------------------
まずはRGBアトリビュートすべてに直接、値を代入する方法。

if($dist<1)
$color = 1;

else if(11<$dist)
$color = 0.5;

else if(1<$dist)
$color = (1-$dist*0.05);

lambert2.colorR=$color;
lambert2.colorG=0.5;
lambert2.colorB=0.5;

NG:距離が最小値のときのみ赤で、それ以外はR=0から変化せず、青緑色のまま。


--------------------
setAttrを使ってcolorRアトリビュートに値を設定する方法

if($dist<1)
{setAttr lambert2.colorR 1;}

else if(11<$dist)
{setAttr lambert2.colorR 0.5;}

else if(1<$dist)
{$color = (1-$dist*0.05);
setAttr lambert2.colorR $color;}


成功!!これでちゃんと動いてくれた。
カラー・アトリビュートに値を入れるときは、setAttrを使った方が動作的に安定するようだ。

自分が気がついていないだけで、なにかやり方がまずかったのかもしれないが
これからは、アトリビュートに値を設定するときは、setAttrを使うようにしたい。

 

0 件のコメント:

コメントを投稿