Figure に対するバウンディングボリューム
MascotCapsule エクステンション Collision Package ではモデルデータを表す SkinnedMesh 構造体に対し、バウンディングボリューム ( BV ) を設定することが可能となっています。これは BVFigure 構造体とそれに関連した API によって実現されています。
目次
- 1. SkinnedMesh からのBVFigure の作成と設定
- 2. BVFigure 全体に対するバウンディングボリュームの取得
- 3. BVFigure とバウンディングボリュームの衝突判定
- 4. BVFigure の破棄
注意:本サンプルでは説明の都合上、描画に対する効率化を行なっておりません。特にバウンディングボリュームに対応するメッシュの描画は実行速度を低下させる恐れがあります。これはバウンディングボリュームに対するMeshがあくまでもデバッグ用であり、描画速度よりも形状の精度を優先しているためです。
BVFigure 構造体はボーン構造を持ち、キーフレームによるアニメーションを設定することができます。また、BVFigure が持つ各ボーンに対してバウンディングボリュームを設定することが可能です。さらに、BVFigure 全体を包含するバウンディングボリュームを作成することも可能です。従って、モデルデータである SkinnedMesh が関係する衝突判定を行う際には以下の選択を取ることが可能です。
- SkinnedMesh 全体への衝突判定
- SkinnedMesh の個別のボーンに対する衝突判定
- キーフレームによるボーンアニメーションを反映した衝突判定
- SkinnedMesh の持つ基本姿勢への衝突判定
これらの選択は SkinnedMesh からバウンディングボリュームや BVFigure を作成する際に決定されます。
1. SkinnedMesh からのBVFigure の作成と設定
BVFigure 構造体の作成には BVBuilder 関数群を使用します。BVBuilder 関数群には、異なる BVFigure の作成のために、 mcx_BVBuilder_createBVFigure 関数と mcx_BVBuilder_createBVFigureOnlyBone 関数の2種類の関数がが存在します。mcx_BVBuilder_createBVFigure 関数は SkinnedMesh 構造体をもとに、各ボーンにバウンディングボリュームが設定された BVFigure を作成する関数です。一方 mcx_BVBuilder_createOnlyBone 関数は SkinnedMesh 構造体のボーン構造のみを持つ BVFigure を作成します。この BVFigure は作成時にバウンディングボリュームが設定されておらず、必要に応じて各ボーンに対し別途バウンディングボリュームを設定する必要があります。
また、作成された BVFigure は Shape 等と同様に、mcx_BVFigure_setTransform 関数によってワールド座標への変換を行うことができます。このとき BVFigure の作成元となった SkinnedMesh の変換行列を設定することで、モデルデータと BVFigure を一致させることができます。
* m3dMesh* pModel;
* mcxBVFiguref* pBvfig;
* m3dTransform transModel;
* float matrix [ 16 ] ;
*/
/* BVFigure の生成 */
pmcx -> pBvfig = IMICRO3Dv4es_mcx_BVBuilder_createBVFiguref (
MCX_SHAPE_TYPE_BOX, 1.f, &pMe -> e );
/* SkinnedMeshからWorldへの変換行列を得る */
ret = IMICRO3Dv4es_m3dNode_getTransformTo( pMe -> pIM3D,
&pMe -> e );
IMICRO3Dv4es_m3dTransform_get( pMe -> pIM3D, &transModel, matrix );
/* BVFigure に SkinnedMesh の変換行列を設定 */
IMICRO3Dv4es_mcx_BVFigure_setTransformf( pMe -> pIM3D, pmcx -> pBvfig, matrix, &pMe -> e );
また、BVFigure にアニメーションを反映させる場合 BVFigure にもアニメーションキーフレームを設定する必要があります。BVFigure に対して現在のフレーム時間を設定するには、mcx_BVFigure_setPosture 関数を使用します。このとき設定するフレーム時間は、SkinnedMesh ないし、World に設定されたものと同一のものを使用することで、モデルと BVFigure の挙動を一致させることができます。
IMICRO3Dv4es_m3dObject3D_animate( pMe -> pIM3D, ( m3dObject3D * ) pmc -> pWorld, pMe -> total_time, &pMe -> e );
/* BVFigure への現在時刻の設定 */
IMICRO3Dv4es_mcx_BVFigure_setPosturef( pMe -> pIM3D, pmcx -> pBvfig, NULL, 0, pMe -> total_time, &pMe -> e );
2. BVFigure 全体に対するバウンディングボリュームの取得
BVFigure 全体に対するバウンディングボリュームの設定にはいくつかの方法がありますが、 ここでは mcx_BVFigure_calculateBV 関数を使用した設定を行います。BVFigure 全体に設定されたバウンディングボリュームは mcx_BVFigure_getBV 関数によって取得することができ、デバッグ用メッシュの作成および描画が可能です。
また、mcx_BVFigure_calculateBV 関数によって生成されたバウンディングボリュームはアニメーションを反映したものとなります。
* mcxDebugShapeRendererf* pDsr;
* mcxBoundingVolumef* pBV;
*/
/* BVFigure 全体の BV を更新 */
IMICRO3Dv4es_mcx_BVFigure_calculateBVf( pMe -> pIM3D, pmcx -> pBvfig, MCX_SHAPE_TYPE_BOX, 1.f, &pMe -> e );
( 中略 )
/* BVFigure の描画 */
pBv = IMICRO3Dv4es_mcx_BVFigure_getBVf( pMe -> pIM3D, pmcx -> pBvfig );
IMICRO3Dv4es_mcx_DebugShapeRenderer_setColorf( pMe -> pIM3D, pmcx -> pDsr, 0x8800ff00 );
IMICRO3Dv4es_mcx_DebugShapeRenderer_renderShapef( pMe -> pIM3D,
3. BVFigure とバウンディングボリュームの衝突判定
BVFigure とバウンディングボリュームの衝突判定には mcxCollision 構造体の mcx_Collision_isHitShapeToBVFigure 関数を使用します。 ここでは一例として BVFigure 全体を包むバウンディングボリュームと Capsule との衝突判定を示します。
* mcxCollisionf* pCollision;
* mcxCollisionIsHitDataf hitData;
* hi_bool isHit;
* hi_bool isAllHit;
*/
/* BVFigure と Capsule の当たり判定 */
isHit = IMICRO3Dv4es_mcx_Collision_isHitShapeToBVFiguref(
pmcx -> pBvfig, isAllHit, &hitData, &pMe -> e );
4. BVFigure の破棄
描画等の処理を終え、不要になった BVFigure は他の構造体同様、破棄する必要があります。BVFigure の破棄には mcx_BVFigure_destroy 関数を使用します。

