サンプル

バウンディングボリューム(BV)

MascotCapsule エクステンション Collision Package では各種バウンディングボリューム(BV)の作成、移動を行うことができ、また相互の衝突判定が可能となっています。また、デバッグ用にメッシュの作成および描画を行うことも可能です。


バウンディングボリューム(BV)

目次






1. バウンディングボリュームの作成

バウンディングボリュームの作成には各種 Shape を表す各構造体の create 関数を使用します。その後各 Shape の set 関数を使用し、各バウンディングボリュームの形状を設定します。
これら構造体の関数の詳細は API リファレンスマニュアル をご覧ください。

/**
  * mcxBoxf* pBox;
  * mcxCapsulef* pCapsule;
  * mcxSpheref* pSphere;
  * mcxShapef* pShape [ 3 ] ;
  * float box_len [ 3 ] = { 150.0f, 100.0f, 50.0f };
  * float sphere_rad = 30.0f;
  * float cap_rad = 25.0f;
  * float cap_hgt = 90.0f;
  */


/* バウンディングボリュームの作成 */
/* Box */
pmcx -> pBox = IMICRO3Dv4es_mcx_Box_createf( pMe -> pIM3D, pMe -> pAlc, &pMe -> e );
IMICRO3Dv4es_mcx_Box_setf( pMe -> pIM3D, pmcx -> pBox, box_len, &pMe -> e );

/* Capsule */
pmcx -> pCapsule = IMICRO3Dv4es_mcx_Capsule_createf( pMe -> pIM3D, pMe -> pAlc, &pMe -> e );
IMICRO3Dv4es_mcx_Capsule_setf( pMe -> pIM3D, pmcx -> pCapsule, cap_rad, cap_hgt, &pMe -> e );

/* Sphere */
pmcx -> pSphere = IMICRO3Dv4es_mcx_Sphere_createf( pMe -> pIM3D, pMe -> pAlc, &pMe -> e );
IMICRO3Dv4es_mcx_Sphere_setf( pMe -> pIM3D, pmcx -> pSphere, sphere_rad, &pMe -> e );

/* 各 Shape を Shape 用配列に登録 */
pmcx -> pShape[ pmcx -> shapeNumber++ ] = ( mcxShapef * ) pmcx -> pBox;
pmcx -> pShape[ pmcx -> shapeNumber++ ] = ( mcxShapef * ) pmcx -> pCapsule;
pmcx -> pShape[ pmcx -> shapeNumber++ ] = ( mcxShapef * ) pmcx -> pSphere;



2. Shape の移動

Shape の移動には各 Shape の setTransform 関数を使用します。この操作により Shape 座標からワールド座標への変換が行われます。なお setTranform 関数は、引数として変換行列を表す float [ 16 ] の配列を取ります。

/**
  * float x_deg;
  * float y_deg;
  * float angle;
  * float transBV [ 16 ];
  * float f_i;
  */


/* バウンディングボリュームの移動 */
for ( i = 0; i < pmcx -> shapeNumber; i ++ ) {
IMICRO3Dv4es_m3dTransform_setIdentity( pMe -> pIM3D, pmcx -> pTransform );

IMICRO3Dv4es_m3dTransform_postTranslate( pMe -> pIM3D,
pmcx -> pTransform,
IMICRO3Dv4es_m3dFloatCalc_f_mul( pMe -> pIM3D, pmcx -> x_deg, f_i ),
IMICRO3Dv4es_m3dFloatCalc_f_mul( pMe -> pIM3D, pmcx -> y_deg, f_i ),
0.f );
IMICRO3Dv4es_m3dTransform_postRotate( pMe -> pIM3D, pmcx -> pTransform, pmcx -> angle, 1.f, 1.f, 0.f );

IMICRO3Dv4es_m3dTransform_get( pMe -> pIM3D, pmcx -> pTransform, transBV );

IMICRO3Dv4es_mcx_Shape_setTransformf( pMe -> pIM3D, pmcx -> pShape [ i ] , transBV, &pMe -> e );
if ( pMe -> e != mcx_NoException ) {
return HI_FALSE;
}

f_i = IMICRO3Dv4es_m3dFloatCalc_f_add( pMe -> pIM3D, f_i, 1.f );
}



3. デバッグ用メッシュの描画

各 Shape に対応するデバッグ用メッシュを描画する際には、DebugShapeRenderer 構造体とそれに関連する API を利用します。まず、DebugShapeRenderer を作成し、Shape が持つ衝突判定領域を描画するための色や透明度といったメッシュの状態を設定します。その後、実際に各 Shape に対応するメッシュを描画します。

DebugShapeRenderer の作成には mcx_DebugShapeRenderer_create 関数を、実際のメッシュの描画には mcx_DebugShapeRenderer_renderShape 関数を使用します。

また、描画終了後不要になった DebugShapeRenderer は、 mcx_DebugShapeRenderer_destroy 関数により破棄される必要があります。

注意:
デバッグ用メッシュはデバッグ時の支援を目的としているため、描画速度よりも描画精度を優先しています。 そのため、Sphere や Capsule, Cylinder 等の バウンディングボリュームは描画に用いる頂点数が多くなっています。
/* DebugRenderer の生成 */
pmcx -> pDsr = IMICRO3Dv4es_mcx_DebugShapeRenderer_createf( pMe -> pIM3D, pMe -> pAlc, &pMe -> e );
IMICRO3Dv4es_mcx_DebugShapeRenderer_enableLightingf( pMe -> pIM3D, Pmcx -> mcxDsr, HI_FALSE );
IMICRO3Dv4es_mcx_DebugShapeRenderer_enableTransparentf( pMe -> pIM3D, pmcx -> mcxDsr, HI_TRUE );

( 中略 )

/* MCX Collision Package 描画処理 */

( 中略 )

/* 各 Shape の描画 */
for ( i = 0; i < pmcx -> shapeNumber; i ++ ) {

IMICRO3Dv4es_mcx_DebugShapeRenderer_setColorf( pMe -> pIM3D, pmcx -> pDsr, pmcx -> shapeColor [ i ] );
IMICRO3Dv4es_mcx_DebugShapeRenderer_renderShapef( pMe -> pIM3D,
pmcx -> pDsr, pmc -> pG3D, pmcx -> pShape [ i ], 0, &pMe -> e );

}

( 中略 )

/* 終了処理 */
IMICRO3Dv4es_mcx_DebugShapeRenderer_destroyf( pMe -> pIM3D, pmcx -> pDsr );



4. バウンディングボリューム同士の衝突判定

Shape の衝突判定にはCollision 構造体とそれに関連した API を使用します。このとき、判定対象となる Shape の組み合わせによって複数の関数が存在します。ここではバウンディングボリューム同士の単純な衝突判定を行うため、mcx_Collision_isHitShapeToShape 関数を使用しています。
この関数の詳細については API リファレンスマニュアル をご覧ください。

ここでは一例として、 Box オブジェクトと Capsule オブジェクトの衝突判定を示します。

/**
  * mcxCollisionIsHitDataf hitData;
  * hi_sint32 color = 0;
  */


/* Collision オブジェクトの生成 */
pmcx -> pCollision = IMICRO3Dv4es_mcx_Collision_createf( pMe -> pIM3D, pMe -> pAlc, &pMe -> e );

( 中略 )

/* 初期状態の保存 */
color = pmcx -> shapeDefColor;

/* Box と Capsule の当たり判定 */
isHit = IMICRO3Dv4es_mcx_Collision_isHitShapeToShapef(
pMe -> pIM3D, pCollision, ( mcxShapef * ) pmcx -> pBox,
( mcxShapef * ) pmcx -> pCapsule, &hitData, &pMe -> e );
if ( isHit == HI_TRUE ) {
color = pmcx -> shapeHitColor;
}

( 中略 )

/* 衝突情報をもとに Box の色を設定 */
pmcx -> shapeColor [ 0 ] = color;

( 中略 )

/* 終了処理 */
IMICRO3Dv4es_mcx_Collision_destroyf( pMe -> pIM3D, pmcx -> pCollision );

なお、mcx_Collision_isHitShapeToShape 関数の引数である、mcxCollisionIsHitData 構造体は衝突時の詳細な情報を保持する構造体です。




5. バウンディングボリュームの破棄

描画等の処理を終え、不要になったバウンディングボリュームは他の構造体同様、破棄する必要があります。バウンディングボリュームの破棄には各 Shape の destroy 関数を使用します。

IMICRO3Dv4es_mcx_Box_destroyf( pMe -> pIM3D, ( mcxBoxf * ) pmcx -> pShape [ 0 ] );
IMICRO3Dv4es_mcx_Capsule_destroyf( pMe -> pIM3D, ( mcxCapsulef * ) pmcx -> pShape [ 1 ] );
IMICRO3Dv4es_mcx_Sphere_destroyf( pMe -> pIM3D, ( mcxSpheref * ) pmcx -> pShape [ 2 ] );
バウンディングボリューム(BV)


このページの先頭へ戻る