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

2009年5月13日水曜日

二つのオブジェクト間の距離を求める (3)

magコマンドを使用することにこだわらなければ、二つのオブジェクト間の距離を測ることは、CreateメニューにあるDistanceToolを使えば、数クリックでできてしまう。
Create > Measure Tools > Distance Tool

このDistanceToolsを使うと、ロケーターが二つとdistanceDimensionノードが作られる。

出来たロケーターをそれぞれのオブジェクトのピボットへスナップ移動してからペアレントするか、
ポイントコンストレインすれば、オブジェクトの移動に伴いリアルタイムで値がビュー内に表示される。


DistanceDImensionShapeノードを見ると、「距離(Distance)」という読取り専用アトリビュートがあるので、この値を利用すればよい。


当然だが、これで表示される値は、先ほどのmagコマンドを使ったスクリプトと同じ値になる。


試しにコネクションエディターを使ってDistanceDimensionShapeノードの「距離」アトリビュートをシェーダーのカラーRへつないでみた。



距離が0より大きくなるにつれて赤が強くなってくる。
しかもリアルタイムでその結果がわかる。

ちなみにコネクションエディターで行われた作業をスクリプト・エディターで見ると
connectAttr -f distanceDimensionShape1.distance lambert1.colorR;


この値をスクリプト内で活用するためには、変数へ代入しておく必要がある。
それには、この「距離」アトリビュートの値をgeAttrで取得し、float変数へ代入する。

{
float $dist =distanceDimension1Shape.distance;
print $dist;
}



--------------------
上記の手順を踏む場合、必ずGUIでdistanceToolを使ってオブジェクトにロケーターをコンストレインもしくはペアレントをする必要がある。

実際は、ロケータのtranslateアトリビュートをdistanceDimensionShapeノードの始点と終点へつないでいるだけなので、ロケーターの代わりにオブジェクトのtranslateアトリビュートを接続すればそれでよいのかもしれないが、いずれにせよ最初にロケータが作られる。

そこで調べてみたら、なんとこのdistanceDimensionはコマンドとして存在していた。

距離寸法を作成し、指定した 2 点間の距離を表示するために使用します。
オンラインヘルプより

-startPoint (-sp)
-endPoint (-ep)
というフラグで二つのオブジェクトの座標をそれぞれ渡してやれば良いだけだ。

distanceDimension -sp -ep

さっそく、このコマンドを使って先ほどのスクリプトを変更してみることにした。
うまくいけば非常に簡単に距離が得られるスクリプトを作ることができる。

magコマンドとこのdistanceDimensionコマンドを入れ替えてやればよいはずなので以下のようにしてみた。

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

distanceDimension -sp $obj1Vec -ep $obj2Vec;
}

しかしながらエラーとなってしまう。
// エラー: 引数の解析エラーです。 //


引数を変数であらわそうとしているのがダメらしい。
なら引数もコマンドもまずテキストとしてまとめてevalコマンドでそれを実行すれば良いかもしれない。

問題にぶち当たったときに、別の解決策が思い浮かぶようになってきたら、
スクリプティングをするのも、もう少し頑張ろうという意欲がわいてくる。

ためしにオブジェクト1の引数がうまく表示されるかどうかを試してみた。

$test ="distanceDimension -sp"+$obj1Vec;
print $test;

結果
distanceDimension -sp -7.188463783 3.944541318 7.070390447

大丈夫そうだ。

必要な項目を並べてみる。
"distanceDimension -sp"
$obj1Vec
" -ep "
$obj2Vec

上記の4つを+記号で結合してテキストにし,それをevalで評価すればよいので以下のようになる。

{
string $name[] = `ls -sl`;
vector $obj1Vec = `xform -q -t -ws $name[0]`;
vector $obj2Vec = `xform -q -t -ws $name[1]`;
$dist =eval("distanceDimension -sp" + $obj1Vec + " -ep " + $obj2Vec);
print $dist;
}

これを実行してみたところ、エラーは起きなかったが予測とは違った結果となった。
まず、最後のprintコマンドは実行されなかった。
見た感じではevalが実行された時点で止まっている。

そしてdistanceDimensionノードが作成されてビュー内で値が表示されている。
これはどうしたことか?

もう一度ヘルプを見直してみた。
「距離寸法を作成し」と書いてある。
もしやと思い「Dimension」の意味を英和辞書で調べると「寸法」だった!

要するにこのコマンドは始点と終点を指定してdistanceDimensionノードを作成するコマンドなのだ。
「距離」の値のみを得るために使うことはできないということだ。
日本語の罠だった....。

あえて、今回のスクリプトの利点をあげるなら
オブジェクトを選択してやれば自動的にそのピボットポイントにロケータを作成してくれる。
ようするにDistanceToolで作った後にロケーターをスナップ移動する手間が省けることぐらい。
無いよりはまし、ぐらいか。

--------------------
ついでにロケータをコンストレインしてしまうようにするか、
オブジェクトとロケーターを入れ替えて(オブジェクトのTranslateと-spと-epの入力をコネクトして)ロケーターを削除するようにすればもう少し使えるスクリプトにはなりそうだ。

しかしながら今、持ち合わせている知識では複数のロケーターがすでにシーンに存在する時に、このコマンドで作られた二つのロケータの名前を取得する方法がわからないので、今回はやめておく。

(ロケーターが複数すでに存在する場合、必ずしもロケータがlocator1,locator2という名前にはならない。
またdstanceDimensionノードが作成された時mdistanceDimensionと二つ目のlocatorのshapeノードが選択された状態であり、そこからどのようにセレクションリストを変更すればよいのかまだ知らない。)

 

0 件のコメント:

コメントを投稿