summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/animation/backend/additiveclipblend.cpp13
-rw-r--r--src/animation/backend/additiveclipblend_p.h3
-rw-r--r--src/animation/backend/clipblendnode.cpp28
-rw-r--r--src/animation/backend/clipblendnode_p.h6
-rw-r--r--src/animation/backend/clipblendvalue.cpp8
-rw-r--r--src/animation/backend/clipblendvalue_p.h3
-rw-r--r--src/animation/backend/lerpclipblend.cpp13
-rw-r--r--src/animation/backend/lerpclipblend_p.h3
-rw-r--r--tests/auto/animation/additiveclipblend/tst_additiveclipblend.cpp194
-rw-r--r--tests/auto/animation/clipblendnode/tst_clipblendnode.cpp53
-rw-r--r--tests/auto/animation/clipblendnodemanager/tst_clipblendnodemanager.cpp6
-rw-r--r--tests/auto/animation/lerpclipblend/tst_lerpclipblend.cpp194
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)