123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include "EditorDefs.h"
- #include "DirectorNodeAnimator.h"
- // CryCommon
- #include <CryCommon/Maestro/Types/AnimParamType.h> // for AnimParamType
- // Editor
- #include "TrackView/TrackViewSequenceManager.h" // for CTrackViewSequence
- ////////////////////////////////////////////////////////////////////////////
- CDirectorNodeAnimator::CDirectorNodeAnimator([[maybe_unused]] CTrackViewAnimNode* pDirectorNode)
- {
- }
- ////////////////////////////////////////////////////////////////////////////
- void CDirectorNodeAnimator::Animate(CTrackViewAnimNode* pNode, const SAnimContext& ac)
- {
- if (!pNode->IsActiveDirector())
- {
- // Don't animate if it's not the sequence track of the active director
- return;
- }
- CTrackViewTrack* pSequenceTrack = pNode->GetTrackForParameter(AnimParamType::Sequence);
- if (pSequenceTrack && !pSequenceTrack->IsDisabled())
- {
- std::vector<CTrackViewSequence*> inactiveSequences;
- std::vector<CTrackViewSequence*> activeSequences;
- // Construct sets of sequences that need to be bound/unbound at this point
- const float time = ac.time;
- const unsigned int numKeys = pSequenceTrack->GetKeyCount();
- for (unsigned int i = 0; i < numKeys; ++i)
- {
- CTrackViewKeyHandle keyHandle = pSequenceTrack->GetKey(i);
- ISequenceKey sequenceKey;
- keyHandle.GetKey(&sequenceKey);
- CTrackViewSequence* pSequence = GetSequenceFromSequenceKey(sequenceKey);
- if (pSequence)
- {
- if (sequenceKey.time <= time)
- {
- stl::push_back_unique(activeSequences, pSequence);
- stl::find_and_erase(inactiveSequences, pSequence);
- }
- else
- {
- if (!stl::find(activeSequences, pSequence))
- {
- stl::push_back_unique(inactiveSequences, pSequence);
- }
- }
- }
- }
- // Unbind must occur before binding, because entities can be referenced in multiple sequences
- for (auto iter = inactiveSequences.begin(); iter != inactiveSequences.end(); ++iter)
- {
- CTrackViewSequence* pSequence = *iter;
- if (pSequence->IsBoundToEditorObjects())
- {
- // No notifications because unbinding would call ForceAnimation again
- CTrackViewSequenceNoNotificationContext context(pSequence);
- pSequence->UnBindFromEditorObjects();
- }
- }
- // Now bind sequences
- for (auto iter = activeSequences.begin(); iter != activeSequences.end(); ++iter)
- {
- CTrackViewSequence* pSequence = *iter;
- if (!pSequence->IsBoundToEditorObjects())
- {
- // No notifications because binding would call ForceAnimation again
- CTrackViewSequenceNoNotificationContext context(pSequence);
- pSequence->BindToEditorObjects();
- // Make sure the sequence is active, harmless to call if the sequences is already
- // active. The sequence may not be active in the Editor if this key was just created.
- pSequence->Activate();
- }
- }
- // Animate sub sequences
- ForEachActiveSequence(ac, pSequenceTrack, true,
- [&](CTrackViewSequence* pSequence, const SAnimContext& newAnimContext)
- {
- pSequence->Animate(newAnimContext);
- },
- [&](CTrackViewSequence* pSequence, [[maybe_unused]] const SAnimContext& newAnimContext)
- {
- pSequence->Reset(false);
- }
- );
- }
- }
- ////////////////////////////////////////////////////////////////////////////
- void CDirectorNodeAnimator::Render(CTrackViewAnimNode* pNode, const SAnimContext& ac)
- {
- if (!pNode->IsActiveDirector())
- {
- // Don't animate if it's not the sequence track of the active director
- return;
- }
- CTrackViewTrack* pSequenceTrack = pNode->GetTrackForParameter(AnimParamType::Sequence);
- if (pSequenceTrack && !pSequenceTrack->IsDisabled())
- {
- // Render sub sequences
- ForEachActiveSequence(ac, pSequenceTrack, false,
- [&](CTrackViewSequence* pSequence, [[maybe_unused]] const SAnimContext& newAnimContext)
- {
- pSequence->Render(newAnimContext);
- },
- [&]([[maybe_unused]] CTrackViewSequence* pSequence, [[maybe_unused]] const SAnimContext& newAnimContext) {}
- );
- }
- }
- ////////////////////////////////////////////////////////////////////////////
- void CDirectorNodeAnimator::ForEachActiveSequence(const SAnimContext& ac, CTrackViewTrack* pSequenceTrack,
- const bool bHandleOtherKeys, std::function<void(CTrackViewSequence*, const SAnimContext&)> animateFunction,
- std::function<void(CTrackViewSequence*, const SAnimContext&)> resetFunction)
- {
- const unsigned int numKeys = pSequenceTrack->GetKeyCount();
- if (bHandleOtherKeys)
- {
- // Reset all non-active sequences first
- for (unsigned int i = 0; i < numKeys; ++i)
- {
- CTrackViewKeyHandle keyHandle = pSequenceTrack->GetKey(i);
- ISequenceKey sequenceKey;
- keyHandle.GetKey(&sequenceKey);
- CTrackViewSequence* pSequence = GetSequenceFromSequenceKey(sequenceKey);
- if (pSequence)
- {
- SAnimContext newAnimContext = ac;
- const float duration = sequenceKey.fDuration;
- const float sequenceTime = ac.time - sequenceKey.time + sequenceKey.fStartTime;
- const float sequenceDuration = duration + sequenceKey.fStartTime;
- newAnimContext.time = std::min(sequenceTime, sequenceDuration);
- const bool bInsideKeyRange = (sequenceTime >= 0.0f) && (sequenceTime <= sequenceDuration);
- if (!bInsideKeyRange)
- {
- if (ac.forcePlay && sequenceTime >= 0.0f && newAnimContext.time != pSequence->GetTime())
- {
- // If forcing animation force previous keys to their last playback position
- animateFunction(pSequence, newAnimContext);
- }
- resetFunction(pSequence, newAnimContext);
- }
- }
- }
- }
- for (unsigned int i = 0; i < numKeys; ++i)
- {
- CTrackViewKeyHandle keyHandle = pSequenceTrack->GetKey(i);
- ISequenceKey sequenceKey;
- keyHandle.GetKey(&sequenceKey);
- CTrackViewSequence* pSequence = GetSequenceFromSequenceKey(sequenceKey);
- if (pSequence)
- {
- SAnimContext newAnimContext = ac;
- const float duration = sequenceKey.fDuration;
- const float sequenceTime = ac.time - sequenceKey.time + sequenceKey.fStartTime;
- const float sequenceDuration = duration + sequenceKey.fStartTime;
- newAnimContext.time = std::min(sequenceTime, sequenceDuration);
- const bool bInsideKeyRange = (sequenceTime >= 0.0f) && (sequenceTime <= sequenceDuration);
- if ((bInsideKeyRange && (newAnimContext.time != pSequence->GetTime() || ac.forcePlay)))
- {
- animateFunction(pSequence, newAnimContext);
- }
- }
- }
- }
- ////////////////////////////////////////////////////////////////////////////
- void CDirectorNodeAnimator::UnBind([[maybe_unused]] CTrackViewAnimNode* pNode)
- {
- const CTrackViewSequenceManager* pSequenceManager = GetIEditor()->GetSequenceManager();
- const unsigned int numSequences = pSequenceManager->GetCount();
- for (unsigned int sequenceIndex = 0; sequenceIndex < numSequences; ++sequenceIndex)
- {
- CTrackViewSequence* pSequence = pSequenceManager->GetSequenceByIndex(sequenceIndex);
- if (pSequence->IsActiveSequence())
- {
- // Don't care about the active sequence
- continue;
- }
- if (pSequence->IsBoundToEditorObjects())
- {
- pSequence->UnBindFromEditorObjects();
- }
- }
- }
- /*static*/ CTrackViewSequence* CDirectorNodeAnimator::GetSequenceFromSequenceKey(const ISequenceKey& sequenceKey)
- {
- CTrackViewSequence* retSequence = nullptr;
- const CTrackViewSequenceManager* sequenceManager = GetIEditor()->GetSequenceManager();
- if (sequenceManager)
- {
- if (sequenceKey.sequenceEntityId.IsValid())
- {
- retSequence = sequenceManager->GetSequenceByEntityId(sequenceKey.sequenceEntityId);
- AZ_Assert(retSequence, "Null sequence returned when a Sequence Component was expected.");
- }
- }
- return retSequence;
- }
|