コンストレイン
コンストレインとは
コンストレインとは、リジッドボディの運動を制限するものです。
これによって、振り子・蝶番(ちょうつがい)など、
空間中の点や他のリジッドボディに、動きを拘束されたアニメーションを作成することができます。
オブジェクトにコンストレインを設定すると、
そのオブジェクトは自動的にリジッドボディになります。
コンストレインは pymel.core.constrain() によって作られます。
コンストレインの種類
各コンストレンは作成した後、
オブジェクトやコンストレインを移動すると
コンストレンの長さや位置を変化させることができます。
- ネイル(Nail) コンストレイン
- 1 つのアクティブリジッドボディーから作られるコンストレインです。
一方を空間中の点に固定された、棒によってつながれたような動きを表現できます。
- ピン(Pin) コンストレイン
- 2 つのリジッドボディーから作られるコンストレインです。
2 つのリジッドボディの間を、ピンでとめたようになります。
- ヒンジ(Hinge) コンストレイン
- 1 つまたは 2 つのリジッドボディーから作られるコンストレインです。
空間の 1 点、または他のリジッドボディにとめられた、
蝶番(ちょうつがい)のような動きを作ることができます。
壁につけたドアや、窓などを作ることができます。
- バリア(Barrier) コンストレイン
- 1 つのリジッドボディーから作られるコンストレインです。
バリア(Barrier) コンストレインは大きなプレーンがオブジェクトのバリアとなって、
それ以上オブジェクトが進めなくなります。
- スプリング(Spring) コンストレイン
- 1 つまたは 2 つのリジッドボディーから作られるコンストレインです。
オブジェクトが、バネにつながれたような状態になります。
constrain コマンドのフラグ
- nail=True
- 1 つのリジッドボディーから ネイル(Nail) コンストレインを作成します。
- pinConstraint=True
- 2 つのリジッドボディーから ピン(Pin) コンストレインを作成します。
- hinge=True
- 1 つまたは 2 つのリジッドボディーから ヒンジ(Hinge) コンストレインを作成します。
- directionalHinge=True
- 2 つのリジッドボディーから一方向の ヒンジ(Hinge) コンストレインを作成します。
- barrier=True
- 1 つのリジッドボディーから バリア(Barrier) コンストレインを作成します。
- spring=True
- 1 つまたは 2 つのリジッドボディーから スプリング(Spring) コンストレインを作成します。
- stiffness=float
- スプリングの固さの定数を設定します。デフォルト値は 5.0 です。
- damping=float
- ダンピング定数を設定します。
値を大きくすると、動きに対して抵抗力が大きくなります。
負の値にすると、動きを増すような力が働きます。
デフォルト値は 0.1、 範囲は -1000.0 〜 1000.0 です。
- restLength=float
- 休止の長さを設定します。デフォルト値: 1.0 です。
- position=(float, float, float)
- コンストレインの位置を設定します。
デフォルト値は、 1 つのリジッドボディから作られるコンストレインでは、オブジェクトの重心、
2 つのリジッドボディから作られるコンストレインでは、リジッドボディの中間点になります。
- orientation=(float, float, float)
- コンストレインの向きを設定します。
ヒンジ(Hinge) および バリア(Barrier) のみについて有効です。
デフォルト値は (0.0, 0.0, 0.0) です。
- interpenetrate=boolean
- リジッドボディーが貫通するかどうかを設定します。
True で貫通、False で貫通しません。
鎖を作る
ここでは、 ピン コンストレインを使用して鎖を作ってみましょう。
コンストレインを使用して鎖を作ると、物理的には正確な動きにはなりません。
その代わり、リジッドボディのコリジョンだけを使用した場合に比べて、計算が軽くなるし、
リジッドボディ同士が貫入するというトラブルを避けることができます。
作り方
- 鎖の輪を作ります。
輪はプリミティブのトーラスでも、独自のオブジェクトでもかまいません。
- 次の輪を前の輪と重ならないように、適当に回転・移動させて作ります。
- 2 つ輪の間を ピン コンストレインでとめます。
- 2, 3 を繰り返します。
constrain コマンドの使用例
上の作り方を参考にして、以下のように鎖を作るスクリプトを作ってみましょう。
- プログラムを簡単にするために、輪としてプリミティブのトーラスを使います。
- 輪には、重力 フィールドを作用させておきます。
- 全体が落ちてゆかないように、
1 個目の輪だけ ネイル コンストレインで固定しておきます。
- 以下の MEL スクリプトをPyMELスクリプトに書き換えて makeChain1.py という名前で作ります。
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];
}
}
- 以下の Python スクリプトを makeChain1.py という名前で作ります。
import pymel.core
def makeChain1():
gname = pymel.core.gravity()
for i in range(1,11):
tname = pymel.core.torus(hr=0.2)
pymel.core.scale((2, 3, 2))
pymel.core.rotate((0, (i % 2 * 90), 90))
pymel.core.move(((i * 4), 0, 0))
if i == 1:
pymel.core.constrain(tname[0], nail=True, p=(0, 5, 0))
else:
pymel.core.constrain(ptname, tname[0], pin=True)
pymel.core.connectDynamic(tname[0], f=gname)
ptname = tname[0]
- の によって makeChain1.py を読み込みます。
- のインプット ウインドウから makeChain1() と打ち込んで実行します。
- プレイバックしてアニメーションを実行します。
MEL スクリプトの解説
global proc makeChain1()
- makeChain1() というプロシージャの宣言です。
int $i;
- for ループ用の変数です。
string $tname[];
- 鎖の輪になる、トーラスの名前を入れておく配列変数です。
string $ptname;
- 次の鎖の輪と ピン コンストレインでつなぐために、
一時的にトーラスのトランスフォームノードの名前を入れておく変数です。
string $gname[] = `gravity`;
- 重力 フィールドを作って名前を $gname に代入します。
for($i = 1; $i <= 10; $i++)
- $i を 1 から 10 まで、 10 回ループさせて鎖の輪を 10 個作ります。
$tname = `torus -hr 0.2`;
- NURBS のトーラスを作成します。
輪の半径は、-hr フラグによってトーラスの半径の 0.2 倍で作り、
名前を $tname に代入します。
トーラスの半径は、デフォールトで 1.0 なので、輪の半径は 0.2 になります。
torus コマンドの返り値は、
トランスフォームノード名とインプットノード名の 2 つです。
$tname[0] にトランスフォームノード、
$tname[1] にインプットノードの名前が入ります。
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)を使って
0 5 0 の位置にとめておきます。
else
constrain -pin $ptname $tname[0];
- 2 個目以降の輪($tname)は、 1 個前に作られた輪($ptname)と
ピン コンストレイン(-pin)でとめてゆきます。
costrainコマンドを使用することによって、
2 つのトーラス $tname と $ptname は、
自動的にリジッドボディになります。
connectDynamic -f $gname[0] $tname[0];
- 輪に 重力 フィールド($gname)を作用させます。
$ptname = $tname[0];
- 次の輪とコンストレインするために、
現在の輪のトランスフォームノードの名前 $tname[0] を
$ptname に代入しておきます。
Tips(torus)
トーラスにおける全体の半径と、輪の半径との関係は、以下のようになっています。
- NURBS
- r フラグで表される、
全体の半径に hr フラグで表される数値を乗算した値が、輪の半径になります。
(例)
全体の半径が 4 、輪の半径が 2 ( = 4 * 0.5) の NURBS トーラス
pymel.core.torus(r=4, hr=0.5)
- ポリゴン
- r フラグの値が全体の半径、 sr フラグの値が輪の半径になります。
(例)
全体の半径が 4 、輪の半径が 2 の ポリゴントーラス
ppymel.core.polyTorus(r=4, sr=2)
Tips(ベイク)
鎖の個数が多くなった場合には、
ベイク処理をしてアニメーションをキーフレームに変換しておくと、
アニメーションの表示が軽くなります。
GUI のメニューでは
、
MEL では bakeResults コマンドを使用します。
以下のコマンドは、nurbsTorus1 〜 nurbsTorus10 に対して
1 フレームから 300 フレームまで
アトリビュートの tx, ty, tz, rx, ry, rz をベイク処理する関数です。
pymel.core.bakeResults(nurbsTorus1, nurbsTorus2, nurbsTorus3, nurbsTorus4, nurbsTorus5, nurbsTorus6, nurbsTorus7, nurbsTorus8, nurbsTorus9, nurbsTorus10, simulation=True, t="1:300", sampleBy=1, at=("tx", "ty", "tz", "rx", "ry", "rz"))
ダイナミクスのベイク処理をする場合には、上のように simulation=True が必要です。
練習
- 使用例の makeChain1.py を参考にして makeChain2.py を作り、
輪の個数、太さ(hr)、X, Y, Z 方向のスケールを、
引数で変化させることができるようにしてみましょう。
また、太さやスケールの値によって、各輪を移動させる距離も計算するようにしてみましょう。
(プロシージャの名前と引数)
makeChain2(number=10, hr=0.2, scaleX=1.0, scaleY=1.0, scaleZ=1.0)
- number
- 輪の個数
- hr
- 太さ
- scaleX
- X方向のスケール
- scaleY
- Y方向のスケール
- scaleZ
- Z方向のスケール
(注意)
トーラスの輪同士がぶつからないように、
各パラメータの値を決めないとエラーになるので注意してください。
(例)
makeChain2(hr=0.1, scaleX=3.0, scaleY=4.0, scaleZ=3.0)
(プレイバック実行後)
- makeChain2.py を参考にして makeChain3.py という名前のMELスクリプト作り、
読み込むと、以下のようなウインドウが表示されるようにしてください。
作成 ボタンを押すと 指定した色(カラーゲイン)の、
fractal テクスチャーがついた鎖が作られるようにしてください。
(実行方法)
- スクリプトエディターの によって makeChain3.mel を読み込みます。
すると、以下のウインドウが表示されます。
- 個数 スライダーによって鎖の個数、半径 スライダーよって鎖の半径、スケール X, スケール Y, スケール Z によって鎖のスケール値を指定します。
- カラー の Canvas をクリックすると カラー チューザ が開いて fractal テクスチャーの カラーゲイン の色を指定できます。
- 作成 ボタンを押すとスライダーの値によって、カラーゲイン で指定された色で鎖が作られます。
- プレイバックするとアニメーションが実行されます。
(スライダーの値)
- 個数
- 範囲
- 0 から 30
- ステップ
- 1
- 初期値
- 10
- 半径
- 範囲
- 0.0 から 1.0
- ステップ
- 0.1
- 初期値
- 0.1
- スケール X
- 範囲
- 0.0から10.0
- ステップ
- 0.1
- 初期値
- 2.0
- スケール Y
- 範囲
- 0.0から10.0
- ステップ
- 0.1
- 初期値
- 3.0
- スケール Z
- 範囲
- 0.0から10.0
- ステップ
- 0.1
- 初期値
- 2.0
- テクスチャーの色(カラーゲイン)
- 最初の色
- 赤 (1.0, 0.0, 0.0)
(ヒント)
マテリアルに、fractalテクスチャをアサインする方法を解説します。
- 色を指定するためには pymel.core.colorSliderGrp() を使用します。
colorSliderGrp() の使用方法は、floatSliderGrp() などと似ています。
- colorSliderGrp を作成するときは、
以下のようにフラグなどをつけて実行します。
pymel.core.colorSliderGrp(スライダ名, label='ラベル', rgb=(赤, 緑, 青))
- 他のスライダーと同じようにユニークな名前をつけておきます。
- ラベルは label でつけます。
- 最初の色は rgb の後に赤・緑・青の 3 つの値を float のリストまたはタプルで指定します。
- プロシージャ内で、colorSliderGrp の現在の色を知りたいときは、
以下のように実行します。
変数1 = pymel.core.colorSliderGrp(スライダ名, q=True, rgb=True)
- 調べる colorSliderGrp の名前をつけておきます。
- q, rgb フラグをつけます。
色の値が float のリストとなって返ってきます。
(赤が 変数1[0]、緑が 変数1[1]、青が 変数1[2])
- 鎖に fractal テクスチャーをアサインして、
カラーゲイン アトリビュートを変更できるようにするためには、
以下の順序で実行してゆきます。
各コマンドの返り値が必要なものは、
適当に変数または配列を作って代入しておきます。
(返り値がリストになっている場合は、リストの 0 番目に求める名前が入っています)
- 鎖(torus)のトランスフォームノード名から、トーラス のシェイプノード名を求めます。
最初のスクリプト(makeChain1.py)では、tname[0] に torus のトランスフォームノード名が入っています。
変数2 = pymel.core.listRelatives(tname[0], s=True)
(返り値は リスト)
- 鎖のシェイプノード名から ShadingEngine 名を求めます。
変数3 = pymel.core.listSets(type=1, object=変数2[0])
(返り値は リスト)
- ShadingEngine 名からマテリアル名を求めます。
変数4 = pymel.core.listConnections(変数3[0] + '.surfaceShader')
(返り値は リスト)
- fractal テクスチャーのノードを作ります。
変数5 = pymel.core.shadingNode('fractal', asTexture=True)
(返り値は fractalノードオブジェクトが返ります)
- 2次元テクスチャー(fractal) を配置するためのノード(place2dTexture)を作ります。
変数6 = pymel.core.shadingNode('place2dTexture', asUtility=True)
(返り値はplace2dTextureノードオブジェクトが返ります)
- place2dTexture ノードの outUV アトリビュートを fractal ノードの uv アトリビュートにコネクトします。
変数6.outUV >> 変数5.uv
- place2dTexture ノードの outUvFilterSize アトリビュートを fractal名 ノードの uvFilterSize アトリビュートにコネクトします。
変数6.outUvFilterSize >> 変数5.uvFilterSize
- fractal ノードの outColor アトリビュートを 3. で求めたマテリアルの color アトリビュートにコネクトします。
変数5.outColor >> 変数4[0].color
- place2dTexture ノードの repeatU と repeatV アトリビュートに適当に値を入れておきます。
(ここでは 2 と 10)
変数6.repeatU.set(2)
変数6.repeatV.set(10)
- fractal ノードの カラーゲイン の色を変更します。
以下の赤・緑・青の値は pymel.core.colorSliderGrp(q=True, rgb=True) の返り値です。
変数1[0]・変数1[1]・変数1[2] に入っています。
pymel.core.setAttr(変数5 + '.colorGain', 変数1, type='double3')
または
変数5.colorGain.set(変数1)
参考
Prev | Next
Home | Contents
Mail