summaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer@kdab.com>2017-03-17 17:16:06 +0000
committerSean Harmer <sean.harmer@kdab.com>2017-03-25 14:23:08 +0000
commit6961c308fb9d98006c98654a8131593f390c89a8 (patch)
treececa08b394bd3a66d63df6c1873f7a4871e35247 /tests/auto
parent1da93b2fcf57dc442952b65d599db4e209faa59f (diff)
Add virtual doBlend to ClipBlendNode and subclasses
This is called by the non virtual performBlend (will be renamed once old implementation is removed). The key here is that all nodes in the blend tree will have the exact same layout for the ClipResults for a given animator. This means we don't need to have a mapping data structure for every node in the tree. This really simplifies the blending implementation and will allow us to parallelise this much better in the future as each blend node could make use of a parallel_for() or map() type operation. To achieve this we will need to perform a gather operation that maps the ClipResults coming straight out of an animation clip to the ClipResults layout used by the blend tree as described above. This will be done in a follow up commit. Change-Id: I389383d3b9197a6ef36b529f44ac89cb5c593023 Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'tests/auto')
-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
4 files changed, 446 insertions, 1 deletions
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)