summaryrefslogtreecommitdiffstats
path: root/src/animation/backend/clipblendnode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/animation/backend/clipblendnode.cpp')
-rw-r--r--src/animation/backend/clipblendnode.cpp156
1 files changed, 75 insertions, 81 deletions
diff --git a/src/animation/backend/clipblendnode.cpp b/src/animation/backend/clipblendnode.cpp
index a763f7f48..94a956837 100644
--- a/src/animation/backend/clipblendnode.cpp
+++ b/src/animation/backend/clipblendnode.cpp
@@ -36,7 +36,7 @@
#include "clipblendnode_p.h"
#include <Qt3DAnimation/qclipblendnodecreatedchange.h>
-#include <Qt3DAnimation/qanimationclip.h>
+#include <Qt3DAnimation/qabstractanimationclip.h>
#include <Qt3DCore/qpropertynoderemovedchange.h>
#include <Qt3DCore/qpropertynodeaddedchange.h>
@@ -57,107 +57,101 @@ ClipBlendNode::~ClipBlendNode()
{
}
-Qt3DCore::QNodeId ClipBlendNode::parentId() const
-{
- return m_parentId;
-}
-
-Qt3DCore::QNodeIdVector ClipBlendNode::childrenIds() const
-{
- return m_childrenIds;
-}
-
-Qt3DCore::QNodeIdVector ClipBlendNode::clipIds() const
-{
- return m_clipIds;
-}
-
-void ClipBlendNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
-{
- switch (e->type()) {
-
- case Qt3DCore::PropertyValueAdded: {
- Qt3DCore::QPropertyNodeAddedChangePtr change = qSharedPointerCast<Qt3DCore::QPropertyNodeAddedChange>(e);
- if (change->metaObject()->inherits(&QAbstractClipBlendNode::staticMetaObject))
- addChildId(change->addedNodeId());
- else if (change->metaObject()->inherits(&QAnimationClip::staticMetaObject))
- m_clipIds.push_back(change->addedNodeId());
- break;
- }
-
- case Qt3DCore::PropertyValueRemoved: {
- Qt3DCore::QPropertyNodeRemovedChangePtr change = qSharedPointerCast<Qt3DCore::QPropertyNodeRemovedChange>(e);
- if (change->metaObject()->inherits(&QAbstractClipBlendNode::staticMetaObject))
- removeChildId(change->removedNodeId());
- else if (change->metaObject()->inherits(&QAnimationClip::staticMetaObject))
- m_clipIds.removeOne(change->removedNodeId());
- break;
- }
-
- default:
- break;
- }
-
- Qt3DCore::QBackendNode::sceneChangeEvent(e);
-}
-
void ClipBlendNode::setClipBlendNodeManager(ClipBlendNodeManager *manager)
{
m_manager = manager;
}
-ClipBlendNodeManager *ClipBlendNode::clipBlendNodeManager() const
+void ClipBlendNode::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
{
- return m_manager;
+ Q_UNUSED(change);
}
-void ClipBlendNode::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+ClipBlendNode::BlendType Animation::ClipBlendNode::blendType() const
{
- const auto creationChange = qSharedPointerCast<QClipBlendNodeCreatedChangeBase>(change);
- setParentId(creationChange->parentClipBlendNodeId());
- m_clipIds = creationChange->clips();
+ return m_blendType;
}
-void ClipBlendNode::setParentId(Qt3DCore::QNodeId parentId)
+void ClipBlendNode::setClipResults(Qt3DCore::QNodeId animatorId, const ClipResults &clipResults)
{
- if (parentId != m_parentId) {
- // We already had a parent, tell it to abandon us
- if (!m_parentId.isNull()) {
- ClipBlendNode *parent = m_manager->lookupNode(m_parentId);
- if (parent != nullptr)
- parent->m_childrenIds.removeAll(peerId());
- }
- m_parentId = parentId;
- ClipBlendNode *parent = m_manager->lookupNode(m_parentId);
- if (parent != nullptr && !parent->m_childrenIds.contains(peerId()))
- parent->m_childrenIds.append(peerId());
+ // Do we already have an entry for this animator?
+ const int animatorIndex = m_animatorIds.indexOf(animatorId);
+ if (animatorIndex == -1) {
+ // Nope, add it
+ m_animatorIds.push_back(animatorId);
+ m_clipResults.push_back(clipResults);
+ } else {
+ m_clipResults[animatorIndex] = clipResults;
}
}
-void ClipBlendNode::addChildId(Qt3DCore::QNodeId childId)
+ClipResults ClipBlendNode::clipResults(Qt3DCore::QNodeId animatorId) const
{
- if (!m_childrenIds.contains(childId)) {
- ClipBlendNode *child = m_manager->lookupNode(childId);
- if (child != nullptr) {
- m_childrenIds.push_back(childId);
- child->m_parentId = peerId();
- }
- }
+ const int animatorIndex = m_animatorIds.indexOf(animatorId);
+ if (animatorIndex != -1)
+ return m_clipResults[animatorIndex];
+ return ClipResults();
}
-void ClipBlendNode::removeChildId(Qt3DCore::QNodeId childId)
+/*!
+ \fn QVector<Qt3DCore::QNodeId> ClipBlendNode::currentDependencyIds() const
+ \internal
+
+ Each subclass of ClipBlendNode must implement this function such that it
+ returns a vector of the ids of ClipBlendNodes upon which is it dependent
+ in order to be able to evaluate given its current internal state.
+
+ For example, a subclass implementing a simple lerp blend between two
+ other nodes, would always return the ids of the nodes between which it
+ is lerping.
+
+ A more generalised lerp node that is capable of lerping between a
+ series of nodes would return the ids of the two nodes that correspond
+ to the blend values which sandwich the currently set blend value.
+
+ The animation handler will submit a job that uses this function to
+ build a list of clips that must be evaluated in order to later
+ evaluate the entire blend tree. In this way, the clips can all be
+ evaluated in one pass, and the tree in a subsequent pass.
+*/
+
+/*!
+ \fn QVector<Qt3DCore::QNodeId> ClipBlendNode::allDependencyIds() const
+ \internal
+
+ Similar to currentDependencyIds() but returns the ids of all potential
+ dependency nodes, not just those that are dependencies given the current
+ internal state. For example a generalised lerp node would return the ids
+ of all nodes that can participate in the lerp for any value of the blend
+ parameter. Not just those bounding the current blend value.
+*/
+
+/*!
+ \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::blend(Qt3DCore::QNodeId animatorId)
{
- if (m_childrenIds.contains(childId)) {
- ClipBlendNode *child = m_manager->lookupNode(childId);
- if (child != nullptr)
- child->m_parentId = Qt3DCore::QNodeId();
- m_childrenIds.removeAll(childId);
+ // Obtain the clip results from each of the dependencies
+ const QVector<Qt3DCore::QNodeId> dependencyNodeIds = currentDependencyIds();
+ 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);
}
-}
-ClipBlendNode::BlendType Animation::ClipBlendNode::blendType() const
-{
- return m_blendType;
+ // Ask the blend node to perform the actual blend operation on the data
+ // from the dependencies
+ ClipResults blendedResults = doBlend(blendData);
+ setClipResults(animatorId, blendedResults);
}
} // Animation