diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2017-10-08 11:01:30 +0100 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2018-01-22 09:45:15 +0000 |
commit | ea12f3be4b6b4e5d117bad6d5446ca8517905c0b (patch) | |
tree | 280a38bf62cd1b545b8092f967502ca917e4e8ce /src/animation | |
parent | f91ee783c5704b0d55da0d96dacf6eca8933e748 (diff) |
Generate default channel values as needed
Change-Id: I20871448ba10cf6459b156d00bebdf7a7c8a319b
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'src/animation')
-rw-r--r-- | src/animation/backend/animationutils_p.h | 8 | ||||
-rw-r--r-- | src/animation/backend/buildblendtreesjob.cpp | 35 | ||||
-rw-r--r-- | src/animation/backend/clipblendvalue.cpp | 12 | ||||
-rw-r--r-- | src/animation/backend/clipblendvalue_p.h | 3 |
4 files changed, 53 insertions, 5 deletions
diff --git a/src/animation/backend/animationutils_p.h b/src/animation/backend/animationutils_p.h index 6a1b18936..8946eb755 100644 --- a/src/animation/backend/animationutils_p.h +++ b/src/animation/backend/animationutils_p.h @@ -191,6 +191,13 @@ inline QDebug operator<<(QDebug dbg, const ChannelNameAndType &nameAndType) } #endif +struct ComponentValue +{ + int componentIndex; + float value; +}; +QT3D_DECLARE_TYPEINFO_2(Qt3DAnimation, Animation, ComponentValue, Q_PRIMITIVE_TYPE) + struct ClipFormat { // TODO: Remove the mask and store both the sourceClipIndices and @@ -200,6 +207,7 @@ struct ClipFormat QVector<QBitArray> sourceClipMask; QVector<ComponentIndices> formattedComponentIndices; QVector<ChannelNameAndType> namesAndTypes; + QVector<ComponentValue> defaultComponentValues; }; #ifndef QT_NO_DEBUG_STREAM diff --git a/src/animation/backend/buildblendtreesjob.cpp b/src/animation/backend/buildblendtreesjob.cpp index a08aa2a34..581b133b5 100644 --- a/src/animation/backend/buildblendtreesjob.cpp +++ b/src/animation/backend/buildblendtreesjob.cpp @@ -90,10 +90,17 @@ void BuildBlendTreesJob::run() QVector<QBitArray> blendTreeChannelMask; const QVector<Qt3DCore::QNodeId> valueNodeIds = gatherValueNodesToEvaluate(m_handler, blendClipAnimator->blendTreeRootId()); + + // Store the clip value nodes to avoid further lookups below. + // TODO: Refactor this next block into a function in animationutils.cpp that takes + // a QVector<QClipBlendValue*> as input. + QVector<ClipBlendValue *> valueNodes; + valueNodes.reserve(valueNodeIds.size()); for (const auto valueNodeId : valueNodeIds) { ClipBlendValue *valueNode = static_cast<ClipBlendValue *>(m_handler->clipBlendNodeManager()->lookupNode(valueNodeId)); Q_ASSERT(valueNode); + valueNodes.push_back(valueNode); const Qt3DCore::QNodeId clipId = valueNode->clipId(); AnimationClip *clip = m_handler->animationClipLoaderManager()->lookupResource(clipId); @@ -132,6 +139,34 @@ void BuildBlendTreesJob::run() } } + // Now that we know the overall blend tree mask, go back and compare this to + // the masks from each of the value nodes. If the overall mask requires a + // channel but the value node does not provide it, we need to store default + // values to use for that channel so that the blending evaluation works as + // expected. + for (const auto valueNode : valueNodes) { + ClipFormat &f = valueNode->clipFormat(blendClipAnimator->peerId()); + + const int channelCount = blendTreeChannelMask.size(); + for (int i = 0; i < channelCount; ++i) { + if (blendTreeChannelMask[i] == f.sourceClipMask[i]) + continue; // Masks match, nothing to do + + // If we get to here then we need to obtain a default value + // for this channel and store it for later application to any + // missing components of this channel. + const QVector<float> defaultValue = defaultValueForChannel(m_handler, + f.namesAndTypes[i]); + + // Find the indices where we later need to inject these default + // values and store them in the format. + const ComponentIndices &componentIndices = f.formattedComponentIndices[i]; + Q_ASSERT(componentIndices.size() == defaultValue.size()); + for (int j = 0; j < defaultValue.size(); ++j) + f.defaultComponentValues.push_back({componentIndices[j], defaultValue[j]}); + } + } + // Finally, build the mapping data vector for this blended clip animator. This // gets used during the final stage of evaluation when sending the property changes // out to the targets of the animation. We do the costly work once up front. diff --git a/src/animation/backend/clipblendvalue.cpp b/src/animation/backend/clipblendvalue.cpp index c1de1fea7..5685d5191 100644 --- a/src/animation/backend/clipblendvalue.cpp +++ b/src/animation/backend/clipblendvalue.cpp @@ -102,12 +102,16 @@ void ClipBlendValue::setClipFormat(Qt3DCore::QNodeId animatorId, const ClipForma } } -ClipFormat ClipBlendValue::clipFormat(Qt3DCore::QNodeId animatorId) +ClipFormat &ClipBlendValue::clipFormat(Qt3DCore::QNodeId animatorId) { const int animatorIndex = m_animatorIds.indexOf(animatorId); - if (animatorIndex != -1) - return m_clipFormats[animatorIndex]; - return ClipFormat(); + return m_clipFormats[animatorIndex]; +} + +const ClipFormat &ClipBlendValue::clipFormat(Qt3DCore::QNodeId animatorId) const +{ + const int animatorIndex = m_animatorIds.indexOf(animatorId); + return m_clipFormats[animatorIndex]; } } // namespace Animation diff --git a/src/animation/backend/clipblendvalue_p.h b/src/animation/backend/clipblendvalue_p.h index 3e2987ed7..7b028583c 100644 --- a/src/animation/backend/clipblendvalue_p.h +++ b/src/animation/backend/clipblendvalue_p.h @@ -79,7 +79,8 @@ public: double duration() const Q_DECL_OVERRIDE; void setClipFormat(Qt3DCore::QNodeId animatorId, const ClipFormat &formatIndices); - ClipFormat clipFormat(Qt3DCore::QNodeId animatorId); + ClipFormat &clipFormat(Qt3DCore::QNodeId animatorId); + const ClipFormat &clipFormat(Qt3DCore::QNodeId animatorId) const; protected: ClipResults doBlend(const QVector<ClipResults> &blendData) const Q_DECL_OVERRIDE; |