動作融合是一種將當前動作跟目標動作中骨骼位置進行動態(tài)插值的算法扁掸。得到的結果可以使角色的動作表現(xiàn)更加的平滑。
irrlicht引擎也提供了相應的功能税产,下面就這個功能的使用方法進行說明辐益。
功能函數(shù)
引用下irrlicht的代碼
//! Sets the transition time in seconds (note: This needs to enable joints, and setJointmode maybe set to 2)
//! you must call animateJoints(), or the mesh will not animate
void CAnimatedMeshSceneNode::setTransitionTime(f32 time)
{
const u32 ttime = (u32)core::floor32(time*1000.0f);
if (TransitionTime==ttime)
return;
TransitionTime = ttime;
if (ttime != 0)
setJointMode(EJUOR_CONTROL);
else
setJointMode(EJUOR_NONE);
}
使用這個函數(shù),就可以在播放下一個動作的時候自動進行插值肄满。但是谴古,只使用這一個函數(shù)质涛,只會讓你的模型骨骼便的不受控制。
好在這個時候我們注意到函數(shù)前面的兩行注釋掰担,什么意思呢汇陆?
設置融合時間,單位秒(注意:這個需要有骨骼带饱,并且設置骨骼模式為2毡代,就是EJUOR_CONTROL)
你必須調用animateJoints(),否則動畫可就不動了喲
然而注釋沒有提到的是勺疼,你必須沒一幀都調用animateJoints()月趟,否則動畫還是不動喲
這里有英文版解釋
Now if you also want your mesh to animate using any built-in animation in the model, call:
Node->animateJoints();
In your game loop, before drawAll().
意思就是你如果要播已有的動畫,你需要在游戲的主循環(huán)中調用animateJoints()恢口;
步驟
- 設置 setTransitionTime(f32 time)
- 每幀調用 animateJoints()
做完這兩件事孝宗,你就可以可到動作融合可以正常使用了。
更多的要求
但是還不夠耕肩。當功能正常使用的時候因妇,我們可能會有更多的需求:
- 對不同的動作設置不同的動作融合
- 某些特別的動作不要融合
前面的兩個步驟,在動作融合及不融合來回切換的時候會導致模型節(jié)點不受控制猿诸。有兩處問題婚被,再看代碼
void CAnimatedMeshSceneNode::setTransitionTime(f32 time)
{
const u32 ttime = (u32)core::floor32(time*1000.0f);
// 問題2
if (TransitionTime==ttime)
return;
TransitionTime = ttime;
if (ttime != 0)
setJointMode(EJUOR_CONTROL);
else
setJointMode(EJUOR_NONE); // 問題1
}
問題1:在把動畫的融合設置為0時,期望的是關閉動作融合梳虽。但實際導致骨骼模式變成NONE址芯,子節(jié)點不能正常變換位置。手動調用 node->setJointMode(scene::EJUOR_READ)解決
問題2:試想下面的操作過程窜觉,
- 設置融合時間setTransitionTime(0.3)
- 關閉動作融合setJointMode(scene::EJUOR_READ)
- 再次設置setTransitionTime(0.3)
第三步操作時谷炸,代碼在 if (TransitionTime==ttime)
處返回,于是沒有自動執(zhí)行setJointMode(EJUOR_CONTROL);
所以結論是:在setTransitionTime時同時設置setJointMode(MODE)來避免這個問題
if (m_AniPlayData.blend > 0) {
node->setTransitionTime(m_AniPlayData.blend);
node->setJointMode(irr::scene::EJUOR_CONTROL);
} else {
node->setTransitionTime(0);
node->setJointMode(irr::scene::EJUOR_READ);
}
最后完整的步驟是:
- 設置 setTransitionTime(f32 time)
- 同1時設置 setJointMode(MODE);
- 每幀調用 animateJoints()
至此禀挫,動畫融合就完全可用了旬陡。
PS:如果你的主模型的子節(jié)點也需要做動畫的話,對子節(jié)點也需要上述三個步驟语婴。