summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAntti Määttä <antti.maatta@qt.io>2019-11-14 09:13:39 +0200
committerAntti Määttä <antti.maatta@qt.io>2019-11-20 16:09:00 +0200
commitc4d0de4f1c2d20a10abfb6f385ba1efa3b0f9a1e (patch)
tree86a372a85befa8530127b458646d9a20ff39fdfd /src
parenta0570efd0bb4f424d763818b5dfca1cffadc6c5c (diff)
Allow setting timeline value when element is about to activate
Task-number: QT3DS-4001 Change-Id: I9fbb1367999d2a3e3bea6520f9e59a820ef50c28 Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io> Reviewed-by: Jere Tuliniemi <jere.tuliniemi@qt.io> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/api/studio3d/q3dsdatainput_p.h2
-rw-r--r--src/api/studio3d/q3dspresentation.cpp22
-rw-r--r--src/api/studio3d/q3dspresentation_p.h3
-rw-r--r--src/runtime/Qt3DSComponentManager.cpp2
-rw-r--r--src/runtime/Qt3DSElementSystem.h8
-rw-r--r--src/runtime/Qt3DSQmlEngine.cpp2
6 files changed, 33 insertions, 6 deletions
diff --git a/src/api/studio3d/q3dsdatainput_p.h b/src/api/studio3d/q3dsdatainput_p.h
index 546e06a..1bba66a 100644
--- a/src/api/studio3d/q3dsdatainput_p.h
+++ b/src/api/studio3d/q3dsdatainput_p.h
@@ -75,6 +75,8 @@ protected:
QVariant m_value;
float m_max = 0;
float m_min = 0;
+ // Used to order API calls
+ int m_callIdx = 0;
bool m_dirty = false;
bool m_forced = false;
diff --git a/src/api/studio3d/q3dspresentation.cpp b/src/api/studio3d/q3dspresentation.cpp
index 05e2e8e..50a9d6c 100644
--- a/src/api/studio3d/q3dspresentation.cpp
+++ b/src/api/studio3d/q3dspresentation.cpp
@@ -1066,7 +1066,7 @@ void Q3DSPresentation::setDataInputValue(const QString &name, const QVariant &va
if (!di->d_ptr->m_forced)
di->d_ptr->m_forced = force;
- d_ptr->setDataInputDirty(name, true);
+ d_ptr->setDataInputDirty(name, true, d_ptr->m_dataInputCallIndex++);
// We batch datainput changes within a frame, so just tell the presentation that one
// or more datainputs have changed value.
d_ptr->m_dataInputsChanged = true;
@@ -1853,10 +1853,12 @@ void Q3DSPresentationPrivate::setDataInputsChanged(bool changed)
m_dataInputsChanged = changed;
}
-void Q3DSPresentationPrivate::setDataInputDirty(const QString &name, bool dirty)
+void Q3DSPresentationPrivate::setDataInputDirty(const QString &name, bool dirty, int callIdx)
{
- if (m_dataInputs.contains(name))
+ if (m_dataInputs.contains(name)) {
m_dataInputs[name]->d_ptr->setDirty(dirty);
+ m_dataInputs[name]->d_ptr->m_callIdx = callIdx;
+ }
}
void Q3DSPresentationPrivate::setShaderCacheFile(const QUrl &fileName)
@@ -2235,10 +2237,12 @@ bool Q3DSPresentationPrivate::dataInputsChanged() const
void Q3DSPresentationPrivate::setDataInputValueBatch()
{
QVector<QPair<QString, QVariant>> *theProperties = new QVector<QPair<QString, QVariant>>();
+ QVector<int> order;
for (const auto &di : qAsConst(m_dataInputs)) {
if (di->d_ptr->m_dirty) {
if (di->value() != di->d_ptr->m_committedValue || di->d_ptr->m_forced) {
theProperties->append({di->name(), di->value()});
+ order.append(di->d_ptr->m_callIdx);
di->d_ptr->m_dirty = false;
di->d_ptr->m_forced = false; // Reset also forced flag as it is per-frame.
di->d_ptr->setCommittedValue(di->value()); // Make note of value that was actually
@@ -2247,6 +2251,18 @@ void Q3DSPresentationPrivate::setDataInputValueBatch()
}
}
+ // Sort
+ for (int i = 0; i < order.size() - 1; ++i) {
+ for (int j = i + 1; j < order.size(); ++j) {
+ if (order[i] > order[j]) {
+ std::swap((*theProperties)[i], (*theProperties)[j]);
+ std::swap(order[i], order[j]);
+ }
+ }
+ }
+
+ m_dataInputCallIndex = 0;
+
if (!theProperties->empty()) {
if (m_commandQueue) { // QML context
m_commandQueue->queueCommand({}, CommandType_SetDataInputBatch, {}, theProperties);
diff --git a/src/api/studio3d/q3dspresentation_p.h b/src/api/studio3d/q3dspresentation_p.h
index 45231b4..0925dff 100644
--- a/src/api/studio3d/q3dspresentation_p.h
+++ b/src/api/studio3d/q3dspresentation_p.h
@@ -72,7 +72,7 @@ public:
void setCommandQueue(CommandQueue *queue);
void setDelayedLoading(bool enable);
void setDataInputsChanged(bool changed);
- void setDataInputDirty(const QString &name, bool dirty);
+ void setDataInputDirty(const QString &name, bool dirty, int callIdx);
void setShaderCacheFile(const QUrl &fileName);
void registerElement(Q3DSElement *element);
@@ -134,6 +134,7 @@ private:
QByteArray m_shaderCacheExport;
QUrl m_shaderCacheWritePending;
bool m_shaderCacheDumpPending = false;
+ int m_dataInputCallIndex = 0;
friend class Q3DSStudio3D;
};
diff --git a/src/runtime/Qt3DSComponentManager.cpp b/src/runtime/Qt3DSComponentManager.cpp
index 8f33ec8..8849b5b 100644
--- a/src/runtime/Qt3DSComponentManager.cpp
+++ b/src/runtime/Qt3DSComponentManager.cpp
@@ -366,7 +366,7 @@ void CComponentManager::GoToTime(TElement *inComponent, const TTimeUnit inTime)
{
if (inComponent == NULL)
return;
- if (inComponent->GetActive() == false) {
+ if (!inComponent->GetActive() && !inComponent->AboutToActivate()) {
qCCritical(qt3ds::INVALID_OPERATION)
<< "Runtime: Attempt to goto time on inactive component!";
return;
diff --git a/src/runtime/Qt3DSElementSystem.h b/src/runtime/Qt3DSElementSystem.h
index 2784420..4eda166 100644
--- a/src/runtime/Qt3DSElementSystem.h
+++ b/src/runtime/Qt3DSElementSystem.h
@@ -444,6 +444,14 @@ namespace runtime {
void SetActive(bool inValue) { SetFlag(Q3DStudio::ELEMENTFLAG_GLOBALACTIVE, inValue); }
bool GetActive() const { return m_Flags.IsActive(); }
+ // Return true if we are about to activate, but have not yet been activated
+ bool AboutToActivate() const
+ {
+ if (!IsDirty())
+ return false;
+ return IsExplicitActive();
+ }
+
void SetPickEnabled(bool inValue)
{
SetFlag(Q3DStudio::ELEMENTFLAG_PICKENABLED, inValue);
diff --git a/src/runtime/Qt3DSQmlEngine.cpp b/src/runtime/Qt3DSQmlEngine.cpp
index 994354b..5ab5c10 100644
--- a/src/runtime/Qt3DSQmlEngine.cpp
+++ b/src/runtime/Qt3DSQmlEngine.cpp
@@ -1968,7 +1968,7 @@ bool CQmlEngineImpl::GetSlideInfo(const char *element, int &currentIndex, int &p
void CQmlEngineImpl::GotoTime(const char *component, const Q3DStudio::FLOAT time)
{
TElement *theTarget = getTarget(component);
- if (theTarget && theTarget->GetActive()) {
+ if (theTarget && (theTarget->GetActive() || theTarget->AboutToActivate())) {
UVariant theArg1;
UVariant theArg2;