summaryrefslogtreecommitdiffstats
path: root/src/animation
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer@kdab.com>2017-10-08 11:01:30 +0100
committerSean Harmer <sean.harmer@kdab.com>2018-01-22 09:45:15 +0000
commitea12f3be4b6b4e5d117bad6d5446ca8517905c0b (patch)
tree280a38bf62cd1b545b8092f967502ca917e4e8ce /src/animation
parentf91ee783c5704b0d55da0d96dacf6eca8933e748 (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.h8
-rw-r--r--src/animation/backend/buildblendtreesjob.cpp35
-rw-r--r--src/animation/backend/clipblendvalue.cpp12
-rw-r--r--src/animation/backend/clipblendvalue_p.h3
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;