float NxAnimation::GetKeyFramesAtTime( float timeIndex, NxKeyframe** keyFrame1, NxKeyframe** keyFrame2, unsigned short* firstKeyIndex) const { // Parametric time // t1 = time of previous keyframe // t2 = time of next keyframe Nx::Real t1, t2; // Wrap time assert(mTotalAnimationLength > 0.0f && "Invalid animation length!"); while( timeIndex > mTotalAnimationLength && mTotalAnimationLength > 0.0f ) { timeIndex -= mTotalAnimationLength; } KeyFrameList::const_iterator i; // No global keyframe index, need to search with local keyframes. NxKeyframe timeKey( timeIndex ); i = std::lower_bound(mKeyFrames.begin(), mKeyFrames.end(), &timeKey, KeyFrameTimeLess()); if (i == mKeyFrames.end()) { // There is no keyframe after this time, wrap back to first *keyFrame2 = mKeyFrames.front(); t2 = mTotalAnimationLength + (*keyFrame2)->GetTime(); // Use last keyframe as previous keyframe --i; } else { *keyFrame2 = *i; t2 = (*keyFrame2)->GetTime(); // Find last keyframe before or on current time if (i != mKeyFrames.begin() && timeIndex < (*i)->GetTime()) { --i; } } // Fill index of the first key if (firstKeyIndex) { *firstKeyIndex = static_cast<unsigned short>(std::distance(mKeyFrames.begin(), i)); } *keyFrame1 = *i; t1 = (*keyFrame1)->GetTime(); if (t1 == t2) { return 0.0;// Same KeyFrame (only one) } else { return (timeIndex - t1) / (t2 - t1); } }
//--------------------------------------------------------------------- KeyFrame* AnimationTrack::createKeyFrame(Real timePos) { KeyFrame* kf = createKeyFrameImpl(timePos); // Insert just before upper bound KeyFrameList::iterator i = std::upper_bound(mKeyFrames.begin(), mKeyFrames.end(), kf, KeyFrameTimeLess()); mKeyFrames.insert(i, kf); _keyFrameDataChanged(); mParent->_keyFrameListChanged(); return kf; }
void NxAnimation::GetEventsAtTime( float timeIndex, NxEvent** keyFrame1 ) const { EventList::const_iterator i; NxEvent timeKey( timeIndex ); i = std::lower_bound( mEvents.begin(), mEvents.end(), &timeKey, KeyFrameTimeLess()); if (i == mEvents.end()){ --i; } else{ if (i != mEvents.begin() && timeIndex < (*i)->GetTime()){ --i; } } *keyFrame1 = *i; }
void NxAnimation::AddEvent( NxEvent * Event ) { EventList::iterator i = std::upper_bound(mEvents.begin(), mEvents.end(), Event, KeyFrameTimeLess()); mEvents.insert(i, Event); }
void NxAnimation::AddKeyframe( NxKeyframe * Key ) { // Insert just before upper bound KeyFrameList::iterator i = std::upper_bound(mKeyFrames.begin(), mKeyFrames.end(), Key, KeyFrameTimeLess()); mKeyFrames.insert(i, Key); }
//--------------------------------------------------------------------- Real AnimationTrack::getKeyFramesAtTime(const TimeIndex& timeIndex, KeyFrame** keyFrame1, KeyFrame** keyFrame2, unsigned short* firstKeyIndex) const { // Parametric time // t1 = time of previous keyframe // t2 = time of next keyframe Real t1, t2; Real timePos = timeIndex.getTimePos(); // Find first keyframe after or on current time KeyFrameList::const_iterator i; if (timeIndex.hasKeyIndex()) { // Global keyframe index available, map to local keyframe index directly. assert(timeIndex.getKeyIndex() < mKeyFrameIndexMap.size()); i = mKeyFrames.begin() + mKeyFrameIndexMap[timeIndex.getKeyIndex()]; #if OGRE_DEBUG_MODE KeyFrame timeKey(0, timePos); if (i != std::lower_bound(mKeyFrames.begin(), mKeyFrames.end(), &timeKey, KeyFrameTimeLess())) { OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Optimised key frame search failed", "AnimationTrack::getKeyFramesAtTime"); } #endif } else { // Wrap time Real totalAnimationLength = mParent->getLength(); OgreAssertDbg(totalAnimationLength > 0.0f, "Invalid animation length!"); if( timePos > totalAnimationLength && totalAnimationLength > 0.0f ) timePos = std::fmod( timePos, totalAnimationLength ); // No global keyframe index, need to search with local keyframes. KeyFrame timeKey(0, timePos); i = std::lower_bound(mKeyFrames.begin(), mKeyFrames.end(), &timeKey, KeyFrameTimeLess()); } if (i == mKeyFrames.end()) { // There is no keyframe after this time, wrap back to first *keyFrame2 = mKeyFrames.front(); t2 = mParent->getLength() + (*keyFrame2)->getTime(); // Use last keyframe as previous keyframe --i; } else { *keyFrame2 = *i; t2 = (*keyFrame2)->getTime(); // Find last keyframe before or on current time if (i != mKeyFrames.begin() && timePos < (*i)->getTime()) { --i; } } // Fill index of the first key if (firstKeyIndex) { *firstKeyIndex = static_cast<unsigned short>(std::distance(mKeyFrames.begin(), i)); } *keyFrame1 = *i; t1 = (*keyFrame1)->getTime(); if (t1 == t2) { // Same KeyFrame (only one) return 0.0; } else { return (timePos - t1) / (t2 - t1); } }