summaryrefslogtreecommitdiffstats
path: root/src/dm/systems/cores/AnimationCoreProducer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/dm/systems/cores/AnimationCoreProducer.cpp')
-rw-r--r--src/dm/systems/cores/AnimationCoreProducer.cpp488
1 files changed, 488 insertions, 0 deletions
diff --git a/src/dm/systems/cores/AnimationCoreProducer.cpp b/src/dm/systems/cores/AnimationCoreProducer.cpp
new file mode 100644
index 0000000..14d1824
--- /dev/null
+++ b/src/dm/systems/cores/AnimationCoreProducer.cpp
@@ -0,0 +1,488 @@
+/****************************************************************************
+**
+** Copyright (C) 1993-2009 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "Qt3DSDMPrefix.h"
+#include "AnimationCoreProducer.h"
+#include "HandleSystemTransactions.h"
+#include "VectorTransactions.h"
+#include "SignalsImpl.h"
+#ifdef _WIN32
+#pragma warning(disable : 4512) // assignment operator not generated
+#endif
+
+using namespace std;
+
+namespace qt3dsdm {
+
+struct SArtistEditedUndoRedoScope
+{
+ TSimpleAnimationCorePtr m_AnimationCore;
+ Qt3DSDMAnimationHandle m_Animation;
+ TTransactionConsumerPtr m_Consumer;
+ bool m_ArtistEdited;
+ SArtistEditedUndoRedoScope(TSimpleAnimationCorePtr inAnimCore, Qt3DSDMAnimationHandle inAnim,
+ TTransactionConsumerPtr inConsumer)
+ : m_AnimationCore(inAnimCore)
+ , m_Animation(inAnim)
+ , m_Consumer(inConsumer)
+ , m_ArtistEdited(inAnimCore->IsArtistEdited(inAnim))
+ {
+ }
+ ~SArtistEditedUndoRedoScope()
+ {
+ bool edited = m_AnimationCore->IsArtistEdited(m_Animation);
+ if (m_Consumer && edited != m_ArtistEdited) {
+ m_Consumer->OnTransaction(TTransactionPtr(CREATE_GENERIC_TRANSACTION(
+ std::bind(&CSimpleAnimationCore::SetIsArtistEdited, m_AnimationCore, m_Animation,
+ edited),
+ std::bind(&CSimpleAnimationCore::SetIsArtistEdited, m_AnimationCore, m_Animation,
+ m_ArtistEdited))));
+ }
+ }
+};
+
+struct SLookupCacheDoUndoOp : public ITransaction
+{
+ std::shared_ptr<SAnimationTrack> m_Animation;
+ TSimpleAnimationCorePtr m_AnimationCore;
+ bool m_AddOnDo;
+ SLookupCacheDoUndoOp(const char *inFile, int inLine, Qt3DSDMAnimationHandle inAnimHandle,
+ TSimpleAnimationCorePtr inCore, bool addOnDo)
+ : ITransaction(inFile, inLine)
+ , m_AnimationCore(inCore)
+ , m_AddOnDo(addOnDo)
+ {
+ THandleObjectMap::const_iterator theIter(inCore->m_Objects.find(inAnimHandle));
+ if (theIter != inCore->m_Objects.end())
+ m_Animation = static_pointer_cast<SAnimationTrack>(theIter->second);
+ }
+ void Remove()
+ {
+ if (m_Animation)
+ m_AnimationCore->RemoveAnimationFromLookupCache(m_Animation);
+ }
+ void Add()
+ {
+ if (m_Animation)
+ m_AnimationCore->AddAnimationToLookupCache(m_Animation);
+ }
+ void Do() override
+ {
+ if (m_AddOnDo)
+ Add();
+ else
+ Remove();
+ }
+ void Undo() override
+ {
+ if (m_AddOnDo)
+ Remove();
+ else
+ Add();
+ }
+};
+
+Qt3DSDMAnimationHandle
+CAnimationCoreProducer::CreateAnimation(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex,
+ EAnimationType inAnimationType, bool inFirstKeyframeDynamic)
+{
+ Qt3DSDMAnimationHandle retval = m_Data->CreateAnimation(inSlide, inInstance, inProperty, inIndex,
+ inAnimationType, inFirstKeyframeDynamic);
+
+ CREATE_HANDLE_CREATE_TRANSACTION(m_Consumer, retval, m_Data->m_Objects);
+ if (m_Consumer)
+ m_Consumer->OnTransaction(
+ std::make_shared<SLookupCacheDoUndoOp>(__FILE__, __LINE__, retval, m_Data, true));
+ GetSignalSender()->SendAnimationCreated(retval, inSlide, inInstance, inProperty, inIndex,
+ inAnimationType);
+ return retval;
+}
+
+void CAnimationCoreProducer::DeleteAnimation(Qt3DSDMAnimationHandle inAnimation)
+{
+ // Ensure animation exists
+ SAnimationTrack *theAnimation =
+ CSimpleAnimationCore::GetAnimationNF(inAnimation, m_Data->m_Objects);
+ GetSignalSender()->SendBeforeAnimationDeleted(inAnimation);
+ if (m_Consumer)
+ m_Consumer->OnTransaction(std::make_shared<SLookupCacheDoUndoOp>(
+ __FILE__, __LINE__, inAnimation, m_Data, false));
+ CREATE_HANDLE_DELETE_TRANSACTION(m_Consumer, inAnimation, m_Data->m_Objects);
+ do_all(theAnimation->m_Keyframes,
+ std::bind(DoCreateHandleDeleteTransaction, __FILE__, __LINE__, m_Consumer,
+ std::placeholders::_1, std::ref(m_Data->m_Objects)));
+ SAnimationInfo theInfo = m_Data->GetAnimationInfo(inAnimation);
+ m_Data->DeleteAnimation(inAnimation);
+ GetSignalSender()->SendAnimationDeleted(inAnimation, theInfo.m_Slide, theInfo.m_Instance,
+ theInfo.m_Property, theInfo.m_Index,
+ theInfo.m_AnimationType);
+}
+
+Qt3DSDMAnimationHandle CAnimationCoreProducer::GetAnimation(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ size_t inIndex) const
+{
+ return m_Data->GetAnimation(inSlide, inInstance, inProperty, inIndex);
+}
+
+SAnimationInfo CAnimationCoreProducer::GetAnimationInfo(Qt3DSDMAnimationHandle inAnimation) const
+{
+ return m_Data->GetAnimationInfo(inAnimation);
+}
+
+void CAnimationCoreProducer::GetAnimations(TAnimationHandleList &outAnimations) const
+{
+ return m_Data->GetAnimations(outAnimations);
+}
+
+void CAnimationCoreProducer::GetAnimations(TAnimationInfoList &outAnimations,
+ Qt3DSDMSlideHandle inMaster,
+ Qt3DSDMSlideHandle inSlide) const
+{
+ return m_Data->GetAnimations(outAnimations, inMaster, inSlide);
+}
+
+void CAnimationCoreProducer::SetFirstKeyframeDynamic(Qt3DSDMAnimationHandle inAnimation,
+ bool inValue)
+{
+ SAnimationInfo theInfo(m_Data->GetAnimationInfo(inAnimation));
+ SArtistEditedUndoRedoScope __editedScope(m_Data, inAnimation, m_Consumer);
+ if (m_Consumer) {
+ m_Consumer->OnTransaction(TTransactionPtr(CREATE_GENERIC_TRANSACTION(
+ std::bind(&CSimpleAnimationCore::SetFirstKeyframeDynamic, m_Data, inAnimation,
+ inValue),
+ std::bind(&CSimpleAnimationCore::SetFirstKeyframeDynamic, m_Data, inAnimation,
+ theInfo.m_DynamicFirstKeyframe))));
+ }
+ m_Data->SetFirstKeyframeDynamic(inAnimation, inValue);
+ GetSignalSender()->SendFirstKeyframeDynamicSet(inAnimation, inValue);
+}
+
+inline void DirtyKeyframes(Qt3DSDMAnimationHandle inAnimation, THandleObjectMap &inObjects)
+{
+ SAnimationTrack *theAnimation = CSimpleAnimationCore::GetAnimationNF(inAnimation, inObjects);
+ theAnimation->m_KeyframesDirty = true;
+}
+
+inline void CreateDirtyKeyframesTransaction(TTransactionConsumerPtr inConsumer,
+ Qt3DSDMAnimationHandle inAnimation,
+ THandleObjectMap &inObjects)
+{
+ if (inConsumer) {
+ inConsumer->OnTransaction(TTransactionPtr(CREATE_GENERIC_TRANSACTION(
+ std::bind(DirtyKeyframes, inAnimation, std::ref(inObjects)),
+ std::bind(DirtyKeyframes, inAnimation, std::ref(inObjects)))));
+ }
+}
+
+Qt3DSDMKeyframeHandle CAnimationCoreProducer::InsertKeyframe(Qt3DSDMAnimationHandle inAnimation,
+ const TKeyframe &inKeyframe)
+{
+ SArtistEditedUndoRedoScope __editedScope(m_Data, inAnimation, m_Consumer);
+ Qt3DSDMKeyframeHandle retval = m_Data->InsertKeyframe(inAnimation, inKeyframe);
+ SAnimationTrack *theAnimation =
+ CSimpleAnimationCore::GetAnimationNF(inAnimation, m_Data->m_Objects);
+ CreateVecInsertTransaction<Qt3DSDMKeyframeHandle>(__FILE__, __LINE__, m_Consumer, retval,
+ theAnimation->m_Keyframes);
+ CREATE_HANDLE_CREATE_TRANSACTION(m_Consumer, retval, m_Data->m_Objects);
+ CreateDirtyKeyframesTransaction(m_Consumer, inAnimation, m_Data->m_Objects);
+ GetSignalSender()->SendKeyframeInserted(inAnimation, retval, inKeyframe);
+ return retval;
+}
+
+void CAnimationCoreProducer::EraseKeyframe(Qt3DSDMKeyframeHandle inKeyframe)
+{
+ SKeyframe *theKeyframe = CSimpleAnimationCore::GetKeyframeNF(inKeyframe, m_Data->m_Objects);
+ SArtistEditedUndoRedoScope __editedScope(m_Data, theKeyframe->m_Animation, m_Consumer);
+ GetSignalSender()->SendBeforeKeyframeErased(inKeyframe);
+ SAnimationTrack *theAnimation =
+ CSimpleAnimationCore::GetAnimationNF(theKeyframe->m_Animation, m_Data->m_Objects);
+ if (exists(theAnimation->m_Keyframes, std::bind(equal_to<int>(), inKeyframe,
+ std::placeholders::_1))) {
+ CreateVecEraseTransaction<Qt3DSDMKeyframeHandle>(__FILE__, __LINE__, m_Consumer, inKeyframe,
+ theAnimation->m_Keyframes);
+ CREATE_HANDLE_DELETE_TRANSACTION(m_Consumer, inKeyframe, m_Data->m_Objects);
+ CreateDirtyKeyframesTransaction(m_Consumer, theKeyframe->m_Animation, m_Data->m_Objects);
+ }
+ int theKeyframeHandle = theKeyframe->m_Handle;
+ TKeyframe theData = theKeyframe->m_Keyframe;
+ m_Data->EraseKeyframe(inKeyframe);
+ GetSignalSender()->SendKeyframeErased(theAnimation->m_Handle, theKeyframeHandle, theData);
+}
+
+template <typename TDataType>
+struct VectorSwapTransaction : public ITransaction
+{
+ vector<TDataType> m_Data;
+ vector<TDataType> &m_Target;
+ VectorSwapTransaction(const char *inFile, int inLine, vector<TDataType> &inTarget)
+ : ITransaction(inFile, inLine)
+ , m_Data(inTarget)
+ , m_Target(inTarget)
+ {
+ }
+ void Do() override { std::swap(m_Data, m_Target); }
+ void Undo() override { Do(); }
+};
+
+void CAnimationCoreProducer::DeleteAllKeyframes(Qt3DSDMAnimationHandle inAnimation)
+{
+ // Ensure animation exists
+ SAnimationTrack *theAnimation =
+ CSimpleAnimationCore::GetAnimationNF(inAnimation, m_Data->m_Objects);
+ SArtistEditedUndoRedoScope __editedScope(m_Data, inAnimation, m_Consumer);
+ GetSignalSender()->SendBeforeAllKeyframesErased(inAnimation);
+ do_all(theAnimation->m_Keyframes,
+ std::bind(DoCreateHandleDeleteTransaction, __FILE__, __LINE__, m_Consumer,
+ std::placeholders::_1, std::ref(m_Data->m_Objects)));
+ if (m_Consumer)
+ m_Consumer->OnTransaction(std::make_shared<VectorSwapTransaction<Qt3DSDMKeyframeHandle>>(
+ __FILE__, __LINE__, std::ref(theAnimation->m_Keyframes)));
+ theAnimation->m_Keyframes.clear();
+}
+
+Qt3DSDMAnimationHandle
+CAnimationCoreProducer::GetAnimationForKeyframe(Qt3DSDMKeyframeHandle inKeyframe) const
+{
+ return m_Data->GetAnimationForKeyframe(inKeyframe);
+}
+
+struct KeyframeDataTransaction : public ITransaction, public IMergeableTransaction<TKeyframe>
+{
+ TSimpleAnimationCorePtr m_AnimationCore;
+ Qt3DSDMKeyframeHandle m_Keyframe;
+ TKeyframe m_OldData;
+ TKeyframe m_NewData;
+
+ KeyframeDataTransaction(const char *inFile, int inLine, TSimpleAnimationCorePtr animCore,
+ Qt3DSDMKeyframeHandle keyframe, TKeyframe oldData, TKeyframe newData)
+ : ITransaction(inFile, inLine)
+ , m_AnimationCore(animCore)
+ , m_Keyframe(keyframe)
+ , m_OldData(oldData)
+ , m_NewData(newData)
+ {
+ }
+
+ void Do() override { m_AnimationCore->DoSetKeyframeData(m_Keyframe, m_NewData); }
+ void Undo() override { m_AnimationCore->DoSetKeyframeData(m_Keyframe, m_OldData); }
+
+ void Update(const TKeyframe &inKeyframe) override { m_NewData = inKeyframe; }
+};
+
+void CAnimationCoreProducer::SetKeyframeData(Qt3DSDMKeyframeHandle inKeyframe,
+ const TKeyframe &inData)
+{
+ SKeyframe *theKeyframe = CSimpleAnimationCore::GetKeyframeNF(inKeyframe, m_Data->m_Objects);
+ SArtistEditedUndoRedoScope __editedScope(m_Data, theKeyframe->m_Animation, m_Consumer);
+ TKeyframe theNewData(inData);
+ TKeyframe theOldData = theKeyframe->m_Keyframe;
+ m_Data->SetKeyframeData(inKeyframe, inData);
+ TKeyframeDataMergeMap::iterator iter(m_KeyframeMergeMap.find(inKeyframe));
+ if (iter != m_KeyframeMergeMap.end())
+ iter->second->Update(theNewData);
+ else {
+ if (m_Consumer) {
+ std::shared_ptr<KeyframeDataTransaction> theKeyframeTransaction(
+ std::make_shared<KeyframeDataTransaction>(__FILE__, __LINE__, m_Data, inKeyframe,
+ theOldData, theNewData));
+ m_Consumer->OnTransaction(static_pointer_cast<ITransaction>(theKeyframeTransaction));
+ m_KeyframeMergeMap.insert(make_pair(
+ inKeyframe,
+ static_pointer_cast<IMergeableTransaction<TKeyframe>>(theKeyframeTransaction)));
+ }
+ GetSignalSender()->SendKeyframeUpdated(inKeyframe, inData);
+ }
+}
+
+TKeyframe CAnimationCoreProducer::GetKeyframeData(Qt3DSDMKeyframeHandle inKeyframe) const
+{
+ return m_Data->GetKeyframeData(inKeyframe);
+}
+
+void CAnimationCoreProducer::GetKeyframes(Qt3DSDMAnimationHandle inAnimation,
+ TKeyframeHandleList &outKeyframes) const
+{
+ return m_Data->GetKeyframes(inAnimation, outKeyframes);
+}
+
+size_t CAnimationCoreProducer::GetKeyframeCount(Qt3DSDMAnimationHandle inAnimation) const
+{
+ return m_Data->GetKeyframeCount(inAnimation);
+}
+
+void CAnimationCoreProducer::OffsetAnimations(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ long inMillisecondOffset)
+{
+ float theOffsetSeconds = static_cast<float>(inMillisecondOffset) / 1000.f;
+ for (THandleObjectMap::const_iterator iter = m_Data->m_Objects.begin(),
+ end = m_Data->m_Objects.end();
+ iter != end; ++iter) {
+ SAnimationTrack *theTrack = static_cast<SAnimationTrack *>(iter->second.get());
+ if (theTrack->m_Slide == inSlide && theTrack->m_Instance == inInstance) {
+ for (size_t keyframeIdx = 0, keyframeEnd = theTrack->m_Keyframes.size();
+ keyframeIdx < keyframeEnd; ++keyframeIdx) {
+ Qt3DSDMKeyframeHandle theKeyframeHandle(theTrack->m_Keyframes[keyframeIdx]);
+ TKeyframe theCurrentKeyframe = m_Data->GetKeyframeData(theKeyframeHandle);
+
+ float seconds = qt3dsdm::GetKeyframeSeconds(theCurrentKeyframe);
+
+ theCurrentKeyframe =
+ qt3dsdm::SetKeyframeSeconds(theCurrentKeyframe, seconds + theOffsetSeconds);
+
+ SetKeyframeData(theKeyframeHandle, theCurrentKeyframe);
+ }
+ }
+ }
+}
+
+void CAnimationCoreProducer::SetIsArtistEdited(Qt3DSDMAnimationHandle inAnimation, bool inEdited)
+{
+ SArtistEditedUndoRedoScope __editedScope(m_Data, inAnimation, m_Consumer);
+ m_Data->SetIsArtistEdited(inAnimation, inEdited);
+}
+
+bool CAnimationCoreProducer::IsArtistEdited(Qt3DSDMAnimationHandle inAnimation) const
+{
+ return m_Data->IsArtistEdited(inAnimation);
+}
+// Animation Evaluation.
+float CAnimationCoreProducer::EvaluateAnimation(Qt3DSDMAnimationHandle inAnimation,
+ float inSeconds) const
+{
+ return m_Data->EvaluateAnimation(inAnimation, inSeconds);
+}
+
+bool CAnimationCoreProducer::KeyframeValid(Qt3DSDMKeyframeHandle inKeyframe) const
+{
+ return m_Data->KeyframeValid(inKeyframe);
+}
+
+bool CAnimationCoreProducer::AnimationValid(Qt3DSDMAnimationHandle inAnimation) const
+{
+ return m_Data->AnimationValid(inAnimation);
+}
+
+void CAnimationCoreProducer::CopyAnimations(Qt3DSDMSlideHandle inSourceSlide,
+ Qt3DSDMInstanceHandle inSourceInstance,
+ Qt3DSDMSlideHandle inDestSlide,
+ Qt3DSDMInstanceHandle inDestInstance)
+{
+ std::vector<SAnimationTrack *> theAnimations;
+ for (THandleObjectMap::const_iterator iter = m_Data->m_Objects.begin(),
+ end = m_Data->m_Objects.end();
+ iter != end; ++iter) {
+ SAnimationTrack *theTrack = static_cast<SAnimationTrack *>(iter->second.get());
+ if (theTrack->m_Instance == inSourceInstance && theTrack->m_Slide == inSourceSlide)
+ theAnimations.push_back(theTrack);
+ }
+ for (size_t idx = 0, end = theAnimations.size(); idx < end; ++idx) {
+ const SAnimationTrack &newTrack(*theAnimations[idx]);
+ Qt3DSDMAnimationHandle theNewAnimation(
+ CreateAnimation(inDestSlide, inDestInstance, newTrack.m_Property, newTrack.m_Index,
+ newTrack.m_AnimationType, newTrack.m_FirstKeyframeDynamic));
+ for (size_t keyIdx = 0, keyEnd = newTrack.m_Keyframes.size(); keyIdx < keyEnd; ++keyIdx)
+ InsertKeyframe(theNewAnimation, GetKeyframeData(newTrack.m_Keyframes[keyIdx]));
+ }
+}
+
+// ITransactionProducer implementation
+void CAnimationCoreProducer::SetConsumer(TTransactionConsumerPtr inConsumer)
+{
+ m_Consumer = inConsumer;
+ m_KeyframeMergeMap.clear();
+}
+
+TSignalConnectionPtr CAnimationCoreProducer::ConnectAnimationCreated(
+ const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle, size_t, EAnimationType)> &inCallback)
+{
+ return GetSignalProvider()->ConnectAnimationCreated(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectBeforeAnimationDeleted(
+ const std::function<void(Qt3DSDMAnimationHandle)> &inCallback)
+{
+ return GetSignalProvider()->ConnectBeforeAnimationDeleted(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectAnimationDeleted(
+ const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMSlideHandle, Qt3DSDMInstanceHandle,
+ Qt3DSDMPropertyHandle, size_t, EAnimationType)> &inCallback)
+{
+ return GetSignalProvider()->ConnectAnimationDeleted(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectKeyframeInserted(
+ const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMKeyframeHandle, const TKeyframe &)>
+ &inCallback)
+{
+ return GetSignalProvider()->ConnectKeyframeInserted(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectBeforeKeyframeErased(
+ const std::function<void(Qt3DSDMKeyframeHandle)> &inCallback)
+{
+ return GetSignalProvider()->ConnectBeforeKeyframeErased(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectKeyframeErased(
+ const std::function<void(Qt3DSDMAnimationHandle, Qt3DSDMKeyframeHandle, const TKeyframe &)>
+ &inCallback)
+{
+ return GetSignalProvider()->ConnectKeyframeErased(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectBeforeAllKeyframesErased(
+ const std::function<void(Qt3DSDMAnimationHandle)> &inCallback)
+{
+ return GetSignalProvider()->ConnectBeforeAllKeyframesErased(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectKeyframeUpdated(
+ const std::function<void(Qt3DSDMKeyframeHandle, const TKeyframe &)> &inCallback)
+{
+ return GetSignalProvider()->ConnectKeyframeUpdated(inCallback);
+}
+TSignalConnectionPtr CAnimationCoreProducer::ConnectFirstKeyframeDynamicSet(
+ const std::function<void(Qt3DSDMAnimationHandle, bool)> &inCallback)
+{
+ return GetSignalProvider()->ConnectFirstKeyframeDynamicSet(inCallback);
+}
+
+void CAnimationCoreProducer::InitSignaller()
+{
+ m_Signaller = CreateAnimationCoreSignaller();
+}
+
+IAnimationCoreSignalProvider *CAnimationCoreProducer::GetSignalProvider()
+{
+ return dynamic_cast<IAnimationCoreSignalProvider *>(m_Signaller.get());
+}
+
+IAnimationCoreSignalSender *CAnimationCoreProducer::GetSignalSender()
+{
+ return dynamic_cast<IAnimationCoreSignalSender *>(m_Signaller.get());
+}
+}