diff options
-rw-r--r-- | src/animation/backend/additiveclipblend.cpp | 13 | ||||
-rw-r--r-- | src/animation/backend/additiveclipblend_p.h | 3 | ||||
-rw-r--r-- | src/animation/backend/clipblendnode.cpp | 28 | ||||
-rw-r--r-- | src/animation/backend/clipblendnode_p.h | 6 | ||||
-rw-r--r-- | src/animation/backend/clipblendvalue.cpp | 8 | ||||
-rw-r--r-- | src/animation/backend/clipblendvalue_p.h | 3 | ||||
-rw-r--r-- | src/animation/backend/lerpclipblend.cpp | 13 | ||||
-rw-r--r-- | src/animation/backend/lerpclipblend_p.h | 3 | ||||
-rw-r--r-- | tests/auto/animation/additiveclipblend/tst_additiveclipblend.cpp | 194 | ||||
-rw-r--r-- | tests/auto/animation/clipblendnode/tst_clipblendnode.cpp | 53 | ||||
-rw-r--r-- | tests/auto/animation/clipblendnodemanager/tst_clipblendnodemanager.cpp | 6 | ||||
-rw-r--r-- | tests/auto/animation/lerpclipblend/tst_lerpclipblend.cpp | 194 |
12 files changed, 523 insertions, 1 deletions
diff --git a/src/animation/backend/additiveclipblend.cpp b/src/animation/backend/additiveclipblend.cpp index 4100c8b53..a6342dd23 100644 --- a/src/animation/backend/additiveclipblend.cpp +++ b/src/animation/backend/additiveclipblend.cpp @@ -76,6 +76,19 @@ float AdditiveClipBlend::blend(float value1, float value2) const return value1 + (m_additiveFactor * value2); } +ClipResults AdditiveClipBlend::doBlend(const QVector<ClipResults> &blendData) const +{ + Q_ASSERT(blendData.size() == 2); + Q_ASSERT(blendData[0].size() == blendData[1].size()); + const int elementCount = blendData.first().size(); + ClipResults blendResults(elementCount); + + for (int i = 0; i < elementCount; ++i) + blendResults[i] = blendData[0][i] + m_additiveFactor * blendData[1][i]; + + return blendResults; +} + void AdditiveClipBlend::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) { ClipBlendNode::initializeFromPeer(change); diff --git a/src/animation/backend/additiveclipblend_p.h b/src/animation/backend/additiveclipblend_p.h index 8ac53d364..9a9b4aa07 100644 --- a/src/animation/backend/additiveclipblend_p.h +++ b/src/animation/backend/additiveclipblend_p.h @@ -86,6 +86,9 @@ public: return node->duration(); } +protected: + ClipResults doBlend(const QVector<ClipResults> &blendData) const Q_DECL_FINAL; + private: void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_FINAL; diff --git a/src/animation/backend/clipblendnode.cpp b/src/animation/backend/clipblendnode.cpp index 18d57b0c7..f22df7b74 100644 --- a/src/animation/backend/clipblendnode.cpp +++ b/src/animation/backend/clipblendnode.cpp @@ -200,6 +200,34 @@ ClipResults ClipBlendNode::clipResults(Qt3DCore::QNodeId animatorId) const evaluated in one pass, and the tree in a subsequent pass. */ +/*! + \internal + + Fetches the ClipResults from the nodes listed in the dependencyIds + and passes them to the doBlend() virtual function which should be + implemented in subclasses to perform the actual blend operation. + The results are then inserted into the clip results for this blend + node indexed by the \a animatorId. +*/ +void ClipBlendNode::performBlend(Qt3DCore::QNodeId animatorId) +{ + // Obtain the clip results from each of the dependencies + const QVector<Qt3DCore::QNodeId> dependencyNodeIds = dependencyIds(); + const int dependencyCount = dependencyNodeIds.size(); + QVector<ClipResults> blendData; + blendData.reserve(dependencyCount); + for (const auto dependencyId : dependencyNodeIds) { + ClipBlendNode *dependencyNode = clipBlendNodeManager()->lookupNode(dependencyId); + ClipResults blendDataElement = dependencyNode->clipResults(animatorId); + blendData.push_back(blendDataElement); + } + + // Ask the blend node to perform the actual blend operation on the data + // from the dependencies + ClipResults blendedResults = doBlend(blendData); + setClipResults(animatorId, blendedResults); +} + } // Animation } // Qt3DAnimation diff --git a/src/animation/backend/clipblendnode_p.h b/src/animation/backend/clipblendnode_p.h index 4784c81a7..b4eceb2c1 100644 --- a/src/animation/backend/clipblendnode_p.h +++ b/src/animation/backend/clipblendnode_p.h @@ -81,8 +81,12 @@ public: Qt3DCore::QNodeIdVector clipIds() const; void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE; + + // TODO: Remove this old blend() virtual and rename performBlend() to blend() virtual float blend(float value1, float value2) const = 0; + void performBlend(Qt3DCore::QNodeId animatorId); + ClipResults clipResults(Qt3DCore::QNodeId animatorId) const; virtual QVector<Qt3DCore::QNodeId> dependencyIds() const = 0; @@ -94,6 +98,8 @@ protected: void setClipResults(Qt3DCore::QNodeId animatorId, const ClipResults &clipResults); + virtual ClipResults doBlend(const QVector<ClipResults> &blendData) const = 0; + private: void setParentId(Qt3DCore::QNodeId parentId); void addChildId(Qt3DCore::QNodeId childId); diff --git a/src/animation/backend/clipblendvalue.cpp b/src/animation/backend/clipblendvalue.cpp index b8216ec38..a1726a40a 100644 --- a/src/animation/backend/clipblendvalue.cpp +++ b/src/animation/backend/clipblendvalue.cpp @@ -81,6 +81,14 @@ float ClipBlendValue::blend(float value1, float value2) const return 0.0f; } +ClipResults ClipBlendValue::doBlend(const QVector<ClipResults> &blendData) const +{ + // Should never be called for the value node + Q_UNUSED(blendData); + Q_UNREACHABLE(); + return ClipResults(); +} + double ClipBlendValue::duration() const { if (m_clipId.isNull()) diff --git a/src/animation/backend/clipblendvalue_p.h b/src/animation/backend/clipblendvalue_p.h index a50bd8e9a..f06800488 100644 --- a/src/animation/backend/clipblendvalue_p.h +++ b/src/animation/backend/clipblendvalue_p.h @@ -74,6 +74,9 @@ public: double duration() const Q_DECL_OVERRIDE; +protected: + ClipResults doBlend(const QVector<ClipResults> &blendData) const Q_DECL_OVERRIDE; + private: void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_FINAL; diff --git a/src/animation/backend/lerpclipblend.cpp b/src/animation/backend/lerpclipblend.cpp index 7b1efbf50..7e61a35ca 100644 --- a/src/animation/backend/lerpclipblend.cpp +++ b/src/animation/backend/lerpclipblend.cpp @@ -75,6 +75,19 @@ float LerpClipBlend::blend(float value1, float value2) const return ((1.0f - m_blendFactor) * value1) + (m_blendFactor * value2); } +ClipResults LerpClipBlend::doBlend(const QVector<ClipResults> &blendData) const +{ + Q_ASSERT(blendData.size() == 2); + Q_ASSERT(blendData[0].size() == blendData[1].size()); + const int elementCount = blendData.first().size(); + ClipResults blendResults(elementCount); + + for (int i = 0; i < elementCount; ++i) + blendResults[i] = (1.0f - m_blendFactor) * blendData[0][i] + (m_blendFactor * blendData[1][i]); + + return blendResults; +} + void LerpClipBlend::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) { ClipBlendNode::initializeFromPeer(change); diff --git a/src/animation/backend/lerpclipblend_p.h b/src/animation/backend/lerpclipblend_p.h index 36b2c17e3..57baf71ed 100644 --- a/src/animation/backend/lerpclipblend_p.h +++ b/src/animation/backend/lerpclipblend_p.h @@ -81,6 +81,9 @@ public: double duration() const Q_DECL_OVERRIDE; +protected: + ClipResults doBlend(const QVector<ClipResults> &blendData) const Q_DECL_FINAL; + private: void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_FINAL; diff --git a/tests/auto/animation/additiveclipblend/tst_additiveclipblend.cpp b/tests/auto/animation/additiveclipblend/tst_additiveclipblend.cpp index 7ec327cdc..5e25cccb9 100644 --- a/tests/auto/animation/additiveclipblend/tst_additiveclipblend.cpp +++ b/tests/auto/animation/additiveclipblend/tst_additiveclipblend.cpp @@ -37,6 +37,9 @@ using namespace Qt3DAnimation::Animation; +Q_DECLARE_METATYPE(Handler *) +Q_DECLARE_METATYPE(AdditiveClipBlend *) + namespace { class TestClipBlendNode : public ClipBlendNode @@ -58,6 +61,10 @@ public: double duration() const Q_DECL_FINAL { return m_duration; } +protected: + ClipResults doBlend(const QVector<ClipResults> &) const Q_DECL_FINAL { return ClipResults(); } + +private: double m_duration; }; @@ -73,10 +80,36 @@ public: auto id = Qt3DCore::QNodeId::createId(); TestClipBlendNode *node = new TestClipBlendNode(duration); setPeerId(node, id); + node->setHandler(handler); + node->setClipBlendNodeManager(handler->clipBlendNodeManager()); handler->clipBlendNodeManager()->appendNode(id, node); return node; } + AdditiveClipBlend *createAdditiveClipBlendNode(Handler *handler, const float &blendFactor) + { + auto id = Qt3DCore::QNodeId::createId(); + AdditiveClipBlend *node = new AdditiveClipBlend(); + node->setAdditiveFactor(blendFactor); + setPeerId(node, id); + node->setHandler(handler); + node->setClipBlendNodeManager(handler->clipBlendNodeManager()); + handler->clipBlendNodeManager()->appendNode(id, node); + return node; + } + + BlendedClipAnimator *createBlendedClipAnimator(Handler *handler, + qint64 globalStartTimeNS, + int loops) + { + auto animatorId = Qt3DCore::QNodeId::createId(); + BlendedClipAnimator *animator = handler->blendedClipAnimatorManager()->getOrCreateResource(animatorId); + setPeerId(animator, animatorId); + animator->setStartTime(globalStartTimeNS); + animator->setLoops(loops); + return animator; + } + private Q_SLOTS: void checkInitialState() @@ -261,6 +294,167 @@ private Q_SLOTS: // THEN QCOMPARE(actualDuration, expectedDuration); } + + void checkDoBlend_data() + { + QTest::addColumn<Handler *>("handler"); + QTest::addColumn<AdditiveClipBlend *>("blendNode"); + QTest::addColumn<Qt3DCore::QNodeId>("animatorId"); + QTest::addColumn<ClipResults>("expectedResults"); + + { + auto handler = new Handler(); + + const qint64 globalStartTimeNS = 0; + const int loopCount = 1; + auto animator = createBlendedClipAnimator(handler, globalStartTimeNS, loopCount); + + const double duration = 1.0; + auto baseNode = createTestBlendNode(handler, duration); + baseNode->setClipResults(animator->peerId(), { 0.0f, 0.0f, 0.0f }); + auto additiveNode = createTestBlendNode(handler, duration); + additiveNode->setClipResults(animator->peerId(), { 1.0f, 1.0f, 1.0f }); + + const float additiveFactor = 0.0f; + auto blendNode = createAdditiveClipBlendNode(handler, additiveFactor); + blendNode->setBaseClipId(baseNode->peerId()); + blendNode->setAdditiveClipId(additiveNode->peerId()); + blendNode->setAdditiveFactor(additiveFactor); + + ClipResults expectedResults = { 0.0f, 0.0f, 0.0f }; + + QTest::addRow("unit additive, beta = 0.0") + << handler << blendNode << animator->peerId() << expectedResults; + } + + { + auto handler = new Handler(); + + const qint64 globalStartTimeNS = 0; + const int loopCount = 1; + auto animator = createBlendedClipAnimator(handler, globalStartTimeNS, loopCount); + + const double duration = 1.0; + auto baseNode = createTestBlendNode(handler, duration); + baseNode->setClipResults(animator->peerId(), { 0.0f, 0.0f, 0.0f }); + auto additiveNode = createTestBlendNode(handler, duration); + additiveNode->setClipResults(animator->peerId(), { 1.0f, 1.0f, 1.0f }); + + const float additiveFactor = 0.5f; + auto blendNode = createAdditiveClipBlendNode(handler, additiveFactor); + blendNode->setBaseClipId(baseNode->peerId()); + blendNode->setAdditiveClipId(additiveNode->peerId()); + blendNode->setAdditiveFactor(additiveFactor); + + ClipResults expectedResults = { 0.5f, 0.5f, 0.5f }; + + QTest::addRow("unit additive, beta = 0.5") + << handler << blendNode << animator->peerId() << expectedResults; + } + + { + auto handler = new Handler(); + + const qint64 globalStartTimeNS = 0; + const int loopCount = 1; + auto animator = createBlendedClipAnimator(handler, globalStartTimeNS, loopCount); + + const double duration = 1.0; + auto baseNode = createTestBlendNode(handler, duration); + baseNode->setClipResults(animator->peerId(), { 0.0f, 0.0f, 0.0f }); + auto additiveNode = createTestBlendNode(handler, duration); + additiveNode->setClipResults(animator->peerId(), { 1.0f, 1.0f, 1.0f }); + + const float additiveFactor = 1.0f; + auto blendNode = createAdditiveClipBlendNode(handler, additiveFactor); + blendNode->setBaseClipId(baseNode->peerId()); + blendNode->setAdditiveClipId(additiveNode->peerId()); + blendNode->setAdditiveFactor(additiveFactor); + + ClipResults expectedResults = { 1.0f, 1.0f, 1.0f }; + + QTest::addRow("unit additive, beta = 1.0") + << handler << blendNode << animator->peerId() << expectedResults; + } + + { + auto handler = new Handler(); + + const qint64 globalStartTimeNS = 0; + const int loopCount = 1; + auto animator = createBlendedClipAnimator(handler, globalStartTimeNS, loopCount); + + const double duration = 1.0; + auto baseNode = createTestBlendNode(handler, duration); + baseNode->setClipResults(animator->peerId(), { 0.0f, 1.0f, 2.0f }); + auto additiveNode = createTestBlendNode(handler, duration); + additiveNode->setClipResults(animator->peerId(), { 1.0f, 2.0f, 3.0f }); + + const float blendFactor = 0.5f; + auto blendNode = createAdditiveClipBlendNode(handler, blendFactor); + blendNode->setBaseClipId(baseNode->peerId()); + blendNode->setAdditiveClipId(additiveNode->peerId()); + blendNode->setAdditiveFactor(blendFactor); + + ClipResults expectedResults = { 0.5f, 2.0f, 3.5f }; + + QTest::addRow("lerp varying data, beta = 0.5") + << handler << blendNode << animator->peerId() << expectedResults; + } + + { + auto handler = new Handler(); + + const qint64 globalStartTimeNS = 0; + const int loopCount = 1; + auto animator = createBlendedClipAnimator(handler, globalStartTimeNS, loopCount); + + const double duration = 1.0; + const int dataCount = 1000; + ClipResults baseData(dataCount); + ClipResults additiveData(dataCount); + ClipResults expectedResults(dataCount); + for (int i = 0; i < dataCount; ++i) { + baseData[i] = float(i); + additiveData[i] = 2.0f * float(i); + expectedResults[i] = 2.0f * float(i); + } + auto baseNode = createTestBlendNode(handler, duration); + baseNode->setClipResults(animator->peerId(), baseData); + auto additiveNode = createTestBlendNode(handler, duration); + additiveNode->setClipResults(animator->peerId(), additiveData); + + const float blendFactor = 0.5f; + auto blendNode = createAdditiveClipBlendNode(handler, blendFactor); + blendNode->setBaseClipId(baseNode->peerId()); + blendNode->setAdditiveClipId(additiveNode->peerId()); + blendNode->setAdditiveFactor(blendFactor); + + QTest::addRow("lerp lots of data, beta = 0.5") + << handler << blendNode << animator->peerId() << expectedResults; + } + } + + void checkDoBlend() + { + // GIVEN + QFETCH(Handler *, handler); + QFETCH(AdditiveClipBlend *, blendNode); + QFETCH(Qt3DCore::QNodeId, animatorId); + QFETCH(ClipResults, expectedResults); + + // WHEN + blendNode->performBlend(animatorId); + + // THEN + const ClipResults actualResults = blendNode->clipResults(animatorId); + QCOMPARE(actualResults.size(), expectedResults.size()); + for (int i = 0; i < actualResults.size(); ++i) + QCOMPARE(actualResults[i], expectedResults[i]); + + // Cleanup + delete handler; + } }; QTEST_MAIN(tst_AdditiveClipBlend) diff --git a/tests/auto/animation/clipblendnode/tst_clipblendnode.cpp b/tests/auto/animation/clipblendnode/tst_clipblendnode.cpp index 22d020c47..c214cea58 100644 --- a/tests/auto/animation/clipblendnode/tst_clipblendnode.cpp +++ b/tests/auto/animation/clipblendnode/tst_clipblendnode.cpp @@ -49,8 +49,9 @@ namespace { class TestClipBlendNode : public ClipBlendNode { public: - TestClipBlendNode() + TestClipBlendNode(const ClipResults &clipResults = ClipResults()) : ClipBlendNode(ClipBlendNode::LerpBlendType) + , m_clipResults(clipResults) {} float blend(float , float ) const Q_DECL_FINAL { return 0.0f; } @@ -63,6 +64,15 @@ public: using ClipBlendNode::setClipResults; double duration() const Q_DECL_FINAL { return 0.0f; } + +protected: + ClipResults doBlend(const QVector<ClipResults> &) const Q_DECL_FINAL + { + return m_clipResults; + } + +private: + ClipResults m_clipResults; }; } // anonymous @@ -72,6 +82,27 @@ Q_DECLARE_METATYPE(TestClipBlendNode *) class tst_ClipBlendNode : public Qt3DCore::QBackendNodeTester { Q_OBJECT +public: + TestClipBlendNode *createTestClipBlendNode(Handler *handler, const ClipResults &clipResults) + { + auto id = Qt3DCore::QNodeId::createId(); + TestClipBlendNode *node = new TestClipBlendNode(clipResults); + setPeerId(node, id); + handler->clipBlendNodeManager()->appendNode(id, node); + return node; + } + + BlendedClipAnimator *createBlendedClipAnimator(Handler *handler, + qint64 globalStartTimeNS, + int loops) + { + auto animatorId = Qt3DCore::QNodeId::createId(); + BlendedClipAnimator *animator = handler->blendedClipAnimatorManager()->getOrCreateResource(animatorId); + setPeerId(animator, animatorId); + animator->setStartTime(globalStartTimeNS); + animator->setLoops(loops); + return animator; + } private Q_SLOTS: @@ -364,6 +395,26 @@ private Q_SLOTS: delete blendNode; } + + void checkPerformBlend() + { + // GIVEN + auto handler = new Handler(); + ClipResults expectedResults = { 1.0f, 2.0f, 3.0f }; + auto blendNode = createTestClipBlendNode(handler, expectedResults); + const qint64 globalStartTimeNS = 0; + const int loopCount = 1; + auto animator = createBlendedClipAnimator(handler, globalStartTimeNS, loopCount); + + // WHEN + blendNode->performBlend(animator->peerId()); + + // THEN + const ClipResults actualResults = blendNode->clipResults(animator->peerId()); + QCOMPARE(actualResults.size(), expectedResults.size()); + for (int i = 0; i < actualResults.size(); ++i) + QCOMPARE(actualResults[i], expectedResults[i]); + } }; QTEST_MAIN(tst_ClipBlendNode) diff --git a/tests/auto/animation/clipblendnodemanager/tst_clipblendnodemanager.cpp b/tests/auto/animation/clipblendnodemanager/tst_clipblendnodemanager.cpp index 8a3d0972f..4cf8fe5ce 100644 --- a/tests/auto/animation/clipblendnodemanager/tst_clipblendnodemanager.cpp +++ b/tests/auto/animation/clipblendnodemanager/tst_clipblendnodemanager.cpp @@ -57,6 +57,12 @@ public: } double duration() const Q_DECL_FINAL { return 0.0f; } + +protected: + Qt3DAnimation::Animation::ClipResults doBlend(const QVector<Qt3DAnimation::Animation::ClipResults> &) const Q_DECL_FINAL + { + return Qt3DAnimation::Animation::ClipResults(); + } }; } // anonymous diff --git a/tests/auto/animation/lerpclipblend/tst_lerpclipblend.cpp b/tests/auto/animation/lerpclipblend/tst_lerpclipblend.cpp index 6dac3c8d9..f9ebfec4e 100644 --- a/tests/auto/animation/lerpclipblend/tst_lerpclipblend.cpp +++ b/tests/auto/animation/lerpclipblend/tst_lerpclipblend.cpp @@ -37,6 +37,9 @@ using namespace Qt3DAnimation::Animation; +Q_DECLARE_METATYPE(Handler *) +Q_DECLARE_METATYPE(LerpClipBlend *) + namespace { class TestClipBlendNode : public ClipBlendNode @@ -58,6 +61,10 @@ public: double duration() const Q_DECL_FINAL { return m_duration; } +protected: + ClipResults doBlend(const QVector<ClipResults> &) const Q_DECL_FINAL { return ClipResults(); } + +private: double m_duration; }; @@ -73,10 +80,36 @@ public: auto id = Qt3DCore::QNodeId::createId(); TestClipBlendNode *node = new TestClipBlendNode(duration); setPeerId(node, id); + node->setHandler(handler); + node->setClipBlendNodeManager(handler->clipBlendNodeManager()); handler->clipBlendNodeManager()->appendNode(id, node); return node; } + LerpClipBlend *createLerpClipBlendNode(Handler *handler, const float &blendFactor) + { + auto id = Qt3DCore::QNodeId::createId(); + LerpClipBlend *node = new LerpClipBlend(); + node->setBlendFactor(blendFactor); + setPeerId(node, id); + node->setHandler(handler); + node->setClipBlendNodeManager(handler->clipBlendNodeManager()); + handler->clipBlendNodeManager()->appendNode(id, node); + return node; + } + + BlendedClipAnimator *createBlendedClipAnimator(Handler *handler, + qint64 globalStartTimeNS, + int loops) + { + auto animatorId = Qt3DCore::QNodeId::createId(); + BlendedClipAnimator *animator = handler->blendedClipAnimatorManager()->getOrCreateResource(animatorId); + setPeerId(animator, animatorId); + animator->setStartTime(globalStartTimeNS); + animator->setLoops(loops); + return animator; + } + private Q_SLOTS: void checkInitialState() @@ -233,6 +266,167 @@ private Q_SLOTS: // THEN QCOMPARE(actualDuration, expectedDuration); } + + void checkDoBlend_data() + { + QTest::addColumn<Handler *>("handler"); + QTest::addColumn<LerpClipBlend *>("blendNode"); + QTest::addColumn<Qt3DCore::QNodeId>("animatorId"); + QTest::addColumn<ClipResults>("expectedResults"); + + { + auto handler = new Handler(); + + const qint64 globalStartTimeNS = 0; + const int loopCount = 1; + auto animator = createBlendedClipAnimator(handler, globalStartTimeNS, loopCount); + + const double duration = 1.0; + auto startNode = createTestBlendNode(handler, duration); + startNode->setClipResults(animator->peerId(), { 0.0f, 0.0f, 0.0f }); + auto endNode = createTestBlendNode(handler, duration); + endNode->setClipResults(animator->peerId(), { 1.0f, 1.0f, 1.0f }); + + const float blendFactor = 0.0f; + auto blendNode = createLerpClipBlendNode(handler, blendFactor); + blendNode->setStartClipId(startNode->peerId()); + blendNode->setEndClipId(endNode->peerId()); + blendNode->setBlendFactor(blendFactor); + + ClipResults expectedResults = { 0.0f, 0.0f, 0.0f }; + + QTest::addRow("unit lerp, beta = 0.0") + << handler << blendNode << animator->peerId() << expectedResults; + } + + { + auto handler = new Handler(); + + const qint64 globalStartTimeNS = 0; + const int loopCount = 1; + auto animator = createBlendedClipAnimator(handler, globalStartTimeNS, loopCount); + + const double duration = 1.0; + auto startNode = createTestBlendNode(handler, duration); + startNode->setClipResults(animator->peerId(), { 0.0f, 0.0f, 0.0f }); + auto endNode = createTestBlendNode(handler, duration); + endNode->setClipResults(animator->peerId(), { 1.0f, 1.0f, 1.0f }); + + const float blendFactor = 0.5f; + auto blendNode = createLerpClipBlendNode(handler, blendFactor); + blendNode->setStartClipId(startNode->peerId()); + blendNode->setEndClipId(endNode->peerId()); + blendNode->setBlendFactor(blendFactor); + + ClipResults expectedResults = { 0.5f, 0.5f, 0.5f }; + + QTest::addRow("unit lerp, beta = 0.5") + << handler << blendNode << animator->peerId() << expectedResults; + } + + { + auto handler = new Handler(); + + const qint64 globalStartTimeNS = 0; + const int loopCount = 1; + auto animator = createBlendedClipAnimator(handler, globalStartTimeNS, loopCount); + + const double duration = 1.0; + auto startNode = createTestBlendNode(handler, duration); + startNode->setClipResults(animator->peerId(), { 0.0f, 0.0f, 0.0f }); + auto endNode = createTestBlendNode(handler, duration); + endNode->setClipResults(animator->peerId(), { 1.0f, 1.0f, 1.0f }); + + const float blendFactor = 1.0f; + auto blendNode = createLerpClipBlendNode(handler, blendFactor); + blendNode->setStartClipId(startNode->peerId()); + blendNode->setEndClipId(endNode->peerId()); + blendNode->setBlendFactor(blendFactor); + + ClipResults expectedResults = { 1.0f, 1.0f, 1.0f }; + + QTest::addRow("unit lerp, beta = 1.0") + << handler << blendNode << animator->peerId() << expectedResults; + } + + { + auto handler = new Handler(); + + const qint64 globalStartTimeNS = 0; + const int loopCount = 1; + auto animator = createBlendedClipAnimator(handler, globalStartTimeNS, loopCount); + + const double duration = 1.0; + auto startNode = createTestBlendNode(handler, duration); + startNode->setClipResults(animator->peerId(), { 0.0f, 1.0f, 2.0f }); + auto endNode = createTestBlendNode(handler, duration); + endNode->setClipResults(animator->peerId(), { 1.0f, 2.0f, 3.0f }); + + const float blendFactor = 0.5f; + auto blendNode = createLerpClipBlendNode(handler, blendFactor); + blendNode->setStartClipId(startNode->peerId()); + blendNode->setEndClipId(endNode->peerId()); + blendNode->setBlendFactor(blendFactor); + + ClipResults expectedResults = { 0.5f, 1.5f, 2.5f }; + + QTest::addRow("lerp varying data, beta = 0.5") + << handler << blendNode << animator->peerId() << expectedResults; + } + + { + auto handler = new Handler(); + + const qint64 globalStartTimeNS = 0; + const int loopCount = 1; + auto animator = createBlendedClipAnimator(handler, globalStartTimeNS, loopCount); + + const double duration = 1.0; + const int dataCount = 1000; + ClipResults startData(dataCount); + ClipResults endData(dataCount); + ClipResults expectedResults(dataCount); + for (int i = 0; i < dataCount; ++i) { + startData[i] = float(i); + endData[i] = 2.0f * float(i); + expectedResults[i] = 1.5f * float(i); + } + auto startNode = createTestBlendNode(handler, duration); + startNode->setClipResults(animator->peerId(), startData); + auto endNode = createTestBlendNode(handler, duration); + endNode->setClipResults(animator->peerId(), endData); + + const float blendFactor = 0.5f; + auto blendNode = createLerpClipBlendNode(handler, blendFactor); + blendNode->setStartClipId(startNode->peerId()); + blendNode->setEndClipId(endNode->peerId()); + blendNode->setBlendFactor(blendFactor); + + QTest::addRow("lerp lots of data, beta = 0.5") + << handler << blendNode << animator->peerId() << expectedResults; + } + } + + void checkDoBlend() + { + // GIVEN + QFETCH(Handler *, handler); + QFETCH(LerpClipBlend *, blendNode); + QFETCH(Qt3DCore::QNodeId, animatorId); + QFETCH(ClipResults, expectedResults); + + // WHEN + blendNode->performBlend(animatorId); + + // THEN + const ClipResults actualResults = blendNode->clipResults(animatorId); + QCOMPARE(actualResults.size(), expectedResults.size()); + for (int i = 0; i < actualResults.size(); ++i) + QCOMPARE(actualResults[i], expectedResults[i]); + + // Cleanup + delete handler; + } }; QTEST_MAIN(tst_LerpClipBlend) |