diff options
-rw-r--r-- | src/runtime/Qt3DSAnimationSystem.cpp | 28 | ||||
-rw-r--r-- | src/runtime/Qt3DSAnimationSystem.h | 2 | ||||
-rw-r--r-- | src/runtime/Qt3DSElementSystem.cpp | 18 | ||||
-rw-r--r-- | src/runtime/Qt3DSElementSystem.h | 3 |
4 files changed, 51 insertions, 0 deletions
diff --git a/src/runtime/Qt3DSAnimationSystem.cpp b/src/runtime/Qt3DSAnimationSystem.cpp index b4074f8..199b7f2 100644 --- a/src/runtime/Qt3DSAnimationSystem.cpp +++ b/src/runtime/Qt3DSAnimationSystem.cpp @@ -163,6 +163,11 @@ struct SAnimSystem : public IAnimationSystem NVDataRef<QT3DSU8> m_LoadData; QT3DSI32 m_NextTrackId; QT3DSI32 m_RefCount; + // Keep element handle to track mapping so that we can query if an element has animation tracks, + // and can turn them on/off. Combine element and property id:s to a single 64 bit hash + // so we can utilise nvhash_map and allocators without needing to implement multimap, + // or resort to Qt containers. (Single element can have several animation tracks associated.) + nvhash_map<QT3DSI64, SAnimationTrack *> m_ElemPropsToActiveTracks; SAnimSystem(NVFoundationBase &inFoundation) : m_Foundation(inFoundation) @@ -175,6 +180,7 @@ struct SAnimSystem : public IAnimationSystem , m_ActiveSet(inFoundation.getAllocator(), "m_ActiveSet") , m_NextTrackId(1) , m_RefCount(0) + , m_ElemPropsToActiveTracks(inFoundation.getAllocator(), "m_ElemPropsToActiveTracks") { } @@ -223,6 +229,11 @@ struct SAnimSystem : public IAnimationSystem new (theNewTrack) SAnimationTrack(inElement, inserter.first->first, *theIndex, inDynamic); inserter.first->second = theNewTrack; m_LastInsertedTrack = theNewTrack; + + m_ElemPropsToActiveTracks.insert( + eastl::make_pair(static_cast<QT3DSI64>(inElement.m_Handle) << 32 + | static_cast<QT3DSI64>(inPropertyName), + theNewTrack)); ++m_NextTrackId; return inserter.first->first; } @@ -376,6 +387,23 @@ struct SAnimSystem : public IAnimationSystem m_ActiveSet.remove(*theTrack); } } + + QT3DSI32 getActiveTrackForElemProp( + element::SElement *inElement, QT3DSU32 inPropertyHash) override + { + nvhash_map<QT3DSI64, SAnimationTrack *>::iterator iter + = m_ElemPropsToActiveTracks.find(static_cast<QT3DSI64>(inElement->m_Handle) << 32 + | static_cast<QT3DSI64>(inPropertyHash)); + if (iter == m_ElemPropsToActiveTracks.end()) + return 0; + + // Only return track if it is actually active + if (!m_ActiveSet.contains(*iter->second)) + return 0; + + return iter->second->m_Id; + } + //============================================================================== /** * Recomputes control point values for Studio animation based off of new start diff --git a/src/runtime/Qt3DSAnimationSystem.h b/src/runtime/Qt3DSAnimationSystem.h index 24542ad..d8ee501 100644 --- a/src/runtime/Qt3DSAnimationSystem.h +++ b/src/runtime/Qt3DSAnimationSystem.h @@ -59,6 +59,8 @@ namespace runtime { virtual void Update() = 0; virtual void SetActive(QT3DSI32 inTrackId, bool inActive) = 0; virtual void UpdateDynamicKey(QT3DSI32 inTrackId) = 0; + virtual QT3DSI32 getActiveTrackForElemProp(element::SElement *inElement, + QT3DSU32 inPropertyName) = 0; static IAnimationSystem &CreateAnimationSystem(NVFoundationBase &inFoundation); }; diff --git a/src/runtime/Qt3DSElementSystem.cpp b/src/runtime/Qt3DSElementSystem.cpp index f77bac5..81a27b1 100644 --- a/src/runtime/Qt3DSElementSystem.cpp +++ b/src/runtime/Qt3DSElementSystem.cpp @@ -43,6 +43,7 @@ #include "foundation/SerializationTypes.h" #include "foundation/IOStreams.h" #include "foundation/Qt3DSIndexableLinkedList.h" +#include "Qt3DSAnimationSystem.h" using namespace qt3ds::runtime::element; using namespace qt3ds; @@ -651,12 +652,29 @@ void SElement::SetAttribute(const Q3DStudio::TAttributeHash inKey, SetAttribute(*existing, inValue); } +void SElement::stopAnimations(QT3DSU32 propHash) +{ + QT3DSI32 animTrack = m_BelongedPresentation->GetAnimationSystem().getActiveTrackForElemProp( + this, propHash); + + if (animTrack != 0) { + qWarning() << "Property animation in element" << m_Name.c_str() + << "stopped due to datainput or setAttribute targeting the same property"; + + m_BelongedPresentation->GetAnimationSystem().SetActive(animTrack, false); + } +} void SElement::SetAttribute(TPropertyDescAndValuePtr inKey, const Q3DStudio::UVariant inValue, bool forceSet) { Q3DStudio::EAttributeType theType = inKey.first.m_Type; Q3DStudio::UVariant *currentValue = inKey.second; QT3DSU32 attHash = inKey.first.GetNameHash(); + + // If there is an active animation for this property, disable it. Otherwise the set value + // gets overwritten immediately as animation update takes place. + // Do this even if the value gets rejected in the code below. + stopAnimations(attHash); if (!forceSet) { switch (theType) { case Q3DStudio::ATTRIBUTETYPE_FLOAT: // Early return diff --git a/src/runtime/Qt3DSElementSystem.h b/src/runtime/Qt3DSElementSystem.h index 6e61a02..15895c0 100644 --- a/src/runtime/Qt3DSElementSystem.h +++ b/src/runtime/Qt3DSElementSystem.h @@ -519,6 +519,9 @@ namespace runtime { child = child->m_Sibling; } } + + // Sets animation on property to inactive. + void stopAnimations(QT3DSU32 propHash); }; struct SGetElementNodeDirtyIndex |