HIKCharacter をプログラムでキャラクタライズする

次の手順では、新しい HIKCharacter を作成し、HumanIK API で提供される関数を使用して、プログラムでキャラクタライゼーションをセットアップします。

ユーザ独自のコードでこのキャラクタライゼーション プロセスの実行を試みる前に、このドキュメントの次のセクションの内容を読んで理解しておく必要があります。

手順 1. HIKCharacterDefinition を作成する

キャラクタの HIKCharacterDefinition を作成する必要があります。これは、その定義から作成されるすべての HIKCharacter に存在するノードまたはジョイントを識別する設計図です。

このクラスには、1 つの主要なメンバーである mUsedNodes が含まれます。これは、HIKNodeId 列挙値に示されている、事前に決定された使用可能なジョイントの要素が含まれる整数の配列です。HIKCharacterDefinition クラスのインスタンスを作成し、各要素の値を mUsedNodes 配列で設定して、対応するノード ID を HIKCharacterDefinition で使用するかどうかを示します。

HIKCharacterDefinition で使用するノード ID にフラグを付けるには、mUsedNode 配列の対応する要素の値を HIKNodeUsed に設定します。ノード ID を未使用として HIKCharacterDefinition でフラグを付けるには、mUsedNode インデックスの該当する要素の値を HIKNodeNotUsed に設定します。

たとえば、次のサンプル コードは、HIKCharacterDefinition を作成し、その定義から作成されるすべての HIKCharacter で使用されるノードを初期化するための典型的なメソッドを示しています。

// first, create an array containing the Node IDs 
// that represent joints you want to use. This example uses only
// the mandatory Node Ids required by HumanIK, listed below. 
int gCharacterJointTotal = 15;
const int fJointIds[] = {HipsNodeId, 
                         LeftHipNodeId,
                         LeftKneeNodeId,
                         LeftAnkleNodeId,
                         RightHipNodeId, 
                         RightKneeNodeId,
                         RightAnkleNodeId, 
                         WaistNodeId,
                         LeftShoulderNodeId,
                         LeftElbowNodeId,
                         LeftWristNodeId,
                         RightShoulderNodeId,
                         RightElbowNodeId,
                         RightWristNodeId,
                         HeadNodeId};

// Next, create an HIKCharacterDefinition object, and initialize
// its memory space to 0 (or HIKNodeNotUsed). 
HIKCharacterDefinition MyDef;
memset(&MyDef, 0, sizeof(HIKCharacterDefinition));

// Finally, iterate through the array of Node IDs to be used, and 
// set the corresponding element in the mUsedNodes array to 
// HIKNodeUsed. 
int ii; 
for (ii = 0; ii < gCharacterJointTotal; ++ii) 
{ 
   MyDef.mUsedNodes[fJointIds[ii]] = HIKNodeUsed;
} 

特定の状況では、HIKNodeUsed および HIKNodeNotUsed の 2 つの代用方法も使用できます。

HIKCharacterDefinition は、少なくとも HumanIK で必要となる 15 個すべてのノードを有効にする必要があります。詳細は、「HumanIK ノードおよびエフェクタにジョイントをマッピングする」を参照してください。

手順 2. HIKCharacterDefinition から HIKCharacter を作成する

手順 初期化 で作成した HIKCharacterDefinition を基に HIKCharacter を作成するには、HIKCharacterCreate() 関数を呼び出します。この関数には次の引数が必要です。

例:

HIKCharacter * MyChar = HIKCharacterCreate(&MyDef, &malloc, AutodeskCustomerString, AutodeskCustomerKey); 
if (MyChar == 0)
{
    // the character could not be created. Handle the error here.
}

新しく作成された HIKCharacter には、HIKNodeUsedHIKNodeLimits、または HIKNodeParentOffset フラグで設定されたジョイントのみが HIKCharacterDefinition に含まれています。

HIKCharacterCreate() 関数が NULL ポインタを返す場合、ほとんどはライセンス キーまたはキャラクタ定義に問題があります。「トラブル シューティング」を参照してください。

手順 3. HIKCharacter のジオメトリをセットアップする

この時点で、足首、膝、肘などのジョイント セットでキャラクタが初期化されました。ただし、キャラクタがデフォルトの T スタンスで立っているときに、各ジョイントのトランスレーション、回転、スケールを指定して、キャラクタのスケルトンをさらに定義する必要があります。この T スタンスの詳細は、「デフォルトの T スタンス」を参照してください。

これらのデフォルトの位置と向きを指定するには、キャラクタによって使用されるノードごとに HIKSetCharacterizeNodeStateTQSfv() 関数を呼び出します。この関数には次の引数が必要です。

例:

float trans[4];
float quat[4];
float scale[4];
for (ii = 0; ii < LastNodeId; ++ii) 
{ 
   if (sSuccess == fJointIds.find(ii)) 
   { 
      HIKSetCharacterizeNodeStateTQSfv(MyChar, ii, trans, quat, scale); 
   }
} 

HIKSetCharacterizeNodeStateTQSfv() の代わりに、4x4 変換行列で表したトランスレーション、向き、スケール値を受け入れる HIKSetCharacterizeNodeStatefv() 関数を呼び出すことができます。この行列の詳細は、「変換配列」を参照してください。

手順 4. Degrees of Freedom をセットアップする(オプション)

キャラクタのノードで Degrees of Freedom を設定し、好ましくない状態または不自然な状態で回転しないように制限するには、この時点で制限(Limit)を設定する必要があります。

Degrees of Freedom を設定できるのは、HIKCharacterDefinitionHIKNodeLimits フラグを割り当てて指定したノードのみであることに注意してください。上記の手順「HIKCharacter をプログラムでキャラクタライズする」を参照してください。

キャラクタの Degrees of Freedom を設定するには、希望のノードごとに HIKSetLimitsfv() 関数を呼び出します。設定ができるパラメータの詳細は、API リファレンスで関数の説明を参照してください。Degrees of Freedom は常にローカル スペースで指定し、角度ではなくラジアン単位で指定する必要があることに注意してください。

例:

const float minValues[] = {0.0f, 0.7854f, 0.0f};
const float maxValues[] = {1.571f, 1.571f, 0.0f};
const float preRot[] = {0.0f, 0.0f, 0.0f, 1.0f};
const float postRot[] = {0.0f, 0.0f, 0.0f, 1.0f};

HIKSetLimitsfv (MyCharacter1, RightKneeNodeId, minValues, maxValues, preRot, postPost, HIKActiveMinX | HIKActiveMaxX | HIKActiveMinY | HIKActiveMaxY, HIKOrderEulerXYZ);

詳細は、「Degrees of Freedom 」を参照してください。

手順 5. キャラクタライゼーションを確定する

HIKCharacter で使用されるノードごとに、適切なトランスレーション、回転、スケール値を指定したら、HIKCharacterizeGeometry() 関数を呼び出し、HIKCharacter へのポインタを渡してキャラクタのジオメトリを確定する必要があります。

例:

bool result = HIKCharacterizeGeometry(MyChar);
if (result == false)
{ 
    // The characterization was unsuccessful; handle the error. 
}

キャラクタライゼーションを確定すると、HIKCharacter を使用できるようになります。引き続き「初期化」の手順に従って、キャラクタに必要なその他の HumanIK オブジェクトをセットアップします。

HIKCharacterizeGeometry() 関数が false を返す場合、ほとんどはキャラクタの T スタンスに問題があります。「トラブル シューティング」を参照してください。