コンストレイントを使用すると、オブジェクトのアニメーションを使用して別のオブジェクトをアニメートできます。 あるオブジェクトの位置や方向などのさまざまなプロパティを別のオブジェクトのプロパティに拘束します。 ユーザ独自のコンストレイントは作成できませんが、Softimage には SDK を使って適用、操作できるさまざまなタイプのコンストレイントが用意されています。
コンストレイントは、1 つまたは複数のオブジェクトをコンストレイニング(拘束する側) オブジェクトとして認識し、1 つのオブジェクトを被コンストレイント(拘束される側) オブジェクトとして認識します。 コンストレイントを「所有」するのは、拘束される側の被コンストレイント オブジェクトです。コンストレイントは、被コンストレイント オブジェクトのキネマティクスからアクセスできます。 ユーザはコンストレイニング側と被コンストレイント側のオブジェクトの両方にコンストレイントからアクセスできます(詳細は「SDK を使ってコンストレイントへアクセスする」を参照)。
コンストレイントは、コンストレイニング オブジェクトと被コンストレイント オブジェクトとの間を取り持つデータ断片です。 また、コンストレイントはコンストレイントのタイプに応じて特定の接続ポイント セットを予想します。たとえば、サーフェス コンストレイントでは、拘束する側が NURBS サーフェスであると予想します。一方、ポーズ コンストレイントでは、コンストレイニング オブジェクトが任意の 3D オブジェクトであると予想します。
以下のようにスクリプト コマンド、オブジェクト モデル、または C++ API を使用して、コンストレイントを適用できます。
スクリプト コマンド: SIApplyCns
このほかに、サイクル チェックを実行する ApplyCns コマンドを使用できます。ただし、サイクル チェックを行うと、無視して問題ない場合(意図的にサイクルを行っている場合)も含めて多数の警告がログに記録される可能性があるため、問題が生じる場合があります。 別の問題として、サイクルが検出されるとメッセージが画面表示されることが挙げられます。その場合、自動化されたツールは停止され、サイクル警告メッセージを 1 つずつ手動で解決する必要があります。
オブジェクトモデル: Kinematics.AddConstraint メソッド
C++ API: Kinematics::AddConstraint メンバ
SDK を使ってコンストレイントを削除する場合は、以下のいずれかのスクリプト コマンドのみを使用できます。
RemoveCns: 名前で識別されるコンストレイントを削除します。
DeleteObj: 指定されたオブジェクトを削除するための汎用コマンド。
オブジェクト モデル(JScript の例: Constraint オブジェクトへのアクセス)および C++ API(C++ API の例: Constraint オブジェクトへのアクセス)の両方のキネマティクス プロパティからオブジェクトへ適用したコンストレイントを取得できます。 スクリプト コマンドの場合は、被コンストレイント オブジェクトを GetConstrainedObjects コマンドで取得できます。
そこから、Constraint オブジェクトは、コンストレイニング オブジェクト、被コンストレイント オブジェクト、および UpVector リファレンス(被コンストレイント オブジェクトが指す必要がある方向を決定するオブジェクト)へのアクセスを提供します。 以下の例は、Constraint オブジェクトとそのプロパティにアクセスする方法を示します。
JScript の例: Constraint オブジェクトへのアクセス
// "obj" is a pointer to a constrained object var cnslist = obj.Kinematics.Constraints; // Enumerate over the ConstraintCollection for ( var i=0; i<cnslist.Count; i++ ) { var cns = cnslist(0); var myself = cns.Constrained; // this should point to the original 'obj' var stuckonyou = cns.Constraining; // everyone constraining 'obj' var upvect = cns.UpVectorReference; // object used as my upvector reference Application.LogMessage( "Constraint type: " + cns.Type ); Application.LogMessage( "Constrained object: " + myself ); Application.LogMessage( "# of Constraining objects: " + stuckonyou.Count ); Application.LogMessage( "UpVectorRef: " + upvect ); } // So if you had a sphere pose-constrained by a null (with no up-vector // reference), you would get something like this: //INFO : Constraint type: posecns //INFO : Constrained object: sphere //INFO : # of Constraining objects: 1 //INFO : UpVectorRef: null
C++ API の例: Constraint オブジェクトへのアクセス
// "obj" is a pointer to a constrained object Kinematics kine = obj.GetKinematics(); CRefArray cnslist = kine.GetConstraints(); // Enumerate over the CRefArray of Constraints for ( LONG i=0; i<cnslist.GetCount(); ++i ) { CRef ref = cnslist.GetItem(i); if ( ref.IsA(siConstraintID) ) { Constraint cns(ref); X3DObject myself = cns.GetConstrained(); // this should point to the original 'obj' CRefArray stuckonyou = cns.GetConstraining(); // everyone constraining 'obj' X3DObject upvect = cns.GetUpVectorReference(); // object used as my upvector reference app.LogMessage( L"Constraint type: " + cns.GetType() ); app.LogMessage( L"Constrained object: " + myself.GetName() ); app.LogMessage( L" # of Constraining objects: " + stuckonyou.GetCount() ); app.LogMessage( L"UpVectorRef: " + upvect.GetName() ); } } // So if you had a sphere pose-constrained by a null (with no up-vector // reference), you would get something like this: //INFO : Constraint type: posecns //INFO : Constrained object: sphere //INFO : # of Constraining objects: //INFO : UpVectorRef:
また、コンストレイントに基づくクリップとソースからアニメーション情報を取得することも可能です。 詳細については「コンストレイントとミキサ」を参照してください。
コンストレイント スタックは、被コンストレイント オブジェクトのキネマティクス プロパティの下にネストされたコンストレイントのコレクションです。 UI に表示される順序は一般のオペレータ スタックを反映しています。つまり、最後に適用したコンストレイントがスタックの最上部に表示されます。 SDK を使ってコンストレイントのコレクションにアクセスすると、適用時と同じ順序でコンストレイントを取得します。
オブジェクトに複数のコンストレイントが適用されており、コンストレイントの比重をブレンドする場合は、Constraint オブジェクトから blendweight パラメータにアクセスします。
blendweight パラメータは、ショートカット表記または標準(フル)表記(ParameterCollection から名前によってパラメータを取得)によって特定できます:
// "cns" is a pointer to a constraint cns.blendweight.Value = .25;// shortcut notation cns.Parameters("blendweight").Value = .25;// full notation
blendweight パラメータの値は、便利な ProjectItem::PutParameterValue 関数または標準(フル)表記(CParameterRefArray から名前でパラメータを取得)を使用して変更できます。
// "cns" is a pointer to a constraint cns.PutParameterValue(L"blendweight", 0.75);// use convenience method CParameterRefArray paramlist = cns.GetParameters();// full notation Parameter param = paramlist.GetItem(L"blendweight"); param.PutValue(0.75);
コンストレイントは ActionSource または ActionSource 内にあるタイプのアニメーションとして Animation Mixer で使用できます。ただし、コンストレイントは、アクションの基本 DataSource として使用すると、FCurves または FCurves または ShapeKeys または ShapeKeys などの別タイプのデータ ソースとは異なり、クリップやソースからアクセスできなくなります。これは、パフォーマンス上の理由から、完全なコンストレイントがアクション内に格納されていないためです。 コンストレイントのクリップはソースから独立して別に独自のデータを保持するので、コンストレイント(ソース)を更新しても、新しい値はミキサ内のクリップに反映されません。
SDK でアクション ソースを作成する唯一の方法は、StoreAction コマンドを使用することです。 StoreAction コマンドはあらゆる種類のアクションを保存するので、そのパラメータを確実に正しく設定する必要があります。 以下に従うべきガイドラインをいくつか示します。
InputObjs パラメータでは、コンストレイント自体ではなく、影響を受けるパラメータを指定します。 その際、コンストレイントは常にグローバル空間で定義されるので、影響を受けるパラメータは常にグローバル変換のパラメータであることに注意してください。
もう 1 つ覚えておくべき重要な点は、影響を受けたパラメータを相対名で指定する必要があることです。指定しないと、後でミキサーのクリップとしてこのソースをインスタンス化する場合に、接続に問題が起こることがあります。
RemoveAnimパラメータでは、TRUE(既定)を指定すると、コンストレイントがアニメートされたパラメータから削除されます。
AddClip パラメータでは、FALSE(既定)を指定すると、後で AddClip コマンドをこのソースに実行して、ミキサーにインスタンスを作成できます。
コンストレイントに基づくアクションソースとクリップは、他のアクション ソースやミキサ クリップと同じようにアクセスできます(詳細は「ソースとクリップ」を参照)。 ただし、コンストレイントベースのソースは完全なコンストレイントを保存しないので、ベースとなるコンストレイント オブジェクトには以下のいずれの方法でもアクセスできません。
コンストレイントでサイクルを作成するときは、常に注意が必要です(詳細は「アニメーション(ユーザ)ガイド」を参照)。しかし、ミキサ内のコンストレイントベースのアニメーションで作業する場合は、潜在的なサイクルを見失いやすいので、特に 1 つのオブジェクトから別のオブジェクトにソースをコピーしているときには注意が必要です。
CycleChecking コマンドはこのようなサイクルの検出に役立ちますが、サイクルに対処する機能はありません。 唯一の解決策は、シーン内のサイクルを生み出す箇所を修正することで、循環的な依存を取り去ることです。
コンストレイントは、カスタム オペレータ(スクリプト オペレータ)に似ています。 ただし、Softimage への実装方法に基本的な違いがいくつかあるため、動作と外観の面で以下のような相違点があります。
UI 上で、コンストレイントは、被コンストレイント オブジェクトのキネマティクス プロパティの下に、プロパティのコレクションとして表示されます。一方、カスタム オペレータは出力パラメータの下にネストされます。
コンストレイントはカスタム オペレータとは異なり、一般にオブジェクト全体に適用されます。一方、カスタム オペレータは常に特定のパラメータに直接適用されます。 コンストレイントはオブジェクトのパラメータではなく、オブジェクトのグローバル変換に影響を与えます。
コンストレイントとカスタム オペレータの両方を、ミュートや削除できます。ただし、コンストレイントによる変更を加えたオブジェクトは、コンストレイントを取り去った時点のままで残ります。一方、カスタム オペレータの影響を受けたオブジェクトは、オペレータ適用前の状況に戻されます。