Esempio n. 1
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. 2
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. 3
0
bool
CalCoreTrack::keyframeEliminatable( CalCoreKeyframe * prev, 
                                   CalCoreKeyframe * p, 
                                   CalCoreKeyframe * next,
                                   double transTolerance,
                                   double rotTolerance )
{
  CalVector translation;
  CalQuaternion rotation;
  assert( prev && p && next );
  float time = p->getTime();
  float blendFactor;
  blendFactor = ( time - prev->getTime() ) / ( next->getTime() - prev->getTime() );

  // blend between the two keyframes
  translation = prev->getTranslation();
  translation.blend( blendFactor, next->getTranslation() );
  rotation = prev->getRotation();
  rotation.blend( blendFactor, next->getRotation() );
  CalVector const ppos = p->getTranslation();
  CalQuaternion const pori = p->getRotation();
  return Near( translation, rotation, ppos, pori, transTolerance, rotTolerance );
}
Esempio n. 4
0
CalQuaternion CMilkBoneNode::GetRelativeRotation(float time)
{
	// get the initial rotation component
  msVec3 orientation;
  msBone_GetRotation(m_pIBone, orientation);

	// calculate the initial rotation component
  CalQuaternion initialRotation;
  initialRotation = ConvertToQuaternion(orientation);

  // return if the initial state is requested or if there are no keyframes
  if((time < 0.0f) || (msBone_GetRotationKeyCount(m_pIBone) == 0)) return initialRotation;

  // calculate the real frame time
  // REMEMBER: milkshape starts at 1.0!
  float frameTime;
  frameTime = 1.0f + time * (float)theExporter.GetInterface()->GetFps();

  // find the keyframe just before the requested time
  msRotationKey *pKeyBefore;
  pKeyBefore = msBone_GetRotationKeyAt(m_pIBone, msBone_GetRotationKeyCount(m_pIBone) - 1);

  int keyId;
  for(keyId = 0; keyId < msBone_GetRotationKeyCount(m_pIBone); keyId++)
  {
    // get the keyframe
    msRotationKey *pKey;
    pKey = msBone_GetRotationKeyAt(m_pIBone, keyId);

    // stop if we are over the requested time
    if(pKey->fTime > frameTime) break;

    pKeyBefore = pKey;
  }

  // get the keyframe just after the requested time
  msRotationKey *pKeyAfter;
  pKeyAfter = msBone_GetRotationKeyAt(m_pIBone, 0);

  if(keyId < msBone_GetRotationKeyCount(m_pIBone))
  {
    pKeyAfter = msBone_GetRotationKeyAt(m_pIBone, keyId);
  }

  // calculate the "just before" rotation component
  CalQuaternion rotationBefore;
  if(pKeyBefore != 0)
  {
    rotationBefore = ConvertToQuaternion(pKeyBefore->Rotation);

    // return if there is no key after this one
    if(pKeyAfter == 0) return initialRotation * rotationBefore;
  }

	// calculate the "just after" rotation component
  CalQuaternion rotationAfter;
  if(pKeyAfter != 0)
  {
    rotationAfter = ConvertToQuaternion(pKeyAfter->Rotation);

    // return if there is no key before this one
    if(pKeyBefore == 0) return initialRotation * rotationAfter;
  }

  // return if both keys are actually the same
  if(pKeyBefore == pKeyAfter) return initialRotation * rotationAfter;

  // calculate the blending factor
  float factor;
  factor = (frameTime - pKeyBefore->fTime) / (pKeyAfter->fTime - pKeyBefore->fTime);

  // blend the two rotation components
  rotationBefore.blend(factor, rotationAfter);

  return initialRotation * rotationBefore;
}