ジョイントを使用することで2つのボディの間に拘束 (constraint) を設定し、相互の関係を定義できます。
hinge = dJointCreateHinge( world, 0 ); // ジョイントの作成 dJointAttach( hinge, body1, body2 ); // ジョイントで2つのボディを接続 dJointSetHingeAnchor( hinge, 0, 0, 0 ); // 中心点の設定 dJointSetHingeAxis( hinge, 1, 0, 0 ); // 回転軸の設定
≫デモプログラム (demo_hinge)
種類 | イメージ | パラメータ | 自由度 | 対偶 |
---|---|---|---|---|
ボール (A ball-and-socket joint) |
|
3 | 球 | |
ヒンジ (A hinge joint) |
|
1 | 回転 | |
スライダー (A slider joint) |
|
1 | 直進 | |
ユニバーサル (A universal joint) |
|
2 | 回転×2 | |
ヒンジ2 (A hinge-2 joint) |
|
2×2 | 回転×2 |
種類 | イメージ | パラメータ |
---|---|---|
固定 (A fixed joint) |
なし | |
接触 (A contact joint) |
|
|
角度モーター (An angular motor joint) |
|
ジョイントを作成するには、それぞれのジョイントの種類に対応した関数を使用します。
このときdWorldIDにはジョイントが格納されるワールドを、dJointGroupIDにはジョイント グループを指定します。ただし一般的なジョイントはグループ化する必要がないため、通常dJointGroupIDは0とします。
種類 | 関数 |
---|---|
ボール (Ball) |
dJointCreateBall( dWorldID, dJointGroupID ); |
ヒンジ (Hinge) |
dJointCreateHinge( dWorldID, dJointGroupID ); |
スライダー (Slider) |
dJointCreateSlider( dWorldID, dJointGroupID ); |
ユニバーサル (Universal) |
dJointCreateUniversal( dWorldID, dJointGroupID ); |
ヒンジ2 (Hinge2) |
dJointCreateHinge2( dWorldID, dJointGroupID ); |
種類 | 関数 |
---|---|
固定 (Fixed) | dJointCreateFixed( dWorldID, dJointGroupID ); |
接触 (Contact) |
dJointCreateContact(
dWorldID,
dJointGroupID,
const dContact * // 接触面の定義
);
|
角度モーター (Angular Motor) |
dJointCreateAMotor( dWorldID, dJointGroupID ); |
ジョイントを破棄するときは、その種類に関係なくdJointDestroy()を使用します。
ワールドを破棄したときには、そこに格納されるジョイントも自動で破棄されます。またジョイント グループを破棄したときには、そ含れジョイントも自動で破棄されます。よって通常は、明示的にジョイントを破棄する必要はありません。
void dJointDestroy ( dJointID );
dJointAttach()により、2つのボディをジイントにり接続できます。
指定したジョイントがすでに他のボディの接続に使用されていた場合には、そのボディの接続は解除されます。
body1またはbody2に0が指定された場合には、他方のボディは静的な環境 (static environment) と接続され移動しなくなります。
void dJointAttach ( dJointID joint, // 接続するジョイント dBodyID body1, // 接続されるボディ1 dBodyID body2 // 接続されるボディ2 );
dJointGetBody()によって、dJointAttach()で接続されたボディを調べられます。
引数indexでは次の定数で、調べる対象のボディを指定します。
dBodyID dJointGetBody ( dJointID, int index );
indexに0と1を指定し2つのボディについて調べた場合、得られる結果には次の3通りの意味があります。
dAreConnected()とdAreConnectedExcluding()によって、指定の2つのボディがジョイントによって接続されているか確認できます。
接続されている場合には1、さもなければ0が返されます。
int dAreConnected ( dBodyID body1, dBodyID body2 );
dAreConnectedExcluding()では、引数のjoint_typeで例外を設定できます。ここで指定したジョイントは確認対象から除外されるため、特定のジョイントで接続されているかどうかを確認できます。
これはおもに、ボディに接触ジョイントを設定するかどうかの判断に使用されます。
int dAreConnectedExcluding ( dBodyID body1, dBodyID body2, int joint_type );
定数 | 説明 |
---|---|
dJointTypeNone | |
dJointTypeNull | |
dJointTypeBall | ボール |
dJointTypeHinge | ヒンジ |
dJointTypeSlider | スライダー |
dJointTypeUniversal | ユニバーサル |
dJointTypeHinge2 | ヒンジ2 |
dJointTypeFixed | 固定 |
dJointTypeContact | 接触 |
dJointTypeAMotor | 角度モーター |
dJointTypeLMotor | |
dJointTypePlane2D | |
dJointTypePR | PR |
dJointTypePU | PU |
dJointTypePiston | ピストン |
各ジョイントには、その中心点と回転軸の設定・取得を行う関数があります。例外がボールとスライダーで、それぞれ回転軸と中心点がありません。
中心点はx、y、zの3成分を絶対座標で指定します。回転軸は軸方向をx、y、zの軸ベクトルで指定します。
軸が1つであるにもかかわらず中心点を取得する関数が2つあるジョイントは、計算誤差により2つのボディに対してその位置がずれることがあるためです。なおそのような計算誤差は、ERPの値を調整することで抑えられます。
PositionやPositionRateといった位置や速度に関する関数は、取得のみを行えます。また力とトルクは別の関数になります。
※下表では関数名の一部を省略しています。正確には、
のようなdJoint~の形式となります。
種類 | 中心点 (Anchor) | 回転軸 (Axis) | 位置、角度 (Position,Angle) | |
---|---|---|---|---|
ボール |
Set |
|
--- | --- |
Get |
|
--- | ||
ヒンジ |
Set |
|
|
--- |
Get |
|
|
|
|
スライダー |
Set | --- |
|
--- |
Get |
|
|
||
ユニバーサル |
Set |
|
|
--- |
Get |
|
|
|
|
ヒンジ2 |
Set |
|
|
--- |
Get |
|
|
|
|
PR | Set |
|
|
--- |
Get |
|
|
|
|
PU | Set |
|
|
--- |
Get |
|
|
|
|
ピストン | Set |
|
|
--- |
Get |
|
|
|
ジョイントに働く力とトルクは他のパラメータとは異なり、すぐには取得できません。これは不要な演算を省いてパフォーマンスを向上するためで、取得するにはまずフィードバックを返すように設定する必要があります。フィードバックはdJointFeedback構造体として、
typedef struct dJointFeedback { dVector3 f1; // ジョイントが ボディ1に作用する力 dVector3 t1; // ジョイントが ボディ1に作用するトルク dVector3 f2; // ジョイントが ボディ2に作用する力 dVector3 t2; // ジョイントが ボディ2に作用するトルク } dJointFeedback;
のように定義されています。
フィードバックの設定にはdJointSetFeedback()を使用します。これにdJointFeedback構造体のポインタを渡すことでフィードバックが有効となり、逆に0を渡すことでこの機能を無効にできます。
void dJointSetFeedback ( dJointID, dJointFeedback * );
フィードバックはシミュレーションのステップごとに計算され、このdJointFeedback構造体のポインタを通して力とトルクを取得できます。
ジョイントに設定せれているdJointFeedback構造体のポインタは、dJointGetFeedback()で取得できます。フィードバックの設定時にdJointFeedbackを保持しているならば、この関数によって取得する必要はありません。なおフィードバックが設定されていない場合は、0が返されます。
dJointFeedback *dJointGetFeedback ( dJointID );
スライダーやピストンのような直線運動するものには力、それ以外はトルクになります。
void dJointAddSliderForce ( dJointID joint, dReal force ); void dJointAddPistonForce ( dJointID joint, dReal force );
void dJointAddHingeTorque ( dJointID joint, dReal torque ); void dJointAddPRTorque ( dJointID j, dReal torque ); void dJointAddPUTorque ( dJointID j, dReal torque );
2つの軸を持つジョイントは、トルクを2つ指定します。
void dJointAddUniversalTorques ( dJointID joint, dReal torque1, dReal torque2 ); void dJointAddHinge2Torques ( dJointID joint, dReal torque1, dReal torque2 );
これらの関数はボディの力の関数 (dBodyAddForce、dBodyAddTorque) のただのラッパーであり、接続されているボディに対してそれらの関数により力が加算されます。
void dJointSetBallParam ( dJointID, int parameter, dReal value ); void dJointSetHingeParam ( dJointID, int parameter, dReal value ); void dJointSetSliderParam ( dJointID, int parameter, dReal value ); void dJointSetUniversalParam ( dJointID, int parameter, dReal value ); void dJointSetHinge2Param ( dJointID, int parameter, dReal value ); void dJointSetFixedParam ( dJointID, int parameter, dReal value ); void dJointSetAMotorParam ( dJointID, int parameter, dReal value );
dReal dJointGetBallParam ( dJointID, int parameter ); dReal dJointGetHingeParam ( dJointID, int parameter ); dReal dJointGetSliderParam ( dJointID, int parameter ); dReal dJointGetUniversalParam ( dJointID, int parameter ); dReal dJointGetHinge2Param ( dJointID, int parameter ); dReal dJointGetFixedParam ( dJointID, int parameter ); dReal dJointGetAMotorParam ( dJointID, int parameter );
引数parameterで下表の定数を用いて対象とするパラメータを指定します。
定数 | 説明 | 範囲 | 既定値 |
---|---|---|---|
dParamLoStop | 角度または位置の下限。-dInfinityで制限が無効となる。 | -πより大きな値 | -dInfinity |
dParamHiStop | 角度または位置の上限。dInfinityで制限が無効となる。dParamLoStopより小さいと、dParamLoStopの制限も無効となる。 | πより小さな値 | dInfinity |
dParamVel | 目標とする速度または角速度 | ||
dParamFMax | dParamVelを達成するために発生する最大の力またはトルク。0とすると停止する。 | 0以上 | 0 |
dParamFudgeFactor | 停止状態から動作を始めるときに発生する、過大な力を抑制する。これは実装上の問題であり、このパラメータはそれをごまかす (fudge)。 | 0 ~ 1 | 1 |
dParamBounce | 反発係数。0とするとまったく弾まない。 | 0 ~ 1 | |
dParamERP | 停止するとき以外のERP | 0.1~0.8 | 0.2 |
dParamCFM | 停止するとき以外のCFM | 10⁻⁹~1 | 10⁻¹⁰ |
dParamStopERP | 停止するときのERP | 0.1~0.8 | 0.2 |
dParamStopCFM | 停止するときのCFM | 10⁻⁹~1 | 10⁻¹⁰ |
dParamSuspensionERP | サスペンションのERP (ヒンジ2のみで有効) | ||
dParamSuspensionCFM | サスペンションのCFM (ヒンジ2のみで有効) |