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 <alan.alpert@nokia.com>
This commit is contained in:
Alan Alpert 2011-10-20 18:03:37 +10:00 committed by Qt by Nokia
parent a06ec0c299
commit 728a32d0e2
4 changed files with 52 additions and 45 deletions

View File

@ -84,7 +84,7 @@ Item {
ParticleSystem { id: sys }
Gravity {
system: sys
acceleration: 32
magnitude: 32
angle: ground.rotation + 90
}
Emitter {

View 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,10 +60,15 @@ 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
@ -71,34 +76,22 @@ const qreal CONV = 0.017453292520444443;
*/
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

View 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

View 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);