From bc9eae90c098b0080e65b4e553b5c34f040c9382 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 18 May 2018 13:28:43 +0200 Subject: Ensure animated color components are in range [0, 1] ...and never very slightly above 1. Change-Id: I9ba17d75a383c3f2a76464f59db471eb12b045dc Reviewed-by: Christian Stromme --- src/runtime/q3dsanimationmanager.cpp | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'src/runtime/q3dsanimationmanager.cpp') diff --git a/src/runtime/q3dsanimationmanager.cpp b/src/runtime/q3dsanimationmanager.cpp index 9c8eadb..a7cc96b 100644 --- a/src/runtime/q3dsanimationmanager.cpp +++ b/src/runtime/q3dsanimationmanager.cpp @@ -217,6 +217,8 @@ public: void valueChanged(const QVariant &value) override; private: + QVariant stabilizeAnimatedValue(const QVariant &value, Q3DS::PropertyType type); + Q3DSGraphObject *m_target; Q3DSAnimationManager::Animatable m_animMeta; Q3DSAnimationManager *m_animationManager; @@ -229,12 +231,27 @@ void Q3DSAnimationCallback::valueChanged(const QVariant &value) // invoked once per frame. Q3DSAnimationManager::AnimationValueChange change; - change.value = value; + change.value = stabilizeAnimatedValue(value, m_animMeta.type); change.name = m_animMeta.name; change.setter = m_animMeta.setter; m_animationManager->queueChange(m_target, change); } +QVariant Q3DSAnimationCallback::stabilizeAnimatedValue(const QVariant &value, Q3DS::PropertyType type) +{ + if (type == Q3DS::Color && value.type() == QVariant::Vector3D) { + const QVector3D v = value.value(); + // rgb is already in range [0, 1] but let's make sure the 0 and 1 are really 0 and 1. + // This avoids confusing QColor when qFuzzyCompare(r, 1.0f) && r > 1.0f + const float r = qBound(0.0f, v.x(), 1.0f); + const float g = qBound(0.0f, v.y(), 1.0f); + const float b = qBound(0.0f, v.z(), 1.0f); + return QVariant::fromValue(QColor::fromRgbF(qreal(r), qreal(g), qreal(b))); + } + + return value; +} + static int componentSuffixToIndex(const QString &s) { if (s == QStringLiteral("x")) @@ -483,12 +500,21 @@ void Q3DSAnimationManager::updateAnimationHelper(const AnimationTrackListMapchannel); // Figure out the QVariant/QMetaType type enum value. - const int type = Q3DS::animatablePropertyTypeToMetaType(chIt->meta.type); + int type = Q3DS::animatablePropertyTypeToMetaType(chIt->meta.type); if (type == QVariant::Invalid) { qWarning("Cannot map channel type for animated property %s", qPrintable(channelName)); continue; } + // Workaround for QColor::fromRgbF() warning and generating invalid + // colors when some component is very slightly over 1.0. Due to the + // Qt 3D animation fw or QVariant or something else, we get + // sometimes such results. We can handle this in our side but we + // cannot let Qt 3D do the QColor creation. So pretend we have a + // QVector3D instead. This will be 'reversed' in stabilizeAnimatedValue(). + if (type == QVariant::Color) + type = QVariant::Vector3D; + // Create a mapping with a custom callback. QScopedPointer mapping(new Qt3DAnimation::QCallbackMapping); mapping->setChannelName(channelName); -- cgit v1.2.3