From 728a32d0e231cee3842e32511a3de6909f5d3181 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Thu, 20 Oct 2011 18:03:37 +1000 Subject: [PATCH] Fix Gravity Now simulates acceleration instead of setting it, and properties are renamed to be consistent with AngleDirection Change-Id: I648aa9122c49b46aa7b7d7796bc25d5bd56bfffe Reviewed-by: Alan Alpert --- .../declarative/particles/affectors/gravity.qml | 2 +- src/declarative/particles/qquickgravity.cpp | 49 ++++++++----------- src/declarative/particles/qquickgravity_p.h | 36 ++++++++++----- .../particles/qquickgravity/tst_qquickgravity.cpp | 10 ++-- 4 files changed, 52 insertions(+), 45 deletions(-) diff --git a/examples/declarative/particles/affectors/gravity.qml b/examples/declarative/particles/affectors/gravity.qml index dc55324..7509b11 100644 --- a/examples/declarative/particles/affectors/gravity.qml +++ b/examples/declarative/particles/affectors/gravity.qml @@ -84,7 +84,7 @@ Item { ParticleSystem { id: sys } Gravity { system: sys - acceleration: 32 + magnitude: 32 angle: ground.rotation + 90 } Emitter { diff --git a/src/declarative/particles/qquickgravity.cpp b/src/declarative/particles/qquickgravity.cpp index 010fcb8..fd2fb92 100644 --- a/src/declarative/particles/qquickgravity.cpp +++ b/src/declarative/particles/qquickgravity.cpp @@ -47,11 +47,11 @@ const qreal CONV = 0.017453292520444443; \qmlclass Gravity QQuickGravityAffector \inqmlmodule QtQuick.Particles 2 \inherits Affector - \brief The Gravity element allows you to set a constant accleration in an angle + \brief The Gravity element allows you to set an accleration in an angle - This element will set the acceleration of all affected particles to a vector of - the specified magnitude in the specified angle. If the angle or acceleration is - not varying, it is more efficient to set the specified acceleration on the Emitter. + This element will accelerate all affected particles to a vector of + the specified magnitude in the specified angle. If the angle and acceleration do + not vary, it is more efficient to set the specified acceleration on the Emitter. This element models the gravity of a massive object whose center of gravity is far away (and thus the gravitational pull is effectively constant @@ -60,45 +60,38 @@ const qreal CONV = 0.017453292520444443; */ /*! - \qmlproperty real QtQuick.Particles2::Gravity::acceleration + \qmlproperty real QtQuick.Particles2::Gravity::magnitude Pixels per second that objects will be accelerated by. */ /*! + \qmlproperty real QtQuick.Particles2::Gravity::acceleration + + Name changed to magnitude, will be removed soon. +*/ +/*! \qmlproperty real QtQuick.Particles2::Gravity::angle Angle of acceleration. */ QQuickGravityAffector::QQuickGravityAffector(QQuickItem *parent) : - QQuickParticleAffector(parent), m_acceleration(-10), m_angle(90), m_xAcc(0), m_yAcc(0) + QQuickParticleAffector(parent), m_magnitude(-10), m_angle(90), m_needRecalc(true) { - connect(this, SIGNAL(accelerationChanged(qreal)), - this, SLOT(recalc())); - connect(this, SIGNAL(angleChanged(qreal)), - this, SLOT(recalc())); - recalc(); -} - -void QQuickGravityAffector::recalc() -{ - qreal theta = m_angle * CONV; - m_xAcc = m_acceleration * cos(theta); - m_yAcc = m_acceleration * sin(theta); } bool QQuickGravityAffector::affectParticle(QQuickParticleData *d, qreal dt) { - Q_UNUSED(dt); - bool changed = false; - if (d->ax != m_xAcc){ - d->setInstantaneousAX(m_xAcc); - changed = true; + if (!m_magnitude) + return false; + if (m_needRecalc) { + m_needRecalc = false; + m_dx = m_magnitude * cos(m_angle * CONV); + m_dy = m_magnitude * sin(m_angle * CONV); } - if (d->ay != m_yAcc){ - d->setInstantaneousAY(m_yAcc); - changed = true; - } - return changed; + + d->setInstantaneousVX(d->curVX() + m_dx*dt); + d->setInstantaneousVY(d->curVY() + m_dy*dt); + return true; } QT_END_NAMESPACE diff --git a/src/declarative/particles/qquickgravity_p.h b/src/declarative/particles/qquickgravity_p.h index b02eb49..65f8e5a 100644 --- a/src/declarative/particles/qquickgravity_p.h +++ b/src/declarative/particles/qquickgravity_p.h @@ -53,13 +53,14 @@ QT_MODULE(Declarative) class QQuickGravityAffector : public QQuickParticleAffector { Q_OBJECT - Q_PROPERTY(qreal acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged) + Q_PROPERTY(qreal magnitude READ magnitude WRITE setMagnitude NOTIFY magnitudeChanged) + Q_PROPERTY(qreal acceleration READ magnitude WRITE setAcceleration NOTIFY magnitudeChanged) Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged) public: explicit QQuickGravityAffector(QQuickItem *parent = 0); - qreal acceleration() const + qreal magnitude() const { - return m_acceleration; + return m_magnitude; } qreal angle() const @@ -70,16 +71,27 @@ protected: virtual bool affectParticle(QQuickParticleData *d, qreal dt); signals: - void accelerationChanged(qreal arg); + void magnitudeChanged(qreal arg); void angleChanged(qreal arg); public slots: void setAcceleration(qreal arg) { - if (m_acceleration != arg) { - m_acceleration = arg; - emit accelerationChanged(arg); + qWarning() << "Gravity::acceleration has been renamed Gravity::magnitude"; + if (m_magnitude != arg) { + m_magnitude = arg; + m_needRecalc = true; + emit magnitudeChanged(arg); + } +} + +void setMagnitude(qreal arg) +{ + if (m_magnitude != arg) { + m_magnitude = arg; + m_needRecalc = true; + emit magnitudeChanged(arg); } } @@ -87,18 +99,18 @@ void setAngle(qreal arg) { if (m_angle != arg) { m_angle = arg; + m_needRecalc = true; emit angleChanged(arg); } } -private slots: - void recalc(); private: - qreal m_acceleration; + qreal m_magnitude; qreal m_angle; - qreal m_xAcc; - qreal m_yAcc; + bool m_needRecalc; + qreal m_dx; + qreal m_dy; }; QT_END_NAMESPACE diff --git a/tests/auto/particles/qquickgravity/tst_qquickgravity.cpp b/tests/auto/particles/qquickgravity/tst_qquickgravity.cpp index a80c5c5..bc8cca8 100644 --- a/tests/auto/particles/qquickgravity/tst_qquickgravity.cpp +++ b/tests/auto/particles/qquickgravity/tst_qquickgravity.cpp @@ -66,12 +66,14 @@ void tst_qquickgravity::test_basic() ensureAnimTime(600, system->m_animation); QVERIFY(extremelyFuzzyCompare(system->groupData[0]->size(), 500, 10)); + float mag = 707.10678f; foreach (QQuickParticleData *d, system->groupData[0]->data) { - if (d->t == -1) - continue; //Particle data unused + if (d->t == -1 || !d->stillAlive()) + continue; //Particle data unused or dead - QCOMPARE(d->ax, 707.10678f); - QCOMPARE(d->ay, 707.10678f); + float t = ((qreal)system->timeInt/1000.0) - d->t; + QVERIFY(extremelyFuzzyCompare(d->vx, t*mag, 20.0f)); + QVERIFY(extremelyFuzzyCompare(d->vy, t*mag, 20.0f)); QCOMPARE(d->lifeSpan, 0.5f); QCOMPARE(d->size, 32.f); QCOMPARE(d->endSize, 32.f); -- 1.7.2.5