summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer@kdab.com>2017-08-27 11:35:48 +0100
committerSean Harmer <sean.harmer@kdab.com>2017-10-03 09:01:40 +0000
commit2ff5f87bc36fa4d5e15b49a31232bed0dbecfe5e (patch)
tree5e2ec2cbeeacf8609a28ecd3e24ebd3f940af9f9 /src
parent9c951154256734b36328142e1078382dc2d7ae01 (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.cpp105
-rw-r--r--src/animation/backend/animationutils_p.h1
-rw-r--r--src/animation/backend/channelmapping.cpp6
-rw-r--r--src/animation/backend/channelmapping_p.h1
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; }