Ejemplo n.º 1
0
/** 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;
}
Ejemplo n.º 2
0
unsigned int 
CalMixer::numActiveOneShotAnimations()
{
  
  // get the skeleton we need to update
  CalSkeleton *pSkeleton;
  pSkeleton = m_pModel->getSkeleton();
  if(pSkeleton == 0) return 0;
  unsigned int count = 0;
  
  // loop through all animation actions
  std::list<CalAnimationAction *>::iterator itaa;
  for( itaa = m_listAnimationAction.begin(); itaa != m_listAnimationAction.end(); itaa++ ) {
    
    // get the core animation instance
    CalAnimationAction * aa = * itaa;
    
    // Manual animations can be on or off.  If they are off, they do not apply
    // to the bone.
    if( aa->on() ) {
      count++;
    }
  }
  return count;
}
Ejemplo n.º 3
0
CalAnimationAction * CalMixer::newAnimationAction( int coreAnimationId )
{

  // get the core animation
  CalCoreAnimation *pCoreAnimation;
  pCoreAnimation = m_pModel->getCoreModel()->getCoreAnimation( coreAnimationId );
  if(pCoreAnimation == 0)
  {
    return NULL;
  }

  // allocate a new animation action instance
  CalAnimationAction *pAnimationAction;
  pAnimationAction = new CalAnimationAction();
  if(pAnimationAction == 0)
  {
    CalError::setLastError(CalError::MEMORY_ALLOCATION_FAILED, __FILE__, __LINE__);
    return NULL;
  }

  // create the new animation instance
  if(!pAnimationAction->create(pCoreAnimation))
  {
    delete pAnimationAction;
    return NULL;
  }

  // insert new animation into the table
  m_listAnimationAction.push_front(pAnimationAction);
  return pAnimationAction;
}
Ejemplo n.º 4
0
/** Executes an animation action.
  *
  * This function executes an animation action.
  *
  * @param id The ID of the animation cycle 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 No doxygen comment for this. FIXME.
  * @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)
{

  // Create a new action.  Test for error conditions.
  CalAnimationAction * aa = newAnimationAction(id);
  if( !aa ) return false;

  // If we got the action, then configure it for being update().
  return aa->execute(delayIn, delayOut, weightTarget, autoLock);
}
Ejemplo n.º 5
0
/** Stop the action.
  *
  * Turn off an action.
  *
  * @param id The ID of the core animation.
  *
  * @return One of the following values:
  *         \li \b true was playing (now stopped)
  *         \li \b false if already not playing
  *****************************************************************************/
bool
CalMixer::stopAction( int coreAnimationId )
{
  CalAnimationAction * aa = animationActionFromCoreAnimationId( coreAnimationId );
  if( !aa ) return false;
  m_listAnimationAction.remove( aa );  
  aa->destroy();
  delete aa;
  return true;
}
Ejemplo n.º 6
0
void CalMixer::destroy()
{
  // destroy all active animation actions
  while(!m_listAnimationAction.empty())
  {
    CalAnimationAction *pAnimationAction;
    pAnimationAction = m_listAnimationAction.front();
    m_listAnimationAction.pop_front();

    pAnimationAction->destroy();
    delete pAnimationAction;
  }
  m_pModel = 0;
}
Ejemplo n.º 7
0
/** Sets all the manual animation attributes.
  *
  * Sets all the manual animation attributes.  Action must already be manual.
  *
  * @return One of the following values:
  *         \li \b true if exists and manual
  *         \li \b false otherwise
  *****************************************************************************/
bool
CalMixer::setManualAnimationAttributes( int coreAnimationId, CalMixerManualAnimationAttributes const & p )
{
  CalAnimationAction * aa = animationActionFromCoreAnimationId( coreAnimationId );
  if( !aa ) return false;
  if( !aa->manual() ) return false;
  setManualAnimationOn( aa, p.on_ );
  setManualAnimationTime( aa, p.time_ );
  setManualAnimationWeight( aa, p.weight_ );
  setManualAnimationScale( aa, p.scale_ );
  setManualAnimationRampValue( aa, p.rampValue_ );
  setManualAnimationCompositionFunction( aa, p.compositionFunction_ );
  return true;
}
Ejemplo n.º 8
0
/** Add a manual animation instance.
  *
  * Add a manual animation instance for this core animation if one
  * does not already exist.  Only one instance can exist per core animation.
  * A manual animation instance can be on or off while still existing.
  * If it is off, it retains its state (time, amplitude), but
  * doesn't have any effect on the skeleton.
  *
  * @param id The ID of the core animation.
  *
  * @return One of the following values:
  *         \li \b true if didn't already exist
  *         \li \b false if already existed or allocation failed
  *****************************************************************************/
bool 
CalMixer::addManualAnimation( int coreAnimationId )
{ 
  if( animationActionFromCoreAnimationId( coreAnimationId ) ) {
    return false; // Already existed.
  }

  // Create a new action.  Test for error conditions.
  CalAnimationAction * aa = newAnimationAction( coreAnimationId );
  if( !aa ) return false;

  // If we got the action, then configure it as manual.
  return aa->setManual();
}
Ejemplo n.º 9
0
/** This function returns CalAnimationAction for given coreAnimationId.
  *
  * This function returns CalAnimationAction for given coreAnimationId.
  *
  * @param id The ID of the core animation.
  *
  * @return One of the following values:
  *         \li \b NULL if no action exists for given coreAnimationId.
  *         \li \b pointer to CalAnimationAction for the given coreAnimationId.
  *****************************************************************************/
CalAnimationAction *
CalMixer::animationActionFromCoreAnimationId( int coreAnimationId )
{
  std::list<CalAnimationAction *>::iterator iteratorAnimationAction;
  iteratorAnimationAction = m_listAnimationAction.begin();
  while(iteratorAnimationAction != m_listAnimationAction.end())
  {
    // update and check if animation action is still active
    CalAnimationAction * aa = *iteratorAnimationAction;
    CalCoreAnimation * ca = aa->getCoreAnimation();
    if( ca ) {
      CalCoreAnimation * ca2 = m_pModel->getCoreModel()->getCoreAnimation( coreAnimationId );
      if( ca == ca2 ) return aa;
    }
    ++iteratorAnimationAction;
  }
  return NULL;
}
Ejemplo n.º 10
0
void CalMixer::updateSkeleton()
{

  // get the skeleton we need to update
  CalSkeleton *pSkeleton;
  pSkeleton = m_pModel->getSkeleton();
  if(pSkeleton == 0) return;

  // clear the skeleton state
  pSkeleton->clearState();

  // get the bone vector of the skeleton
  std::vector<CalBone *>& vectorBone = pSkeleton->getVectorBone();

  // The bone adjustments are "replace" so they have to go first, giving them
  // highest priority and full influence.  Subsequent animations affecting the same bones, 
  // including subsequent replace animations, will have their incluence attenuated appropriately.
  applyBoneAdjustments();

  // loop through all animation actions
  std::list<CalAnimationAction *>::iterator itaa;
  for( itaa = m_listAnimationAction.begin(); itaa != m_listAnimationAction.end(); itaa++ ) {

    // get the core animation instance
    CalAnimationAction * aa = * itaa;
    
    // Manual animations can be on or off.  If they are off, they do not apply
    // to the bone.
    if( aa->on() ) {

      CalCoreAnimation * pCoreAnimation = aa->getCoreAnimation();
      
      // get the list of core tracks of above core animation
      std::list<CalCoreTrack *>& listCoreTrack = pCoreAnimation->getListCoreTrack();
      
      // loop through all core tracks of the core animation
      std::list<CalCoreTrack *>::iterator itct;
      for( itct = listCoreTrack.begin(); itct != listCoreTrack.end(); itct++ ) {
        
        // get the appropriate bone of the track
        CalCoreTrack * ct = * itct;
        if( ct->getCoreBoneId() >= int(vectorBone.size()) ) {
          continue;
        }
        CalBone * pBone = vectorBone[ ct->getCoreBoneId() ];
        
        // get the current translation and rotation
        CalVector translation;
        CalQuaternion rotation;
        ct->getState( aa->getTime(), translation, rotation);
        
        // Replace and CrossFade both blend with the replace function.
        bool replace = aa->getCompositionFunction() != CalAnimation::CompositionFunctionAverage;
        float scale = aa->getScale();
        pBone->blendState( aa->getWeight(), translation, rotation, scale, replace, aa->getRampValue() );
      }
    }
  }

  // === What does lockState() mean?  Why do we need it at all?  It seems only to allow us
  // to blend all the animation actions together into a temporary sum, and then
  // blend all the animation cycles together into a different sum, and then blend
  // the two sums together according to their relative weight sums.  I believe this is mathematically
  // equivalent of blending all the animation actions and cycles together into a single sum,
  // according to their relative weights.
  pSkeleton->lockState();

  // let the skeleton calculate its final state
  pSkeleton->calculateState();
}