モデルに物を持たせる場合、右手を表すボーンに合わせて物を配置することになります。
このとき、ワールド座標系から右手のボーン座標系への変換行列が必要となります。このサンプルでは、対象のボーンにバウンディングボリューム( BV ) を設定し BV の変換行列を取得することで、間接的にボーンの変換行列を取得しています。
ボーン変換行列取得のサンプルコード
ここではボーン変換行列の取得を中心にサンプルコードを説明します。
まず、モデルに物を持たせるためには、物を持たせたいボーンに対して BV を設定する必要があります。このように BV を設定することで、ワールド座標系からボーン座標系への変換行列を得ることができるようになります。なお、このとき設定する BV は上記の通り変換行列を取得するためのものですので、ボーンに合わせて作成する必要はなく、適当な形状で構いません。
/* 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 );
/* モデルを表す 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,
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 );
&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 );
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,
( 中略 )
/* Item の描画 */
ret = IMICRO3Dv4es_m3dGraphics3D_render_n( pMe -> pIM3D, pmc -> pG3D,
* 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 );transfl, &pMe -> e );
( 中略 )
/* Item の描画 */
ret = IMICRO3Dv4es_m3dGraphics3D_render_n( pMe -> pIM3D, pmc -> pG3D,
( m3dNode * ) pmc -> pItem, pmcx -> pTransItem );

