summaryrefslogtreecommitdiffstats
path: root/src/animation
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2018-01-20 22:31:32 +0100
committerLiang Qi <liang.qi@qt.io>2018-01-20 22:31:32 +0100
commitfac6dcc70de922dc3f3dd105e9d725092e6fd808 (patch)
tree9930923372c7538a36929abcc3d0adad1b4c0b55 /src/animation
parentcdb9131eda64cf98fbb2f801c901591c1b09d9ef (diff)
parent44aeb43834675a4d6b19bee88e267464ca7ad1f4 (diff)
Merge remote-tracking branch 'origin/5.10' into dev
Diffstat (limited to 'src/animation')
-rw-r--r--src/animation/backend/animationutils.cpp140
-rw-r--r--src/animation/backend/animationutils_p.h112
-rw-r--r--src/animation/backend/buildblendtreesjob.cpp42
-rw-r--r--src/animation/backend/clipanimator.cpp2
-rw-r--r--src/animation/backend/clipanimator_p.h6
-rw-r--r--src/animation/backend/clipblendvalue.cpp12
-rw-r--r--src/animation/backend/clipblendvalue_p.h6
-rw-r--r--src/animation/backend/evaluateblendclipanimatorjob.cpp4
-rw-r--r--src/animation/backend/evaluateclipanimatorjob.cpp4
-rw-r--r--src/animation/backend/findrunningclipanimatorsjob.cpp13
-rw-r--r--src/animation/backend/skeleton_p.h16
11 files changed, 285 insertions, 72 deletions
diff --git a/src/animation/backend/animationutils.cpp b/src/animation/backend/animationutils.cpp
index fb5b19a5d..8652c7df1 100644
--- a/src/animation/backend/animationutils.cpp
+++ b/src/animation/backend/animationutils.cpp
@@ -88,6 +88,16 @@ int componentsForType(int type)
return componentCount;
}
+inline QVector<float> valueToVector(const QVector3D &value)
+{
+ return { value.x(), value.y(), value.z() };
+}
+
+inline QVector<float> valueToVector(const QQuaternion &value)
+{
+ return { value.scalar(), value.x(), value.y(), value.z() };
+}
+
ClipEvaluationData evaluationDataForClip(AnimationClip *clip,
const AnimatorEvaluationData &animatorData)
{
@@ -348,15 +358,15 @@ QVector<Qt3DCore::QSceneChangePtr> preparePropertyChanges(Qt3DCore::QNodeId anim
dirtySkeletons.push_back(mappingData.skeleton);
switch (mappingData.jointTransformComponent) {
- case MappingData::Scale:
+ case Scale:
mappingData.skeleton->setJointScale(mappingData.jointIndex, v.value<QVector3D>());
break;
- case MappingData::Rotation:
+ case Rotation:
mappingData.skeleton->setJointRotation(mappingData.jointIndex, v.value<QQuaternion>());
break;
- case MappingData::Translation:
+ case Translation:
mappingData.skeleton->setJointTranslation(mappingData.jointIndex, v.value<QVector3D>());
break;
@@ -416,7 +426,8 @@ QVector<AnimationCallbackAndValue> prepareCallbacks(const QVector<MappingData> &
// channel names, types and joint indices.
QVector<MappingData> buildPropertyMappings(const QVector<ChannelMapping*> &channelMappings,
const QVector<ChannelNameAndType> &channelNamesAndTypes,
- const QVector<ComponentIndices> &channelComponentIndices)
+ const QVector<ComponentIndices> &channelComponentIndices,
+ const QVector<QBitArray> &sourceClipMask)
{
// Accumulate the required number of mappings
int maxMappingDatas = 0;
@@ -458,12 +469,13 @@ QVector<MappingData> buildPropertyMappings(const QVector<ChannelMapping*> &chann
}
// Try to find matching channel name and type
- const ChannelNameAndType nameAndType = { mapping->channelName(), mapping->type() };
+ const ChannelNameAndType nameAndType = { mapping->channelName(), mapping->type(), mapping->peerId() };
const int index = channelNamesAndTypes.indexOf(nameAndType);
if (index != -1) {
// Do we have any animation data for this channel? If not, don't bother
// adding a mapping for it.
- if (channelComponentIndices[index].isEmpty())
+ const bool hasChannelIndices = sourceClipMask[index].count(true) != 0;
+ if (!hasChannelIndices)
continue;
// We got one!
@@ -475,9 +487,9 @@ QVector<MappingData> buildPropertyMappings(const QVector<ChannelMapping*> &chann
case ChannelMapping::SkeletonMappingType: {
const QVector<ChannelNameAndType> jointProperties
- = { { QLatin1String("Location"), static_cast<int>(QVariant::Vector3D) },
- { QLatin1String("Rotation"), static_cast<int>(QVariant::Quaternion) },
- { QLatin1String("Scale"), static_cast<int>(QVariant::Vector3D) } };
+ = { { QLatin1String("Location"), static_cast<int>(QVariant::Vector3D), Translation },
+ { QLatin1String("Rotation"), static_cast<int>(QVariant::Quaternion), Rotation },
+ { QLatin1String("Scale"), static_cast<int>(QVariant::Vector3D), Scale } };
const QHash<QString, const char *> channelNameToPropertyName
= { { QLatin1String("Location"), "translation" },
{ QLatin1String("Rotation"), "rotation" },
@@ -495,13 +507,17 @@ QVector<MappingData> buildPropertyMappings(const QVector<ChannelMapping*> &chann
// Get the name, type and index
ChannelNameAndType nameAndType = jointProperties[propertyIndex];
nameAndType.jointIndex = jointIndex;
+ nameAndType.mappingId = mapping->peerId();
// Try to find matching channel name and type
const int index = channelNamesAndTypes.indexOf(nameAndType);
+ if (index == -1)
+ continue;
// Do we have any animation data for this channel? If not, don't bother
// adding a mapping for it.
- if (channelComponentIndices[index].isEmpty())
+ const bool hasChannelIndices = sourceClipMask[index].count(true) != 0;
+ if (!hasChannelIndices)
continue;
if (index != -1) {
@@ -514,12 +530,13 @@ QVector<MappingData> buildPropertyMappings(const QVector<ChannelMapping*> &chann
// Convert property name for joint transform components to
// an enumerated type so we can avoid the string comparisons
// when sending the change events after evaluation.
+ // TODO: Replace this logic as we now do it in buildRequiredChannelsAndTypes()
if (qstrcmp(mappingData.propertyName, "scale") == 0)
- mappingData.jointTransformComponent = MappingData::Scale;
+ mappingData.jointTransformComponent = Scale;
else if (qstrcmp(mappingData.propertyName, "rotation") == 0)
- mappingData.jointTransformComponent = MappingData::Rotation;
+ mappingData.jointTransformComponent = Rotation;
else if (qstrcmp(mappingData.propertyName, "translation") == 0)
- mappingData.jointTransformComponent = MappingData::Translation;
+ mappingData.jointTransformComponent = Translation;
mappingDataVec.push_back(mappingData);
}
@@ -557,7 +574,7 @@ QVector<ChannelNameAndType> buildRequiredChannelsAndTypes(Handler *handler,
case ChannelMapping::ChannelMappingType:
case ChannelMapping::CallbackMappingType: {
// Get the name and type
- const ChannelNameAndType nameAndType{ mapping->channelName(), mapping->type() };
+ const ChannelNameAndType nameAndType{ mapping->channelName(), mapping->type(), mappingId };
// Add if not already contained
if (!namesAndTypes.contains(nameAndType))
@@ -570,9 +587,9 @@ QVector<ChannelNameAndType> buildRequiredChannelsAndTypes(Handler *handler,
// Add an entry for each scale/rotation/translation property of each joint index
// of the target skeleton.
const QVector<ChannelNameAndType> jointProperties
- = { { QLatin1String("Location"), static_cast<int>(QVariant::Vector3D) },
- { QLatin1String("Rotation"), static_cast<int>(QVariant::Quaternion) },
- { QLatin1String("Scale"), static_cast<int>(QVariant::Vector3D) } };
+ = { { QLatin1String("Location"), static_cast<int>(QVariant::Vector3D), Translation },
+ { QLatin1String("Rotation"), static_cast<int>(QVariant::Quaternion), Rotation },
+ { QLatin1String("Scale"), static_cast<int>(QVariant::Vector3D), Scale } };
Skeleton *skeleton = handler->skeletonManager()->lookupResource(mapping->skeletonId());
const int jointCount = skeleton->jointCount();
for (int jointIndex = 0; jointIndex < jointCount; ++jointIndex) {
@@ -580,7 +597,9 @@ QVector<ChannelNameAndType> buildRequiredChannelsAndTypes(Handler *handler,
for (int propertyIndex = 0; propertyIndex < propertyCount; ++propertyIndex) {
// Get the name, type and index
ChannelNameAndType nameAndType = jointProperties[propertyIndex];
+ nameAndType.jointName = skeleton->jointName(jointIndex);
nameAndType.jointIndex = jointIndex;
+ nameAndType.mappingId = mappingId;
// Add if not already contained
if (!namesAndTypes.contains(nameAndType))
@@ -656,22 +675,26 @@ QVector<Qt3DCore::QNodeId> gatherValueNodesToEvaluate(Handler *handler,
return clipIds;
}
-ComponentIndices generateClipFormatIndices(const QVector<ChannelNameAndType> &targetChannels,
- QVector<ComponentIndices> &targetIndices,
- const AnimationClip *clip)
+ClipFormat generateClipFormatIndices(const QVector<ChannelNameAndType> &targetChannels,
+ const QVector<ComponentIndices> &targetIndices,
+ const AnimationClip *clip)
{
Q_ASSERT(targetChannels.size() == targetIndices.size());
// Reserve enough storage for all the format indices
+ const int channelCount = targetChannels.size();
+ ClipFormat f;
+ f.namesAndTypes.resize(channelCount);
+ f.formattedComponentIndices.resize(channelCount);
+ f.sourceClipMask.resize(channelCount);
int indexCount = 0;
for (const auto &targetIndexVec : qAsConst(targetIndices))
indexCount += targetIndexVec.size();
- ComponentIndices format;
- format.resize(indexCount);
+ ComponentIndices &sourceIndices = f.sourceClipIndices;
+ sourceIndices.resize(indexCount);
// Iterate through the target channels
- const int channelCount = targetChannels.size();
- auto formatIt = format.begin();
+ auto formatIt = sourceIndices.begin();
for (int i = 0; i < channelCount; ++i) {
// Find the index of the channel from the clip
const ChannelNameAndType &targetChannel = targetChannels[i];
@@ -688,17 +711,23 @@ ComponentIndices generateClipFormatIndices(const QVector<ChannelNameAndType> &ta
targetChannel.type,
baseIndex);
std::copy(channelIndices.begin(), channelIndices.end(), formatIt);
+
+ f.sourceClipMask[i].resize(componentCount);
+ for (int j = 0; j < componentCount; ++j)
+ f.sourceClipMask[i].setBit(j, channelIndices[j] != -1);
} else {
// No such channel in this clip. We'll use default values when
// mapping from the clip to the formatted clip results.
std::fill(formatIt, formatIt + componentCount, -1);
- targetIndices[i].clear();
+ f.sourceClipMask[i].fill(false, componentCount);
}
+ f.formattedComponentIndices[i] = targetIndices[i];
+ f.namesAndTypes[i] = targetChannels[i];
formatIt += componentCount;
}
- return format;
+ return f;
}
ClipResults formatClipResults(const ClipResults &rawClipResults,
@@ -760,6 +789,65 @@ ClipResults evaluateBlendTree(Handler *handler,
return blendTreeRootNode->clipResults(animatorId);
}
+QVector<float> defaultValueForChannel(Handler *handler,
+ const ChannelNameAndType &channelDescription)
+{
+ QVector<float> result;
+
+ // Does the channel repesent a joint in a skeleton or is it a general channel?
+ ChannelMappingManager *mappingManager = handler->channelMappingManager();
+ const ChannelMapping *mapping = mappingManager->lookupResource(channelDescription.mappingId);
+ switch (mapping->mappingType()) {
+ case ChannelMapping::SkeletonMappingType: {
+ // Default channel values for a joint in a skeleton, should be taken
+ // from the default pose of the joint itself. I.e. if a joint is not
+ // explicitly animated, then it should retain it's initial rest pose.
+ Skeleton *skeleton = mapping->skeleton();
+ const int jointIndex = channelDescription.jointIndex;
+ switch (channelDescription.jointTransformComponent) {
+ case Translation:
+ result = valueToVector(skeleton->jointTranslation(jointIndex));
+ break;
+
+ case Rotation:
+ result = valueToVector(skeleton->jointRotation(jointIndex));
+ break;
+
+ case Scale:
+ result = valueToVector(skeleton->jointScale(jointIndex));
+ break;
+
+ case NoTransformComponent:
+ Q_UNREACHABLE();
+ break;
+ }
+ break;
+ }
+
+ case ChannelMapping::ChannelMappingType:
+ case ChannelMapping::CallbackMappingType: {
+ // Do our best to provide a sensible default value.
+ if (channelDescription.type == QMetaType::QQuaternion) {
+ result = valueToVector(QQuaternion()); // (1, 0, 0, 0)
+ break;
+ }
+
+ if (channelDescription.name.toLower() == QLatin1String("scale")) {
+ result = valueToVector(QVector3D(1.0f, 1.0f, 1.0f));
+ break;
+ }
+
+ // Everything else gets all zeros
+ const int componentCount = componentsForType(channelDescription.type);
+ result = QVector<float>(componentCount, 0.0f);
+ break;
+ }
+
+ }
+
+ return result;
+}
+
} // Animation
} // Qt3DAnimation
diff --git a/src/animation/backend/animationutils_p.h b/src/animation/backend/animationutils_p.h
index d8127d8af..6a1b18936 100644
--- a/src/animation/backend/animationutils_p.h
+++ b/src/animation/backend/animationutils_p.h
@@ -54,6 +54,7 @@
#include <Qt3DCore/qnodeid.h>
#include <Qt3DCore/qscenechange.h>
+#include <QtCore/qbitarray.h>
#include <QtCore/qdebug.h>
QT_BEGIN_NAMESPACE
@@ -71,15 +72,15 @@ class ChannelMapping;
typedef QVector<int> ComponentIndices;
+enum JointTransformComponent {
+ NoTransformComponent = 0,
+ Scale,
+ Rotation,
+ Translation
+};
+
struct MappingData
{
- enum JointTransformComponent {
- NoTransformComponent = 0,
- Scale,
- Rotation,
- Translation
- };
-
Qt3DCore::QNodeId targetId;
Skeleton *skeleton = nullptr;
int jointIndex = -1;
@@ -124,32 +125,109 @@ typedef QVector<float> ClipResults;
struct ChannelNameAndType
{
+ QString jointName;
QString name;
int type;
int jointIndex;
+ Qt3DCore::QNodeId mappingId;
+ JointTransformComponent jointTransformComponent;
+ float pad; // Unused
static const int invalidIndex = -1;
ChannelNameAndType()
- : name()
+ : jointName()
+ , name()
, type(-1)
, jointIndex(-1)
+ , mappingId()
+ , jointTransformComponent(NoTransformComponent)
{}
- ChannelNameAndType(const QString &_name, int _type, int _jointIndex = invalidIndex)
- : name(_name)
+ ChannelNameAndType(const QString &_name,
+ int _type,
+ Qt3DCore::QNodeId _mappingId = Qt3DCore::QNodeId(),
+ int _jointIndex = invalidIndex)
+ : jointName()
+ , name(_name)
, type(_type)
, jointIndex(_jointIndex)
+ , mappingId(_mappingId)
+ , jointTransformComponent(NoTransformComponent)
+ {}
+
+ ChannelNameAndType(const QString &_name,
+ int _type,
+ JointTransformComponent _jointTransformComponent)
+ : jointName()
+ , name(_name)
+ , type(_type)
+ , jointIndex(invalidIndex)
+ , mappingId()
+ , jointTransformComponent(_jointTransformComponent)
{}
bool operator==(const ChannelNameAndType &rhs) const
{
return name == rhs.name
&& type == rhs.type
- && jointIndex == rhs.jointIndex;
+ && jointIndex == rhs.jointIndex
+ && mappingId == rhs.mappingId
+ && jointTransformComponent == rhs.jointTransformComponent;
}
};
+#ifndef QT_NO_DEBUG_STREAM
+inline QDebug operator<<(QDebug dbg, const ChannelNameAndType &nameAndType)
+{
+ QDebugStateSaver saver(dbg);
+ dbg << "name =" << nameAndType.name
+ << "type =" << nameAndType.type
+ << "mappingId =" << nameAndType.mappingId
+ << "jointIndex =" << nameAndType.jointIndex
+ << "jointName =" << nameAndType.jointName
+ << "jointTransformComponent =" << nameAndType.jointTransformComponent;
+ return dbg;
+}
+#endif
+
+struct ClipFormat
+{
+ // TODO: Remove the mask and store both the sourceClipIndices and
+ // formattedComponentIndices in flat vectors. This will require a
+ // way to look up the offset and number of elements for each channel.
+ ComponentIndices sourceClipIndices;
+ QVector<QBitArray> sourceClipMask;
+ QVector<ComponentIndices> formattedComponentIndices;
+ QVector<ChannelNameAndType> namesAndTypes;
+};
+
+#ifndef QT_NO_DEBUG_STREAM
+inline QDebug operator<<(QDebug dbg, const ClipFormat &format)
+{
+ QDebugStateSaver saver(dbg);
+ int sourceIndex = 0;
+ for (int i = 0; i < format.namesAndTypes.size(); ++i) {
+ dbg << i
+ << format.namesAndTypes[i].jointIndex
+ << format.namesAndTypes[i].jointName
+ << format.namesAndTypes[i].name
+ << format.namesAndTypes[i].type
+ << "formatted results dst indices =" << format.formattedComponentIndices[i];
+ const int componentCount = format.formattedComponentIndices[i].size();
+
+ dbg << "clip src indices =";
+ for (int j = sourceIndex; j < sourceIndex + componentCount; ++j)
+ dbg << format.sourceClipIndices[j] << "";
+
+ dbg << "src clip mask =" << format.sourceClipMask[i];
+ dbg << endl;
+ sourceIndex += componentCount;
+ }
+ return dbg;
+}
+#endif
+
struct AnimationCallbackAndValue
{
QAnimationCallback *callback;
@@ -219,7 +297,8 @@ QVector<AnimationCallbackAndValue> prepareCallbacks(const QVector<MappingData> &
Q_AUTOTEST_EXPORT
QVector<MappingData> buildPropertyMappings(const QVector<ChannelMapping *> &channelMappings,
const QVector<ChannelNameAndType> &channelNamesAndTypes,
- const QVector<ComponentIndices> &channelComponentIndices);
+ const QVector<ComponentIndices> &channelComponentIndices,
+ const QVector<QBitArray> &sourceClipMask);
Q_AUTOTEST_EXPORT
QVector<ChannelNameAndType> buildRequiredChannelsAndTypes(Handler *handler,
@@ -243,9 +322,9 @@ QVector<Qt3DCore::QNodeId> gatherValueNodesToEvaluate(Handler *handler,
Qt3DCore::QNodeId blendTreeRootId);
Q_AUTOTEST_EXPORT
-ComponentIndices generateClipFormatIndices(const QVector<ChannelNameAndType> &targetChannels,
- QVector<ComponentIndices> &targetIndices,
- const AnimationClip *clip);
+ClipFormat generateClipFormatIndices(const QVector<ChannelNameAndType> &targetChannels,
+ const QVector<ComponentIndices> &targetIndices,
+ const AnimationClip *clip);
Q_AUTOTEST_EXPORT
ClipResults formatClipResults(const ClipResults &rawClipResults,
@@ -256,6 +335,9 @@ ClipResults evaluateBlendTree(Handler *handler,
BlendedClipAnimator *animator,
Qt3DCore::QNodeId blendNodeId);
+Q_AUTOTEST_EXPORT
+QVector<float> defaultValueForChannel(Handler *handler, const ChannelNameAndType &channelDescription);
+
} // Animation
} // Qt3DAnimation
diff --git a/src/animation/backend/buildblendtreesjob.cpp b/src/animation/backend/buildblendtreesjob.cpp
index cb7eb19c8..a08aa2a34 100644
--- a/src/animation/backend/buildblendtreesjob.cpp
+++ b/src/animation/backend/buildblendtreesjob.cpp
@@ -78,15 +78,16 @@ void BuildBlendTreesJob::run()
// tree when used with this animator
const ChannelMapper *mapper = m_handler->channelMapperManager()->lookupResource(blendClipAnimator->mapperId());
Q_ASSERT(mapper);
- QVector<ChannelNameAndType> channelNamesAndTypes
+ const QVector<ChannelNameAndType> channelNamesAndTypes
= buildRequiredChannelsAndTypes(m_handler, mapper);
- QVector<ComponentIndices> channelComponentIndices
+ const QVector<ComponentIndices> channelComponentIndices
= assignChannelComponentIndices(channelNamesAndTypes);
// Find the leaf value nodes of the blend tree and for each of them
// create a set of format indices that can later be used to map the
// raw ClipResults resulting from evaluating an animation clip to the
// layout used by the blend tree for this animator
+ QVector<QBitArray> blendTreeChannelMask;
const QVector<Qt3DCore::QNodeId> valueNodeIds
= gatherValueNodesToEvaluate(m_handler, blendClipAnimator->blendTreeRootId());
for (const auto valueNodeId : valueNodeIds) {
@@ -98,14 +99,37 @@ void BuildBlendTreesJob::run()
AnimationClip *clip = m_handler->animationClipLoaderManager()->lookupResource(clipId);
Q_ASSERT(clip);
- const ComponentIndices formatIndices
- = generateClipFormatIndices(channelNamesAndTypes,
- channelComponentIndices,
- clip);
- valueNode->setFormatIndices(blendClipAnimator->peerId(), formatIndices);
+ const ClipFormat format = generateClipFormatIndices(channelNamesAndTypes,
+ channelComponentIndices,
+ clip);
+ valueNode->setClipFormat(blendClipAnimator->peerId(), format);
// this BlendClipAnimator needs to be notified when the clip has been loaded
clip->addDependingBlendedClipAnimator(blendClipAnimator->peerId());
+
+ // Combine the masks from each source clip to see which channels should be
+ // evaluated and result in a mappingData being created. If any contributing clip
+ // supports a channel, that will produce a channel mapping. Clips with those channels
+ // missing will use default values when blending:
+ //
+ // Default scale = (1, 1, 1)
+ // Default rotation = (1, 0, 0, 0)
+ // Default translation = (0, 0, 0)
+ // Default joint transforms should be taken from the skeleton initial pose
+ //
+ // Everything else has all components set to 0. If user wants something else, they
+ // should provide a clip with a single keyframe at the desired default value.
+ if (blendTreeChannelMask.isEmpty()) {
+ // Initialize the blend tree mask from the mask of the first clip
+ blendTreeChannelMask = format.sourceClipMask;
+ } else {
+ // We allow through a channel if any source clip in the tree has
+ // data for that channel. Clips without data for a channel will
+ // have default values substituted when evaluating the blend tree.
+ int channelIndex = 0;
+ for (const auto &channelMask : qAsConst(format.sourceClipMask))
+ blendTreeChannelMask[channelIndex++] |= channelMask;
+ }
}
// Finally, build the mapping data vector for this blended clip animator. This
@@ -119,10 +143,12 @@ void BuildBlendTreesJob::run()
Q_ASSERT(mapping);
channelMappings.push_back(mapping);
}
+
const QVector<MappingData> mappingDataVec
= buildPropertyMappings(channelMappings,
channelNamesAndTypes,
- channelComponentIndices);
+ channelComponentIndices,
+ blendTreeChannelMask);
blendClipAnimator->setMappingData(mappingDataVec);
}
}
diff --git a/src/animation/backend/clipanimator.cpp b/src/animation/backend/clipanimator.cpp
index 21c08b80a..b294d57a2 100644
--- a/src/animation/backend/clipanimator.cpp
+++ b/src/animation/backend/clipanimator.cpp
@@ -115,7 +115,7 @@ void ClipAnimator::cleanup()
m_clockId = Qt3DCore::QNodeId();
m_running = false;
m_loops = 1;
- m_formatIndices.clear();
+ m_clipFormat = ClipFormat();
}
void ClipAnimator::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
diff --git a/src/animation/backend/clipanimator_p.h b/src/animation/backend/clipanimator_p.h
index 4c33819f5..28c0ae51d 100644
--- a/src/animation/backend/clipanimator_p.h
+++ b/src/animation/backend/clipanimator_p.h
@@ -96,8 +96,8 @@ public:
void animationClipMarkedDirty() { setDirty(Handler::ClipAnimatorDirty); }
- void setFormatIndices(const ComponentIndices &formatIndices) { m_formatIndices = formatIndices; }
- ComponentIndices formatIndices() const { return m_formatIndices; }
+ void setClipFormat(const ClipFormat &clipFormat) { m_clipFormat = clipFormat; }
+ ClipFormat clipFormat() const { return m_clipFormat; }
qint64 nsSincePreviousFrame(qint64 currentGlobalTimeNS);
void setLastGlobalTimeNS(qint64 lastGlobalTimeNS);
@@ -120,7 +120,7 @@ private:
QVector<MappingData> m_mappingData;
int m_currentLoop;
- ComponentIndices m_formatIndices;
+ ClipFormat m_clipFormat;
};
} // namespace Animation
diff --git a/src/animation/backend/clipblendvalue.cpp b/src/animation/backend/clipblendvalue.cpp
index 2d4ed99d2..c1de1fea7 100644
--- a/src/animation/backend/clipblendvalue.cpp
+++ b/src/animation/backend/clipblendvalue.cpp
@@ -89,25 +89,25 @@ double ClipBlendValue::duration() const
return clip->duration();
}
-void ClipBlendValue::setFormatIndices(Qt3DCore::QNodeId animatorId, const ComponentIndices &formatIndices)
+void ClipBlendValue::setClipFormat(Qt3DCore::QNodeId animatorId, const ClipFormat &formatIndices)
{
// 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_formatIndicies.push_back(formatIndices);
+ m_clipFormats.push_back(formatIndices);
} else {
- m_formatIndicies[animatorIndex] = formatIndices;
+ m_clipFormats[animatorIndex] = formatIndices;
}
}
-ComponentIndices ClipBlendValue::formatIndices(Qt3DCore::QNodeId animatorId)
+ClipFormat ClipBlendValue::clipFormat(Qt3DCore::QNodeId animatorId)
{
const int animatorIndex = m_animatorIds.indexOf(animatorId);
if (animatorIndex != -1)
- return m_formatIndicies[animatorIndex];
- return ComponentIndices();
+ return m_clipFormats[animatorIndex];
+ return ClipFormat();
}
} // namespace Animation
diff --git a/src/animation/backend/clipblendvalue_p.h b/src/animation/backend/clipblendvalue_p.h
index f0ae65589..63dfe6ddc 100644
--- a/src/animation/backend/clipblendvalue_p.h
+++ b/src/animation/backend/clipblendvalue_p.h
@@ -78,8 +78,8 @@ public:
double duration() const override;
- void setFormatIndices(Qt3DCore::QNodeId animatorId, const ComponentIndices &formatIndices);
- ComponentIndices formatIndices(Qt3DCore::QNodeId animatorId);
+ void setClipFormat(Qt3DCore::QNodeId animatorId, const ClipFormat &formatIndices);
+ ClipFormat clipFormat(Qt3DCore::QNodeId animatorId);
protected:
ClipResults doBlend(const QVector<ClipResults> &blendData) const override;
@@ -90,7 +90,7 @@ private:
Qt3DCore::QNodeId m_clipId;
QVector<Qt3DCore::QNodeId> m_animatorIds;
- QVector<ComponentIndices> m_formatIndicies;
+ QVector<ClipFormat> m_clipFormats;
};
} // namespace Animation
diff --git a/src/animation/backend/evaluateblendclipanimatorjob.cpp b/src/animation/backend/evaluateblendclipanimatorjob.cpp
index abd50f174..5382b9c92 100644
--- a/src/animation/backend/evaluateblendclipanimatorjob.cpp
+++ b/src/animation/backend/evaluateblendclipanimatorjob.cpp
@@ -103,8 +103,8 @@ void EvaluateBlendClipAnimatorJob::run()
ClipResults rawClipResults = evaluateClipAtPhase(clip, phase);
// Reformat the clip results into the layout used by this animator/blend tree
- ComponentIndices format = valueNode->formatIndices(blendedClipAnimator->peerId());
- ClipResults formattedClipResults = formatClipResults(rawClipResults, format);
+ const ClipFormat format = valueNode->clipFormat(blendedClipAnimator->peerId());
+ ClipResults formattedClipResults = formatClipResults(rawClipResults, format.sourceClipIndices);
valueNode->setClipResults(blendedClipAnimator->peerId(), formattedClipResults);
}
diff --git a/src/animation/backend/evaluateclipanimatorjob.cpp b/src/animation/backend/evaluateclipanimatorjob.cpp
index 90999fd64..15953b83a 100644
--- a/src/animation/backend/evaluateclipanimatorjob.cpp
+++ b/src/animation/backend/evaluateclipanimatorjob.cpp
@@ -75,8 +75,8 @@ void EvaluateClipAnimatorJob::run()
const ClipResults rawClipResults = evaluateClipAtLocalTime(clip, preEvaluationDataForClip.localTime);
// Reformat the clip results into the layout used by this animator/blend tree
- ComponentIndices format = clipAnimator->formatIndices();
- ClipResults formattedClipResults = formatClipResults(rawClipResults, format);
+ const ClipFormat clipFormat = clipAnimator->clipFormat();
+ ClipResults formattedClipResults = formatClipResults(rawClipResults, clipFormat.sourceClipIndices);
if (preEvaluationDataForClip.isFinalFrame)
clipAnimator->setRunning(false);
diff --git a/src/animation/backend/findrunningclipanimatorsjob.cpp b/src/animation/backend/findrunningclipanimatorsjob.cpp
index 16b84359e..291f369f6 100644
--- a/src/animation/backend/findrunningclipanimatorsjob.cpp
+++ b/src/animation/backend/findrunningclipanimatorsjob.cpp
@@ -81,19 +81,20 @@ void FindRunningClipAnimatorsJob::run()
const QVector<ChannelNameAndType> channelNamesAndTypes
= buildRequiredChannelsAndTypes(m_handler, mapper);
- QVector<ComponentIndices> channelComponentIndices
+ const QVector<ComponentIndices> channelComponentIndices
= assignChannelComponentIndices(channelNamesAndTypes);
const AnimationClip *clip = m_handler->animationClipLoaderManager()->lookupResource(clipAnimator->clipId());
Q_ASSERT(clip);
- const ComponentIndices formatIndices = generateClipFormatIndices(channelNamesAndTypes,
- channelComponentIndices,
- clip);
- clipAnimator->setFormatIndices(formatIndices);
+ const ClipFormat format = generateClipFormatIndices(channelNamesAndTypes,
+ channelComponentIndices,
+ clip);
+ clipAnimator->setClipFormat(format);
const QVector<MappingData> mappingData = buildPropertyMappings(channelMappings,
channelNamesAndTypes,
- channelComponentIndices);
+ format.formattedComponentIndices,
+ format.sourceClipMask);
clipAnimator->setMappingData(mappingData);
}
diff --git a/src/animation/backend/skeleton_p.h b/src/animation/backend/skeleton_p.h
index e26e276d9..f1ddb1e81 100644
--- a/src/animation/backend/skeleton_p.h
+++ b/src/animation/backend/skeleton_p.h
@@ -65,22 +65,38 @@ public:
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE;
int jointCount() const { return m_jointLocalPoses.size(); }
+ QString jointName(int jointIndex) const { return m_jointNames.at(jointIndex); }
void setJointScale(int jointIndex, const QVector3D &scale)
{
m_jointLocalPoses[jointIndex].scale = scale;
}
+ QVector3D jointScale(int jointIndex) const
+ {
+ return m_jointLocalPoses[jointIndex].scale;
+ }
+
void setJointRotation(int jointIndex, const QQuaternion &rotation)
{
m_jointLocalPoses[jointIndex].rotation = rotation;
}
+ QQuaternion jointRotation(int jointIndex) const
+ {
+ return m_jointLocalPoses[jointIndex].rotation;
+ }
+
void setJointTranslation(int jointIndex, const QVector3D &translation)
{
m_jointLocalPoses[jointIndex].translation = translation;
}
+ QVector3D jointTranslation(int jointIndex) const
+ {
+ return m_jointLocalPoses[jointIndex].translation;
+ }
+
void sendLocalPoses();
#if defined(QT_BUILD_INTERNAL)