From def6ae900bea0a6e10e765be5d6a814f6e1b0f7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antti=20M=C3=A4=C3=A4tt=C3=A4?= Date: Fri, 16 Dec 2016 12:58:37 +0200 Subject: Fix autotests Change-Id: If7bd1299c7ccd4f5f40714a45025a40ac164db43 Reviewed-by: Sean Harmer --- src/animation/frontend/qabstractanimation_p.h | 2 +- src/animation/frontend/qanimationcontroller.cpp | 15 ++- src/animation/frontend/qanimationcontroller_p.h | 2 + src/animation/frontend/qkeyframeanimation.cpp | 62 ++++++++----- src/animation/frontend/qkeyframeanimation.h | 12 +-- src/animation/frontend/qkeyframeanimation_p.h | 1 - src/animation/frontend/qmorphinganimation.cpp | 113 ++++++++++++++--------- src/animation/frontend/qmorphinganimation.h | 8 +- src/animation/frontend/qmorphinganimation_p.h | 2 + src/animation/frontend/qvertexblendanimation.cpp | 2 + 10 files changed, 138 insertions(+), 81 deletions(-) diff --git a/src/animation/frontend/qabstractanimation_p.h b/src/animation/frontend/qabstractanimation_p.h index 197d8ab1c..e1c412b01 100644 --- a/src/animation/frontend/qabstractanimation_p.h +++ b/src/animation/frontend/qabstractanimation_p.h @@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE namespace Qt3DAnimation { -class QAbstractAnimationPrivate : public QObjectPrivate +class Q_AUTOTEST_EXPORT QAbstractAnimationPrivate : public QObjectPrivate { public: QAbstractAnimationPrivate(QAbstractAnimation::AnimationType type); diff --git a/src/animation/frontend/qanimationcontroller.cpp b/src/animation/frontend/qanimationcontroller.cpp index 86d9eb537..a735ba7ed 100644 --- a/src/animation/frontend/qanimationcontroller.cpp +++ b/src/animation/frontend/qanimationcontroller.cpp @@ -47,6 +47,7 @@ QAnimationControllerPrivate::QAnimationControllerPrivate() : QObjectPrivate() , m_activeAnimationGroup(0) , m_position(0.0f) + , m_scaledPosition(0.0f) , m_positionScale(1.0f) , m_positionOffset(0.0f) , m_entity(nullptr) @@ -58,10 +59,14 @@ QAnimationControllerPrivate::QAnimationControllerPrivate() void QAnimationControllerPrivate::updatePosition(float position) { m_position = position; - if (m_activeAnimationGroup >= 0 && m_activeAnimationGroup < m_animationGroups.size()) { - const float pos = m_positionScale * position + m_positionOffset; - m_animationGroups[m_activeAnimationGroup]->setPosition(pos); - } + m_scaledPosition = scaledPosition(position); + if (m_activeAnimationGroup >= 0 && m_activeAnimationGroup < m_animationGroups.size()) + m_animationGroups[m_activeAnimationGroup]->setPosition(m_scaledPosition); +} + +float QAnimationControllerPrivate::scaledPosition(float position) const +{ + return m_positionScale * position + m_positionOffset; } QAnimationGroup *QAnimationControllerPrivate::findGroup(const QString &name) @@ -186,7 +191,7 @@ void QAnimationController::setActiveAnimationGroup(int index) void QAnimationController::setPosition(float position) { Q_D(QAnimationController); - if (!qFuzzyCompare(d->m_position, position)) { + if (!qFuzzyCompare(d->m_scaledPosition, d->scaledPosition(position))) { d->updatePosition(position); emit positionChanged(position); } diff --git a/src/animation/frontend/qanimationcontroller_p.h b/src/animation/frontend/qanimationcontroller_p.h index 1c309a183..c06484911 100644 --- a/src/animation/frontend/qanimationcontroller_p.h +++ b/src/animation/frontend/qanimationcontroller_p.h @@ -64,6 +64,7 @@ public: int m_activeAnimationGroup; QVector m_animationGroups; float m_position; + float m_scaledPosition; float m_positionScale; float m_positionOffset; Qt3DCore::QEntity *m_entity; @@ -73,6 +74,7 @@ public: void extractAnimations(); void clearAnimations(); QAnimationGroup *findGroup(const QString &name); + float scaledPosition(float position) const; Q_DECLARE_PUBLIC(QAnimationController) }; diff --git a/src/animation/frontend/qkeyframeanimation.cpp b/src/animation/frontend/qkeyframeanimation.cpp index 2e63e96c8..981437d28 100644 --- a/src/animation/frontend/qkeyframeanimation.cpp +++ b/src/animation/frontend/qkeyframeanimation.cpp @@ -45,7 +45,6 @@ namespace Qt3DAnimation { QKeyframeAnimationPrivate::QKeyframeAnimationPrivate() : QAbstractAnimationPrivate(QAbstractAnimation::KeyframeAnimation) - , m_prevPosition(-1.0f) , m_target(nullptr) , m_minposition(0.0f) , m_maxposition(0.0f) @@ -68,7 +67,7 @@ void QKeyframeAnimation::setFramePositions(const QVector &positions) { Q_D(QKeyframeAnimation); d->m_framePositions = positions; - d->m_prevPosition = -1.0f; + d->m_position = -1.0f; if (d->m_framePositions.size() == 0) { d->m_minposition = d->m_maxposition = 0.0f; return; @@ -116,9 +115,35 @@ QQuaternion lslerp(QQuaternion q1, QQuaternion q2, float t) void QKeyframeAnimationPrivate::calculateFrame(float position) { if (m_target && m_framePositions.size() > 0 - && m_keyframes.size() == m_framePositions.size() - && m_prevPosition != m_position) { - if (m_position >= m_minposition && m_position < m_maxposition) { + && m_keyframes.size() == m_framePositions.size()) { + if (position < m_minposition) { + if (m_startMode == QKeyframeAnimation::None) { + return; + } else if (m_startMode == QKeyframeAnimation::Constant) { + m_target->setRotation(m_keyframes.first()->rotation()); + m_target->setScale3D(m_keyframes.first()->scale3D()); + m_target->setTranslation(m_keyframes.first()->translation()); + return; + } else { + // must be repeat + position = std::fmod(-(position - m_minposition), m_maxposition - m_minposition) + + m_minposition; + } + } else if (position >= m_maxposition) { + if (m_endMode == QKeyframeAnimation::None) { + return; + } else if (m_endMode == QKeyframeAnimation::Constant) { + m_target->setRotation(m_keyframes.last()->rotation()); + m_target->setScale3D(m_keyframes.last()->scale3D()); + m_target->setTranslation(m_keyframes.last()->translation()); + return; + } else { + // must be repeat + position = std::fmod(position - m_minposition, m_maxposition - m_minposition) + + m_minposition; + } + } + if (position >= m_minposition && position < m_maxposition) { for (int i = 0; i < m_framePositions.size() - 1; i++) { if (position >= m_framePositions.at(i) && position < m_framePositions.at(i+1)) { @@ -140,16 +165,7 @@ void QKeyframeAnimationPrivate::calculateFrame(float position) return; } } - } else if (position < m_minposition) { - m_target->setRotation(m_keyframes.first()->rotation()); - m_target->setScale3D(m_keyframes.first()->scale3D()); - m_target->setTranslation(m_keyframes.first()->translation()); - } else { - m_target->setRotation(m_keyframes.last()->rotation()); - m_target->setScale3D(m_keyframes.last()->scale3D()); - m_target->setTranslation(m_keyframes.last()->translation()); } - m_prevPosition = m_position; } } @@ -177,7 +193,7 @@ void QKeyframeAnimation::setTarget(Qt3DCore::QTransform *target) if (d->m_target != target) { d->m_target = target; emit targetChanged(d->m_target); - d->m_prevPosition = -1.0f; + d->m_position = -1.0f; if (target) { d->m_baseScale = target->scale3D(); @@ -199,11 +215,11 @@ QKeyframeAnimation::RepeatMode QKeyframeAnimation::endMode() const return d->m_endMode; } -void QKeyframeAnimation::setEasing(QEasingCurve::Type easing) +void QKeyframeAnimation::setEasing(const QEasingCurve &easing) { Q_D(QKeyframeAnimation); - if (d->m_easing.type() != easing) { - d->m_easing.setType(easing); + if (d->m_easing != easing) { + d->m_easing = easing; emit easingChanged(easing); } } @@ -211,8 +227,10 @@ void QKeyframeAnimation::setEasing(QEasingCurve::Type easing) void QKeyframeAnimation::setTargetName(const QString &name) { Q_D(QKeyframeAnimation); - d->m_targetName = name; - emit targetNameChanged(name); + if (d->m_targetName != name) { + d->m_targetName = name; + emit targetNameChanged(name); + } } void QKeyframeAnimation::setStartMode(QKeyframeAnimation::RepeatMode mode) @@ -245,10 +263,10 @@ QString QKeyframeAnimation::targetName() const return d->m_targetName; } -QEasingCurve::Type QKeyframeAnimation::easing() const +QEasingCurve QKeyframeAnimation::easing() const { Q_D(const QKeyframeAnimation); - return d->m_easing.type(); + return d->m_easing; } Qt3DCore::QTransform *QKeyframeAnimation::target() const diff --git a/src/animation/frontend/qkeyframeanimation.h b/src/animation/frontend/qkeyframeanimation.h index d34f6cfba..19cb192b4 100644 --- a/src/animation/frontend/qkeyframeanimation.h +++ b/src/animation/frontend/qkeyframeanimation.h @@ -55,7 +55,7 @@ class QT3DANIMATIONSHARED_EXPORT QKeyframeAnimation : public QAbstractAnimation Q_OBJECT Q_PROPERTY(QVector framePositions READ framePositions WRITE setFramePositions NOTIFY framePositionsChanged) Q_PROPERTY(Qt3DCore::QTransform *target READ target WRITE setTarget NOTIFY targetChanged) - Q_PROPERTY(QEasingCurve::Type easing READ easing WRITE setEasing NOTIFY easingChanged) + Q_PROPERTY(QEasingCurve easing READ easing WRITE setEasing NOTIFY easingChanged) Q_PROPERTY(QString targetName READ targetName WRITE setTargetName NOTIFY targetNameChanged) Q_PROPERTY(QKeyframeAnimation::RepeatMode startMode READ startMode WRITE setStartMode NOTIFY startModeChanged) Q_PROPERTY(QKeyframeAnimation::RepeatMode endMode READ endMode WRITE setEndMode NOTIFY endModeChanged) @@ -74,7 +74,7 @@ public: QVector framePositions() const; QVector keyframeList() const; Qt3DCore::QTransform *target() const; - QEasingCurve::Type easing() const; + QEasingCurve easing() const; QString targetName() const; RepeatMode startMode() const; RepeatMode endMode() const; @@ -86,7 +86,7 @@ public: public Q_SLOTS: void setFramePositions(const QVector &positions); void setTarget(Qt3DCore::QTransform *target); - void setEasing(QEasingCurve::Type easing); + void setEasing(const QEasingCurve &easing); void setTargetName(const QString &name); void setStartMode(RepeatMode mode); void setEndMode(RepeatMode mode); @@ -94,10 +94,10 @@ public Q_SLOTS: Q_SIGNALS: void framePositionsChanged(const QVector &positions); void targetChanged(Qt3DCore::QTransform *target); - void easingChanged(QEasingCurve::Type easing); + void easingChanged(const QEasingCurve &easing); void targetNameChanged(const QString &name); - void startModeChanged(RepeatMode startMode); - void endModeChanged(RepeatMode endMode); + void startModeChanged(QKeyframeAnimation::RepeatMode startMode); + void endModeChanged(QKeyframeAnimation::RepeatMode endMode); private: void updateAnimation(float position); diff --git a/src/animation/frontend/qkeyframeanimation_p.h b/src/animation/frontend/qkeyframeanimation_p.h index 60fc50fb1..b9b1f8585 100644 --- a/src/animation/frontend/qkeyframeanimation_p.h +++ b/src/animation/frontend/qkeyframeanimation_p.h @@ -63,7 +63,6 @@ public: void calculateFrame(float position); - float m_prevPosition; QVector m_framePositions; QVector m_keyframes; Qt3DCore::QTransform *m_target; diff --git a/src/animation/frontend/qmorphinganimation.cpp b/src/animation/frontend/qmorphinganimation.cpp index 4463f6cbf..4ee20f9cf 100644 --- a/src/animation/frontend/qmorphinganimation.cpp +++ b/src/animation/frontend/qmorphinganimation.cpp @@ -43,13 +43,15 @@ namespace Qt3DAnimation { QMorphingAnimationPrivate::QMorphingAnimationPrivate() : QAbstractAnimationPrivate(QAbstractAnimation::MorphingAnimation) + , m_minposition(0.0f) + , m_maxposition(0.0f) , m_flattened(nullptr) , m_method(QMorphingAnimation::Relative) , m_interpolator(0.0f) , m_target(nullptr) , m_currentTarget(nullptr) { - m_easing.setType(QEasingCurve::InOutCubic); + } QMorphingAnimationPrivate::~QMorphingAnimationPrivate() @@ -64,46 +66,60 @@ void QMorphingAnimationPrivate::updateAnimation(float position) if (!m_target || !m_target->geometry()) return; + QVector relevantValues; + float sum = 0.0f; + float interpolator; m_morphKey.resize(m_morphTargets.size()); - for (int i = 0; i < m_targetPositions.size() - 1; ++i) { - if (position > m_targetPositions.at(i) && position <= m_targetPositions.at(i + 1)) { - float interpolator = (position - m_targetPositions.at(i)) - / (m_targetPositions.at(i + 1) - m_targetPositions.at(i)); - interpolator = m_easing.valueForProgress(interpolator); - float iip = 1.0f - interpolator; - float sum = 0.0f; - QVector relevantValues; - for (int j = 0; j < m_morphTargets.size(); ++j) { - m_morphKey[j] = interpolator * m_weights.at(i + 1)->at(j) - + iip * m_weights.at(i)->at(j); - sum += m_morphKey[j]; - if (!qFuzzyIsNull(m_morphKey[j])) - relevantValues.push_back(j); - } - - if (relevantValues.size() == 0 || qFuzzyIsNull(sum)) { - // only base is used - interpolator = 0.0f; - } else if (relevantValues.size() == 1) { - // one morph target has non-zero weight - setTargetInterpolated(relevantValues[0]); - interpolator = sum; - } else { - // more than one morph target has non-zero weight - // flatten morph targets to one - qWarning() << Q_FUNC_INFO << "Flattening required"; + // calculate morph key + if (position < m_minposition) { + m_morphKey = *m_weights.first(); + } else if (position >= m_maxposition) { + m_morphKey = *m_weights.last(); + } else { + for (int i = 0; i < m_targetPositions.size() - 1; ++i) { + if (position >= m_targetPositions.at(i) && position < m_targetPositions.at(i + 1)) { + interpolator = (position - m_targetPositions.at(i)) + / (m_targetPositions.at(i + 1) - m_targetPositions.at(i)); + interpolator = m_easing.valueForProgress(interpolator); + float iip = 1.0f - interpolator; + + for (int j = 0; j < m_morphTargets.size(); ++j) { + m_morphKey[j] = interpolator * m_weights.at(i + 1)->at(j) + + iip * m_weights.at(i)->at(j); + } } - if (!qFuzzyCompare(interpolator, m_interpolator)) { - if (m_method == QMorphingAnimation::Normalized) - m_interpolator = interpolator; - else - m_interpolator = -interpolator; - emit q->interpolatorChanged(m_interpolator); - } - return; } } + + // check relevant values + for (int j = 0; j < m_morphKey.size(); ++j) { + sum += m_morphKey[j]; + if (!qFuzzyIsNull(m_morphKey[j])) + relevantValues.push_back(j); + } + + if (relevantValues.size() == 0 || qFuzzyIsNull(sum)) { + // only base is used + interpolator = 0.0f; + } else if (relevantValues.size() == 1) { + // one morph target has non-zero weight + setTargetInterpolated(relevantValues[0]); + interpolator = sum; + } else { + // more than one morph target has non-zero weight + // flatten morph targets to one + qWarning() << Q_FUNC_INFO << "Flattening required"; + } + + // Relative method uses negative interpolator, normalized uses positive + if (m_method == QMorphingAnimation::Relative) + interpolator = -interpolator; + + if (!qFuzzyCompare(interpolator, m_interpolator)) { + m_interpolator = interpolator; + emit q->interpolatorChanged(m_interpolator); + } } void QMorphingAnimationPrivate::setTargetInterpolated(int morphTarget) @@ -170,10 +186,10 @@ QMorphingAnimation::Method QMorphingAnimation::method() const return d->m_method; } -QEasingCurve::Type QMorphingAnimation::easing() const +QEasingCurve QMorphingAnimation::easing() const { Q_D(const QMorphingAnimation); - return d->m_easing.type(); + return d->m_easing; } void QMorphingAnimation::setMorphTargets(const QVector &targets) @@ -181,19 +197,25 @@ void QMorphingAnimation::setMorphTargets(const QVectorm_morphTargets = targets; d->m_attributeNames = targets[0]->attributeNames(); + d->m_position = -1.0f; } void QMorphingAnimation::addMorphTarget(Qt3DAnimation::QMorphTarget *target) { Q_D(QMorphingAnimation); - if (!d->m_morphTargets.contains(target)) + if (!d->m_morphTargets.contains(target)) { d->m_morphTargets.push_back(target); + d->m_position = -1.0f; + if (d->m_attributeNames.empty()) + d->m_attributeNames = target->attributeNames(); + } } void QMorphingAnimation::removeMorphTarget(Qt3DAnimation::QMorphTarget *target) { Q_D(QMorphingAnimation); d->m_morphTargets.removeAll(target); + d->m_position = -1.0f; } void QMorphingAnimation::setTargetPositions(const QVector &targetPositions) @@ -201,6 +223,8 @@ void QMorphingAnimation::setTargetPositions(const QVector &targetPosition Q_D(QMorphingAnimation); d->m_targetPositions = targetPositions; emit targetPositionsChanged(targetPositions); + d->m_minposition = targetPositions.first(); + d->m_maxposition = targetPositions.last(); setDuration(d->m_targetPositions.last()); if (d->m_weights.size() < targetPositions.size()) { d->m_weights.resize(targetPositions.size()); @@ -209,12 +233,14 @@ void QMorphingAnimation::setTargetPositions(const QVector &targetPosition d->m_weights[i] = new QVector(); } } + d->m_position = -1.0f; } void QMorphingAnimation::setTarget(Qt3DRender::QGeometryRenderer *target) { Q_D(QMorphingAnimation); if (d->m_target != target) { + d->m_position = -1.0f; d->m_target = target; emit targetChanged(target); } @@ -228,6 +254,7 @@ void QMorphingAnimation::setWeights(int positionIndex, const QVector &wei if (d->m_weights[positionIndex] == nullptr) d->m_weights[positionIndex] = new QVector(); *d->m_weights[positionIndex] = weights; + d->m_position = -1.0f; } QVector QMorphingAnimation::getWeights(int positionIndex) @@ -256,15 +283,17 @@ void QMorphingAnimation::setMethod(QMorphingAnimation::Method method) Q_D(QMorphingAnimation); if (d->m_method != method) { d->m_method = method; + d->m_position = -1.0f; emit methodChanged(method); } } -void QMorphingAnimation::setEasing(QEasingCurve::Type easing) +void QMorphingAnimation::setEasing(const QEasingCurve &easing) { Q_D(QMorphingAnimation); - if (d->m_easing.type() != easing) { - d->m_easing.setType(easing); + if (d->m_easing != easing) { + d->m_easing = easing; + d->m_position = -1.0f; emit easingChanged(easing); } } diff --git a/src/animation/frontend/qmorphinganimation.h b/src/animation/frontend/qmorphinganimation.h index b83288d04..2944fad91 100644 --- a/src/animation/frontend/qmorphinganimation.h +++ b/src/animation/frontend/qmorphinganimation.h @@ -59,7 +59,7 @@ class QT3DANIMATIONSHARED_EXPORT QMorphingAnimation : public QAbstractAnimation Q_PROPERTY(Qt3DRender::QGeometryRenderer *target READ target WRITE setTarget NOTIFY targetChanged) Q_PROPERTY(QString targetName READ targetName WRITE setTargetName NOTIFY targetNameChanged) Q_PROPERTY(QMorphingAnimation::Method method READ method WRITE setMethod NOTIFY methodChanged) - Q_PROPERTY(QEasingCurve::Type easing READ easing WRITE setEasing NOTIFY easingChanged) + Q_PROPERTY(QEasingCurve easing READ easing WRITE setEasing NOTIFY easingChanged) public: enum Method @@ -76,7 +76,7 @@ public: Qt3DRender::QGeometryRenderer *target() const; QString targetName() const; QMorphingAnimation::Method method() const; - QEasingCurve::Type easing() const; + QEasingCurve easing() const; void setMorphTargets(const QVector &targets); void addMorphTarget(Qt3DAnimation::QMorphTarget *target); @@ -92,7 +92,7 @@ public Q_SLOTS: void setTarget(Qt3DRender::QGeometryRenderer *target); void setTargetName(const QString name); void setMethod(QMorphingAnimation::Method method); - void setEasing(QEasingCurve::Type easing); + void setEasing(const QEasingCurve &easing); Q_SIGNALS: void targetPositionsChanged(const QVector &targetPositions); @@ -100,7 +100,7 @@ Q_SIGNALS: void targetChanged(Qt3DRender::QGeometryRenderer *target); void targetNameChanged(const QString &name); void methodChanged(QMorphingAnimation::Method method); - void easingChanged(QEasingCurve::Type easing); + void easingChanged(const QEasingCurve &easing); private: diff --git a/src/animation/frontend/qmorphinganimation_p.h b/src/animation/frontend/qmorphinganimation_p.h index d9a04343c..c306f3309 100644 --- a/src/animation/frontend/qmorphinganimation_p.h +++ b/src/animation/frontend/qmorphinganimation_p.h @@ -67,6 +67,8 @@ public: void updateAnimation(float position); void setTargetInterpolated(int morphTarget); + float m_minposition; + float m_maxposition; QVector m_targetPositions; QVector*> m_weights; QVector m_morphKey; diff --git a/src/animation/frontend/qvertexblendanimation.cpp b/src/animation/frontend/qvertexblendanimation.cpp index 0bad72abf..8eb0e5751 100644 --- a/src/animation/frontend/qvertexblendanimation.cpp +++ b/src/animation/frontend/qvertexblendanimation.cpp @@ -44,6 +44,8 @@ namespace Qt3DAnimation { QVertexBlendAnimationPrivate::QVertexBlendAnimationPrivate() : QAbstractAnimationPrivate(QAbstractAnimation::VertexBlendAnimation) + , m_interpolator(0.0f) + , m_target(nullptr) , m_currentBase(nullptr) , m_currentTarget(nullptr) { -- cgit v1.2.3