aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/particles/qquickcustomaffector.cpp46
-rw-r--r--src/particles/qquickparticleaffector.cpp30
-rw-r--r--src/particles/qquickparticleaffector_p.h5
-rw-r--r--tests/auto/particles/qquickcustomaffector/data/affectedSignal.qml90
-rw-r--r--tests/auto/particles/qquickcustomaffector/tst_qquickcustomaffector.cpp14
5 files changed, 149 insertions, 36 deletions
diff --git a/src/particles/qquickcustomaffector.cpp b/src/particles/qquickcustomaffector.cpp
index 788e2446b4..72b1536c54 100644
--- a/src/particles/qquickcustomaffector.cpp
+++ b/src/particles/qquickcustomaffector.cpp
@@ -108,7 +108,12 @@ bool QQuickCustomAffector::isAffectConnected()
void QQuickCustomAffector::affectSystem(qreal dt)
{
- if (!isAffectConnected()) {
+ //Acts a bit differently, just emits affected for everyone it might affect, when the only thing is connecting to affected(x,y)
+ bool justAffected = (m_acceleration == &m_nullVector
+ && m_speed == &m_nullVector
+ && m_position == &m_nullVector
+ && isAffectedConnected());
+ if (!isAffectConnected() && !justAffected) {
QQuickParticleAffector::affectSystem(dt);
return;
}
@@ -126,6 +131,15 @@ void QQuickCustomAffector::affectSystem(qreal dt)
if (toAffect.isEmpty())
return;
+ if (justAffected) {
+ foreach (QQuickParticleData* d, toAffect) {//Not postAffect to avoid saying the particle changed
+ if (m_onceOff)
+ m_onceOffed << qMakePair(d->group, d->index);
+ emit affected(d->curX(), d->curY());
+ }
+ return;
+ }
+
if (m_onceOff)
dt = 1.0;
@@ -167,24 +181,30 @@ bool QQuickCustomAffector::affectParticle(QQuickParticleData *d, qreal dt)
if (m_acceleration != &m_nullVector){
QPointF pos = m_acceleration->sample(curPos);
+ QPointF curAcc = QPointF(d->curAX(), d->curAY());
if (m_relative) {
pos *= dt;
- pos += QPointF(d->curAX(), d->curAY());
+ pos += curAcc;
+ }
+ if (pos != curAcc) {
+ d->setInstantaneousAX(pos.x());
+ d->setInstantaneousAY(pos.y());
+ changed = true;
}
- d->setInstantaneousAX(pos.x());
- d->setInstantaneousAY(pos.y());
- changed = true;
}
if (m_speed != &m_nullVector){
QPointF pos = m_speed->sample(curPos);
+ QPointF curVel = QPointF(d->curVX(), d->curVY());
if (m_relative) {
pos *= dt;
- pos += QPointF(d->curVX(), d->curVY());
+ pos += curVel;
+ }
+ if (pos != curVel) {
+ d->setInstantaneousVX(pos.x());
+ d->setInstantaneousVY(pos.y());
+ changed = true;
}
- d->setInstantaneousVX(pos.x());
- d->setInstantaneousVY(pos.y());
- changed = true;
}
if (m_position != &m_nullVector){
@@ -193,9 +213,11 @@ bool QQuickCustomAffector::affectParticle(QQuickParticleData *d, qreal dt)
pos *= dt;
pos += curPos;
}
- d->setInstantaneousX(pos.x());
- d->setInstantaneousY(pos.y());
- changed = true;
+ if (pos != curPos) {
+ d->setInstantaneousX(pos.x());
+ d->setInstantaneousY(pos.y());
+ changed = true;
+ }
}
return changed;
diff --git a/src/particles/qquickparticleaffector.cpp b/src/particles/qquickparticleaffector.cpp
index 471484e287..978c53e9a2 100644
--- a/src/particles/qquickparticleaffector.cpp
+++ b/src/particles/qquickparticleaffector.cpp
@@ -114,30 +114,16 @@ QT_BEGIN_NAMESPACE
non-rectangular area.
*/
/*!
- \qmlsignal QtQuick.Particles2::Affector::onAffected(x, y)
-
- This signal is emitted each time the affector actually affects a particle.
-
- x,y are the coordinates of the affected particle, relative to the ParticleSystem.
-
-*/
-
-/*!
- \qmlsignal QtQuick.Particles2::Affector::affectParticle(particle particle, real dt)
-
- This handler is called when particles are selected to be affected.
-
- dt is the time since the last time it was affected. Use dt to normalize
- trajectory manipulations to real time.
-
- Note that JS is slower to execute, so it is not recommended to use this in
- high-volume particle systems.
-*/
-/*!
\qmlsignal QtQuick.Particles2::Affector::affected(real x, real y)
- This handler is called when a particle is selected to be affected. It will
- only be called if signal is set to true.
+ This handler is called when a particle is selected to be affected. It will not be called
+ if a particle is considered by the Affector but not actually altered in any way.
+
+ In the special case where an Affector has no possible effect (e.g. Affector {}), affected
+ will be emitted for all particles being considered if you connect to it. This allows you to
+ execute arbitrary code in response to particles (see \l affectParticles if you want to execute
+ code which affects the particles themselves) . As this executes JS scritps per particle, it is
+ not recommended to use this signal with a high-volume particle system.
x,y is the particles current position.
*/
diff --git a/src/particles/qquickparticleaffector_p.h b/src/particles/qquickparticleaffector_p.h
index 4147488f87..3aec072b7d 100644
--- a/src/particles/qquickparticleaffector_p.h
+++ b/src/particles/qquickparticleaffector_p.h
@@ -178,13 +178,14 @@ protected:
bool shouldAffect(QQuickParticleData* datum);//Call to do the logic on whether it is affecting that datum
void postAffect(QQuickParticleData* datum);//Call to do the post-affect logic on particles which WERE affected(once off, needs reset, affected signal)
virtual void componentComplete();
- QPointF m_offset;
bool isAffectedConnected();
static const qreal simulationDelta;
static const qreal simulationCutoff;
+
+ QPointF m_offset;
+ QSet<QPair<int, int> > m_onceOffed;
private:
QSet<int> m_groupIds;
- QSet<QPair<int, int> > m_onceOffed;
bool m_updateIntSet;
QQuickParticleExtruder* m_shape;
diff --git a/tests/auto/particles/qquickcustomaffector/data/affectedSignal.qml b/tests/auto/particles/qquickcustomaffector/data/affectedSignal.qml
new file mode 100644
index 0000000000..71f343a358
--- /dev/null
+++ b/tests/auto/particles/qquickcustomaffector/data/affectedSignal.qml
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ ParticleSystem {
+ id: sys
+ objectName: "system"
+ anchors.fill: parent
+ property real resultX1: 1234
+ property real resultY1: 1234
+ property real resultX2: 1234
+ property real resultY2: 1234
+
+ ImageParticle {
+ source: "../../shared/star.png"
+ rotation: 90
+ }
+
+ Emitter{
+ //0,100 position
+ y: 100
+ size: 32
+ emitRate: 1000
+ lifeSpan: 500
+ }
+
+ Affector {
+ once: true
+ onAffected: {//Does nothing else, so should be called for all particles
+ sys.resultX1 = x;
+ sys.resultY1 = y;
+ }
+ }
+
+ Affector {
+ once: true
+ relative: false
+ position: PointDirection { x: 0; y: 100; }
+ onAffected: {//Does something, so should only be called when it causes a change (it won't)
+ sys.resultX2 = x;
+ sys.resultY2 = y;
+ }
+ }
+ }
+}
diff --git a/tests/auto/particles/qquickcustomaffector/tst_qquickcustomaffector.cpp b/tests/auto/particles/qquickcustomaffector/tst_qquickcustomaffector.cpp
index b63cde14f3..8b10b720c5 100644
--- a/tests/auto/particles/qquickcustomaffector/tst_qquickcustomaffector.cpp
+++ b/tests/auto/particles/qquickcustomaffector/tst_qquickcustomaffector.cpp
@@ -56,6 +56,7 @@ private slots:
void initTestCase();
void test_basic();
void test_move();
+ void test_affectedSignal();
};
void tst_qquickcustomaffector::initTestCase()
@@ -124,6 +125,19 @@ void tst_qquickcustomaffector::test_move()
delete view;
}
+void tst_qquickcustomaffector::test_affectedSignal()
+{
+ QQuickView* view = createView(testFileUrl("affectedSignal.qml"), 600);
+ QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system");
+ ensureAnimTime(600, system->m_animation);
+
+ QCOMPARE(system->property("resultX1").toInt(), 0);
+ QCOMPARE(system->property("resultY1").toInt(), 100);
+ QCOMPARE(system->property("resultX2").toInt(), 1234);
+ QCOMPARE(system->property("resultY2").toInt(), 1234);
+ delete view;
+}
+
QTEST_MAIN(tst_qquickcustomaffector);
#include "tst_qquickcustomaffector.moc"