diff options
author | Sean Harmer <sean.harmer@kdab.com> | 2017-08-26 14:53:20 +0100 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2017-09-02 18:10:31 +0000 |
commit | bbb9b6c25650fc17868c47d9c82501f9068dd158 (patch) | |
tree | e70e6658ad0efc1f654a1045caa5a39d3c6a31fa | |
parent | 9a14388cd5f3e509658e8ec1a1c582f9215f53ca (diff) |
Extend buildRequiredChannelsAndTypes to handle indexed targets
Specifically, this is needed for animating joints of a skeleton. If
we later find other such indexed targets we can rename the jointIndex
member to something more generic. For now this naming helps with
reasoning as there are many kinds of index in play within the animation
system.
Change-Id: I348f255ee622aa11f26e5a3c1055bf5c12071c17
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
-rw-r--r-- | src/animation/backend/animationutils.cpp | 42 | ||||
-rw-r--r-- | src/animation/backend/animationutils_p.h | 19 | ||||
-rw-r--r-- | src/animation/backend/channelmapping.cpp | 3 | ||||
-rw-r--r-- | src/animation/backend/channelmapping_p.h | 11 | ||||
-rw-r--r-- | src/animation/backend/skeleton_p.h | 7 | ||||
-rw-r--r-- | tests/auto/animation/animationutils/tst_animationutils.cpp | 42 |
6 files changed, 118 insertions, 6 deletions
diff --git a/src/animation/backend/animationutils.cpp b/src/animation/backend/animationutils.cpp index e33a31b7b..8fe31bc24 100644 --- a/src/animation/backend/animationutils.cpp +++ b/src/animation/backend/animationutils.cpp @@ -458,12 +458,44 @@ QVector<ChannelNameAndType> buildRequiredChannelsAndTypes(Handler *handler, ChannelMapping *mapping = mappingManager->lookupResource(mappingId); Q_ASSERT(mapping); - // Get the name and type - const ChannelNameAndType nameAndType{ mapping->channelName(), mapping->type() }; + switch (mapping->mappingType()) { + case ChannelMapping::ChannelMappingType: + case ChannelMapping::CallbackMappingType: { + // Get the name and type + const ChannelNameAndType nameAndType{ mapping->channelName(), mapping->type() }; - // Add if not already contained - if (!namesAndTypes.contains(nameAndType)) - namesAndTypes.push_back(nameAndType); + // Add if not already contained + if (!namesAndTypes.contains(nameAndType)) + namesAndTypes.push_back(nameAndType); + + break; + } + + case ChannelMapping::SkeletonMappingType: { + // 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) } }; + Skeleton *skeleton = handler->skeletonManager()->lookupResource(mapping->skeletonId()); + const int jointCount = skeleton->jointCount(); + for (int jointIndex = 0; jointIndex < jointCount; ++jointIndex) { + 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; + + // Add if not already contained + if (!namesAndTypes.contains(nameAndType)) + namesAndTypes.push_back(nameAndType); + } + } + + break; + } + } } return namesAndTypes; diff --git a/src/animation/backend/animationutils_p.h b/src/animation/backend/animationutils_p.h index bcc50fce2..7fcd9ead5 100644 --- a/src/animation/backend/animationutils_p.h +++ b/src/animation/backend/animationutils_p.h @@ -100,10 +100,27 @@ struct ChannelNameAndType { QString name; int type; + int jointIndex; + + static const int invalidIndex = -1; + + ChannelNameAndType() + : name() + , type(-1) + , jointIndex(-1) + {} + + ChannelNameAndType(const QString &_name, int _type, int _jointIndex = invalidIndex) + : name(_name) + , type(_type) + , jointIndex(_jointIndex) + {} bool operator==(const ChannelNameAndType &rhs) const { - return name == rhs.name && type == rhs.type; + return name == rhs.name + && type == rhs.type + && jointIndex == rhs.jointIndex; } }; diff --git a/src/animation/backend/channelmapping.cpp b/src/animation/backend/channelmapping.cpp index bf5be8383..417c10a1a 100644 --- a/src/animation/backend/channelmapping.cpp +++ b/src/animation/backend/channelmapping.cpp @@ -74,6 +74,7 @@ void ChannelMapping::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePt m_propertyName = data.propertyName; m_callback = data.callback; m_callbackFlags = data.callbackFlags; + m_mappingType = ChannelMappingType; break; } @@ -81,11 +82,13 @@ void ChannelMapping::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePt const auto typedChange = qSharedPointerCast<QChannelMappingCreatedChange<QSkeletonMappingData>>(change); const auto &data = typedChange->data; m_skeletonId = data.skeletonId; + m_mappingType = SkeletonMappingType; break; } case QChannelMappingCreatedChangeBase::CallbackMapping: { // TODO: Refactor callback support out of QChannelMapping and into its own type + m_mappingType = CallbackMappingType; break; } } diff --git a/src/animation/backend/channelmapping_p.h b/src/animation/backend/channelmapping_p.h index 1be89cc88..5cebbaf55 100644 --- a/src/animation/backend/channelmapping_p.h +++ b/src/animation/backend/channelmapping_p.h @@ -66,6 +66,12 @@ class Handler; class Q_AUTOTEST_EXPORT ChannelMapping : public BackendNode { public: + enum MappingType { + ChannelMappingType = 0, + SkeletonMappingType, + CallbackMappingType + }; + ChannelMapping(); void cleanup(); @@ -96,6 +102,9 @@ public: void setSkeletonId(Qt3DCore::QNodeId skeletonId) { m_skeletonId = skeletonId; } Qt3DCore::QNodeId skeletonId() const { return m_skeletonId; } + void setMappingType(MappingType mappingType) { m_mappingType = mappingType; } + MappingType mappingType() const { return m_mappingType; } + private: void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) Q_DECL_FINAL; @@ -112,6 +121,8 @@ private: // Properties from QSkeletonMapping Qt3DCore::QNodeId m_skeletonId; + + MappingType m_mappingType; }; } // namespace Animation diff --git a/src/animation/backend/skeleton_p.h b/src/animation/backend/skeleton_p.h index 0674a28a1..19da98261 100644 --- a/src/animation/backend/skeleton_p.h +++ b/src/animation/backend/skeleton_p.h @@ -64,7 +64,14 @@ public: void cleanup(); void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE; + int jointCount() const { return m_jointLocalPoses.size(); } + #if defined(QT_BUILD_INTERNAL) + void setJointCount(int jointCount) + { + m_jointNames.resize(jointCount); + m_jointLocalPoses.resize(jointCount); + } void setJointNames(const QVector<QString> &names) { m_jointNames = names; } QVector<QString> jointNames() const { return m_jointNames; } void setJointLocalPoses(const QVector<Qt3DCore::Sqt> &localPoses) { m_jointLocalPoses = localPoses; } diff --git a/tests/auto/animation/animationutils/tst_animationutils.cpp b/tests/auto/animation/animationutils/tst_animationutils.cpp index 14181b893..ae68381f0 100644 --- a/tests/auto/animation/animationutils/tst_animationutils.cpp +++ b/tests/auto/animation/animationutils/tst_animationutils.cpp @@ -154,6 +154,18 @@ public: channelMapping->setPropertyName(propertyName); channelMapping->setChannelName(channelName); channelMapping->setType(type); + channelMapping->setMappingType(ChannelMapping::ChannelMappingType); + return channelMapping; + } + + ChannelMapping *createChannelMapping(Handler *handler, + const Qt3DCore::QNodeId skeletonId) + { + auto channelMappingId = Qt3DCore::QNodeId::createId(); + ChannelMapping *channelMapping = handler->channelMappingManager()->getOrCreateResource(channelMappingId); + setPeerId(channelMapping, channelMappingId); + channelMapping->setSkeletonId(skeletonId); + channelMapping->setMappingType(ChannelMapping::SkeletonMappingType); return channelMapping; } @@ -247,6 +259,15 @@ public: return node; } + Skeleton *createSkeleton(Handler *handler, int jointCount) + { + auto skeletonId = Qt3DCore::QNodeId::createId(); + Skeleton *skeleton = handler->skeletonManager()->getOrCreateResource(skeletonId); + setPeerId(skeleton, skeletonId); + skeleton->setJointCount(jointCount); + return skeleton; + } + private Q_SLOTS: void checkBuildPropertyMappings_data() { @@ -2509,6 +2530,27 @@ private Q_SLOTS: QTest::addRow("Multiple channels with repeats") << handler << channelMapper << expectedResults; } + + { + auto handler = new Handler(); + const int jointCount = 10; + auto skeleton = createSkeleton(handler, jointCount); + auto channelMapping = createChannelMapping(handler, skeleton->peerId()); + QVector<ChannelMapping *> channelMappings; + channelMappings.push_back(channelMapping); + + auto channelMapper = createChannelMapper(handler, + QVector<Qt3DCore::QNodeId>() << channelMapping->peerId()); + + QVector<ChannelNameAndType> expectedResults; + for (int i = 0; i < jointCount; ++i) { + expectedResults.push_back({ QLatin1String("Location"), static_cast<int>(QVariant::Vector3D), i }); + expectedResults.push_back({ QLatin1String("Rotation"), static_cast<int>(QVariant::Quaternion), i }); + expectedResults.push_back({ QLatin1String("Scale"), static_cast<int>(QVariant::Vector3D), i }); + } + + QTest::addRow("Skeleton, 10 joints") << handler << channelMapper << expectedResults; + } } void checkBuildRequiredChannelsAndTypes() |