AnimationContext.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "EditorDefs.h"
  9. #include "AnimationContext.h"
  10. // CryCommon
  11. #include <CryCommon/Maestro/Bus/EditorSequenceBus.h>
  12. // Editor
  13. #include "TrackView/TrackViewDialog.h"
  14. #include "ViewManager.h"
  15. #include "Include/IObjectManager.h"
  16. #include "Objects/EntityObject.h"
  17. #include <AzCore/Serialization/Locale.h>
  18. #include <AzCore/Time/ITime.h>
  19. //////////////////////////////////////////////////////////////////////////
  20. // Movie Callback.
  21. //////////////////////////////////////////////////////////////////////////
  22. class CMovieCallback
  23. : public IMovieCallback
  24. {
  25. protected:
  26. void OnMovieCallback(ECallbackReason reason, [[maybe_unused]] IAnimNode* pNode) override
  27. {
  28. switch (reason)
  29. {
  30. case CBR_CHANGENODE:
  31. // Invalidate nodes
  32. break;
  33. case CBR_CHANGETRACK:
  34. {
  35. // Invalidate tracks
  36. CTrackViewDialog* pTrackViewDialog = CTrackViewDialog::GetCurrentInstance();
  37. if (pTrackViewDialog)
  38. {
  39. pTrackViewDialog->InvalidateDopeSheet();
  40. }
  41. }
  42. break;
  43. }
  44. }
  45. void OnSetCamera(const SCameraParams& Params) override
  46. {
  47. // Only switch camera when in Play mode.
  48. GUID camObjId = GUID_NULL;
  49. if (Params.cameraEntityId.IsValid())
  50. {
  51. // Find owner editor entity.
  52. CEntityObject* pEditorEntity = CEntityObject::FindFromEntityId(Params.cameraEntityId);
  53. if (pEditorEntity)
  54. {
  55. camObjId = pEditorEntity->GetId();
  56. }
  57. }
  58. // Switch camera in active rendering view.
  59. if (GetIEditor()->GetViewManager())
  60. {
  61. GetIEditor()->GetViewManager()->SetCameraObjectId(camObjId);
  62. }
  63. };
  64. bool IsSequenceCamUsed() const override
  65. {
  66. if (gEnv->IsEditorGameMode() == true)
  67. {
  68. return true;
  69. }
  70. if (GetIEditor()->GetViewManager() == nullptr)
  71. {
  72. return false;
  73. }
  74. CViewport* pRendView = GetIEditor()->GetViewManager()->GetViewport(ET_ViewportCamera);
  75. if (pRendView)
  76. {
  77. return pRendView->IsSequenceCamera();
  78. }
  79. return false;
  80. }
  81. };
  82. static CMovieCallback s_movieCallback;
  83. //////////////////////////////////////////////////////////////////////////
  84. //-----------------------------------------------------------------------------
  85. //!
  86. class CAnimationContextPostRender
  87. : public IPostRenderer
  88. {
  89. public:
  90. CAnimationContextPostRender(CAnimationContext* pAC)
  91. : m_pAC(pAC){}
  92. void OnPostRender() const override { assert(m_pAC); m_pAC->OnPostRender(); }
  93. protected:
  94. CAnimationContext* m_pAC;
  95. };
  96. //////////////////////////////////////////////////////////////////////////
  97. CAnimationContext::CAnimationContext()
  98. {
  99. m_paused = 0;
  100. m_playing = false;
  101. m_recording = false;
  102. m_bSavedRecordingState = false;
  103. m_timeRange.Set(0, 0);
  104. m_timeMarker.Set(0, 0);
  105. m_currTime = 0.0f;
  106. m_lastTimeChangedNotificationTime = .0f;
  107. m_bForceUpdateInNextFrame = false;
  108. m_fTimeScale = 1.0f;
  109. m_pSequence = nullptr;
  110. m_mostRecentSequenceId.SetInvalid();
  111. m_mostRecentSequenceTime = 0.0f;
  112. m_bLooping = false;
  113. m_bAutoRecording = false;
  114. m_fRecordingTimeStep = 0;
  115. m_bSingleFrame = false;
  116. m_bPostRenderRegistered = false;
  117. m_bForcingAnimation = false;
  118. GetIEditor()->GetUndoManager()->AddListener(this);
  119. GetIEditor()->GetSequenceManager()->AddListener(this);
  120. GetIEditor()->RegisterNotifyListener(this);
  121. }
  122. //////////////////////////////////////////////////////////////////////////
  123. CAnimationContext::~CAnimationContext()
  124. {
  125. GetIEditor()->GetSequenceManager()->RemoveListener(this);
  126. GetIEditor()->GetUndoManager()->RemoveListener(this);
  127. GetIEditor()->UnregisterNotifyListener(this);
  128. }
  129. //////////////////////////////////////////////////////////////////////////
  130. void CAnimationContext::Init()
  131. {
  132. if (gEnv->pMovieSystem)
  133. {
  134. gEnv->pMovieSystem->SetCallback(&s_movieCallback);
  135. }
  136. REGISTER_COMMAND("mov_goToFrameEditor", (ConsoleCommandFunc)GoToFrameCmd, 0, "Make a specified sequence go to a given frame time in the editor.");
  137. }
  138. //////////////////////////////////////////////////////////////////////////
  139. void CAnimationContext::AddListener(IAnimationContextListener* pListener)
  140. {
  141. stl::push_back_unique(m_contextListeners, pListener);
  142. }
  143. //////////////////////////////////////////////////////////////////////////
  144. void CAnimationContext::RemoveListener(IAnimationContextListener* pListener)
  145. {
  146. stl::find_and_erase(m_contextListeners, pListener);
  147. }
  148. void CAnimationContext::NotifyTimeChangedListenersUsingCurrTime() const
  149. {
  150. for (size_t i = 0; i < m_contextListeners.size(); ++i)
  151. {
  152. m_contextListeners[i]->OnTimeChanged(m_currTime);
  153. }
  154. m_lastTimeChangedNotificationTime = m_currTime;
  155. }
  156. //////////////////////////////////////////////////////////////////////////
  157. void CAnimationContext::SetSequence(CTrackViewSequence* sequence, bool force, bool noNotify, bool user)
  158. {
  159. float newSeqStartTime = .0f;
  160. CTrackViewSequence* pCurrentSequence = m_pSequence;
  161. if (!force && sequence == pCurrentSequence)
  162. {
  163. return;
  164. }
  165. // Prevent keys being created from time change
  166. const bool bRecording = m_recording;
  167. m_recording = false;
  168. SetRecordingInternal(false);
  169. if (sequence)
  170. {
  171. newSeqStartTime = sequence->GetTimeRange().start;
  172. }
  173. m_currTime = newSeqStartTime;
  174. m_fRecordingCurrTime = newSeqStartTime;
  175. if (!m_bPostRenderRegistered)
  176. {
  177. if (GetIEditor() && GetIEditor()->GetViewManager())
  178. {
  179. CViewport* pViewport = GetIEditor()->GetViewManager()->GetViewport(ET_ViewportCamera);
  180. if (pViewport)
  181. {
  182. pViewport->AddPostRenderer(new CAnimationContextPostRender(this));
  183. m_bPostRenderRegistered = true;
  184. }
  185. }
  186. }
  187. if (m_pSequence)
  188. {
  189. m_pSequence->Deactivate();
  190. if (m_playing)
  191. {
  192. m_pSequence->EndCutScene();
  193. }
  194. m_pSequence->UnBindFromEditorObjects();
  195. }
  196. m_pSequence = sequence;
  197. // Notify a new sequence was just selected.
  198. Maestro::EditorSequenceNotificationBus::Broadcast(&Maestro::EditorSequenceNotificationBus::Events::OnSequenceSelected, m_pSequence ? m_pSequence->GetSequenceComponentEntityId() : AZ::EntityId());
  199. if (m_pSequence)
  200. {
  201. // Set the last valid sequence that was selected.
  202. m_mostRecentSequenceId = m_pSequence->GetSequenceComponentEntityId();
  203. if (m_playing)
  204. {
  205. m_pSequence->BeginCutScene(true);
  206. }
  207. m_timeRange = m_pSequence->GetTimeRange();
  208. m_timeMarker = m_timeRange;
  209. m_pSequence->Activate();
  210. m_pSequence->PrecacheData(newSeqStartTime);
  211. m_pSequence->BindToEditorObjects();
  212. }
  213. else if (user)
  214. {
  215. // If this was a sequence that was selected by the user in Track View
  216. // and it was "No Sequence" clear the m_mostRecentSequenceId so the sequence
  217. // will not be reselected at unwanted events like an undo operation.
  218. m_mostRecentSequenceId.SetInvalid();
  219. }
  220. ForceAnimation();
  221. if (!noNotify)
  222. {
  223. NotifyTimeChangedListenersUsingCurrTime();
  224. for (size_t i = 0; i < m_contextListeners.size(); ++i)
  225. {
  226. m_contextListeners[i]->OnSequenceChanged(m_pSequence);
  227. }
  228. }
  229. TimeChanged(newSeqStartTime);
  230. m_recording = bRecording;
  231. SetRecordingInternal(bRecording);
  232. }
  233. //////////////////////////////////////////////////////////////////////////
  234. void CAnimationContext::UpdateTimeRange()
  235. {
  236. if (m_pSequence)
  237. {
  238. m_timeRange = m_pSequence->GetTimeRange();
  239. // reset the current time to make sure it is clamped
  240. // to the new range.
  241. SetTime(m_currTime);
  242. }
  243. }
  244. //////////////////////////////////////////////////////////////////////////
  245. void CAnimationContext::SetTime(float t)
  246. {
  247. if (t < m_timeRange.start)
  248. {
  249. t = m_timeRange.start;
  250. }
  251. if (t > m_timeRange.end)
  252. {
  253. t = m_timeRange.end;
  254. }
  255. if (fabs(m_currTime - t) < 0.001f)
  256. {
  257. return;
  258. }
  259. m_currTime = t;
  260. m_fRecordingCurrTime = t;
  261. ForceAnimation();
  262. NotifyTimeChangedListenersUsingCurrTime();
  263. }
  264. void CAnimationContext::TimeChanged(float newTime)
  265. {
  266. if (m_pSequence)
  267. {
  268. m_mostRecentSequenceTime = newTime;
  269. m_pSequence->TimeChanged(newTime);
  270. }
  271. }
  272. //////////////////////////////////////////////////////////////////////////
  273. void CAnimationContext::OnSequenceActivated(AZ::EntityId entityId)
  274. {
  275. // If nothing is selected and there is a valid most recent selected
  276. // try to find that sequence by id and select it. This is useful
  277. // for restoring the selected sequence during undo and redo.
  278. if (m_pSequence == nullptr && m_mostRecentSequenceId.IsValid())
  279. {
  280. if (entityId == m_mostRecentSequenceId)
  281. {
  282. auto editor = GetIEditor();
  283. if (editor != nullptr)
  284. {
  285. auto manager = editor->GetSequenceManager();
  286. if (manager != nullptr)
  287. {
  288. auto sequence = manager->GetSequenceByEntityId(m_mostRecentSequenceId);
  289. if (sequence != nullptr)
  290. {
  291. // Hang onto this because SetSequence() will reset it.
  292. float lastTime = m_mostRecentSequenceTime;
  293. SetSequence(sequence, false, false);
  294. // Restore the current time.
  295. SetTime(lastTime);
  296. // Notify time may have changed, use m_currTime incase it was clamped by SetTime()
  297. TimeChanged(m_currTime);
  298. }
  299. }
  300. }
  301. }
  302. }
  303. }
  304. //////////////////////////////////////////////////////////////////////////
  305. void CAnimationContext::Pause()
  306. {
  307. assert(m_paused >= 0);
  308. m_paused++;
  309. if (m_recording)
  310. {
  311. SetRecordingInternal(false);
  312. }
  313. if (GetIEditor()->GetMovieSystem())
  314. {
  315. GetIEditor()->GetMovieSystem()->Pause();
  316. }
  317. if (m_pSequence)
  318. {
  319. m_pSequence->Pause();
  320. }
  321. }
  322. //////////////////////////////////////////////////////////////////////////
  323. void CAnimationContext::Resume()
  324. {
  325. assert(m_paused > 0);
  326. m_paused--;
  327. if (m_recording && m_paused == 0)
  328. {
  329. SetRecordingInternal(true);
  330. }
  331. if (GetIEditor()->GetMovieSystem())
  332. {
  333. GetIEditor()->GetMovieSystem()->Resume();
  334. }
  335. if (m_pSequence)
  336. {
  337. m_pSequence->Resume();
  338. }
  339. }
  340. //////////////////////////////////////////////////////////////////////////
  341. void CAnimationContext::SetRecording(bool recording)
  342. {
  343. if (recording == m_recording)
  344. {
  345. return;
  346. }
  347. m_paused = 0;
  348. m_recording = recording;
  349. m_playing = false;
  350. if (!recording && m_fRecordingTimeStep != 0)
  351. {
  352. SetAutoRecording(false, 0);
  353. }
  354. // If started recording, assume we have modified the document.
  355. GetIEditor()->SetModifiedFlag();
  356. SetRecordingInternal(recording);
  357. }
  358. //////////////////////////////////////////////////////////////////////////
  359. //////////////////////////////////////////////////////////////////////////
  360. void CAnimationContext::SetPlaying(bool playing)
  361. {
  362. if (playing == m_playing)
  363. {
  364. return;
  365. }
  366. m_paused = 0;
  367. m_playing = playing;
  368. m_recording = false;
  369. SetRecordingInternal(false);
  370. IMovieSystem* pMovieSystem = GetIEditor()->GetMovieSystem();
  371. if (pMovieSystem)
  372. {
  373. if (playing)
  374. {
  375. pMovieSystem->Resume();
  376. if (m_pSequence)
  377. {
  378. m_pSequence->Resume();
  379. IMovieUser* pMovieUser = pMovieSystem->GetUser();
  380. if (pMovieUser)
  381. {
  382. m_pSequence->BeginCutScene(true);
  383. }
  384. }
  385. pMovieSystem->ResumeCutScenes();
  386. }
  387. else
  388. {
  389. pMovieSystem->Pause();
  390. if (m_pSequence)
  391. {
  392. m_pSequence->Pause();
  393. }
  394. pMovieSystem->PauseCutScenes();
  395. if (m_pSequence)
  396. {
  397. IMovieUser* pMovieUser = pMovieSystem->GetUser();
  398. if (pMovieUser)
  399. {
  400. m_pSequence->EndCutScene();
  401. }
  402. }
  403. }
  404. }
  405. }
  406. //////////////////////////////////////////////////////////////////////////
  407. void CAnimationContext::Update()
  408. {
  409. if (m_bForceUpdateInNextFrame)
  410. {
  411. ForceAnimation();
  412. m_bForceUpdateInNextFrame = false;
  413. }
  414. // If looking through camera object and recording animation, do not allow camera shake
  415. if ((GetIEditor()->GetViewManager()->GetCameraObjectId() != GUID_NULL) && GetIEditor()->GetAnimation()->IsRecording())
  416. {
  417. if (GetIEditor()->GetMovieSystem())
  418. {
  419. GetIEditor()->GetMovieSystem()->EnableCameraShake(false);
  420. }
  421. }
  422. else
  423. {
  424. if (GetIEditor()->GetMovieSystem())
  425. {
  426. GetIEditor()->GetMovieSystem()->EnableCameraShake(true);
  427. }
  428. }
  429. if (m_paused > 0 || !(m_playing || m_bAutoRecording))
  430. {
  431. if (m_pSequence)
  432. {
  433. m_pSequence->StillUpdate();
  434. }
  435. if (!m_recording)
  436. {
  437. if (GetIEditor()->GetMovieSystem())
  438. {
  439. GetIEditor()->GetMovieSystem()->StillUpdate();
  440. }
  441. }
  442. return;
  443. }
  444. const AZ::TimeUs frameDeltaTimeUs = AZ::GetSimulationTickDeltaTimeUs();
  445. const float frameDeltaTime = AZ::TimeUsToSeconds(frameDeltaTimeUs);
  446. if (!m_bAutoRecording)
  447. {
  448. AnimateActiveSequence();
  449. m_currTime += frameDeltaTime * m_fTimeScale;
  450. if (!m_recording)
  451. {
  452. if (GetIEditor()->GetMovieSystem())
  453. {
  454. GetIEditor()->GetMovieSystem()->PreUpdate(frameDeltaTime);
  455. GetIEditor()->GetMovieSystem()->PostUpdate(frameDeltaTime);
  456. }
  457. }
  458. }
  459. else
  460. {
  461. m_fRecordingCurrTime += frameDeltaTime * m_fTimeScale;
  462. if (fabs(m_fRecordingCurrTime - m_currTime) > m_fRecordingTimeStep)
  463. {
  464. m_currTime += m_fRecordingTimeStep;
  465. }
  466. }
  467. if (m_currTime > m_timeMarker.end)
  468. {
  469. if (m_bAutoRecording)
  470. {
  471. SetAutoRecording(false, 0);
  472. }
  473. else
  474. {
  475. if (m_bLooping)
  476. {
  477. m_currTime = m_timeMarker.start;
  478. if (m_pSequence)
  479. {
  480. m_pSequence->OnLoop();
  481. }
  482. }
  483. else
  484. {
  485. SetPlaying(false);
  486. m_currTime = m_timeMarker.end;
  487. }
  488. }
  489. }
  490. if (fabs(m_lastTimeChangedNotificationTime - m_currTime) > 0.001f)
  491. {
  492. NotifyTimeChangedListenersUsingCurrTime();
  493. }
  494. }
  495. //////////////////////////////////////////////////////////////////////////
  496. void CAnimationContext::ForceAnimation()
  497. {
  498. if (m_bForcingAnimation)
  499. {
  500. // reentrant calls are possible when using subsequences
  501. return;
  502. }
  503. m_bForcingAnimation = true;
  504. // Before animating node, pause recording.
  505. if (m_bAutoRecording)
  506. {
  507. Pause();
  508. }
  509. AnimateActiveSequence();
  510. // Animate a second time to properly update camera DoF
  511. AnimateActiveSequence();
  512. if (m_bAutoRecording)
  513. {
  514. Resume();
  515. }
  516. m_bForcingAnimation = false;
  517. }
  518. //////////////////////////////////////////////////////////////////////////
  519. void CAnimationContext::SetAutoRecording(bool bEnable, float fTimeStep)
  520. {
  521. if (bEnable)
  522. {
  523. m_bAutoRecording = true;
  524. m_fRecordingTimeStep = fTimeStep;
  525. SetRecording(bEnable);
  526. }
  527. else
  528. {
  529. m_bAutoRecording = false;
  530. m_fRecordingTimeStep = 0;
  531. }
  532. }
  533. //////////////////////////////////////////////////////////////////////////
  534. void CAnimationContext::GoToFrameCmd(IConsoleCmdArgs* pArgs)
  535. {
  536. if (pArgs->GetArgCount() < 2)
  537. {
  538. gEnv->pLog->LogError("GoToFrame: You must provide a 'frame time' to go to");
  539. return;
  540. }
  541. assert(GetIEditor()->GetAnimation());
  542. CTrackViewSequence* pSeq = GetIEditor()->GetAnimation()->GetSequence();
  543. if (!pSeq)
  544. {
  545. gEnv->pLog->LogError("GoToFrame: No active animation sequence");
  546. return;
  547. }
  548. // console commands are in the invariant locale, for atof()
  549. AZ::Locale::ScopedSerializationLocale scopedLocale;
  550. float targetFrame = (float)atof(pArgs->GetArg(1));
  551. scopedLocale.Deactivate();
  552. if (pSeq->GetTimeRange().start > targetFrame || targetFrame > pSeq->GetTimeRange().end)
  553. {
  554. gEnv->pLog->LogError("GoToFrame: requested time %f is outside the range of sequence %s (%f, %f)", targetFrame, pSeq->GetName().c_str(), pSeq->GetTimeRange().start, pSeq->GetTimeRange().end);
  555. return;
  556. }
  557. GetIEditor()->GetAnimation()->m_currTime = targetFrame;
  558. GetIEditor()->GetAnimation()->m_bSingleFrame = true;
  559. GetIEditor()->GetAnimation()->ForceAnimation();
  560. }
  561. //////////////////////////////////////////////////////////////////////////
  562. void CAnimationContext::OnPostRender()
  563. {
  564. if (m_pSequence)
  565. {
  566. SAnimContext ac;
  567. ac.dt = 0;
  568. const AZ::TimeUs frameDeltaTimeUs = AZ::GetSimulationTickDeltaTimeUs();
  569. const float frameDeltaTime = AZ::TimeUsToSeconds(frameDeltaTimeUs);
  570. ac.fps = 1.0f / frameDeltaTime;
  571. ac.time = m_currTime;
  572. ac.singleFrame = true;
  573. ac.forcePlay = true;
  574. m_pSequence->Render(ac);
  575. }
  576. }
  577. void CAnimationContext::BeginUndoTransaction()
  578. {
  579. m_bSavedRecordingState = m_recording;
  580. SetRecordingInternal(false);
  581. }
  582. //////////////////////////////////////////////////////////////////////////
  583. void CAnimationContext::EndUndoTransaction()
  584. {
  585. if (m_pSequence)
  586. {
  587. m_pSequence->BindToEditorObjects();
  588. }
  589. SetRecordingInternal(m_bSavedRecordingState);
  590. }
  591. //////////////////////////////////////////////////////////////////////////
  592. void CAnimationContext::TogglePlay()
  593. {
  594. if (!IsPlaying())
  595. {
  596. SetPlaying(true);
  597. }
  598. else
  599. {
  600. SetPlaying(false);
  601. }
  602. }
  603. //////////////////////////////////////////////////////////////////////////
  604. void CAnimationContext::OnSequenceRemoved(CTrackViewSequence* pSequence)
  605. {
  606. if (m_pSequence == pSequence)
  607. {
  608. SetSequence(nullptr, true, false);
  609. }
  610. }
  611. //////////////////////////////////////////////////////////////////////////
  612. void CAnimationContext::OnEditorNotifyEvent(EEditorNotifyEvent event)
  613. {
  614. switch (event)
  615. {
  616. case eNotify_OnBeginGameMode:
  617. if (m_pSequence)
  618. {
  619. m_pSequence->Resume();
  620. }
  621. case eNotify_OnBeginSceneSave:
  622. case eNotify_OnBeginLayerExport:
  623. if (m_pSequence)
  624. {
  625. m_sequenceToRestore = m_pSequence->GetSequenceComponentEntityId();
  626. }
  627. else
  628. {
  629. m_sequenceToRestore.SetInvalid();
  630. }
  631. m_sequenceRestoreTime = GetTime();
  632. m_bSavedRecordingState = m_recording;
  633. SetRecordingInternal(false);
  634. SetSequence(nullptr, true, true);
  635. break;
  636. case eNotify_OnEndGameMode:
  637. case eNotify_OnEndSceneSave:
  638. case eNotify_OnEndLayerExport:
  639. m_currTime = m_sequenceRestoreTime;
  640. SetSequence(GetIEditor()->GetSequenceManager()->GetSequenceByEntityId(m_sequenceToRestore), true, true);
  641. SetTime(m_sequenceRestoreTime);
  642. SetRecordingInternal(m_bSavedRecordingState);
  643. break;
  644. case eNotify_OnQuit:
  645. case eNotify_OnCloseScene:
  646. SetSequence(nullptr, true, false);
  647. break;
  648. case eNotify_OnBeginNewScene:
  649. SetSequence(nullptr, false, false);
  650. break;
  651. case eNotify_OnBeginLoad:
  652. m_mostRecentSequenceId.SetInvalid();
  653. m_mostRecentSequenceTime = 0.0f;
  654. m_bSavedRecordingState = m_recording;
  655. SetRecordingInternal(false);
  656. GetIEditor()->GetAnimation()->SetSequence(nullptr, false, false);
  657. break;
  658. case eNotify_OnEndLoad:
  659. SetRecordingInternal(m_bSavedRecordingState);
  660. break;
  661. }
  662. }
  663. void CAnimationContext::SetRecordingInternal(bool enableRecording)
  664. {
  665. if (GetIEditor()->GetMovieSystem())
  666. {
  667. GetIEditor()->GetMovieSystem()->SetRecording(enableRecording);
  668. }
  669. if (m_pSequence)
  670. {
  671. m_pSequence->SetRecording(enableRecording);
  672. }
  673. }
  674. void CAnimationContext::AnimateActiveSequence()
  675. {
  676. if (!m_pSequence)
  677. {
  678. return;
  679. }
  680. SAnimContext ac;
  681. ac.dt = 0;
  682. const AZ::TimeUs frameDeltaTimeUs = AZ::GetSimulationTickDeltaTimeUs();
  683. const float frameDeltaTime = AZ::TimeUsToSeconds(frameDeltaTimeUs);
  684. ac.fps = 1.0f / frameDeltaTime;
  685. ac.time = m_currTime;
  686. ac.singleFrame = true;
  687. ac.forcePlay = true;
  688. m_pSequence->Animate(ac);
  689. m_pSequence->SyncToConsole(ac);
  690. }