コンストレイン
コンストレインとは
コンストレインとは、リジッドボディの運動を制限するものです。
これによって、振り子・蝶番(ちょうつがい)など、
空間中の点や他のリジッドボディに、動きを拘束されたアニメーションを作成することができます。
オブジェクトにコンストレインを設定すると、
そのオブジェクトは自動的にリジッドボディになります。
コンストレインは pm.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 個目の輪だけ ネイル コンストレインで固定しておきます。
- 以下の Python スクリプトを makeChain1.py という名前で作ります。
import pymel.core as pm
def makeChain1():
gname = pm.gravity()
for i in range(1,11):
tname = pm.torus(hr=0.2)
pm.scale([2, 3, 2])
pm.rotate([0, (i % 2 * 90), 90])
pm.move([(i * 4), 0, 0])
if i == 1:
pm.constrain(tname[0], nail=True, p=[0, 5, 0])
else:
pm.constrain(ptname, tname[0], pin=True)
pm.connectDynamic(tname[0], f=gname)
ptname = tname[0]
- の によって makeChain1.py を読み込みます。
- のインプット ウインドウから makeChain1() と打ち込んで実行します。
- プレイバックしてアニメーションを実行します。
Python スクリプトの解説
import pymel.core as pm
- pymel.core モジュールをインポートしてpmという名前で使用できるようにします。
def makeChain1():
- makeChain1() という関数の宣言です。
gname = pm.gravity()
- 重力 フィールドを作って gname に代入します。
for i in range(1,11):
- 1 から 10 まで、 10 回ループさせて鎖の輪を 10 個作ります。
tname = pm.torus(hr=0.2)
- NURBS のトーラスを作成します。
輪の半径は、hr フラグによってトーラスの半径の 0.2 倍で作り、tname に代入します。
トーラスの半径は、デフォールトで 1.0 なので、輪の半径は 0.2 になります。
torus コマンドの返り値は、
トランスフォームノード名とインプットノード名の 2 つです。
tname[0] にトランスフォームノード、
tname[1] にインプットノードの名前が入ります。
pm.scale([2, 3, 2])
- トーラスに適当にスケールをかけておきます。
同時に、輪の半径もスケールされることに注意してください。
pm.rotate([0, (i % 2 * 90), 90])
- トーラスを、1 つおきに Y 軸方向に 90 度回転させます。
輪が X 軸方向に並ぶように、 Z 軸にも 90 度回転させます。
pm.move([(i * 4), 0, 0])
- となりの輪が重ならない程度に X 軸方向に移動させます。
if i == 1:
pm.constrain(tname[0], nail=True, p=[0, 5, 0])
- 1 個目の輪だけは、 ネイル コンストレイン(nail)を使って
(0, 5, 0)の位置にとめておきます。
else:
pm.constrain(ptname, tname[0], pin=True)
- 2 個目以降の輪(tname)は、 1 個前に作られた輪(ptname)と
ピン コンストレイン(pin)でとめてゆきます。
costrainコマンドを使用することによって、
2 つのトーラス tname と ptname は、
自動的にリジッドボディになります。
pm.connectDynamic(tname[0], f=gname)
- 輪に 重力 フィールド(gname)を作用させます。
ptname = tname[0]
- 次の輪とコンストレインするために、
現在の輪のトランスフォームノードの名前 tname[0] を
ptname に代入しておきます。
Tips(torus)
トーラスにおける全体の半径と、輪の半径との関係は、以下のようになっています。
- NURBS
- r フラグで表される、
全体の半径に hr フラグで表される数値を乗算した値が、輪の半径になります。
(例)
全体の半径が 4 、輪の半径が 2 ( = 4 * 0.5) の NURBS トーラス
pm.torus(r=4, hr=0.5)
- ポリゴン
- r フラグの値が全体の半径、 sr フラグの値が輪の半径になります。
(例)
全体の半径が 4 、輪の半径が 2 の ポリゴントーラス
pm.polyTorus(r=4, sr=2)
Tips(ベイク)
鎖の個数が多くなった場合には、
ベイク処理をしてアニメーションをキーフレームに変換しておくと、
アニメーションの表示が軽くなります。
GUI のメニューでは
、
MEL では bakeResults コマンドを使用します。
以下のコマンドは、nurbsTorus1 〜 nurbsTorus10 に対して
1 フレームから 300 フレームまで
アトリビュートの tx, ty, tz, rx, ry, rz をベイク処理する関数です。
pm.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 方向のスケールを、
引数で変化させることができるようにしてみましょう。
また、太さやスケールの値によって、各輪を移動させる距離も計算するようにしてみましょう。
(プロシージャの名前と引数)
def makeChain2(number, hr, scaleX, scaleY, scaleZ):
- number
- 輪の個数
- hr
- 太さ
- scaleX
- X方向のスケール
- scaleY
- Y方向のスケール
- scaleZ
- Z方向のスケール
(注意)
トーラスの輪同士がぶつからないように、
各パラメータの値を決めないとエラーになるので注意してください。
(例)
makeChain2(20, 0.1, 2.5, 3.0, 2.5)
(プレイバック実行後)
参考
- Maya
Maya, MEL, PyMEL, Maya関係のコマンドなどのページ。
Prev | Next
Home | Contents
Mail