#include "stdafx.h" #include "ITimeline.h" #include "AnimationManager.h" AnimationManager::AnimationManager(IEngine& argEngine) : m_Engine(argEngine) , m_PreviousDemoTime(0.0) , m_PreviousRealTime(0.0) { } AnimationManager::~AnimationManager() { } void AnimationManager::AddDemoTimeAnimation(double argBeginTime, double argEndTime, IAnimateable* argValue, unsigned int argUserData) { m_ForwardSortedAnimations[r_AnimationInterval(argBeginTime, argEndTime)].push_back(std::make_pair(argValue, argUserData)); m_BackwardSortedAnimations[r_AnimationInterval(argBeginTime, argEndTime)].push_back(std::make_pair(argValue, argUserData)); } void AnimationManager::AddRealTimeAnimation(double argBeginTime, double argEndTime, IAnimateable* argValue, unsigned int argUserData) { m_RealTimeAnimations[r_AnimationInterval(argBeginTime, argEndTime)].push_back(std::make_pair(argValue, argUserData)); } void AnimationManager::AddDemoTimeEvent(double argTime, IEvent* argValue, unsigned int argUserData) { m_DemoTimeEvents[argTime].push_back(std::make_pair(argValue, argUserData)); } void AnimationManager::AddRealTimeEvent(double argTime, IEvent* argValue, unsigned int argUserData) { m_RealTimeEvents[argTime].push_back(std::make_pair(argValue, argUserData)); } void AnimationManager::Animate() { ITimeline& timeline = m_Engine.get_Timeline(); double ld_DemoTime = timeline.get_DemoTime(); double ld_RealTime = timeline.get_RealTime(); // Gather all active animations, they are the ones that started before now and end after now. // Do this for both the demo time and real time. std::vector > lk_ActiveAnimations; std::vector lk_AnimationTimes; // Demo time animations: Demo time can go backwards, so search from both directions if (timeline.get_SpeedAndDirection() > 0) { tk_ForwardAnims::iterator lk_Iter = m_ForwardSortedAnimations.begin(); for (; lk_Iter != m_ForwardSortedAnimations.end(); ++lk_Iter) { if (lk_Iter->first.m_Begin <= ld_DemoTime && lk_Iter->first.m_End >= ld_DemoTime) { std::vector >::iterator lk_AnimIter = lk_Iter->second.begin(); for (; lk_AnimIter != lk_Iter->second.end(); ++lk_AnimIter) { lk_ActiveAnimations.push_back(*lk_AnimIter); lk_AnimationTimes.push_back((ld_DemoTime - lk_Iter->first.m_Begin) / (lk_Iter->first.m_End - lk_Iter->first.m_Begin)); } } if (lk_Iter->first.m_Begin > ld_DemoTime) break; } } else if (timeline.get_SpeedAndDirection() < 0) { tk_BackwardAnims::iterator lk_Iter = m_BackwardSortedAnimations.begin(); for (; lk_Iter != m_BackwardSortedAnimations.end(); ++lk_Iter) { if (lk_Iter->first.m_End >= ld_DemoTime && lk_Iter->first.m_Begin <= ld_DemoTime) { std::vector >::iterator lk_AnimIter = lk_Iter->second.begin(); for (; lk_AnimIter != lk_Iter->second.end(); ++lk_AnimIter) { lk_ActiveAnimations.push_back(*lk_AnimIter); lk_AnimationTimes.push_back((ld_DemoTime - lk_Iter->first.m_Begin) / (lk_Iter->first.m_End - lk_Iter->first.m_Begin)); } } if (lk_Iter->first.m_End < ld_DemoTime) break; } } // Real time animations: The time that we know doesn't allow us to travel to the past, so just check into the future: { tk_ForwardAnims::iterator lk_Iter = m_RealTimeAnimations.begin(); for (; lk_Iter != m_RealTimeAnimations.end(); ++lk_Iter) { if (lk_Iter->first.m_Begin <= ld_RealTime && lk_Iter->first.m_End >= ld_RealTime) { std::vector >::iterator lk_AnimIter = lk_Iter->second.begin(); for (; lk_AnimIter != lk_Iter->second.end(); ++lk_AnimIter) { lk_ActiveAnimations.push_back(*lk_AnimIter); lk_AnimationTimes.push_back((ld_RealTime - lk_Iter->first.m_End) / (lk_Iter->first.m_Begin - lk_Iter->first.m_End)); } } if (lk_Iter->first.m_Begin > ld_RealTime) break; } } // Now that we know what animations correspond to this time, animate them! std::vector >::iterator lk_AnimIter = lk_ActiveAnimations.begin(); std::vector::iterator lk_TimeIter = lk_AnimationTimes.begin(); for (; lk_AnimIter != lk_ActiveAnimations.end(); ++lk_AnimIter, ++lk_TimeIter) { IAnimateable* lr_Animateable_ = lk_AnimIter->first; lr_Animateable_->OnAnimate(*lk_TimeIter, lk_AnimIter->second); } // Fire all events that happened since last time: tk_Events::iterator lk_EventIter = m_DemoTimeEvents.begin(); for (; lk_EventIter != m_DemoTimeEvents.end(); ++lk_EventIter) { double ld_Time = lk_EventIter->first; std::vector >::iterator lk_EventVecIter = lk_EventIter->second.begin(); for (; lk_EventVecIter != lk_EventIter->second.end(); ++lk_EventVecIter) { IEvent* lr_Event_ = lk_EventVecIter->first; unsigned int lui_UserData = lk_EventVecIter->second; if (((timeline.get_SpeedAndDirection() > 0) && (ld_Time >= m_PreviousDemoTime && ld_Time <= ld_DemoTime)) || ((timeline.get_SpeedAndDirection() < 0) && (ld_Time <= m_PreviousDemoTime && ld_Time >= ld_DemoTime))) { lr_Event_->OnEvent(lui_UserData); } } } lk_EventIter = m_RealTimeEvents.begin(); for (; lk_EventIter != m_RealTimeEvents.end(); ++lk_EventIter) { double ld_Time = lk_EventIter->first; std::vector >::iterator lk_EventVecIter = lk_EventIter->second.begin(); for (; lk_EventVecIter != lk_EventIter->second.end(); ++lk_EventVecIter) { IEvent* lr_Event_ = lk_EventVecIter->first; unsigned int lui_UserData = lk_EventVecIter->second; if (ld_Time >= m_PreviousRealTime && ld_Time <= ld_RealTime) { lr_Event_->OnEvent(lui_UserData); } } } m_PreviousDemoTime = ld_DemoTime; m_PreviousRealTime = ld_RealTime; }