summaryrefslogtreecommitdiffstats
path: root/src
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 /src
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 'src')
-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
8 files changed, 77 insertions, 0 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;