diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2019-03-28 08:31:42 +0100 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2019-04-03 13:00:08 +0000 |
commit | f0f5a2de1da2e05e3587d2a6486687ebbe649339 (patch) | |
tree | 80cfacbe85d1a88571c169d38dc495b3df687937 /src/animation/frontend | |
parent | 03234c59244ed77cb8eea5fca6b93741f40ca59d (diff) |
Animations: handle variable length properties
For that we know determine the expected number of channel components for a
given property in the frontend where we have access to both the type and the
value rather than in the backend using the type only.
Change-Id: I75aca20d43dd1b3db316c303af041acd557c07e4
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/animation/frontend')
-rw-r--r-- | src/animation/frontend/qabstractchannelmapping_p.h | 2 | ||||
-rw-r--r-- | src/animation/frontend/qchannelmapping.cpp | 78 | ||||
-rw-r--r-- | src/animation/frontend/qchannelmapping_p.h | 10 |
3 files changed, 83 insertions, 7 deletions
diff --git a/src/animation/frontend/qabstractchannelmapping_p.h b/src/animation/frontend/qabstractchannelmapping_p.h index 1a1de4ba9..2d77ee265 100644 --- a/src/animation/frontend/qabstractchannelmapping_p.h +++ b/src/animation/frontend/qabstractchannelmapping_p.h @@ -60,7 +60,7 @@ namespace Qt3DAnimation { class QAbstractChannelMapping; -class QAbstractChannelMappingPrivate : public Qt3DCore::QNodePrivate +class Q_AUTOTEST_EXPORT QAbstractChannelMappingPrivate : public Qt3DCore::QNodePrivate { public: QAbstractChannelMappingPrivate(); diff --git a/src/animation/frontend/qchannelmapping.cpp b/src/animation/frontend/qchannelmapping.cpp index 0d9150c50..0dbe68c8c 100644 --- a/src/animation/frontend/qchannelmapping.cpp +++ b/src/animation/frontend/qchannelmapping.cpp @@ -47,6 +47,61 @@ QT_BEGIN_NAMESPACE namespace Qt3DAnimation { +namespace { + +template<typename T> +int componentCountForValue(const T &) +{ + return 0; +} + +template<> +int componentCountForValue<QVector<float>>(const QVector<float> &v) +{ + return v.size(); +} + +template<> +int componentCountForValue<QVariantList>(const QVariantList &v) +{ + return v.size(); +} + + +int componentCountForType(int type, const QVariant &value) +{ + const int vectorOfFloatTypeId = qMetaTypeId<QVector<float>>(); + + if (type == vectorOfFloatTypeId) + return componentCountForValue<QVector<float>>(value.value<QVector<float>>()); + + switch (type) { + case QMetaType::Float: + case QVariant::Double: + return 1; + + case QVariant::Vector2D: + return 2; + + case QVariant::Vector3D: + case QVariant::Color: + return 3; + + case QVariant::Vector4D: + case QVariant::Quaternion: + return 4; + + case QVariant::List: + return componentCountForValue<QVariantList>(value.toList()); + + default: + qWarning() << "Unhandled animation type"; + return 0; + } +} + +} // anonymous + QChannelMappingPrivate::QChannelMappingPrivate() : QAbstractChannelMappingPrivate() , m_channelName() @@ -54,6 +109,7 @@ QChannelMappingPrivate::QChannelMappingPrivate() , m_property() , m_propertyName(nullptr) , m_type(static_cast<int>(QVariant::Invalid)) + , m_componentCount(0) { m_mappingType = QChannelMappingCreatedChangeBase::ChannelMapping; } @@ -63,9 +119,10 @@ QChannelMappingPrivate::QChannelMappingPrivate() Find the type of the property specified on the target node */ -void QChannelMappingPrivate::updatePropertyNameAndType() +void QChannelMappingPrivate::updatePropertyNameTypeAndComponentCount() { int type; + int componentCount = 0; const char *propertyName = nullptr; if (!m_target || m_property.isNull()) { @@ -76,8 +133,8 @@ void QChannelMappingPrivate::updatePropertyNameAndType() QMetaProperty mp = mo->property(propertyIndex); propertyName = mp.name(); type = mp.userType(); + const QVariant currentValue = m_target->property(mp.name()); if (type == QMetaType::QVariant) { - QVariant currentValue = m_target->property(mp.name()); if (currentValue.isValid()) { type = currentValue.userType(); } else { @@ -85,6 +142,7 @@ void QChannelMappingPrivate::updatePropertyNameAndType() "Set a value first in order to be able to determine the type."); } } + componentCount = componentCountForType(type, currentValue); } if (m_type != type) { @@ -98,6 +156,17 @@ void QChannelMappingPrivate::updatePropertyNameAndType() notifyObservers(e); } + if (m_componentCount != componentCount) { + m_componentCount = componentCount; + + // Send update to the backend + Q_Q(QChannelMapping); + auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(q->id()); + e->setPropertyName("componentCount"); + e->setValue(QVariant(m_componentCount)); + notifyObservers(e); + } + if (qstrcmp(m_propertyName, propertyName) != 0) { m_propertyName = propertyName; @@ -178,7 +247,7 @@ void QChannelMapping::setTarget(Qt3DCore::QNode *target) d->registerDestructionHelper(d->m_target, &QChannelMapping::setTarget, d->m_target); emit targetChanged(target); - d->updatePropertyNameAndType(); + d->updatePropertyNameTypeAndComponentCount(); } void QChannelMapping::setProperty(const QString &property) @@ -189,7 +258,7 @@ void QChannelMapping::setProperty(const QString &property) d->m_property = property; emit propertyChanged(property); - d->updatePropertyNameAndType(); + d->updatePropertyNameTypeAndComponentCount(); } Qt3DCore::QNodeCreatedChangeBasePtr QChannelMapping::createNodeCreationChange() const @@ -201,6 +270,7 @@ Qt3DCore::QNodeCreatedChangeBasePtr QChannelMapping::createNodeCreationChange() data.targetId = Qt3DCore::qIdForNode(d->m_target); data.property = d->m_property; data.type = d->m_type; + data.componentCount = d->m_componentCount; data.propertyName = d->m_propertyName; return creationChange; } diff --git a/src/animation/frontend/qchannelmapping_p.h b/src/animation/frontend/qchannelmapping_p.h index b7de3b821..6a3f1afc5 100644 --- a/src/animation/frontend/qchannelmapping_p.h +++ b/src/animation/frontend/qchannelmapping_p.h @@ -50,25 +50,27 @@ #include <Qt3DAnimation/private/qabstractchannelmapping_p.h> #include <Qt3DAnimation/qanimationcallback.h> +#include <QVector> QT_BEGIN_NAMESPACE namespace Qt3DAnimation { -class QChannelMappingPrivate : public QAbstractChannelMappingPrivate +class Q_AUTOTEST_EXPORT QChannelMappingPrivate : public QAbstractChannelMappingPrivate { public: QChannelMappingPrivate(); Q_DECLARE_PUBLIC(QChannelMapping) - void updatePropertyNameAndType(); + void updatePropertyNameTypeAndComponentCount(); QString m_channelName; Qt3DCore::QNode *m_target; QString m_property; const char *m_propertyName; int m_type; + int m_componentCount; }; struct QChannelMappingData @@ -77,6 +79,7 @@ struct QChannelMappingData Qt3DCore::QNodeId targetId; QString property; int type; + int componentCount; const char *propertyName; }; @@ -85,4 +88,7 @@ struct QChannelMappingData QT_END_NAMESPACE +// Used to define the meta type id +Q_DECLARE_METATYPE(QVector<float>) // LCOV_EXCL_LINE + #endif // QT3DANIMATION_QCHANNELMAPPING_P_H |