📄 mixer.cpp
字号:
//****************************************************************************//// mixer.cpp //// Copyright (C) 2001, 2002 Bruno 'Beosil' Heidelberger ////****************************************************************************//// This library is free software; you can redistribute it and/or modify it //// under the terms of the GNU Lesser General Public License as published by //// the Free Software Foundation; either version 2.1 of the License, or (at //// your option) any later version. ////****************************************************************************//#ifdef HAVE_CONFIG_H#include "config.h"#endif//****************************************************************************//// Includes ////****************************************************************************//#include "cal3d/error.h"#include "cal3d/mixer.h"#include "cal3d/coremodel.h"#include "cal3d/corebone.h"#include "cal3d/coreanimation.h"#include "cal3d/coretrack.h"#include "cal3d/corekeyframe.h"#include "cal3d/model.h"#include "cal3d/skeleton.h"#include "cal3d/bone.h"#include "cal3d/animation.h"#include "cal3d/animation_action.h"#include "cal3d/animation_cycle.h" /*****************************************************************************//** Constructs the mixer instance. * * This function is the default constructor of the mixer instance. *****************************************************************************/CalMixer::CalMixer(CalModel* pModel){ assert(pModel); m_pModel = pModel; // build the animation table int coreAnimationCount = m_pModel->getCoreModel()->getCoreAnimationCount(); m_vectorAnimation.reserve(coreAnimationCount); CalAnimation* null = 0; m_vectorAnimation.insert(m_vectorAnimation.begin(), coreAnimationCount, null); // set the animation time/duration values to default m_animationTime = 0.0f; m_animationDuration = 0.0f; m_timeFactor = 1.0f;} /*****************************************************************************//** Destructs the mixer instance. * * This function is the destructor of the mixer instance. *****************************************************************************/CalMixer::~CalMixer(){ // destroy all active animation actions while(!m_listAnimationAction.empty()) { CalAnimationAction *pAnimationAction = m_listAnimationAction.front(); m_listAnimationAction.pop_front(); delete pAnimationAction; } // destroy all active animation cycles while(!m_listAnimationCycle.empty()) { CalAnimationCycle *pAnimationCycle; pAnimationCycle = m_listAnimationCycle.front(); m_listAnimationCycle.pop_front(); delete pAnimationCycle; } // clear the animation table m_vectorAnimation.clear(); m_pModel = 0;}////// Examines the given animation and if the first and last keyframe of a given track/// do not match up, the first key frame is duplicated and added to the end of the track/// to ensure smooth looping.///static void addExtraKeyframeForLoopedAnim(CalCoreAnimation* pCoreAnimation){ std::list<CalCoreTrack*>& listCoreTrack = pCoreAnimation->getListCoreTrack(); if(listCoreTrack.size() == 0) return; CalCoreTrack *coreTrack = listCoreTrack.front(); if(coreTrack == 0) return; CalCoreKeyframe *lastKeyframe = coreTrack->getCoreKeyframe(coreTrack->getCoreKeyframeCount()-1); if(lastKeyframe == 0) return; if(lastKeyframe->getTime() < pCoreAnimation->getDuration()) { std::list<CalCoreTrack *>::iterator itr; for(itr=listCoreTrack.begin();itr!=listCoreTrack.end();++itr) { coreTrack = *itr; CalCoreKeyframe *firstKeyframe = coreTrack->getCoreKeyframe(0); CalCoreKeyframe *newKeyframe = new CalCoreKeyframe(); newKeyframe->setTranslation(firstKeyframe->getTranslation()); newKeyframe->setRotation(firstKeyframe->getRotation()); newKeyframe->setTime(pCoreAnimation->getDuration()); coreTrack->addCoreKeyframe(newKeyframe); } }} /*****************************************************************************//** Interpolates the weight of an animation cycle. * * This function interpolates the weight of an animation cycle to a new value * in a given amount of time. If the specified animation cycle is not active * yet, it is activated. * * @param id The ID of the animation cycle that should be blended. * @param weight The weight to interpolate the animation cycle to. * @param delay The time in seconds until the new weight should be reached. * * @return One of the following values: * \li \b true if successful * \li \b false if an error happend *****************************************************************************/bool CalMixer::blendCycle(int id, float weight, float delay){ if((id < 0) || (id >= (int)m_vectorAnimation.size())) { CalError::setLastError(CalError::INVALID_HANDLE, __FILE__, __LINE__); return false; } // get the animation for the given id CalAnimation *pAnimation = m_vectorAnimation[id]; // create a new animation instance if it is not active yet if(pAnimation == 0) { // take the fast way out if we are trying to clear an inactive animation if(weight == 0.0f) return true; // get the core animation CalCoreAnimation *pCoreAnimation = m_pModel->getCoreModel()->getCoreAnimation(id); if(pCoreAnimation == 0) return false; // Ensure that the animation's first and last key frame match for proper // looping. ::addExtraKeyframeForLoopedAnim(pCoreAnimation); // allocate a new animation cycle instance CalAnimationCycle *pAnimationCycle = new CalAnimationCycle(pCoreAnimation); if(pAnimationCycle == 0) { CalError::setLastError(CalError::MEMORY_ALLOCATION_FAILED, __FILE__, __LINE__); return false; } // insert new animation into the tables m_vectorAnimation[id] = pAnimationCycle; m_listAnimationCycle.push_front(pAnimationCycle); // blend the animation return pAnimationCycle->blend(weight, delay); } // check if this is really a animation cycle instance if(pAnimation->getType() != CalAnimation::TYPE_CYCLE) { CalError::setLastError(CalError::INVALID_ANIMATION_TYPE, __FILE__, __LINE__); return false; } // clear the animation cycle from the active vector if the target weight is zero if(weight == 0.0f) { m_vectorAnimation[id] = 0; } // cast it to an animation cycle CalAnimationCycle *pAnimationCycle; pAnimationCycle = (CalAnimationCycle *)pAnimation; // blend the animation cycle pAnimationCycle->blend(weight, delay); pAnimationCycle->checkCallbacks(0,m_pModel); return true;} /*****************************************************************************//** Fades an animation cycle out. * * This function fades an animation cycle out in a given amount of time. * * @param id The ID of the animation cycle that should be faded out. * @param delay The time in seconds until the the animation cycle is * completely removed. * * @return One of the following values: * \li \b true if successful * \li \b false if an error happend *****************************************************************************/bool CalMixer::clearCycle(int id, float delay){ // check if the animation id is valid if((id < 0) || (id >= (int)m_vectorAnimation.size())) { CalError::setLastError(CalError::INVALID_HANDLE, __FILE__, __LINE__); return false; } // get the animation for the given id CalAnimation *pAnimation; pAnimation = m_vectorAnimation[id]; // we can only clear cycles that are active if(pAnimation == 0) return true; // check if this is really a animation cycle instance if(pAnimation->getType() != CalAnimation::TYPE_CYCLE) { CalError::setLastError(CalError::INVALID_ANIMATION_TYPE, __FILE__, __LINE__); return false; } // clear the animation cycle from the active vector m_vectorAnimation[id] = 0; // cast it to an animation cycle CalAnimationCycle *pAnimationCycle; pAnimationCycle = (CalAnimationCycle *)pAnimation; // set animation cycle to async state pAnimationCycle->setAsync(m_animationTime, m_animationDuration); // blend the animation cycle pAnimationCycle->blend(0.0f, delay); pAnimationCycle->checkCallbacks(0, m_pModel); return true;}/*****************************************************************************//** Executes an animation action. * * This function executes an animation action. * * @param id The ID of the animation action that should be blended. * @param delayIn The time in seconds until the animation action reaches the * full weight from the beginning of its execution. * @param delayOut The time in seconds in which the animation action reaches * zero weight at the end of its execution. * @param weightTarget The weight to interpolate the animation action to. * @param autoLock This prevents the Action from being reset and removed * on the last keyframe if true. * * @return One of the following values: * \li \b true if successful * \li \b false if an error happend *****************************************************************************/bool CalMixer::executeAction(int id, float delayIn, float delayOut, float weightTarget, bool autoLock){ // get the core animation CalCoreAnimation *pCoreAnimation; pCoreAnimation = m_pModel->getCoreModel()->getCoreAnimation(id); if(pCoreAnimation == 0) { return false; } // allocate a new animation action instance CalAnimationAction *pAnimationAction = new CalAnimationAction(pCoreAnimation); if(pAnimationAction == 0) { CalError::setLastError(CalError::MEMORY_ALLOCATION_FAILED, __FILE__, __LINE__); return false; } // insert new animation into the table m_listAnimationAction.push_front(pAnimationAction); // execute the animation pAnimationAction->execute(delayIn, delayOut, weightTarget, autoLock); pAnimationAction->checkCallbacks(0, m_pModel); return true;}/*****************************************************************************//** Clears an active animation action. * * This function removes an animation action from the blend list. This is * particularly useful with auto-locked actions on their last frame. * * @param id The ID of the animation action that should be removed. * * @return One of the following values: * \li \b true if successful * \li \b false if an error happened or action was not found *****************************************************************************/bool CalMixer::removeAction(int id){ // get the core animation CalCoreAnimation *pCoreAnimation; pCoreAnimation = m_pModel->getCoreModel()->getCoreAnimation(id); if(pCoreAnimation == 0) { return false; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -