Fix Gravity
authorAlan Alpert <alan.alpert@nokia.com>
Thu, 20 Oct 2011 08:03:37 +0000 (18:03 +1000)
committerQt by Nokia <qt-info@nokia.com>
Thu, 3 Nov 2011 05:27:47 +0000 (06:27 +0100)
Now simulates acceleration instead of setting it, and properties are
renamed to be consistent with AngleDirection

Change-Id: I648aa9122c49b46aa7b7d7796bc25d5bd56bfffe
Reviewed-by: Alan Alpert <alan.alpert@nokia.com>
examples/declarative/particles/affectors/gravity.qml
src/declarative/particles/qquickgravity.cpp
src/declarative/particles/qquickgravity_p.h
tests/auto/particles/qquickgravity/tst_qquickgravity.cpp

index dc55324..7509b11 100644 (file)
@@ -84,7 +84,7 @@ Item {
     ParticleSystem { id: sys }
     Gravity {
         system: sys
-        acceleration: 32
+        magnitude: 32
         angle: ground.rotation + 90
     }
     Emitter {
index 010fcb8..fd2fb92 100644 (file)
@@ -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
index b02eb49..65f8e5a 100644 (file)
@@ -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
index a80c5c5..bc8cca8 100644 (file)
@@ -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);