HumanIK オブジェクトとメモリ管理

このセクションでは、HumanIK オブジェクトのメモリの使用と、これらのオブジェクトによって使用されるメモリの管理に使用できる組み込みのアプローチについて詳しく説明します。

オブジェクトのメモリ要件

HumanIK オブジェクトには次のメモリ要件があります。

HIKCharacter

HIKCharacter のサイズは設定に依存します。

  • HIKCharacter の基本サイズは 9616 バイトです。
  • HIKCharacter によって使用される各ノードには、追加の 240 バイトが必要です。
  • Degrees of Freedom により設定された各ノードには、追加の 192 バイトが必要です。
  • ペアレント オフセットがある各ノードには、追加の 48 バイトが必要です。ただし、そのノードにさらに Degrees of Freedom がある場合を除きます(DOF に与えられる上記の値には、48 バイトのペアレント オフセットが含まれます)。

既存の HIKCharacter のメモリ内での現在のサイズを判断するには、HIKCharacterSize() 関数を呼び出します。 この関数には、引数として HIKCharacter へのポインタが必要です。

または、HIKCharacter のメモリ内での予想サイズを作成前に判断するには、HIKCharacterDefinitionSize() 関数を呼び出します。この関数には、引数として、HIKCharacter の作成に使用される HIKCharacterDefinition が必要です。

HIKCharacterState

HIKCharacterState のサイズは、HIKCharacter が使用するノードの数に依存します。

  • HIKCharacterState の基本サイズは 144 バイトです。
  • キャラクタによって使用される各ノードには、追加の 96 バイトが必要です。

既存の HIKCharacterState のメモリ内での現在のサイズを判断するには、HIKCharacterStateSize() 関数を呼び出します。 この関数には、引数として HIKCharacterState へのポインタが必要です。

HIKEffectorSetState

HIKEffectorSetState には 3296 バイトが必要です。

HIKPropertySetState

HIKPropertySetState には 1936 バイトが必要です。

作成するオブジェクトのメモリの割り当てと メモリの割り当て解除

HumanIK 内の、メモリを割り当てる必要があるすべての関数(「HumanIK 入門」の章で紹介した、HIKCharacterHIKCharacterStateHIKEffectorSetStateHIKPropertySetState を作成するための関数など)には、その関数を割り当てるために使用されるコールバック関数への参照が必要です。標準の malloc 関数か、malloc と同じ型定義に従うその他のカスタム メモリ割り当て関数を使用することができます。

同様に、「HumanIK 入門」の章で紹介した、これらのオブジェクトを破棄するための関数には、破棄するオブジェクトに割り当てられたメモリ リソースを解放するために使用するコールバックへの参照が必要です。 標準の free 関数か、free と同じ型定義に従うその他のカスタム メモリ割り当て関数を使用することができます。

たとえば、次のコードでは、mallocfree を使用して HIKCharacterState の作成と破棄を行います。

HIKCharacterState* lcharacterState = HIKCharacterStateCreate(character1, &malloc);
...
HIKCharacterStateDestroy(lcharacterState, &free);

事前に割り当てられたメモリ内にオブジェクトを作成する

HIKCharacterHIKCharacterStateHIKEffectorSetState、または HIKPropertySetState を作成するたびに新しいメモリを割り当てるのではなく、事前に割り当てられたメモリ バッファ内の指定した場所に、新しい HumanIK オブジェクトを作成することができます。単一のメモリ プールを事前に割り当て、そのバッファ内の指定したポインタに関連する HumanIK オブジェクトをすべて作成することで、関連する HumanIK オブジェクトを連続するメモリ ブロック内に維持し、パフォーマンスを向上させることができます。

この方法でオブジェクトを作成するには、HIKCharacterCreateInPlace()HIKCharacterStateCreateInPlace()HIKEffectorSetCreateInPlace()HIKPropertySetCreateInPlace() の各関数を呼び出します。 これらの関数には、「HumanIK 入門」の章で説明したオブジェクト作成関数と同じ引数が必要です。ただし、メモリを割り当てるためのコールバック関数への参照ではなく、有効なメモリ位置への void ポインタが必要です。 このポインタは 16 バイト単位で揃えられている必要があり、バッファは作成するオブジェクトを含むのに十分な大きさである必要があります。 詳細については、前述の「 HumanIK オブジェクトとメモリ管理」を参照してください。

例:

HIKCharacterState* lcharacterState = HIKCharacterStateCreateInPlace(character1, bufferAlignedTo16);

メモリ バッファの割り当てと割り当て解除は、HumanIK の外部で処理される可能性が最も高くなります。したがってこの方法でオブジェクトを作成するときは、通常は「クリーンアップ」で説明した HumanIK のオブジェクト破棄関数を呼び出してオブジェクトを明示的に破棄する必要はありません。

連続するメモリ ブロックを使用する

最良のパフォーマンスを得るには、関連するすべてのオブジェクトを可能な限り単一の連続するメモリ ブロックに割り当てることを強くお勧めします。 たとえば、各ゲーム キャラクタを表す HIKCharacter オブジェクトは、単一の連続するメモリ ブロック内で、そのキャラクタが使用するすべての関連する HIKCharacterState オブジェクト、HIKEffectorSetState オブジェクト、HIKPropertySetState オブジェクトに隣接して割り当てるようにします。これにより、HumanIK ソルバがメモリのデータの読み込みと書き込みを行う時に、最小限のコストでメモリにアクセスできます。

メモリ内のオブジェクトを移動する

HIKCharacterHIKCharacterStateHIKEffectorSetStateHIKPropertySetState を異なるメモリ位置間で自由に移動することができます。 この方法により、カスタム ストリーミング プロセスを使用して HIK オブジェクトをメモリにロードし、ゲームで使用するためにオブジェクトをカスタム ストリームから直接取得することができます。

ファイルからオブジェクトを作成する

保存した HIKCharacterHIKCharacterStateHIKEffectorSetStateHIKPropertySetState をファイルからロードすることができます。 詳細は、「HumanIK オブジェクトをセーブおよびロードする」を参照してください。