summaryrefslogtreecommitdiffstats
path: root/src/animation/frontend
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2019-03-28 08:31:42 +0100
committerPaul Lemire <paul.lemire@kdab.com>2019-04-03 13:00:08 +0000
commitf0f5a2de1da2e05e3587d2a6486687ebbe649339 (patch)
tree80cfacbe85d1a88571c169d38dc495b3df687937 /src/animation/frontend
parent03234c59244ed77cb8eea5fca6b93741f40ca59d (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.h2
-rw-r--r--src/animation/frontend/qchannelmapping.cpp78
-rw-r--r--src/animation/frontend/qchannelmapping_p.h10
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