diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2017-01-25 19:25:15 +0000 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2017-01-27 18:32:25 +0000 |
commit | 744c51c33e4da37bb70528f5398e56e5faf5c504 (patch) | |
tree | fb38379202c9a520fdcebd44a749bfdd467c0bb2 | |
parent | 78a032e2328dddf0f60c0fe3063047888b92cc2a (diff) |
Calculate animation clip duration and send to frontend
Change-Id: Iaafb8b385658be446098d982702955810f76d7c6
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
-rw-r--r-- | src/animation/backend/animationclip.cpp | 39 | ||||
-rw-r--r-- | src/animation/backend/animationclip_p.h | 4 | ||||
-rw-r--r-- | src/animation/frontend/qanimationclip.cpp | 30 | ||||
-rw-r--r-- | src/animation/frontend/qanimationclip.h | 4 | ||||
-rw-r--r-- | src/animation/frontend/qanimationclip_p.h | 5 | ||||
-rw-r--r-- | tests/auto/animation/animationclip/tst_animationclip.cpp | 34 | ||||
-rw-r--r-- | tests/auto/animation/qanimationclip/tst_qanimationclip.cpp | 1 | ||||
-rw-r--r-- | tests/manual/animation-keyframe-simple/main.qml | 2 |
8 files changed, 118 insertions, 1 deletions
diff --git a/src/animation/backend/animationclip.cpp b/src/animation/backend/animationclip.cpp index c7d262507..ae34fa64c 100644 --- a/src/animation/backend/animationclip.cpp +++ b/src/animation/backend/animationclip.cpp @@ -40,6 +40,7 @@ #include <Qt3DAnimation/private/animationlogging_p.h> #include <Qt3DRender/private/qurlhelper_p.h> #include <Qt3DCore/qpropertyupdatedchange.h> +#include <Qt3DCore/private/qpropertyupdatedchangebase_p.h> #include <QtCore/qbytearray.h> #include <QtCore/qfile.h> @@ -53,11 +54,12 @@ namespace Qt3DAnimation { namespace Animation { AnimationClip::AnimationClip() - : BackendNode(ReadOnly) + : BackendNode(ReadWrite) , m_source() , m_name() , m_objectName() , m_channelGroups() + , m_duration(0.0f) { } @@ -75,6 +77,8 @@ void AnimationClip::cleanup() setEnabled(false); m_handler = nullptr; m_source.clear(); + m_channelGroups.clear(); + m_duration = 0.0f; clearData(); } @@ -139,9 +143,28 @@ void AnimationClip::loadAnimation() m_channelGroups[i].read(group); } + const float t = findDuration(); + setDuration(t); + qCDebug(Jobs) << "Loaded animation data:" << *this; } +void AnimationClip::setDuration(float duration) +{ + if (qFuzzyCompare(duration, m_duration)) + return; + + m_duration = duration; + + // Send a change to the frontend + auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId()); + e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll); + Qt3DCore::QPropertyUpdatedChangeBasePrivate::get(e.data())->m_isFinal = true; + e->setPropertyName("duration"); + e->setValue(m_duration); + notifyObservers(e); +} + void AnimationClip::clearData() { m_name.clear(); @@ -149,6 +172,20 @@ void AnimationClip::clearData() m_channelGroups.clear(); } +float AnimationClip::findDuration() +{ + // Iterate over the contained fcurves and find the longest one + double tMax = 0.0; + for (const auto channelGroup : qAsConst(m_channelGroups)) { + for (const auto channel : qAsConst(channelGroup.channels)) { + const float t = channel.fcurve.endTime(); + if (t > tMax) + tMax = t; + } + } + return tMax; +} + } // namespace Animation } // namespace Qt3DAnimation diff --git a/src/animation/backend/animationclip_p.h b/src/animation/backend/animationclip_p.h index 6170c3423..ddfe7e875 100644 --- a/src/animation/backend/animationclip_p.h +++ b/src/animation/backend/animationclip_p.h @@ -75,16 +75,20 @@ public: // Called from jobs void loadAnimation(); + void setDuration(float duration); + float duration() const { return m_duration; } private: void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_FINAL; void clearData(); + float findDuration(); QUrl m_source; QString m_name; QString m_objectName; QVector<ChannelGroup> m_channelGroups; + float m_duration; }; #ifndef QT_NO_DEBUG_STREAM diff --git a/src/animation/frontend/qanimationclip.cpp b/src/animation/frontend/qanimationclip.cpp index 527f1cc30..56fe3978c 100644 --- a/src/animation/frontend/qanimationclip.cpp +++ b/src/animation/frontend/qanimationclip.cpp @@ -36,6 +36,7 @@ #include "qanimationclip.h" #include "qanimationclip_p.h" +#include <Qt3DCore/qpropertyupdatedchange.h> QT_BEGIN_NAMESPACE @@ -43,9 +44,22 @@ namespace Qt3DAnimation { QAnimationClipPrivate::QAnimationClipPrivate() : Qt3DCore::QNodePrivate() + , m_duration(0.0f) { } +void QAnimationClipPrivate::setDuration(float duration) +{ + if (qFuzzyCompare(duration, m_duration)) + return; + + Q_Q(QAnimationClip); + bool wasBlocked = q->blockNotifications(true); + m_duration = duration; + emit q->durationChanged(duration); + q->blockNotifications(wasBlocked); +} + QAnimationClip::QAnimationClip(Qt3DCore::QNode *parent) : Qt3DCore::QNode(*new QAnimationClipPrivate, parent) { @@ -66,6 +80,12 @@ QUrl QAnimationClip::source() const return d->m_source; } +float QAnimationClip::duration() const +{ + Q_D(const QAnimationClip); + return d->m_duration; +} + void QAnimationClip::setSource(QUrl source) { Q_D(QAnimationClip); @@ -76,6 +96,16 @@ void QAnimationClip::setSource(QUrl source) emit sourceChanged(source); } +void QAnimationClip::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) +{ + Q_D(QAnimationClip); + if (change->type() == Qt3DCore::PropertyUpdated) { + Qt3DCore::QPropertyUpdatedChangePtr e = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(change); + if (e->propertyName() == QByteArrayLiteral("duration")) + d->setDuration(e->value().toFloat()); + } +} + Qt3DCore::QNodeCreatedChangeBasePtr QAnimationClip::createNodeCreationChange() const { auto creationChange = Qt3DCore::QNodeCreatedChangePtr<QAnimationClipData>::create(this); diff --git a/src/animation/frontend/qanimationclip.h b/src/animation/frontend/qanimationclip.h index f5394f8ff..55b1910fa 100644 --- a/src/animation/frontend/qanimationclip.h +++ b/src/animation/frontend/qanimationclip.h @@ -51,21 +51,25 @@ class QT3DANIMATIONSHARED_EXPORT QAnimationClip : public Qt3DCore::QNode { Q_OBJECT Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) + Q_PROPERTY(float duration READ duration NOTIFY durationChanged) public: explicit QAnimationClip(Qt3DCore::QNode *parent = nullptr); ~QAnimationClip(); QUrl source() const; + float duration() const; public Q_SLOTS: void setSource(QUrl source); Q_SIGNALS: void sourceChanged(QUrl source); + void durationChanged(float duration); protected: QAnimationClip(QAnimationClipPrivate &dd, Qt3DCore::QNode *parent = nullptr); + void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) Q_DECL_OVERRIDE; private: Q_DECLARE_PRIVATE(QAnimationClip) diff --git a/src/animation/frontend/qanimationclip_p.h b/src/animation/frontend/qanimationclip_p.h index 87ebf99e1..5e3df0e6e 100644 --- a/src/animation/frontend/qanimationclip_p.h +++ b/src/animation/frontend/qanimationclip_p.h @@ -62,7 +62,12 @@ public: Q_DECLARE_PUBLIC(QAnimationClip) + void setDuration(float duration); + QUrl m_source; + + // Set from the backend + float m_duration; }; struct QAnimationClipData diff --git a/tests/auto/animation/animationclip/tst_animationclip.cpp b/tests/auto/animation/animationclip/tst_animationclip.cpp index cd1d2ccf0..f0b45bfeb 100644 --- a/tests/auto/animation/animationclip/tst_animationclip.cpp +++ b/tests/auto/animation/animationclip/tst_animationclip.cpp @@ -33,6 +33,7 @@ #include <Qt3DCore/private/qscene_p.h> #include <Qt3DCore/qpropertyupdatedchange.h> #include <Qt3DCore/private/qbackendnode_p.h> +#include <Qt3DCore/private/qpropertyupdatedchangebase_p.h> #include <qbackendnodetester.h> #include <testpostmanarbiter.h> @@ -71,6 +72,7 @@ private Q_SLOTS: QVERIFY(backendClip.peerId().isNull()); QCOMPARE(backendClip.isEnabled(), false); QCOMPARE(backendClip.source(), QUrl()); + QCOMPARE(backendClip.duration(), 0.0f); // GIVEN Qt3DAnimation::QAnimationClip clip; @@ -84,6 +86,7 @@ private Q_SLOTS: // THEN QCOMPARE(backendClip.source(), QUrl()); QCOMPARE(backendClip.isEnabled(), false); + QCOMPARE(backendClip.duration(), 0.0f); } void checkPropertyChanges() @@ -113,6 +116,37 @@ private Q_SLOTS: // THEN QCOMPARE(backendClip.source(), newSource); } + + void checkDurationPropertyBackendNotification() + { + // GIVEN + TestArbiter arbiter; + Qt3DAnimation::Animation::AnimationClip backendClip; + backendClip.setEnabled(true); + Qt3DCore::QBackendNodePrivate::get(&backendClip)->setArbiter(&arbiter); + + // WHEN + backendClip.setDuration(64.0f); + + // THEN + QCOMPARE(backendClip.duration(), 64.0f); + QCOMPARE(arbiter.events.count(), 1); + Qt3DCore::QPropertyUpdatedChangePtr change = arbiter.events.first().staticCast<Qt3DCore::QPropertyUpdatedChange>(); + QCOMPARE(change->propertyName(), "duration"); + QCOMPARE(change->value().toFloat(), backendClip.duration()); + QCOMPARE(Qt3DCore::QPropertyUpdatedChangeBasePrivate::get(change.data())->m_isFinal, true); + + arbiter.events.clear(); + + // WHEN + backendClip.setDuration(64.0f); + + // THEN + QCOMPARE(backendClip.duration(), 64.0f); + QCOMPARE(arbiter.events.count(), 0); + + arbiter.events.clear(); + } }; QTEST_APPLESS_MAIN(tst_AnimationClip) diff --git a/tests/auto/animation/qanimationclip/tst_qanimationclip.cpp b/tests/auto/animation/qanimationclip/tst_qanimationclip.cpp index 09f41ae99..8c83f6530 100644 --- a/tests/auto/animation/qanimationclip/tst_qanimationclip.cpp +++ b/tests/auto/animation/qanimationclip/tst_qanimationclip.cpp @@ -49,6 +49,7 @@ private Q_SLOTS: // THEN QCOMPARE(clip.source(), QUrl()); + QCOMPARE(clip.duration(), 0.0f); } void checkPropertyChanges() diff --git a/tests/manual/animation-keyframe-simple/main.qml b/tests/manual/animation-keyframe-simple/main.qml index 587f851c5..e53772434 100644 --- a/tests/manual/animation-keyframe-simple/main.qml +++ b/tests/manual/animation-keyframe-simple/main.qml @@ -35,6 +35,8 @@ DefaultSceneEntity { running: true clip: AnimationClip { source: "cubeanimation.json" + + onDurationChanged: console.log("duration = " + duration) } // By default introspect parent Entity and try |