モーションブレンド

ここではモーションブレンドについて解説します。




※ 開発環境によってダウンロードするサンプルデータが異なります。

目次




モーションブレンドとは、最大 4 つまでのアニメーションデータに対してそれぞれに重み付けをしつつ、アニメーションをブレンドする機能です。


1. モーションブレンドの関連付け

アニメーションさせたい対象モデルに対し、1 つだけのアニメーションを関連付けさせたいなら、mceFigure_bindAction( This, actions ) で可能ですが、モーションブレンドのように複数のアニメーションを関連付けさせたい場合は、アニメーションデータ毎に個別に関連付けさせる必要があります。
具体的には、アニメーションさせたい対象モデルに関連付けされている mceAnimatable を取得し、それに mceAction と mceActionController をアニメーションブレンド数だけ関連付けさせます。
下記のサンプルプログラムは、2 つのアニメーションデータを mceAnimatable に関連付けさせることを行っています。

typedef struct tagWork
{
    (中略)

    mceFigure               *Figure;         /* Figure       */

    (中略)

    mceActionTable          *Acttbl0;        /* ActionTable0 */
    mceActionTable          *Acttbl1;        /* ActionTable1 */

    (中略)

    mceAction               *Action0;        /* Action0             */
    mceAction               *Action1;        /* Action1             */
    mceActionController     *Actcnt0;        /* ActionController0   */
    mceActionController     *Actcnt1;        /* ActionController1   */
    mceAnimatable           *Anitbl;         /* Animatable          */

    (中略)
} WORK;
hi_exception exception;

    (中略)

work->Anitbl = (mceAnimatable *)mceObject3D_findObject3D (
                    (mceObject3D *)work->Figure, 
                    ClassId_TransformTree,
                    -1);
if (work->Anitbl == NULL)
{
    return 1;
}

exception = mceAnimatable_setUseActionControllerNum (work->Anitbl, 2);
if (exception != hi_NoException)
{
    return 1;
}

/* Actiontable0からAction0を取得 */
work->Action0 = mceActionTable_findAction (work->Acttbl0, 0);
if (work->Action0 == NULL)
{
    return 1;
}

/* Actiontable1からAction1を取得 */
work->Action1 = mceActionTable_findAction (work->Acttbl1, 0);
if (work->Action1 == NULL)
{
    return 1;
}

/* mceActionControllerの生成 */
/* Action0を関連付け */
work->Actcnt0 = mceActionController_create (work->Action0, 
                                            &exception);
if (exception != hi_NoException)
{
    return 1;
}
/* Action1を関連付け */
work->Actcnt1 = mceActionController_create (work->Action1, 
                                            &exception);
if (exception != hi_NoException)
{
    return 1;
}

/* mceActionControllerによるフレーム値設定を有効化 */
mceActionController_enableFrame (work->Actcnt0, HI_TRUE);
mceActionController_enableFrame (work->Actcnt1, HI_TRUE);

/* mceAnimatableにmceActionを関連付ける */
/* Action0を関連付け */
exception = mceAnimatable_setActions (work->Anitbl, work->Action0, 0);
if (exception != hi_NoException)
{
    return 1;
}

/* Action1を関連付け */
exception = mceAnimatable_setActions (work->Anitbl, work->Action1, 1);
if (exception != hi_NoException)
{
    return 1;
}

/* mceAnimatableにmceActionControllerを関連付ける */
/* ActionController0を関連付ける */
exception = mceAnimatable_setActionController (work->Anitbl, 
                                               work->Actcnt0, 0);
if (exception != hi_NoException)
{
    return 1;
}

/* ActionController1を関連付ける */
exception = mceAnimatable_setActionController (work->Anitbl, 
                                               work->Actcnt1, 1);
if (exception != hi_NoException)
{
    return 1;
}


2. モーションブレンドの設定

モーションブレンドの関連付け後は、mceActionController に対し、mceActionController_setWeight( This, segindex, weight ) 及び、mceActionController_setWeightAll( This, weight ) で重み付けを、mceActionController_setFrame( This, segindex, frame ) 及び、mceActionController_setFrameAll( This, frame ) でブレンドしたいアニメーション再生フレームを設定します。
下記のサンプルプログラムでは、全てのセグメントに対して同じ値を設定していますが、mceActionController_setWeight( This, segindex, weight ) 及び、mceActionController_setFrame( This, segindex, frame ) を使用することで、セグメントを指定しての個別設定も可能です。

typedef struct tagWork
{
    (中略)

    hi_uint8 MotionBlendFlag;      /* モーションブレンド フラグ */

    (中略)

    mceActionController *Actcnt0;  /* ActionController0 */
    mceActionController *Actcnt1;  /* ActionController1 */

    (中略)

    hi_coord AnimeCounter0;        /* オブジェクトアニメ カウンター0 */
    (中略)
    
    hi_coord AnimeCounter1;        /* オブジェクトアニメ カウンター1 */

} WORK;
hi_exception exception;

    (中略)

/* Action0,Action1に対して、モーションブレンドの重みを決定する */
switch (work->MotionBlendFlag)
{
case 0:;
/* Action0の重みを設定 */
    exception = mceActionController_setWeightAll (work->Actcnt0, 
                                                  MCE_F2C (1.0f));
    if (exception != hi_NoException)
    {
        return 1;
    }
/* Action1の重みを設定 */
    exception = mceActionController_setWeightAll (work->Actcnt1, 
                                                  MCE_F2C (0.0f));
    if (exception != hi_NoException)
    {
        return 1;
    }
    break;

case 1:;
/* Action0の重みを設定 */
    exception = mceActionController_setWeightAll (work->Actcnt0, 
                                                  MCE_F2C (0.0f));
    if (exception != hi_NoException)
    {
        return 1;
    }
/* Action1の重みを設定 */
    exception = mceActionController_setWeightAll (work->Actcnt1, 
                                                  MCE_F2C (1.0f));
    if (exception != hi_NoException)
    {
        return 1;
    }
    break;

case 2:;
/* Action0の重みを設定 */
    exception = mceActionController_setWeightAll (work->Actcnt0, 
                                                  MCE_F2C (0.5f));
    if (exception != hi_NoException)
    {
        return 1;
    }
/* Action1の重みを設定 */
    exception = mceActionController_setWeightAll (work->Actcnt1, 
                                                  MCE_F2C (0.5f));
    if (exception != hi_NoException)
    {
        return 1;
    }
    break;
} 

/* フレーム値の設定 */
exception = mceActionController_setFrameAll (work->Actcnt0, 
                                             work->AnimeCounter0);
if (exception != hi_NoException)
{
    return 1;
}

exception = mceActionController_setFrameAll (work->Actcnt1, 
                                             work->AnimeCounter1);
if (exception != hi_NoException)
{
    return 1;
}
アニメーション0 アニメーション1
ブレンドしたアニメーション
描画結果



このページの先頭へ戻る