diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2017-08-27 11:35:48 +0100 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2017-10-03 09:01:40 +0000 |
commit | 2ff5f87bc36fa4d5e15b49a31232bed0dbecfe5e (patch) | |
tree | 5e2ec2cbeeacf8609a28ecd3e24ebd3f940af9f9 /src | |
parent | 9c951154256734b36328142e1078382dc2d7ae01 (diff) |
Extend buildPropertyMappings to support skeleton mapping use case
Change-Id: I2eaf725022f5044d7faf647f8789e73de969d49b
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/animation/backend/animationutils.cpp | 105 | ||||
-rw-r--r-- | src/animation/backend/animationutils_p.h | 1 | ||||
-rw-r--r-- | src/animation/backend/channelmapping.cpp | 6 | ||||
-rw-r--r-- | src/animation/backend/channelmapping_p.h | 1 |
4 files changed, 92 insertions, 21 deletions
diff --git a/src/animation/backend/animationutils.cpp b/src/animation/backend/animationutils.cpp index 4e90d3c1d..83a9a8426 100644 --- a/src/animation/backend/animationutils.cpp +++ b/src/animation/backend/animationutils.cpp @@ -342,37 +342,100 @@ QVector<AnimationCallbackAndValue> prepareCallbacks(const QVector<MappingData> & return callbacks; } +// TODO: Optimize this even more by combining the work done here with the functions: +// buildRequiredChannelsAndTypes() and assignChannelComponentIndices(). We are +// currently repeating the iteration over mappings and extracting/generating +// channel names, types and joint indices. QVector<MappingData> buildPropertyMappings(const QVector<ChannelMapping*> &channelMappings, const QVector<ChannelNameAndType> &channelNamesAndTypes, const QVector<ComponentIndices> &channelComponentIndices) { + // Accumulate the required number of mappings + int maxMappingDatas = 0; + for (const auto mapping : channelMappings) { + switch (mapping->mappingType()) { + case ChannelMapping::ChannelMappingType: + case ChannelMapping::CallbackMappingType: + ++maxMappingDatas; + break; + + case ChannelMapping::SkeletonMappingType: { + Skeleton *skeleton = mapping->skeleton(); + maxMappingDatas += 3 * skeleton->jointCount(); // S, R, T + break; + } + } + } QVector<MappingData> mappingDataVec; - mappingDataVec.reserve(channelMappings.size()); + mappingDataVec.reserve(maxMappingDatas); // Iterate over the mappings for (const auto mapping : channelMappings) { - // Populate the data we need, easy stuff first - MappingData mappingData; - mappingData.targetId = mapping->targetId(); - mappingData.propertyName = mapping->propertyName(); - mappingData.type = mapping->type(); - mappingData.callback = mapping->callback(); - mappingData.callbackFlags = mapping->callbackFlags(); - - if (mappingData.type == static_cast<int>(QVariant::Invalid)) { - qWarning() << "Unknown type for node id =" << mappingData.targetId - << "and property =" << mapping->property() - << "and callback =" << mapping->callback(); - continue; + switch (mapping->mappingType()) { + case ChannelMapping::ChannelMappingType: + case ChannelMapping::CallbackMappingType: { + // Populate the data we need, easy stuff first + MappingData mappingData; + mappingData.targetId = mapping->targetId(); + mappingData.propertyName = mapping->propertyName(); + mappingData.type = mapping->type(); + mappingData.callback = mapping->callback(); + mappingData.callbackFlags = mapping->callbackFlags(); + + if (mappingData.type == static_cast<int>(QVariant::Invalid)) { + qWarning() << "Unknown type for node id =" << mappingData.targetId + << "and property =" << mapping->property() + << "and callback =" << mapping->callback(); + continue; + } + + // Try to find matching channel name and type + const ChannelNameAndType nameAndType = { mapping->channelName(), mapping->type() }; + const int index = channelNamesAndTypes.indexOf(nameAndType); + if (index != -1) { + // We got one! + mappingData.channelIndices = channelComponentIndices[index]; + mappingDataVec.push_back(mappingData); + } + break; } - // Try to find matching channel name and type - const ChannelNameAndType nameAndType = { mapping->channelName(), mapping->type() }; - const int index = channelNamesAndTypes.indexOf(nameAndType); - if (index != -1) { - // We got one! - mappingData.channelIndices = channelComponentIndices[index]; - mappingDataVec.push_back(mappingData); + 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) } }; + const QHash<QString, const char *> channelNameToPropertyName + = { { QLatin1String("Location"), "translation" }, + { QLatin1String("Rotation"), "rotation" }, + { QLatin1String("Scale"), "scale" } }; + Skeleton *skeleton = mapping->skeleton(); + const int jointCount = skeleton->jointCount(); + for (int jointIndex = 0; jointIndex < jointCount; ++jointIndex) { + // Populate the data we need, easy stuff first + MappingData mappingData; + mappingData.targetId = mapping->skeletonId(); + + const int propertyCount = jointProperties.size(); + for (int propertyIndex = 0; propertyIndex < propertyCount; ++propertyIndex) { + // Get the name, type and index + ChannelNameAndType nameAndType = jointProperties[propertyIndex]; + nameAndType.jointIndex = jointIndex; + + // Try to find matching channel name and type + const int index = channelNamesAndTypes.indexOf(nameAndType); + if (index != -1) { + // We got one! + mappingData.propertyName = channelNameToPropertyName[nameAndType.name]; + mappingData.type = nameAndType.type; + mappingData.channelIndices = channelComponentIndices[index]; + mappingData.jointIndex = jointIndex; + mappingDataVec.push_back(mappingData); + } + } + } + break; + } } } diff --git a/src/animation/backend/animationutils_p.h b/src/animation/backend/animationutils_p.h index cf21c448d..5d84f54b0 100644 --- a/src/animation/backend/animationutils_p.h +++ b/src/animation/backend/animationutils_p.h @@ -72,6 +72,7 @@ typedef QVector<int> ComponentIndices; struct MappingData { Qt3DCore::QNodeId targetId; + int jointIndex = -1; const char *propertyName; QAnimationCallback *callback; QAnimationCallback::Flags callbackFlags; diff --git a/src/animation/backend/channelmapping.cpp b/src/animation/backend/channelmapping.cpp index 417c10a1a..4c263edba 100644 --- a/src/animation/backend/channelmapping.cpp +++ b/src/animation/backend/channelmapping.cpp @@ -40,6 +40,7 @@ #include <Qt3DAnimation/private/qskeletonmapping_p.h> #include <Qt3DAnimation/private/animationlogging_p.h> #include <Qt3DAnimation/private/qchannelmappingcreatedchange_p.h> +#include <Qt3DAnimation/private/managers_p.h> #include <Qt3DCore/qpropertyupdatedchange.h> QT_BEGIN_NAMESPACE @@ -137,6 +138,11 @@ void ChannelMapping::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) QBackendNode::sceneChangeEvent(e); } +Skeleton *ChannelMapping::skeleton() const +{ + return m_handler->skeletonManager()->lookupResource(m_skeletonId); +} + } // namespace Animation } // namespace Qt3DAnimation diff --git a/src/animation/backend/channelmapping_p.h b/src/animation/backend/channelmapping_p.h index 5cebbaf55..72b9975ef 100644 --- a/src/animation/backend/channelmapping_p.h +++ b/src/animation/backend/channelmapping_p.h @@ -101,6 +101,7 @@ public: void setSkeletonId(Qt3DCore::QNodeId skeletonId) { m_skeletonId = skeletonId; } Qt3DCore::QNodeId skeletonId() const { return m_skeletonId; } + Skeleton *skeleton() const; void setMappingType(MappingType mappingType) { m_mappingType = mappingType; } MappingType mappingType() const { return m_mappingType; } |