サンプル
特定ボーンのみへのバウンディングボリュームの設定
MascotCapsule エクステンション Collision Package では、モデルデータである SkinnedMesh の特定のボーンを選択して バウンディングボリューム( BV ) を作成・設定することができます。不必要な BV を作成することなく、必要なボーンにのみ BV を設定することで衝突判定の計算コストを抑えることができます。
目次
1. 特定ボーンへの BV 設定の手順
SkinnedMesh の特定ボーンへの BV の設定は、
- FigureからmcxBVFigureを作成
- SkinnedMesh の特定ボーンから BV を作成する
- 作成した BV を BVFigure の特定ボーンに設定する
という手順で行ないます。
さらに、BVFigure に SkinnedMesh と同じ変換行列・キーフレームを設定すれば、ここで作成された BV は自動的にボーンの座標変換・アニメーションに合わせて作成元のボーンに追従します。
本サンプルでは、SkinnedMesh のアニメーションに追従する BV について解説します。
2. 特定ボーンへの BV 設定のサンプルコード
ここでは、特定ボーンへの BV の設定を中心にサンプルコードを説明します。
2.1. ボーン構造のみを持つ BVFigure の作成
特定ボーンへの BV の設定にはまず、BV を設定したい SkinnedMesh からボーン構造のみを持つ BVFigure を作成します。この BVFigure の作成には mcx_BVBuilder_createBVFigureOnlyBone 関数を使用します。この関数によって作成される BVFigure はボーン構造のみの BVFigure で、各ボーンに対して BV が設定されていません。またここでは同時に、ワールド座標への変換行列を設定しています。
* m3dTransform transModel;
* float matrix [ 16 ] ;
* hi_bool ret = HI_FALSE;
*/
/* ボーン構造のみを持つ BVFigure の生成 */
pmcx -> pBvfig = IMICRO3Dv4es_mcx_BVBuilder_createBVFigureOnlyBonef(
/* SkinnedMeshからWorldへの変換行列を得る */
ret = IMICRO3Dv4es_m3dNode_getTransformTo( pMe -> pIM3D,
IMICRO3Dv4es_m3dTransform_get( pMe -> pIM3D, &transModel, matrix );
/* BVFigure に SkinnedMesh の変換行列を設定 */
IMICRO3Dv4es_mcx_BVFigure_setTransformf( pMe -> pIM3D, pmcx -> pBvfig, matrix, &pMe -> e );
2.2. 特定ボーンに対応する BV の作成と設定
特定ボーンに対して、対象となるボーンの形状に沿った BV を作成するためには、mcx_BVBuilder_createBoneBV 関数を使用します。このとき、対象となるボーンを引数として渡す必要があります。モデルデータの各ボーンは、対象となるモデルを表す SkinnedMesh 配下の Group 、Mesh および、そのサブクラスが表す各ノードに対応しています。そのため、対象となるボーンを表す Node をシーングラフ中から取得する必要があります。
所望の BV が得られたら、それを対象となるボーンに設定します。この設定には mcx_BVFigure_setBVToBone 関数を使用します。このとき、設定対象となるのは BVFigure が保持するボーン構造です。
* m3dNode* boneNode = NULL;
* boneTbl は各ノードのユーザ ID から
* ボーン ID への変換を行なうためのテーブル。
* GROUP_UID はモデルデータの Skeleton の root を表す
* Group オブジェクトのユーザ ID を表す。
* hi_sint32 boneNum は BVFigure が持つボーン総数を表す。
*/
/* 対象 Bone を表す Node を取得 */
for ( nodeID = 0; nodeID < boneNum; nodeID++ ) {
if ( pmcx -> boneTbl[ nodeID ] == pmcx -> boneID ) {
( GROUP_UID + nodeID ) );
}
/* 対象 Bone のバウンディングボリュームを取得 */
pmcx -> pBvbone = IMICRO3Dv4es_mcx_BVBuilder_createBoneBV_m3gf(
MCX_SHAPE_TYPE_SPHERE, 1.f, MCX_BV_ROTATE_NONE, &pMe -> e );
/* 対象 Bone に生成されたバウンディングボリュームを設定 */
IMICRO3Dv4es_mcx_BVFigure_setBVToBonef( pMe -> pIM3D, pmcx -> pBvfig, pmcx -> pBvbone, pmcx -> boneID, &pMe ->e );
また、SkinnedMesh のアニメーションに合わせて BV を動かすため、フレーム時間を更新する際には、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 );



