SceneManager:
1.动画对象的管理:
AnimationList mAnimationsList;
AnimationStateSet mAnimationStates;
Animation* SceneManager::createAnimation(const String& name, Real length)
{
OGRE_LOCK_MUTEX(mAnimationsListMutex)
if (mAnimationsList.find(name) != mAnimationsList.end())
{
OGRE_EXCEPT(
Exception::ERR_DUPLICATE_ITEM,
"An animation with the name " + name + " already exists",
"SceneManager::createAnimation" );
}
Animation* pAnim = OGRE_NEW Animation(name, length);
mAnimationsList[name] = pAnim;
return pAnim;
}
AnimationState* SceneManager::createAnimationState(const String& animName)
{
Animation* anim = getAnimation(animName);//如果不存在就会抛异常
return mAnimationStates.createAnimationState(animName, 0, anim->getLength());
}
在SceneManager里面使用Animation时会把Animation保存在mAnimationsList里面,AnimationState保存在mAnimationStates里面,他们通过animName来保持一一对应。生命周期:Animation创建-->AnimationState创建-->AnimationState销毁-->Animation销毁。如果不是按照这种顺序会报异常。
2.动画播放:
void SceneManager::_applySceneAnimations(void)
{
// manual lock over states (extended duration required)
OGRE_LOCK_MUTEX(mAnimationStates.OGRE_AUTO_MUTEX_NAME)
// Iterate twice, once to reset, once to apply, to allow blending
ConstEnabledAnimationStateIterator stateIt = mAnimationStates.getEnabledAnimationStateIterator();
while (stateIt.hasMoreElements())
{
const AnimationState* state = stateIt.getNext();
Animation* anim = getAnimation(state->getAnimationName());
// Reset any nodes involved
Animation::NodeTrackIterator nodeTrackIt = anim->getNodeTrackIterator();
while(nodeTrackIt.hasMoreElements())
{
Node* nd = nodeTrackIt.getNext()->getAssociatedNode();
if (nd)
nd->resetToInitialState();
}
Animation::NumericTrackIterator numTrackIt = anim->getNumericTrackIterator();
while(numTrackIt.hasMoreElements())
{
const AnimableValuePtr& animPtr = numTrackIt.getNext()->getAssociatedAnimable();
if (!animPtr.isNull())
animPtr->resetToBaseValue();
}
}
// this should allow blended animations
stateIt = mAnimationStates.getEnabledAnimationStateIterator();
while (stateIt.hasMoreElements())
{
const AnimationState* state = stateIt.getNext();
Animation* anim = getAnimation(state->getAnimationName());
// Apply the animation
anim->apply(state->getTimePosition(), state->getWeight());
}
}
遍历所有Enabled为true的动画状态,调用node的resetToInitialState()和AnimableValue的resetToBaseValue()方法,分辨对节点动画和数组动画进行reset,最后调用Animation的apply方法进行播放动画。