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