/** 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; }
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(); }