コンストレイン 2
鎖を作る
ここでは pin コンストレインを使用して鎖を作ってみましょう。
コンストレインを使用して鎖を作ると、
物理的に正確な動きにはなりませんが、
リジッドボディのコリジョンだけを使用した場合に比べて計算が軽くなるし、
リジッドボディ同士が貫入するというトラブルを避けることができます。
作り方
- 鎖の輪を作ります。
輪はプリミティブのトーラスでも、独自のオブジェクトでもかまいません。
- 次の輪を前の輪と重ならないように、適当に回転・移動させて作ります。
- 2 つ輪の間を pin コンストレインでとめます。
- 2, 3 を繰り返します。
constrain コマンドの使用例 2
上の作り方を参考にして、以下のように鎖を作るスクリプトを作ってみましょう。
- プログラムを簡単にするために輪としてプリミティブのトーラスを使います。
- アニメーションをわかりやすくするために 1 個目の輪だけ nail コンストレインで固定しておきます。
- すぐにアニメーションを実行できるように gravity フィールドを作用させておきす。
- 以下の MEL スクリプトを makeChain1.mel という名前で作ります。
global proc makeChain1()
{
int $i;
string $tname[];
string $ptname;
string $gname[] = `gravity`;
for($i = 1; $i <= 10; $i++)
{
$tname = `torus -hr 0.2`;
scale 2 3 2;
rotate 0 ($i % 2 * 90) 90;
move ($i * 4) 0 0;
if($i == 1)
{
constrain -nail -p 0 5 0 $tname[0];
}
else
{
constrain -pin $ptname $tname[0];
}
connectDynamic -f $gname[0] $tname[0];
$ptname = $tname[0];
}
}
- の によって makeChain1.mel を読み込みます。
- の下のウインドウから makeChain1(); と打ち込んで実行します。
- プレイバックしてアニメーションを実行します。
スクリプトの解説
global proc makeChain1()
- makeChain1() というプロシージャーの宣言です。
int $i;
- for ループ用の変数です。
string $tname[];
- 鎖の輪になるトーラスの名前を入れておく変数です。
torus コマンドの返り値はトランスフォームノード名とインプットノード名の 2 つなので配列になります。
string $ptname;
- 次の鎖の輪と pin コンストレインでつなぐために、
一時的にトーラスのトランスフォームノードの名前を入れておく変数です。
string $gname[] = `gravity`;
- gravity フィールドを作って名前を $gname に代入します。
for($i = 1; $i <= 10; $i++)
- $i を 1 から 10 まで 10 回ループさせて鎖の輪を 10 個作ります。
$tname = `torus -hr 0.2`;
- トーラスの輪の半径を、
-hr フラグによってトーラスの半径の 0.2 倍にして作り、
名前を $tname に代入します。
トーラスの半径はデフォールトで 1.0 なので輪の半径は 0.2 になります。
scale 2 3 2;
- トーラスに適当にスケールをかけておきます。
同時に輪の半径もスケールされることに注意してください。
rotate 0 ($i % 2 * 90) 90;
- 1 つおきに Y 軸方向に 90 度回転させます。
輪が X 軸方向に並ぶように Z 軸にも 90 度回転させます。
move ($i * 4) 0 0;
- となりの輪が重ならない程度に X 軸方向に移動させます。
if($i == 1)
constrain -nail -p 0 5 0 $tname[0];
- 1 個目の輪だけは nail コンストレイン(-nail)を使って
0 5 0 の位置にとめておきます。
else
constrain -pin $ptname $tname[0];
- 2 個目以降の輪($tname)は 1 個前の輪($ptname)と pin コンストレイン(-pin)でとめてゆきます。
costrainコマンドを使用することによって、
2 つのトーラス $tname と $ptname は、
自動的にリジッドボディになります。
connectDynamic -f $gname[0] $tname[0];
- 輪に gravity フィールド($gname)を作用させます。
$ptname = $tname[0];
- 次の輪とコンストレインするために、
現在の輪のトランスフォームノードの名前 $tname[0] を
$ptname に代入しておきます。
Tips(torus)
トーラスにおける全体の半径と、輪の半径との関係は以下のようになっています。
- NURBS
- -r フラグで表される全体の半径に -hr フラグで表される数値を乗算した値が輪の半径になります。
(例)
全体の半径が 4 、輪の半径が 2 ( = 4 * 0.5) の NURBS トーラス
torus -r 4 -hr 0.5;
- ポリゴン
- -r フラグで表される全体の半径、 -sr フラグの値が輪の半径になります。
(例)
全体の半径が 4 、輪の半径が 2 の ポリゴントーラス
polyTorus -r 4 -sr 2;
Tips(ベイク)
鎖の個数が多くなった場合には、
ベイク処理をしてアニメーションをキーフレームに変換しておくと、
アニメーションの表示が軽くなります。
GUI のメニューでは Edit → Keys → Bake Simulation □ 、
MEL では bakeResults コマンドを使用します。
以下のコマンドは、nurbsTorus1 〜 nurbsTorus10 に対して
1 フレームから 300 フレームまで
アトリビュートの tx, ty, tz, rx, ry, rz をベイク処理するコマンドです。
bakeResults -simulation true -t "1:300" -sampleBy 1 -at "tx" -at "ty" -at "tz" -at "rx" -at "ry" -at "rz" nurbsTorus1 nurbsTorus2 nurbsTorus3 nurbsTorus4 nurbsTorus5 nurbsTorus6 nurbsTorus7 nurbsTorus8 nurbsTorus9 nurbsTorus10;
ダイナミクスのベイク処理をする場合には、上のように -simulation true が必要です。
練習
- 使用例の makeChain1.mel を参考にして makeChain2.mel を作り、
輪の個数、太さ(-hr)、X, Y, Z 方向のスケールを引数で変化させることができるようにしてみましょう。
また、太さやスケールの値によって各輪を移動させる距離も計算するようにしてみましょう。
(プロシージャーの名前と引数)
makeChain2(int 輪の個数, float 太さ, float X方向のスケール, float Y方向のスケール, float Z方向のスケール)
(注意)
トーラスの輪同士がぶつからないように各パラメータの値を決めないとエラーがでるので注意してください。
(例)
makeChain2(10, 0.1, 3.0, 4.0, 3.0)
(プレイバック実行後)
練習課題
参考
Prev | Next
Home | Contents
Mail