DirectorNodeAnimator.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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 "DirectorNodeAnimator.h"
  10. // CryCommon
  11. #include <CryCommon/Maestro/Types/AnimParamType.h> // for AnimParamType
  12. // Editor
  13. #include "TrackView/TrackViewSequenceManager.h" // for CTrackViewSequence
  14. ////////////////////////////////////////////////////////////////////////////
  15. CDirectorNodeAnimator::CDirectorNodeAnimator([[maybe_unused]] CTrackViewAnimNode* pDirectorNode)
  16. {
  17. }
  18. ////////////////////////////////////////////////////////////////////////////
  19. void CDirectorNodeAnimator::Animate(CTrackViewAnimNode* pNode, const SAnimContext& ac)
  20. {
  21. if (!pNode->IsActiveDirector())
  22. {
  23. // Don't animate if it's not the sequence track of the active director
  24. return;
  25. }
  26. CTrackViewTrack* pSequenceTrack = pNode->GetTrackForParameter(AnimParamType::Sequence);
  27. if (pSequenceTrack && !pSequenceTrack->IsDisabled())
  28. {
  29. std::vector<CTrackViewSequence*> inactiveSequences;
  30. std::vector<CTrackViewSequence*> activeSequences;
  31. // Construct sets of sequences that need to be bound/unbound at this point
  32. const float time = ac.time;
  33. const unsigned int numKeys = pSequenceTrack->GetKeyCount();
  34. for (unsigned int i = 0; i < numKeys; ++i)
  35. {
  36. CTrackViewKeyHandle keyHandle = pSequenceTrack->GetKey(i);
  37. ISequenceKey sequenceKey;
  38. keyHandle.GetKey(&sequenceKey);
  39. CTrackViewSequence* pSequence = GetSequenceFromSequenceKey(sequenceKey);
  40. if (pSequence)
  41. {
  42. if (sequenceKey.time <= time)
  43. {
  44. stl::push_back_unique(activeSequences, pSequence);
  45. stl::find_and_erase(inactiveSequences, pSequence);
  46. }
  47. else
  48. {
  49. if (!stl::find(activeSequences, pSequence))
  50. {
  51. stl::push_back_unique(inactiveSequences, pSequence);
  52. }
  53. }
  54. }
  55. }
  56. // Unbind must occur before binding, because entities can be referenced in multiple sequences
  57. for (auto iter = inactiveSequences.begin(); iter != inactiveSequences.end(); ++iter)
  58. {
  59. CTrackViewSequence* pSequence = *iter;
  60. if (pSequence->IsBoundToEditorObjects())
  61. {
  62. // No notifications because unbinding would call ForceAnimation again
  63. CTrackViewSequenceNoNotificationContext context(pSequence);
  64. pSequence->UnBindFromEditorObjects();
  65. }
  66. }
  67. // Now bind sequences
  68. for (auto iter = activeSequences.begin(); iter != activeSequences.end(); ++iter)
  69. {
  70. CTrackViewSequence* pSequence = *iter;
  71. if (!pSequence->IsBoundToEditorObjects())
  72. {
  73. // No notifications because binding would call ForceAnimation again
  74. CTrackViewSequenceNoNotificationContext context(pSequence);
  75. pSequence->BindToEditorObjects();
  76. // Make sure the sequence is active, harmless to call if the sequences is already
  77. // active. The sequence may not be active in the Editor if this key was just created.
  78. pSequence->Activate();
  79. }
  80. }
  81. // Animate sub sequences
  82. ForEachActiveSequence(ac, pSequenceTrack, true,
  83. [&](CTrackViewSequence* pSequence, const SAnimContext& newAnimContext)
  84. {
  85. pSequence->Animate(newAnimContext);
  86. },
  87. [&](CTrackViewSequence* pSequence, [[maybe_unused]] const SAnimContext& newAnimContext)
  88. {
  89. pSequence->Reset(false);
  90. }
  91. );
  92. }
  93. }
  94. ////////////////////////////////////////////////////////////////////////////
  95. void CDirectorNodeAnimator::Render(CTrackViewAnimNode* pNode, const SAnimContext& ac)
  96. {
  97. if (!pNode->IsActiveDirector())
  98. {
  99. // Don't animate if it's not the sequence track of the active director
  100. return;
  101. }
  102. CTrackViewTrack* pSequenceTrack = pNode->GetTrackForParameter(AnimParamType::Sequence);
  103. if (pSequenceTrack && !pSequenceTrack->IsDisabled())
  104. {
  105. // Render sub sequences
  106. ForEachActiveSequence(ac, pSequenceTrack, false,
  107. [&](CTrackViewSequence* pSequence, [[maybe_unused]] const SAnimContext& newAnimContext)
  108. {
  109. pSequence->Render(newAnimContext);
  110. },
  111. [&]([[maybe_unused]] CTrackViewSequence* pSequence, [[maybe_unused]] const SAnimContext& newAnimContext) {}
  112. );
  113. }
  114. }
  115. ////////////////////////////////////////////////////////////////////////////
  116. void CDirectorNodeAnimator::ForEachActiveSequence(const SAnimContext& ac, CTrackViewTrack* pSequenceTrack,
  117. const bool bHandleOtherKeys, std::function<void(CTrackViewSequence*, const SAnimContext&)> animateFunction,
  118. std::function<void(CTrackViewSequence*, const SAnimContext&)> resetFunction)
  119. {
  120. const unsigned int numKeys = pSequenceTrack->GetKeyCount();
  121. if (bHandleOtherKeys)
  122. {
  123. // Reset all non-active sequences first
  124. for (unsigned int i = 0; i < numKeys; ++i)
  125. {
  126. CTrackViewKeyHandle keyHandle = pSequenceTrack->GetKey(i);
  127. ISequenceKey sequenceKey;
  128. keyHandle.GetKey(&sequenceKey);
  129. CTrackViewSequence* pSequence = GetSequenceFromSequenceKey(sequenceKey);
  130. if (pSequence)
  131. {
  132. SAnimContext newAnimContext = ac;
  133. const float duration = sequenceKey.fDuration;
  134. const float sequenceTime = ac.time - sequenceKey.time + sequenceKey.fStartTime;
  135. const float sequenceDuration = duration + sequenceKey.fStartTime;
  136. newAnimContext.time = std::min(sequenceTime, sequenceDuration);
  137. const bool bInsideKeyRange = (sequenceTime >= 0.0f) && (sequenceTime <= sequenceDuration);
  138. if (!bInsideKeyRange)
  139. {
  140. if (ac.forcePlay && sequenceTime >= 0.0f && newAnimContext.time != pSequence->GetTime())
  141. {
  142. // If forcing animation force previous keys to their last playback position
  143. animateFunction(pSequence, newAnimContext);
  144. }
  145. resetFunction(pSequence, newAnimContext);
  146. }
  147. }
  148. }
  149. }
  150. for (unsigned int i = 0; i < numKeys; ++i)
  151. {
  152. CTrackViewKeyHandle keyHandle = pSequenceTrack->GetKey(i);
  153. ISequenceKey sequenceKey;
  154. keyHandle.GetKey(&sequenceKey);
  155. CTrackViewSequence* pSequence = GetSequenceFromSequenceKey(sequenceKey);
  156. if (pSequence)
  157. {
  158. SAnimContext newAnimContext = ac;
  159. const float duration = sequenceKey.fDuration;
  160. const float sequenceTime = ac.time - sequenceKey.time + sequenceKey.fStartTime;
  161. const float sequenceDuration = duration + sequenceKey.fStartTime;
  162. newAnimContext.time = std::min(sequenceTime, sequenceDuration);
  163. const bool bInsideKeyRange = (sequenceTime >= 0.0f) && (sequenceTime <= sequenceDuration);
  164. if ((bInsideKeyRange && (newAnimContext.time != pSequence->GetTime() || ac.forcePlay)))
  165. {
  166. animateFunction(pSequence, newAnimContext);
  167. }
  168. }
  169. }
  170. }
  171. ////////////////////////////////////////////////////////////////////////////
  172. void CDirectorNodeAnimator::UnBind([[maybe_unused]] CTrackViewAnimNode* pNode)
  173. {
  174. const CTrackViewSequenceManager* pSequenceManager = GetIEditor()->GetSequenceManager();
  175. const unsigned int numSequences = pSequenceManager->GetCount();
  176. for (unsigned int sequenceIndex = 0; sequenceIndex < numSequences; ++sequenceIndex)
  177. {
  178. CTrackViewSequence* pSequence = pSequenceManager->GetSequenceByIndex(sequenceIndex);
  179. if (pSequence->IsActiveSequence())
  180. {
  181. // Don't care about the active sequence
  182. continue;
  183. }
  184. if (pSequence->IsBoundToEditorObjects())
  185. {
  186. pSequence->UnBindFromEditorObjects();
  187. }
  188. }
  189. }
  190. /*static*/ CTrackViewSequence* CDirectorNodeAnimator::GetSequenceFromSequenceKey(const ISequenceKey& sequenceKey)
  191. {
  192. CTrackViewSequence* retSequence = nullptr;
  193. const CTrackViewSequenceManager* sequenceManager = GetIEditor()->GetSequenceManager();
  194. if (sequenceManager)
  195. {
  196. if (sequenceKey.sequenceEntityId.IsValid())
  197. {
  198. retSequence = sequenceManager->GetSequenceByEntityId(sequenceKey.sequenceEntityId);
  199. AZ_Assert(retSequence, "Null sequence returned when a Sequence Component was expected.");
  200. }
  201. }
  202. return retSequence;
  203. }