diff options
author | Liang Qi <liang.qi@qt.io> | 2018-01-20 22:31:32 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2018-01-20 22:31:32 +0100 |
commit | fac6dcc70de922dc3f3dd105e9d725092e6fd808 (patch) | |
tree | 9930923372c7538a36929abcc3d0adad1b4c0b55 /src/animation | |
parent | cdb9131eda64cf98fbb2f801c901591c1b09d9ef (diff) | |
parent | 44aeb43834675a4d6b19bee88e267464ca7ad1f4 (diff) |
Merge remote-tracking branch 'origin/5.10' into dev
Change-Id: If94c3e34550fa45ec2df47f813ac7aa22c1de2b1
Diffstat (limited to 'src/animation')
-rw-r--r-- | src/animation/backend/animationutils.cpp | 140 | ||||
-rw-r--r-- | src/animation/backend/animationutils_p.h | 112 | ||||
-rw-r--r-- | src/animation/backend/buildblendtreesjob.cpp | 42 | ||||
-rw-r--r-- | src/animation/backend/clipanimator.cpp | 2 | ||||
-rw-r--r-- | src/animation/backend/clipanimator_p.h | 6 | ||||
-rw-r--r-- | src/animation/backend/clipblendvalue.cpp | 12 | ||||
-rw-r--r-- | src/animation/backend/clipblendvalue_p.h | 6 | ||||
-rw-r--r-- | src/animation/backend/evaluateblendclipanimatorjob.cpp | 4 | ||||
-rw-r--r-- | src/animation/backend/evaluateclipanimatorjob.cpp | 4 | ||||
-rw-r--r-- | src/animation/backend/findrunningclipanimatorsjob.cpp | 13 | ||||
-rw-r--r-- | src/animation/backend/skeleton_p.h | 16 |
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) |