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); } }
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 EventSendingController::leapForward(int milliseconds) { #ifdef USE_WEBPROCESS_EVENT_SIMULATION m_time += milliseconds / 1000.0; #else WKRetainPtr<WKStringRef> EventSenderMessageName(AdoptWK, WKStringCreateWithUTF8CString("EventSender")); WKRetainPtr<WKMutableDictionaryRef> EventSenderMessageBody(AdoptWK, WKMutableDictionaryCreate()); WKRetainPtr<WKStringRef> subMessageKey(AdoptWK, WKStringCreateWithUTF8CString("SubMessage")); WKRetainPtr<WKStringRef> subMessageName(AdoptWK, WKStringCreateWithUTF8CString("LeapForward")); WKDictionaryAddItem(EventSenderMessageBody.get(), subMessageKey.get(), subMessageName.get()); WKRetainPtr<WKStringRef> timeKey(AdoptWK, WKStringCreateWithUTF8CString("TimeInMilliseconds")); WKRetainPtr<WKUInt64Ref> timeRef(AdoptWK, WKUInt64Create(milliseconds)); WKDictionaryAddItem(EventSenderMessageBody.get(), timeKey.get(), timeRef.get()); WKBundlePostSynchronousMessage(InjectedBundle::shared().bundle(), EventSenderMessageName.get(), EventSenderMessageBody.get(), 0); #endif }
//--------------------------------------------------------------------- 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); } }