インバース キネマティックス ソルバ

次のセクションでは、HumanIK インバース キネマティックス ソルバを使用して、キャラクタの新しい位置を計算するために必要なプロセスの概要を示します。

手順 1. HIKCharacterState を更新する

HumanIK インバース キネマティックス ソルバを呼び出して、フォーワード キネマティックス アニメーション中にキャラクタが実行する動作を変更するときは、通常、各フレームでのキャラクタの現在のスタンスを開始点とします。この現在のスタンスは、初期化フェーズで作成した HIKCharacterState で指定します。

インバース キネマティックス ソルバは、各エフェクタに設定された Reach コンストレインを評価するときに、この現在のスタンスを考慮します。たとえば、キャラクタの左膝のエフェクタに対して 0.5 の Reach Translation を設定すると、キャラクタの左膝ノードは、左膝のエフェクタに指定する移動と、この HIKCharacterState に含まれている左膝ノードの移動の中間点になります。詳細は、「Reach」を参照してください。

HumanIK には、HIKCharacterState のノードを、ゲーム エンジンのキャラクタのジョイントの現在の FK 位置と向きに同期するために複数のオプションが用意されています。使用可能なすべてのオプションの詳細は、「アニメーション データを設定および取得する」を参照してください。

1 つの一般的な方法は、HIKCharacterState() の各ノードに対して HIKSetNodeStateTQSfv() 関数を呼び出すことです。この関数には次の引数が必要です。

例:

HIKSetNodeStateTQSfv (MyCharacter, MyCharState, RightHandNodeId,
                                             myModel.GetTranslation(RightHandNodeId), 
                                             myModel.GetQuatRotation(RightHandNodeId), 
                                             myModel.GetScaling(RightHandNodeId));

手順 2. エフェクタの位置と回転を設定する

各フレームで、各キャラクタの四肢の希望の位置と回転を含めるように HIKEffectorSetState を設定する必要があります。すべてのエフェクタの位置と回転を設定する必要はありません。ゴール ポイントとして指定するエフェクタのみで、Reach Translation または Reach Rotation コンストレインにゼロ以外の値を設定します。その他のエフェクタは実質的にインバース キネマティックス ソルバによって無視され、位置と向きは最終ソリューションに対して影響がありません。

次のいずれかの手法を使用して、エフェクタの位置と回転を設定できます。

エフェクタの位置と回転を直接設定する

HumanIK には、エフェクタの 3 次元の位置と向きを設定するためのいくつかのオプションが用意されています。使用可能なすべてのオプションの詳細は、「アニメーション データを設定および取得する」を参照してください。

1 つの一般的な方法は、HIKEffectorSetState の各エフェクタに対して HIKSetEffectorStateTQSfv() 関数を呼び出すことです。この関数には次の引数が必要です。

  • HIKEffectorSetState へのポインタ。
  • 操作するエフェクタの固有の ID。このエフェクタ ID は、humanik.h ファイルの HIKEffectorId 列挙値にリストされている任意の値とすることができます。

    このエフェクタ ID は、HIKCharacterDefinition の作成時に指定した、該当するジョイントのノード ID と同じではないことに注意してください。

  • エフェクタの移動、クォータニオン回転、スケール値を表す 4 つの浮動小数点の個別の配列。

HIKEffectorSetState で設定する移動、回転、スケール値は、内部的な計算のために HumanIK で使用される正規化されたスペースで表現されることが想定されています。キャラクタのデフォルトの T スタンスに回転またはスケールのオフセットが含まれていないノードでは、この正規化されたスペースはグローバル スペースと同じになります。キャラクタのデフォルトの T スタンスに回転またはスケールのオフセットが含まれているノードでは、エフェクタを使用してキャラクタの希望の向きまたはスケールを設定する場合、代わりに HIKSetCharacterSpaceEffectorStateTQSfv() 関数を呼び出す必要があります。正規化された空間の詳細は、「HIKEffectorSetState でデータを設定および取得する」を参照してください。

例:

HIKSetEffectorStateTQSfv (MyEffectorSet, RightHandEffectorId, targetTranslation,
                                                              targetQuatRotation,
                                                              targetScaling);

HIKCharacterState からエフェクタ セットを初期化する

HIKEffectorSetState でエフェクタの位置と回転を設定し、HIKCharacterState 内のノードに合わせることができます。この初期化後は、選択したエフェクタの移動と回転にオフセットを適用できます。

次は一般的に考えられるシナリオと手法です。

HIKCharacterState からエフェクタ セットを初期化するには、HIKEffectorSetFromCharacter 関数を呼び出します。この関数には次の引数が必要です。

例:

HIKEffectorSetFromCharacter (MyChar, MyEffectorSet, MyCharState, MyPropertySet);

HIKEffectorSetState を初期化したら、HIKGetEffectorStateTQSfv() 関数を使用して行列を取得することで各エフェクタの位置と回転を変更し、返された値にオフセットを適用し、HIKSetEffectorStateTQSfv() 関数を使用して、変更された値を再度適用できます。例:

const float trans[4];
const float quatRot[4];
const float scale[4];
HIKGetEffectorStateTQSfv (MyEffectorSet, RightHandEffectorId, trans, quatRot, scale);
...  // offset trans, quatRot and/or scale values here  
HIKSetEffectorStateTQSfv (MyEffectorSet, RightHandEffectorId, trans, quatRot, scale);

手順 3. エフェクタのコンストレインを設定する

各エフェクタの Reach Translation、Reach Rotation、Pull、Resist の値は、HIKEffectorSetState で個別にコントロールできます。

デフォルトでは、これらの各コンストレインは値 0 に設定されます。これにより、インバース キネマティックス ソルバは、ソルバに指定する HIKCharacterState で表されるスタンスにキャラクタのすべてのジョイントを設定します。通常、これにはキャラクタの現在の FK スタンスが含まれます。インバース キネマティックス ソルバでエフェクタが考慮されるためには、次の関数を使用してこれらのコンストレインに対して新しい値を設定する必要があります。

これらの関数では、すべて次の引数が必要です。

たとえば、次の行を指定すると、右手はエフェクタの位置の中間まで移動し、必要に応じてボディの残りが引き寄せられる一方で、右肘は元の角度を維持しようとします。

HIKSetTranslationActive(MyEffectorState, RightHandEffectorId, 0.5f);
HIKSetPull(MyEffectorState, RightHandEffectorId, 1.0f);
HIKSetResist(MyEffectorState, RightElbowEffectorId, 0.75f);

手順 4. ソルバ ステップを設定する

インバース キネマティックス ソルバ プロセスは複数の手順に分割され、各手順で、選択されたジョイント チェーンの新しい位置、Pull などのコンストレインの効果、フロア コンタクト(「足および手のコンタクト」を参照)や Squash ’n’ Stretch(「Squash 'n' Stretch を使用する」を参照)など特殊な変形の結果が計算されます。

インバース キネマティックス ソルバによって実行されるソルバ ステップを指定するには、HIKSetIKSolvingStep() 関数を呼び出します。この関数は次の 2 つの引数が必要です。

例:

HIKSetIKSolvingStep (MyEffectorState, HIKSolvingStepAll);

HIKSolvingStep 列挙値にリストされている複数のソルバ ステップを指定するには、それらの値を | 演算子(ビット単位の OR)で連結する必要があります。例:

HIKSetIKSolvingStep (MyEffectorState, HIKSolvingStepBodyPull |

手順 5. キャラクタ プロパティを設定する

HIKPropertySetState で設定を変更して、HumanIK インバース キネマティックス ソルバのさまざまな動作をコントロールできます。

HIKPropertySetState はデフォルト値の一貫したセットで初期化されるので、HumanIK を動作させるために値を変更する必要はありません。これは任意に指定できます。各キャラクタに対して適切なプロパティ値を設定すると、多くの場合、リアルでより良い結果を得ることができます。これは、スカラ距離の値を維持するキャラクタ プロパティに特に当てはまります。これらのプロパティのデフォルト値は、高さが約 180 ユニットのキャラクタに対してサイズが設定されているためです。

キャラクタに使用できる設定オプションと、そのオプションの値の設定方法の詳細は、「キャラクタ プロパティ」を参照してください。

手順 6. ソルバを起動する

HumanIK インバース キネマティックス ソルバを起動するには、HIKSolveForEffectorSet 関数を呼び出します。この関数には次の引数が必要です。

例:

HIKSolveForEffectorSet (MyChar, MyCharState, MyEffectorSet, MyPropertySet);

手順 7. 生成された HIKCharacterState を取得する

インバース キネマティックス ソルバは、キャラクタに対して生成するポーズを、引数として渡したのと同じ HIKCharacterState に格納します。各ノードの移動、向き、スケールはこの HIKCharacterState で取得し、ゲーム エンジンのキャラクタに適用し直す必要があります。

HumanIK には、HIKCharacterState のノードの 3 次元の位置と回転を取得するためのオプションがいくつか用意されています。使用可能なすべてのオプションの詳細は、「アニメーション データを設定および取得する」を参照してください。

キャラクタに対して計算されたポーズを取得するための 1 つの一般的な方法は、HIKCharacterState の各ノードに対して HIKGetNodeStateTQSfv() 関数を呼び出すことです。この関数には次の引数が必要です。

例:

const float trans[4];
const float quatRot[4];
const float scale[4];
HIKGetNodeStateTQSfv (MyCharState, RightHandNodeId, trans, quatRot, scale); 
... // apply retrieved values back to game engine here 

各ノードに対して取得した値を、ゲーム エンジンのキャラクタの対応するジョイントに再適用するかどうかは、ユーザが決定します。