Japanese | English | Korean

Samples

ボーンの変換行列取得による物持たせ

アニメーションのついたモデルに別の M3G データから取得したモデルを持たせる、というサンプルです。


モデルに物を持たせる場合、右手を表すボーンに合わせて物を配置することになります。
このとき、ワールド座標系から右手のボーン座標系への変換行列が必要となります。このサンプルでは、対象のボーンにバウンディングボリューム( BV ) を設定し BV の変換行列を取得することで、間接的にボーンの変換行列を取得しています。



ボーン変換行列取得のサンプルコード

ここではボーン変換行列の取得を中心にサンプルコードを説明します。

まず、モデルに物を持たせるためには、物を持たせたいボーンに対して BV を設定する必要があります。このように BV を設定することで、ワールド座標系からボーン座標系への変換行列を得ることができるようになります。なお、このとき設定する BV は上記の通り変換行列を取得するためのものですので、ボーンに合わせて作成する必要はなく、適当な形状で構いません。

/* BVFigure の生成 */
pmcx -> pBvfig = IMICRO3Dv4es_mcx_BVBuilder_createBVFigureOnlyBonef(
pMe -> pIM3D, pMe -> pAlc, ( m3dSkinnedMesh * )pmc -> pModel, &pMe -> e );

/* SkinnedMeshからWorldへの変換行列を得る */
ret = IMICRO3Dv4es_m3dNode_getTransformTo( pMe -> pIM3D,
( m3dNode * )pmc -> pModel, ( m3dNode * )pmc -> pWorld, &transModel,
&pMe -> e );

IMICRO3Dv4es_m3dTransform_get( pMe -> pIM3D, &transModel, matrix );

/* BVFigure に SkinnedMesh の変換行列を設定 */
IMICRO3Dv4es_mcx_BVFigure_setTransformf( pMe -> pIM3D, pmcx -> pBvfig, matrix, &pMe -> e );

/* モデルを表す Mesh の手に適当なバウンディングボリュームを設定 */
pmcx -> pBvhand = IMICRO3Dv4es_mcx_Sphere_createf( pMe -> pIM3D, pMe -> pAlc, &pMe -> e );

IMICRO3Dv4es_mcx_Sphere_setf( pMe -> pIM3D, pmcx -> pBvhand, 2.f, &pMe -> e );
IMICRO3Dv4es_mcx_BVFigure_setBVToBonef( pMe -> pIM3D, pmcx -> pBvfig,
( mcxBoundingVolumef * )pmcx -> pBvhand, HAND_ID, &pMe -> e );

また、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 );

/* BVFigure の更新 */
IMICRO3Dv4es_mcx_BVFigure_calculateBVf( pMe -> pIM3D, pmcx -> pBvfig, MCX_SHAPE_TYPE_BOX, 1.f, &pMe -> e );

その後、ボーンに設定した BV から変換行列を取得し、物を描画します。

/**
  * float transfl [ 16 ] ;
  */


/* ボーンに登録した Shape から変換行列を取得 */
IMICRO3Dv4es_mcx_Shape_getTransformf( pMe -> pIM3D,
( mcxShapef * ) pmcx -> pBvhand, MCX_TRANS_SHAPE_WORLD_NOSCALE,
transfl, &pMe -> e );
IMICRO3Dv4es_m3dTransform_set_fl( pMe -> pIM3D, pmcx -> pTransItem, transfl );

( 中略 )

/* Item の描画 */
ret = IMICRO3Dv4es_m3dGraphics3D_render_n( pMe -> pIM3D, pmc -> pG3D,
( m3dNode * ) pmc -> pItem, pmcx -> pTransItem );