Пример #1
0
int CalCoreModel::loadCoreAnimation(const std::string& strFilename, const char* pbyBuffer, unsigned long nBufferSize)
{
  // the core skeleton has to be loaded already
  if(m_pCoreSkeleton == 0)
  {
    CalError::setLastError(CalError::INVALID_HANDLE, __FILE__, __LINE__);
    return -1;
  }

  // load a new core animation
  CalLoader loader;
  CalCoreAnimation *pCoreAnimation;
  pCoreAnimation = loader.loadCoreAnimation(strFilename, pbyBuffer, nBufferSize);
  if(pCoreAnimation == 0) return -1;

  // add core animation to this core model
  int animationId;
  animationId = addCoreAnimation(pCoreAnimation);
  if(animationId == -1)
  {
    pCoreAnimation->release();
    return -1;
  }

  return animationId;
}
Пример #2
0
/////////////////////////////////////
// Purpose:	get the given anim's
//			duration
// Output:	none
// Return:	the duration
/////////////////////////////////////
f32 IgfxObject::AnimGetDuration(s32 animID)
{
	class CalCoreModel *pCalCoreModel = m_mdl->GetCalCoreModel();

	if(!pCalCoreModel)
		return 0;

	CalCoreAnimation *pAnim = pCalCoreModel->getCoreAnimation(animID);

	if(pAnim)
		return pAnim->getDuration();

	return 0;
}
/// \brief	Update function for the Cal3DModelManager
///			Renders immediately, the queued list of renderobjects
/// \return	void
void Cal3DModelManager::Update( DWORD tickCount )
{	
	//check for bad callbacks
	stack< CalCoreAnimation * > deadCallbacks;
	CAL3DANIMATIONTOCALLBACKMAP::iterator iter = m_AnimationCallbacks.begin();
	for(;iter != m_AnimationCallbacks.end(); ++iter)
	{
		Cal3dCallback * cb = (*iter).second;
		if( cb && cb->m_bDelete )
		{
			deadCallbacks.push( (*iter).first );
		}
	}
	//delete dead animation callbacks
	while( !deadCallbacks.empty() )
	{			
		CalCoreAnimation * ca = deadCallbacks.top();
		deadCallbacks.pop();
		iter = m_AnimationCallbacks.find( ca );
		if( iter != m_AnimationCallbacks.end())
		{
			Cal3dCallback * cb = (*iter).second;
			ca->removeCallback( cb );
			delete cb;
			m_AnimationCallbacks.erase( iter);
		}
	}

	OBJECTLIST	objList;
	static CHashString calTypeName( _T("Cal3DRenderObject"));
	//send a dummy file so we get a callback for this first phase	
	IDTOOBJECTMAP::iterator objIter;
	IDTOOBJECTMAP *objMap = GetObjectMap( &calTypeName );
	//update our objects
	if( objMap )
	{		
		IObject * destObject;
		for( objIter = objMap->begin();objIter != objMap->end(); ++objIter )
		{
			destObject = objIter->second;
			destObject->Update();
		}
	}
	
}
Пример #4
0
CoreModel::~CoreModel()
{
    if ( calCoreModel )
    {
        // TODO: report CoreTrack memory leak problem to cal3d maintainers
        for ( int i = 0; i < calCoreModel->getCoreAnimationCount(); i++ )
        {
            CalCoreAnimation* a = calCoreModel->getCoreAnimation( i );
            std::list<CalCoreTrack *>& ct = a->getListCoreTrack();
            for ( std::list<CalCoreTrack *>::iterator
                      t = ct.begin(),
                      tEnd = ct.end();
                  t != tEnd; ++t )
            {
                (*t)->destroy();
                delete (*t);
            }
            ct.clear();
        }

        // cleanup of non-auto released resources
        delete calCoreModel;
    }
}
DWORD Cal3DModelManager::OnGetCallback( DWORD size, void * params )
{
	GETCAL3DCALLBACK * msg;
	VERIFY_MESSAGE_SIZE( size, sizeof( GETCAL3DCALLBACK ) );
	msg = (GETCAL3DCALLBACK*)params;
	if( msg && msg->anim )
	{		
		CAL3DANIMATIONTOCALLBACKMAP::iterator iter = m_AnimationCallbacks.find( msg->anim );
		if( iter != m_AnimationCallbacks.end() )
		{
			msg->instance = (*iter).second;
		}else
		{
			//create new instance
			Cal3dCallback * cb = new Cal3dCallback();
			m_AnimationCallbacks.insert( pair< CalCoreAnimation *, Cal3dCallback * >( msg->anim, cb ) );
			CalCoreAnimation * anim = msg->anim;
			anim->registerCallback( cb,0);
			msg->instance = cb;
		}		
		return MSG_HANDLED_STOP;
	}
	return MSG_ERROR;
}
Пример #6
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();
}
Пример #7
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();

  // loop through all animation actions
  std::list<CalAnimationAction *>::iterator iteratorAnimationAction;
  for(iteratorAnimationAction = m_listAnimationAction.begin(); iteratorAnimationAction != m_listAnimationAction.end(); ++iteratorAnimationAction)
  {
    // get the core animation instance
    CalCoreAnimation *pCoreAnimation;
    pCoreAnimation = (*iteratorAnimationAction)->getCoreAnimation();

    // Ask the animation for the pose at the given time
    std::vector<CalTransform> pose;
    pose.resize(pCoreAnimation->getTrackCount());
    pCoreAnimation->getPose((*iteratorAnimationAction)->getTime(), pose);

    // Blend the pose into the current bone states
    for (unsigned bone_id = 0; bone_id < pSkeleton->getCoreSkeleton()->getVectorCoreBone().size(); ++bone_id)
    {
      int track_number = pCoreAnimation->getTrackAssignment(bone_id);

      // Skip this bone if the bone does not have a track assigned in the animation
      if (track_number == -1)
      {
        continue;
      }

      // Blend the animation pose with the skeleton
      CalBone* pBone = vectorBone[bone_id];
      pBone->blendState((*iteratorAnimationAction)->getWeight(), pose[track_number].getTranslation(), pose[track_number].getRotation());
    }
  }

  // lock the skeleton state
  pSkeleton->lockState();

  // loop through all animation cycles
  std::list<CalAnimationCycle *>::iterator iteratorAnimationCycle;
  for(iteratorAnimationCycle = m_listAnimationCycle.begin(); iteratorAnimationCycle != m_listAnimationCycle.end(); ++iteratorAnimationCycle)
  {
    // get the core animation instance
    CalCoreAnimation *pCoreAnimation;
    pCoreAnimation = (*iteratorAnimationCycle)->getCoreAnimation();

    // calculate adjusted time
    float animationTime;
    if((*iteratorAnimationCycle)->getState() == CalAnimation::STATE_SYNC)
    {
      if(m_animationDuration == 0.0f)
      {
        animationTime = 0.0f;
      }
      else
      {
        animationTime = m_animationTime * pCoreAnimation->getDuration() / m_animationDuration;
      }
    }
    else
    {
      animationTime = (*iteratorAnimationCycle)->getTime();
    }

    // Ask the animation for the pose at the given time
    std::vector<CalTransform> pose;
    pose.resize(pCoreAnimation->getTrackCount());
    pCoreAnimation->getPose(animationTime, pose);

    // Blend the pose into the current bone states
    for (unsigned index = 0; index < pose.size(); ++index)
    {
      int track_number = pCoreAnimation->getTrackAssignment(index);

      // Skip this bone if the bone does not have a track assigned in the animation
      if (track_number == -1)
      {
        continue;
      }

      CalBone* pBone = vectorBone[index];
      pBone->blendState((*iteratorAnimationCycle)->getWeight(), pose[track_number].getTranslation(), pose[track_number].getRotation());
    }
  }

  // lock the skeleton state
  pSkeleton->lockState();

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