Esempio n. 1
0
void
CalCoreTrack::translationCompressibility( bool * transRequiredResult, bool * transDynamicResult, bool * highRangeRequiredResult,
                                  float threshold, float highRangeThreshold, CalCoreSkeleton * skel )
{
  * transRequiredResult = false;
  * transDynamicResult = false;
  * highRangeRequiredResult = false;
  unsigned int numFrames = m_keyframes.size();
  CalCoreBone * cb = skel->getCoreBone( m_coreBoneId );
  const CalVector & cbtrans = cb->getTranslation();
  CalVector trans0;
  float t2 = threshold * threshold;
  unsigned int i;
  for( i = 0; i < numFrames; i++ ) {
    CalCoreKeyframe * keyframe = m_keyframes[ i ];
    const CalVector & kftrans = keyframe->getTranslation();
    if( fabsf( kftrans.x ) >= highRangeThreshold
      ||  fabsf( kftrans.y ) >= highRangeThreshold
      ||  fabsf( kftrans.z ) >= highRangeThreshold ) {
      * highRangeRequiredResult = true;
    }
    if( i == 0 ) {
      trans0 = keyframe->getTranslation();
    } else {
      float d2 = DistanceSquared( trans0, kftrans );
      if( d2 > t2 ) {
        * transDynamicResult = true;
      }
    }
    float d2 = DistanceSquared( cbtrans, kftrans );
    if( d2 > t2 ) {
      * transRequiredResult = true;
    }
  }
}
Esempio n. 2
0
void
CalCoreTrack::fillInvalidTranslations( CalVector const & trans )
{
  unsigned int numFrames = m_keyframes.size();
  for( unsigned int i = 0; i < numFrames; i++ ) {
    CalCoreKeyframe * keyframe = m_keyframes[ i ];
    const CalVector & kftrans = keyframe->getTranslation();
    if( TranslationInvalid( kftrans ) ) {
      keyframe->setTranslation( trans );
    }
  }
}
Esempio n. 3
0
void CalCoreTrack::destroy()
{
  // destroy all core keyframes
  rde::sorted_vector<float, CalCoreKeyframe *>::iterator iteratorCoreKeyframe;

  for(iteratorCoreKeyframe = m_mapCoreKeyframe.begin(); iteratorCoreKeyframe != m_mapCoreKeyframe.end(); ++iteratorCoreKeyframe)
  {
    CalCoreKeyframe *pCoreKeyframe;
    pCoreKeyframe = iteratorCoreKeyframe->second;

    pCoreKeyframe->destroy();
    delete pCoreKeyframe;
  }

  m_mapCoreKeyframe.clear();

  m_coreBoneId = -1;
}
Esempio n. 4
0
bool CalCoreTrack::getState(float time, CalVector& translation, CalQuaternion& rotation) const
{
  std::vector<CalCoreKeyframe*>::const_iterator iteratorCoreKeyframeBefore;
  std::vector<CalCoreKeyframe*>::const_iterator iteratorCoreKeyframeAfter;

  // get the keyframe after the requested time
  iteratorCoreKeyframeAfter = getUpperBound(time);

  // check if the time is after the last keyframe
  if(iteratorCoreKeyframeAfter == m_keyframes.end())
  {
    // return the last keyframe state
    --iteratorCoreKeyframeAfter;
    rotation = (*iteratorCoreKeyframeAfter)->getRotation();
    translation = (*iteratorCoreKeyframeAfter)->getTranslation();

    return true;
  }

  // check if the time is before the first keyframe
  if(iteratorCoreKeyframeAfter == m_keyframes.begin())
  {
    // return the first keyframe state
    rotation = (*iteratorCoreKeyframeAfter)->getRotation();
    translation = (*iteratorCoreKeyframeAfter)->getTranslation();

    return true;
  }

  // get the keyframe before the requested one
  iteratorCoreKeyframeBefore = iteratorCoreKeyframeAfter;
  --iteratorCoreKeyframeBefore;

  // get the two keyframe pointers
  CalCoreKeyframe *pCoreKeyframeBefore;
  pCoreKeyframeBefore = *iteratorCoreKeyframeBefore;
  CalCoreKeyframe *pCoreKeyframeAfter;
  pCoreKeyframeAfter = *iteratorCoreKeyframeAfter;

  // calculate the blending factor between the two keyframe states
  float blendFactor;
  blendFactor = (time - pCoreKeyframeBefore->getTime()) / (pCoreKeyframeAfter->getTime() - pCoreKeyframeBefore->getTime());

  // blend between the two keyframes
  translation = pCoreKeyframeBefore->getTranslation();
  translation.blend(blendFactor, pCoreKeyframeAfter->getTranslation());

  rotation = pCoreKeyframeBefore->getRotation();
  rotation.blend(blendFactor, pCoreKeyframeAfter->getRotation());

  return true;
}
Esempio n. 5
0
bool CalCoreTrack::getState(float time, CalVector& translation, CalQuaternion& rotation)
{
  rde::sorted_vector<float, CalCoreKeyframe *>::iterator iteratorCoreKeyframeBefore;
  rde::sorted_vector<float, CalCoreKeyframe *>::iterator iteratorCoreKeyframeAfter;

  // get the keyframe after the requested time
  iteratorCoreKeyframeAfter = m_mapCoreKeyframe.upper_bound(time);

  // check if the time is after the last keyframe
  if(iteratorCoreKeyframeAfter == m_mapCoreKeyframe.end())
  {
    // return the last keyframe state
    --iteratorCoreKeyframeAfter;
    rotation = (iteratorCoreKeyframeAfter->second)->getRotation();
    translation = (iteratorCoreKeyframeAfter->second)->getTranslation();

    return true;
  }

  // check if the time is before the first keyframe
  if(iteratorCoreKeyframeAfter == m_mapCoreKeyframe.begin())
  {
    // return the first keyframe state
    rotation = (iteratorCoreKeyframeAfter->second)->getRotation();
    translation = (iteratorCoreKeyframeAfter->second)->getTranslation();

    return true;
  }

  // get the keyframe before the requested one
  iteratorCoreKeyframeBefore = iteratorCoreKeyframeAfter;
  --iteratorCoreKeyframeBefore;

  // get the two keyframe pointers
  CalCoreKeyframe *pCoreKeyframeBefore;
  pCoreKeyframeBefore = iteratorCoreKeyframeBefore->second;
  CalCoreKeyframe *pCoreKeyframeAfter;
  pCoreKeyframeAfter = iteratorCoreKeyframeAfter->second;

  // calculate the blending factor between the two keyframe states
  float blendFactor;
  blendFactor = (time - pCoreKeyframeBefore->getTime()) / (pCoreKeyframeAfter->getTime() - pCoreKeyframeBefore->getTime());

  // blend between the two keyframes
  translation = pCoreKeyframeBefore->getTranslation();
  translation.blend(blendFactor, pCoreKeyframeAfter->getTranslation());

  rotation = pCoreKeyframeBefore->getRotation();
  rotation.blend(blendFactor, pCoreKeyframeAfter->getRotation());

  return true;
}
Esempio n. 6
0
// Returns true if rounding took place and they were not exactly equal.
bool
CalCoreTrack::roundTranslation( CalCoreKeyframe const * prevp, CalCoreKeyframe * p, double transTolerance  )
{
  CalCoreKeyframe * prev = const_cast< CalCoreKeyframe * >( prevp );
  CalVector translation;
  assert( prev && p );

  // blend between the two keyframes
  translation = prev->getTranslation();
  CalVector const ppos = p->getTranslation();
  float dist = Distance( translation, ppos );

  // Identical returns false.
  if( dist == 0 ) return false;

  // Compare with tolerance.
  if( dist < transTolerance ) { // equal case handled above.
    p->setTranslation( translation );
    return true;
  } else {
    return false;
  }
}
Esempio n. 7
0
int
CMaxAnimationImport::DoImport(
  const TCHAR* name,
  ImpInterface* ii,
  Interface* i,
  BOOL suppressPrompts)
{
  AFX_MANAGE_STATE(AfxGetStaticModuleState());

  HWND window = i->GetMAXHWnd();

  CFileDialog fileDialog(TRUE, "xsf", 0, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
                         0, CWnd::FromHandle(window));
  if (fileDialog.DoModal() != IDOK) {
    return IMPEXP_CANCEL;
  }

  CString skeleton = fileDialog.GetPathName();
  
	cal3d::RefPtr<CalCoreSkeleton> skel = CalLoader::loadCoreSkeleton(std::string(skeleton));
  if (!skel) {
    MessageBox(
      window, "Loading skeleton file failed",
      "Import Cal3D Animation", MB_OK | MB_ICONERROR);
    return IMPEXP_FAIL;
  }

	cal3d::RefPtr<CalCoreAnimation> anim = CalLoader::loadCoreAnimation(name);
  if (!anim) {
    MessageBox(
      window, "Loading animation file failed",
      "Import Cal3D Animation", MB_OK | MB_ICONERROR);
    return IMPEXP_FAIL;
  }

  typedef std::list<CalCoreTrack*> CoreTrackList;
  CoreTrackList& trackList = anim->getListCoreTrack();
  for (CoreTrackList::iterator itr = trackList.begin(); itr != trackList.end(); ++itr) {
    CalCoreTrack* track = *itr;

    int boneId = track->getCoreBoneId();
    CalCoreBone* bone = skel->getCoreBone(boneId);
    if (!bone) continue;

    INode* node = i->GetINodeByName(bone->getName().c_str());
    if (!node) continue;

    unsigned kfCount = track->getCoreKeyframeCount();

    SuspendAnimate();
    AnimateOn();
    for (unsigned i = 0; i < kfCount; ++i) {
      CalCoreKeyframe* kf = track->getCoreKeyframe(i);
      CalQuaternion kf_q = kf->getRotation();
      CalVector     kf_v = kf->getTranslation();
      TimeValue     time = SecToTicks(kf->getTime());

      Matrix3 tm;
      tm.IdentityMatrix();
      Quat(kf_q.x, kf_q.y, kf_q.z, kf_q.w).MakeMatrix(tm);
      tm.SetTrans(Point3(kf_v.x, kf_v.y, kf_v.z));

      INode* parent = node->GetParentNode();
      if (parent) {
        tm *= parent->GetNodeTM(time);
      }

      node->SetNodeTM(time, tm);
    }
    ResumeAnimate();

/*
    typedef std::map<float, CalCoreKeyframe*> KeyMap;
    KeyMap& keys = track->getMapCoreKeyframe();

    int mapsize = sizeof(keys);

    int size = keys.size();

    int idx = 0;
    for (KeyMap::iterator mi = keys.begin(); mi != keys.end(); ++mi) {
      Point3 p;
      CalCoreKeyframe* kf = mi->second;
      p.x = kf->getTranslation().x;
      p.y = kf->getTranslation().y;
      p.z = kf->getTranslation().z;
      pos->SetValue(SecToTicks(mi->first), &p);
    }
*/

/*
    IKeyControl* kc = GetKeyControlInterface(pos);
    if (!kc) continue;

    typedef std::map<float, CalCoreKeyframe*> KeyMap;
    KeyMap& keys = track->getMapCoreKeyframe();
    kc->SetNumKeys(keys.size());

    int idx = 0;
    for (KeyMap::iterator mi = keys.begin(); mi != keys.end(); ++mi) {
      ITCBPoint3Key key;
      key.time = SecToTicks(mi->first);
      key.tens = 0;
      key.cont = 0;
      key.bias = 0;
      key.easeIn = 25.0;
      key.easeOut = 25.0;
      key.val.x = mi->second->getTranslation().x;
      key.val.y = mi->second->getTranslation().y;
      key.val.z = mi->second->getTranslation().z;

      kc->SetKey(idx++, &key);
    }

    kc->SortKeys();
*/
  }
 
  return IMPEXP_SUCCESS;
}
Esempio n. 8
0
bool CExporter::ExportAnimation(const std::string& strFilename)
{
	// check if a valid interface is set
	if(m_pInterface == 0)
	{
		SetLastError("Invalid handle.", __FILE__, __LINE__);
		return false;
	}

	// build a skeleton candidate
	CSkeletonCandidate skeletonCandidate;

	// show export wizard sheet
	CAnimationExportSheet sheet("Cal3D Animation Export", m_pInterface->GetMainWnd());
	sheet.SetSkeletonCandidate(&skeletonCandidate);
	sheet.SetAnimationTime(m_pInterface->GetStartFrame(), m_pInterface->GetEndFrame(), m_pInterface->GetCurrentFrame(), m_pInterface->GetFps());
	sheet.SetWizardMode();
	if(sheet.DoModal() != ID_WIZFINISH) return true;

	// get the number of selected bone candidates
	int selectedCount;
	selectedCount = skeletonCandidate.GetSelectedCount();
	if(selectedCount == 0)
	{
		SetLastError("No bones selected to export.", __FILE__, __LINE__);
		return false;
	}

	// create the core animation instance
	cal3d::RefPtr<CalCoreAnimation> coreAnimation = new CalCoreAnimation();

	// set the duration of the animation
	float duration;
	duration = (float)(sheet.GetEndFrame() - sheet.GetStartFrame()) / (float)m_pInterface->GetFps();
	coreAnimation->setDuration(duration);

	// get bone candidate vector
	std::vector<CBoneCandidate *>& vectorBoneCandidate = skeletonCandidate.GetVectorBoneCandidate();

	size_t boneCandidateId;
	for(boneCandidateId = 0; boneCandidateId < vectorBoneCandidate.size(); boneCandidateId++)
	{
		// get the bone candidate
		CBoneCandidate *pBoneCandidate;
		pBoneCandidate = vectorBoneCandidate[boneCandidateId];

		// only create tracks for the selected bone candidates
		if(pBoneCandidate->IsSelected())
		{
			// allocate new core track instance
			CalCoreTrack *pCoreTrack;
			pCoreTrack = new CalCoreTrack();
			if(pCoreTrack == 0)
			{
				theExporter.SetLastError("Memory allocation failed.", __FILE__, __LINE__);
				theExporter.GetInterface()->StopProgressInfo();
				return false;
			}

			// create the core track instance
			if(!pCoreTrack->create())
			{
				theExporter.SetLastError(CalError::getLastErrorText(), __FILE__, __LINE__);
				delete pCoreTrack;
				theExporter.GetInterface()->StopProgressInfo();
				return false;
			}

			// set the core bone id
			pCoreTrack->setCoreBoneId(boneCandidateId);

			// add the core track to the core animation instance
			if(!coreAnimation->addCoreTrack(pCoreTrack))
			{
				theExporter.SetLastError(CalError::getLastErrorText(), __FILE__, __LINE__);
				delete pCoreTrack;
				theExporter.GetInterface()->StopProgressInfo();
				return false;
			}
		}
	}

	// start the progress info
	theExporter.GetInterface()->StartProgressInfo("Exporting to animation file...");

	// calculate the end frame
	int endFrame;
	endFrame = (int)(duration * (float)sheet.GetFps() + 0.5f);

	// calculate the displaced frame
  int displacedFrame;
  displacedFrame = (int)(((float)sheet.GetDisplacement() / (float)m_pInterface->GetFps()) * (float)sheet.GetFps() + 0.5f) % endFrame;

	// calculate the possible wrap frame
  int wrapFrame;
  wrapFrame = (displacedFrame > 0) ? 1 : 0;
  float wrapTime;
  wrapTime = 0.0f;

  int frame;
  int outputFrame;
  for(frame = 0,  outputFrame = 0; frame <= (endFrame + wrapFrame); frame++)
	{
		// update the progress info
		m_pInterface->SetProgressInfo(int(100.0f * (float)frame / (float)(endFrame + wrapFrame + 1)));

		// calculate the time in seconds
		float time;
		time = (float)sheet.GetStartFrame() / (float)m_pInterface->GetFps() + (float)displacedFrame / (float)sheet.GetFps();

/* DEBUG
CString str;
str.Format("frame=%d, endframe=%d, disframe=%d, ouputFrame=%d (%f), time=%f\n", frame, endFrame, displacedFrame, outputFrame, (float)outputFrame / (float)sheet.GetFps() + wrapTime, time);
OutputDebugString(str);
*/

		for(boneCandidateId = 0; boneCandidateId < vectorBoneCandidate.size(); boneCandidateId++)
		{
			// get the bone candidate
			CBoneCandidate *pBoneCandidate;
			pBoneCandidate = vectorBoneCandidate[boneCandidateId];

			// only export keyframes for the selected bone candidates
			if(pBoneCandidate->IsSelected())
			{
				// allocate new core keyframe instance
				CalCoreKeyframe *pCoreKeyframe;
				pCoreKeyframe = new CalCoreKeyframe();
				if(pCoreKeyframe == 0)
				{
					theExporter.SetLastError("Memory allocation failed.", __FILE__, __LINE__);
					theExporter.GetInterface()->StopProgressInfo();
					return false;
				}

				// create the core keyframe instance
				if(!pCoreKeyframe->create())
				{
					theExporter.SetLastError(CalError::getLastErrorText(), __FILE__, __LINE__);
					delete pCoreKeyframe;
					theExporter.GetInterface()->StopProgressInfo();
					return false;
				}

				// set the frame time
				pCoreKeyframe->setTime((float)outputFrame / (float)sheet.GetFps() + wrapTime);

				// get the translation and the rotation of the bone candidate
				CalVector translation;
				CalQuaternion rotation;
				skeletonCandidate.GetTranslationAndRotation(boneCandidateId, time, translation, rotation);

				// set the translation and rotation
				pCoreKeyframe->setTranslation(translation);
				pCoreKeyframe->setRotation(rotation);

				// get the core track for this bone candidate
				CalCoreTrack *pCoreTrack;
				pCoreTrack = coreAnimation->getCoreTrack(pBoneCandidate->GetId());
				if(pCoreTrack == 0)
				{
					theExporter.SetLastError(CalError::getLastErrorText(), __FILE__, __LINE__);
					delete pCoreKeyframe;
					theExporter.GetInterface()->StopProgressInfo();
					return false;
				}

				// add this core keyframe to the core track
				pCoreTrack->addCoreKeyframe(pCoreKeyframe);
			}
		}

    // calculate the next displaced frame and its frame time
    if(wrapFrame > 0)
    {
      if(displacedFrame == endFrame)
      {
        wrapTime = 0.0001f;
        displacedFrame = 0;
      }
      else
      {
        wrapTime = 0.0f;
        outputFrame++;
        displacedFrame++;
      }
    }
    else
    {
      outputFrame++;
      displacedFrame++;
   }
	}

	// stop the progress info
	theExporter.GetInterface()->StopProgressInfo();

	// save core animation to the file
	if(!CalSaver::saveCoreAnimation(strFilename, coreAnimation.get()))
	{
		theExporter.SetLastError(CalError::getLastErrorText(), __FILE__, __LINE__);
		return false;
	}

	return true;
}