summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJanne Kangas <janne.kangas@qt.io>2019-07-26 14:49:10 +0300
committerJanne Kangas <janne.kangas@qt.io>2019-08-29 10:55:21 +0300
commit67a5d7ddc604578f69e5add5210f084b9d28addc (patch)
treea1a39c671d317f781bacaf83291b7a330b6d7965
parent9ea345e6372433217915a45b73acb81a81627bde (diff)
Stop animation when property is controlled by datainput
Disable animation for the target property when datainput value is set. This is to prevent running animations from overriding datainput control, which happens by default in runtime engine due to ordering of scene update sequence. Change-Id: I148d7fd80ad01f4ec5ad1d5ba69ecc74865d27fb Task-id: QT3DS-3896 Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
-rw-r--r--src/runtime/Qt3DSAnimationSystem.cpp28
-rw-r--r--src/runtime/Qt3DSAnimationSystem.h2
-rw-r--r--src/runtime/Qt3DSElementSystem.cpp18
-rw-r--r--src/runtime/Qt3DSElementSystem.h3
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