diff options
Diffstat (limited to 'src/animation/backend/clipblendnode.cpp')
-rw-r--r-- | src/animation/backend/clipblendnode.cpp | 156 |
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 |