コンストレイント

 
 
 

コンストレイントを使用すると、オブジェクトのアニメーションを使用して別のオブジェクトをアニメートできます。 あるオブジェクトの位置や方向などのさまざまなプロパティを別のオブジェクトのプロパティに拘束します。 ユーザ独自のコンストレイントは作成できませんが、Softimage には SDK を使って適用、操作できるさまざまなタイプのコンストレイントが用意されています。

ヒント:

Softimage でコンストレイントを使用する際の一般情報については、『Softimage ユーザ ガイド』を参照してください。

コンストレイントは、1 つまたは複数のオブジェクトをコンストレイニング(拘束する側) オブジェクトとして認識し、1 つのオブジェクトを被コンストレイント(拘束される側) オブジェクトとして認識します。 コンストレイントを「所有」するのは、拘束される側の被コンストレイント オブジェクトです。コンストレイントは、被コンストレイント オブジェクトのキネマティクスからアクセスできます。 ユーザはコンストレイニング側と被コンストレイント側のオブジェクトの両方にコンストレイントからアクセスできます(詳細は「SDK を使ってコンストレイントへアクセスする」を参照)。

注:

コンストレイントは変換にグローバル空間のみを使用します。そのため、ローカル パラメータに加える変更は、コンストレイントによって上書きされる可能性があることに注意してください(パラメータがどのようにアニメートされているかに関係なく、グローバル変換がローカル変換を上書きするため)。

コンストレイントは、コンストレイニング オブジェクトと被コンストレイント オブジェクトとの間を取り持つデータ断片です。 また、コンストレイントはコンストレイントのタイプに応じて特定の接続ポイント セットを予想します。たとえば、サーフェス コンストレイントでは、拘束する側が NURBS サーフェスであると予想します。一方、ポーズ コンストレイントでは、コンストレイニング オブジェクトが任意の 3D オブジェクトであると予想します。

SDK を使ってコンストレイントへアクセスする

以下のようにスクリプト コマンド、オブジェクト モデル、または C++ API を使用して、コンストレイントを適用できます。

  • スクリプト コマンド: SIApplyCns

    ヒント:

    この他に、サイクル チェックを実行する ApplyCns コマンドを使用できます。ただし、サイクル チェックを行うと、安全面で無視できる場合(意図的にサイクルを行っている場合)も含めて多数の警告ログ メッセージが作成される可能性があり、問題を生じる場合があります。別の問題として、サイクルが検出されるとメッセージが画面表示されることが挙げられます。その場合、自動化されたツールは停止され、サイクル警告メッセージを 1 つずつ手動で解決することが求められます。

  • オブジェクト モデル: 被コンストレイント オブジェクトの Kinematics.AddConstraint メソッド。

  • C++ API: 被コンストレイント オブジェクトの Kinematics::AddConstraint メンバ。

    注:

    SDKを使ってコンストレイントを削除する場合は、以下のいずれかのスクリプトコマンドのみを使用できます。

    • RemoveCns: 名前で識別されるコンストレイントを削除します。

    • RemoveCnsType: 指定されたコンストレイント タイプに一致するすべてのコンストレイントを削除します。
    • DeleteObj:指定されたオブジェクトを削除するための汎用コマンド。

SDK を使ってコンストレイントへアクセスする

オブジェクト モデル(JScript の例: Constraint オブジェクトへのアクセス)および C++ API(C++ API の例: Constraint オブジェクトへのアクセス)の両方のキネマティクス プロパティからオブジェクトへ適用したコンストレイントを取得できます。 スクリプト コマンドの場合は、被コンストレイント オブジェクトを GetConstrainedObjects コマンドで取得できます。

この操作を実行すると、Constraint オブジェクトにより、コンストレイント オブジェクトのコレクションだけでなく被コンストレイント オブジェクト、アップベクター リファレンス(被コンストレイント オブジェクトの向く方向を決めるオブジェクト)にもアクセスできるようになります。以下の例は、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 パラメータにアクセスします。

重要:

3 つ以上のコンストレイントで作業する場合は、blendweight の設定に若干の特性があります。 この場合の blendweight の設定方法とその必要性については、「アニメーション」の「コンストレイントのブレンド」を参照してください。

JScript の例: コンストレイントのブレンド

次のように blendweight パラメータは、ショートカット表記または標準表記(フル表記)で識別できます(フル表記は ParameterCollection から名前でパラメータを取得する場合に使用します)。

// "cns" is a pointer to a constraint
cns.blendweight.Value = .25;// shortcut notation
cns.Parameters("blendweight").Value = .25;// full notation

C++ APIの例:コンストレイントのブレンド

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 つ覚えておくべき重要な点は、影響を受けたパラメータを相対名で指定する必要があることです。指定しないと、後でミキサーのクリップとしてこのソースをインスタンス化する場合に、接続に問題が起こることがあります。

  • Mode パラメータでは、以下のいずれかの値を指定します。

    • 4 は、コンストレイントのみに基づいてソースを作成する場合。

    • 5 は、F カーブ、式、およびコンストレイントに基づいてソースを作成する場合。

    • 6 は、F カーブ、式、およびコンストレイントに基づき、さらにアニメートされていないパラメータの現在値にも基づいてソースを作成する場合。

  • RemoveAnim パラメータでは、TRUE(既定)を指定すると、コンストレイントがアニメートされたパラメータから削除されます。

  • AddClip パラメータでは、FALSE(既定)を指定すると、後で AddClip コマンドを実行してミキサにこのソースのインスタンスを作成することができます。

コンストレイントベースのソースとクリップにアクセスする

コンストレイントに基づくアクションソースとクリップは、他のアクション ソースやミキサ クリップと同じようにアクセスできます(詳細は「ソースとクリップ」を参照)。 ただし、コンストレイントベースのソースは完全なコンストレイントを保存しないので、ベースとなるコンストレイント オブジェクトには以下のいずれの方法でもアクセスできません。

ソース内のサイクルについて

コンストレイントでサイクルを作成するときは、常に注意が必要です(詳細は「アニメーション(ユーザ)ガイド」を参照)。しかし、ミキサ内のコンストレイントベースのアニメーションで作業する場合は、潜在的なサイクルを見失いやすいので、特に 1 つのオブジェクトから別のオブジェクトにソースをコピーしているときには注意が必要です。

CycleChecking コマンドはこのようなサイクルの検出に役立ちますが、サイクルに対処する機能はありません。唯一の解決策は、シーン内のサイクルを生み出す箇所を修正することで、循環的な依存を取り去ることです。

コンストレイントとカスタム(スクリプト)オペレータの比較

コンストレイントは、カスタム オペレータ(スクリプト オペレータ)に似ています。 ただし、Softimage への実装方法に基本的な違いがいくつかあるため、動作と外観の面で以下のような相違点があります。

  • UI 上で、コンストレイントは、被コンストレイント オブジェクトのキネマティクス プロパティの下に、プロパティのコレクションとして表示されます。一方、カスタム オペレータは出力パラメータの下にネストされます。

  • コンストレイントはカスタム オペレータとは異なり、一般にオブジェクト全体に適用されます。一方、カスタム オペレータは常に特定のパラメータに直接適用されます。 コンストレイントはオブジェクトのパラメータではなく、オブジェクトのグローバル変換に影響を与えます。

  • コンストレイントとカスタム オペレータの両方を、ミュートや削除できます。ただし、コンストレイントによる変更を加えたオブジェクトは、コンストレイントを取り去った時点のままで残ります。一方、カスタム オペレータの影響を受けたオブジェクトは、オペレータ適用前の状況に戻されます。

コンストレイントがオペレータおよび式とコミュニケーションする方法

オペレータと式は、同じオブジェクトのコンストレイントより常に先に評価されます。 オペレータが、コンストレイントで制御されるパラメータからデータを読み取っている場合、オペレータによって引き出されたデータは不適切な場合があります。 この問題の対処法は、null にコンストレイントを適用し、代わりにそこからデータを読み取ることです。