⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mixer.cpp

📁 Cal3D实现虚拟角色 Cal3D实现虚拟角色
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//****************************************************************************//// 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 + -