aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Alpert <alan.alpert@nokia.com>2011-08-11 19:36:07 +1000
committerQt by Nokia <qt-info@nokia.com>2011-08-15 05:16:45 +0200
commit5db92f1f1cacd25791abe6a4e6c6509fdd329e06 (patch)
tree77e56afe1e042fc9e4c7555cd72bdf60869f826b
parent4796c4d9550166500d54b829fa97541e4de6e929 (diff)
Refactor BasicEmitter into Emitter
No real point having a separate class, and it makes the docs more complex. Change-Id: I48aa7bafce541b0b5b792351adb5edf77fc67de2 Reviewed-on: http://codereview.qt.nokia.com/2853 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Alan Alpert <alan.alpert@nokia.com>
-rw-r--r--src/declarative/particles/particles.pri2
-rw-r--r--src/declarative/particles/qsgemitter.cpp262
-rw-r--r--src/declarative/particles/qsgemitter_p.h104
-rw-r--r--src/declarative/particles/qsgfollowemitter.cpp65
-rw-r--r--src/declarative/particles/qsgparticleemitter.cpp272
-rw-r--r--src/declarative/particles/qsgparticleemitter_p.h20
-rw-r--r--src/declarative/particles/qsgparticlesmodule.cpp14
7 files changed, 303 insertions, 436 deletions
diff --git a/src/declarative/particles/particles.pri b/src/declarative/particles/particles.pri
index 582e1d3f8c..1fc5783a73 100644
--- a/src/declarative/particles/particles.pri
+++ b/src/declarative/particles/particles.pri
@@ -4,7 +4,6 @@ HEADERS += \
$$PWD/qsgangleddirection_p.h \
$$PWD/qsgcustomparticle_p.h \
$$PWD/qsgellipseextruder_p.h \
- $$PWD/qsgemitter_p.h \
$$PWD/qsgfollowemitter_p.h \
$$PWD/qsgfriction_p.h \
$$PWD/qsggravity_p.h \
@@ -37,7 +36,6 @@ SOURCES += \
$$PWD/qsgangleddirection.cpp \
$$PWD/qsgcustomparticle.cpp \
$$PWD/qsgellipseextruder.cpp \
- $$PWD/qsgemitter.cpp \
$$PWD/qsgfollowemitter.cpp \
$$PWD/qsgfriction.cpp \
$$PWD/qsggravity.cpp \
diff --git a/src/declarative/particles/qsgemitter.cpp b/src/declarative/particles/qsgemitter.cpp
deleted file mode 100644
index 10d59dfaf8..0000000000
--- a/src/declarative/particles/qsgemitter.cpp
+++ /dev/null
@@ -1,262 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Declarative module 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$
-**
-****************************************************************************/
-
-#include "qsgemitter_p.h"
-#include "qsgparticlesystem_p.h"
-QT_BEGIN_NAMESPACE
-
-/*!
- \qmlclass Emitter QSGBasicEmitter
- \inqmlmodule QtQuick.Particles 2
- \since QtQuick.Particles 2.0
- \brief The Emitter element allows you to emit logical particles.
-
- This element emits logical particles into the ParticleSystem, with the
- given starting attributes.
-
- Note that logical particles are not
- automatically rendered, you will need to have one or more
- ParticlePainter elements visualizing them.
-
- Note that the given starting attributes can be modified at any point
- in the particle's lifetime by any Affector element in the same
- ParticleSystem. This includes attributes like lifespan.
-*/
-
-QSGBasicEmitter::QSGBasicEmitter(QSGItem* parent)
- : QSGParticleEmitter(parent)
- , m_speed_from_movement(0)
- , m_particle_count(0)
- , m_reset_last(true)
- , m_last_timestamp(0)
- , m_last_emission(0)
-{
-// setFlag(ItemHasContents);
-}
-
-/*!
- \qmlproperty ParticleSystem QtQuick.Particles2::Emitter::system
-
- This is the Particle system that the Emitter will emit into.
- This can be omitted if the Emitter is a direct child of the ParticleSystem
-*/
-/*!
- \qmlproperty string QtQuick.Particles2::Emitter::particle
-*/
-/*!
- \qmlproperty Shape QtQuick.Particles2::Emitter::shape
-*/
-/*!
- \qmlproperty bool QtQuick.Particles2::Emitter::emitting
-*/
-/*!
- \qmlproperty real QtQuick.Particles2::Emitter::emitRate
-*/
-/*!
- \qmlproperty int QtQuick.Particles2::Emitter::lifeSpan
-*/
-/*!
- \qmlproperty int QtQuick.Particles2::Emitter::lifeSpanVariation
-*/
-/*!
- \qmlproperty int QtQuick.Particles2::Emitter::emitCap
-*/
-/*!
- \qmlproperty real QtQuick.Particles2::Emitter::size
-*/
-/*!
- \qmlproperty real QtQuick.Particles2::Emitter::endSize
-*/
-/*!
- \qmlproperty real QtQuick.Particles2::Emitter::sizeVariation
-*/
-/*!
- \qmlproperty StochasticDirection QtQuick.Particles2::Emitter::speed
-*/
-/*!
- \qmlproperty StochasticDirection QtQuick.Particles2::Emitter::acceleration
-*/
-/*!
- \qmlproperty qreal QtQuick.Particles2::Emitter::speedFromMovement
-*/
-
-void QSGBasicEmitter::setSpeedFromMovement(qreal t)
-{
- if (t == m_speed_from_movement)
- return;
- m_speed_from_movement = t;
- emit speedFromMovementChanged();
-}
-
-void QSGBasicEmitter::reset()
-{
- m_reset_last = true;
-}
-
-void QSGBasicEmitter::emitWindow(int timeStamp)
-{
- if (m_system == 0)
- return;
- if ((!m_emitting || !m_particlesPerSecond)&& !m_burstLeft && m_burstQueue.isEmpty()){
- m_reset_last = true;
- return;
- }
-
- if (m_reset_last) {
- m_last_emitter = m_last_last_emitter = QPointF(x(), y());
- m_last_timestamp = timeStamp/1000.;
- m_last_emission = m_last_timestamp;
- m_reset_last = false;
- }
-
- if (m_burstLeft){
- m_burstLeft -= timeStamp - m_last_timestamp * 1000.;
- if (m_burstLeft < 0){
- if (!m_emitting)
- timeStamp += m_burstLeft;
- m_burstLeft = 0;
- }
- }
-
- qreal time = timeStamp / 1000.;
-
- qreal particleRatio = 1. / m_particlesPerSecond;
- qreal pt = m_last_emission;
-
- qreal opt = pt; // original particle time
- qreal dt = time - m_last_timestamp; // timestamp delta...
- if (!dt)
- dt = 0.000001;
-
- // emitter difference since last...
- qreal dex = (x() - m_last_emitter.x());
- qreal dey = (y() - m_last_emitter.y());
-
- qreal ax = (m_last_last_emitter.x() + m_last_emitter.x()) / 2;
- qreal bx = m_last_emitter.x();
- qreal cx = (x() + m_last_emitter.x()) / 2;
- qreal ay = (m_last_last_emitter.y() + m_last_emitter.y()) / 2;
- qreal by = m_last_emitter.y();
- qreal cy = (y() + m_last_emitter.y()) / 2;
-
- qreal sizeAtEnd = m_particleEndSize >= 0 ? m_particleEndSize : m_particleSize;
- qreal emitter_x_offset = m_last_emitter.x() - x();
- qreal emitter_y_offset = m_last_emitter.y() - y();
- if (!m_burstQueue.isEmpty() && !m_burstLeft && !m_emitting)//'outside time' emissions only
- pt = time;
- while (pt < time || !m_burstQueue.isEmpty()) {
- //int pos = m_last_particle % m_particle_count;
- QSGParticleData* datum = m_system->newDatum(m_system->m_groupIds[m_particle]);
- if (datum){//actually emit(otherwise we've been asked to skip this one)
- datum->e = this;//###useful?
- qreal t = 1 - (pt - opt) / dt;
- qreal vx =
- - 2 * ax * (1 - t)
- + 2 * bx * (1 - 2 * t)
- + 2 * cx * t;
- qreal vy =
- - 2 * ay * (1 - t)
- + 2 * by * (1 - 2 * t)
- + 2 * cy * t;
-
-
- // Particle timestamp
- datum->t = pt;
- datum->lifeSpan = //TODO:Promote to base class?
- (m_particleDuration
- + ((rand() % ((m_particleDurationVariation*2) + 1)) - m_particleDurationVariation))
- / 1000.0;
-
- // Particle position
- QRectF boundsRect;
- if (!m_burstQueue.isEmpty()){
- boundsRect = QRectF(m_burstQueue.first().second.x() - x(), m_burstQueue.first().second.y() - y(),
- width(), height());
- } else {
- boundsRect = QRectF(emitter_x_offset + dex * (pt - opt) / dt, emitter_y_offset + dey * (pt - opt) / dt
- , width(), height());
- }
- QPointF newPos = effectiveExtruder()->extrude(boundsRect);
- datum->x = newPos.x();
- datum->y = newPos.y();
-
- // Particle speed
- const QPointF &speed = m_speed->sample(newPos);
- datum->vx = speed.x()
- + m_speed_from_movement * vx;
- datum->vy = speed.y()
- + m_speed_from_movement * vy;
-
- // Particle acceleration
- const QPointF &accel = m_acceleration->sample(newPos);
- datum->ax = accel.x();
- datum->ay = accel.y();
-
- // Particle size
- float sizeVariation = -m_particleSizeVariation
- + rand() / float(RAND_MAX) * m_particleSizeVariation * 2;
-
- float size = qMax((qreal)0.0 , m_particleSize + sizeVariation);
- float endSize = qMax((qreal)0.0 , sizeAtEnd + sizeVariation);
-
- datum->size = size;// * float(m_emitting);
- datum->endSize = endSize;// * float(m_emitting);
-
- m_system->emitParticle(datum);
- }
- if (m_burstQueue.isEmpty()){
- pt += particleRatio;
- }else{
- m_burstQueue.first().first--;
- if (m_burstQueue.first().first <= 0)
- m_burstQueue.pop_front();
- }
- }
- m_last_emission = pt;
-
- m_last_last_last_emitter = m_last_last_emitter;
- m_last_last_emitter = m_last_emitter;
- m_last_emitter = QPointF(x(), y());
- m_last_timestamp = time;
-}
-
-
-QT_END_NAMESPACE
diff --git a/src/declarative/particles/qsgemitter_p.h b/src/declarative/particles/qsgemitter_p.h
deleted file mode 100644
index f61da15012..0000000000
--- a/src/declarative/particles/qsgemitter_p.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Declarative module 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$
-**
-****************************************************************************/
-
-#ifndef TRAILSEMITTER_H
-#define TRAILSEMITTER_H
-
-#include <QtCore>//FIXME
-#include <QtGui>
-
-#include "qsgparticleemitter_p.h"
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Declarative)
-
-
-class QSGGeometryNode;
-
-class QSGBasicEmitter : public QSGParticleEmitter
-{
- Q_OBJECT
-
- Q_PROPERTY(qreal speedFromMovement READ speedFromMovement WRITE setSpeedFromMovement NOTIFY speedFromMovementChanged)
-
-public:
- explicit QSGBasicEmitter(QSGItem* parent=0);
- virtual ~QSGBasicEmitter(){}
- virtual void emitWindow(int timeStamp);
-
-
- qreal speedFromMovement() const { return m_speed_from_movement; }
- void setSpeedFromMovement(qreal s);
-
- qreal renderOpacity() const { return m_render_opacity; }
-
-signals:
-
- void speedFromMovementChanged();
-
-public slots:
-public:
- virtual void reset();
-protected:
-
-private:
-
- qreal m_speed_from_movement;
-
- // derived values...
- int m_particle_count;
- bool m_reset_last;
- qreal m_last_timestamp;
- qreal m_last_emission;
-
- QPointF m_last_emitter;
- QPointF m_last_last_emitter;
- QPointF m_last_last_last_emitter;
-
- qreal m_render_opacity;
-};
-
-QT_END_NAMESPACE
-QT_END_HEADER
-#endif // TRAILSEMITTER_H
diff --git a/src/declarative/particles/qsgfollowemitter.cpp b/src/declarative/particles/qsgfollowemitter.cpp
index 0d4e7f73fd..a074f4456f 100644
--- a/src/declarative/particles/qsgfollowemitter.cpp
+++ b/src/declarative/particles/qsgfollowemitter.cpp
@@ -45,21 +45,14 @@
QT_BEGIN_NAMESPACE
/*!
- \qmlclass Emitter QSGBasicEmitter
+ \qmlclass FollowEmitter QSGFollowEmitter
\inqmlmodule QtQuick.Particles 2
+ \inherits QSGParticleEmitter
\since QtQuick.Particles 2.0
- \brief The Emitter element allows you to emit logical particles.
+ \brief The FollowEmitter element allows you to emit logical particles from other logical particles.
This element emits logical particles into the ParticleSystem, with the
- given starting attributes.
-
- Note that logical particles are not
- automatically rendered, you will need to have one or more
- ParticlePainter elements visualizing them.
-
- Note that the given starting attributes can be modified at any point
- in the particle's lifetime by any Affector element in the same
- ParticleSystem. This includes attributes like lifespan.
+ starting positions based on those of other logical particles.
*/
QSGFollowEmitter::QSGFollowEmitter(QSGItem *parent) :
QSGParticleEmitter(parent)
@@ -80,24 +73,17 @@ QSGFollowEmitter::QSGFollowEmitter(QSGItem *parent) :
this, SLOT(recalcParticlesPerSecond()));
}
-
-/*!
- \qmlproperty ParticleSystem QtQuick.Particles2::FollowEmitter::system
-
- This is the Particle system that the FollowEmitter will emit into.
- This can be omitted if the FollowEmitter is a direct child of the ParticleSystem
-*/
-/*!
- \qmlproperty string QtQuick.Particles2::FollowEmitter::particle
-*/
/*!
\qmlproperty string QtQuick.Particles2::FollowEmitter::follow
+
+ The type of logical particle which this is emitting from.
*/
-/*!
- \qmlproperty Shape QtQuick.Particles2::FollowEmitter::shape
-*/
+
/*!
\qmlproperty Shape QtQuick.Particles2::FollowEmitter::emitShape
+
+ As the area of a FollowEmitter is the area it follows, a separate shape can be provided
+ to be the shape it emits out of.
*/
/*!
\qmlproperty real QtQuick.Particles2::FollowEmitter::emitWidth
@@ -106,38 +92,9 @@ QSGFollowEmitter::QSGFollowEmitter(QSGItem *parent) :
\qmlproperty real QtQuick.Particles2::FollowEmitter::emitHeight
*/
/*!
- \qmlproperty bool QtQuick.Particles2::FollowEmitter::emitting
-*/
-/*!
\qmlproperty real QtQuick.Particles2::FollowEmitter::emitRatePerParticle
*/
-/*!
- \qmlproperty int QtQuick.Particles2::FollowEmitter::lifeSpan
-*/
-/*!
- \qmlproperty int QtQuick.Particles2::FollowEmitter::lifeSpanVariation
-*/
-/*!
- \qmlproperty int QtQuick.Particles2::FollowEmitter::emitCap
-*/
-/*!
- \qmlproperty real QtQuick.Particles2::FollowEmitter::size
-*/
-/*!
- \qmlproperty real QtQuick.Particles2::FollowEmitter::endSize
-*/
-/*!
- \qmlproperty real QtQuick.Particles2::FollowEmitter::sizeVariation
-*/
-/*!
- \qmlproperty StochasticDirection QtQuick.Particles2::FollowEmitter::speed
-*/
-/*!
- \qmlproperty StochasticDirection QtQuick.Particles2::FollowEmitter::acceleration
-*/
-/*!
- \qmlproperty qreal QtQuick.Particles2::FollowEmitter::speedFromMovement
-*/
+
void QSGFollowEmitter::recalcParticlesPerSecond(){
if (!m_system)
diff --git a/src/declarative/particles/qsgparticleemitter.cpp b/src/declarative/particles/qsgparticleemitter.cpp
index dfd1618088..c1d6e5ee4c 100644
--- a/src/declarative/particles/qsgparticleemitter.cpp
+++ b/src/declarative/particles/qsgparticleemitter.cpp
@@ -41,7 +41,131 @@
#include "qsgparticleemitter_p.h"
QT_BEGIN_NAMESPACE
-//Not visible from QML, so not documented. Document subclasses.
+
+
+
+/*!
+ \qmlclass Emitter QSGParticleEmitter
+ \inqmlmodule QtQuick.Particles 2
+ \since QtQuick.Particles 2.0
+ \brief The Emitter element allows you to emit logical particles.
+
+ This element emits logical particles into the ParticleSystem, with the
+ given starting attributes.
+
+ Note that logical particles are not
+ automatically rendered, you will need to have one or more
+ ParticlePainter elements visualizing them.
+
+ Note that the given starting attributes can be modified at any point
+ in the particle's lifetime by any Affector element in the same
+ ParticleSystem. This includes attributes like lifespan.
+*/
+
+
+/*!
+ \qmlproperty ParticleSystem QtQuick.Particles2::Emitter::system
+
+ This is the Particle system that the Emitter will emit into.
+ This can be omitted if the Emitter is a direct child of the ParticleSystem
+*/
+/*!
+ \qmlproperty string QtQuick.Particles2::Emitter::particle
+
+ This is the type of logical particle which it will emit.
+
+ Default value is "" (empty string).
+*/
+/*!
+ \qmlproperty Shape QtQuick.Particles2::Emitter::shape
+
+ This shape is applied to the bounding box of the emitter. Particles are then emitting
+ from inside the area of the shape.
+
+*/
+/*!
+ \qmlproperty bool QtQuick.Particles2::Emitter::emitting
+
+ If set to false, the emitter will cease emissions until it is set to true.
+
+ Default value is true.
+*/
+/*!
+ \qmlproperty real QtQuick.Particles2::Emitter::emitRate
+
+ Number of particles emitted per second.
+
+ Default value is 10 particles per second.
+*/
+/*!
+ \qmlproperty int QtQuick.Particles2::Emitter::lifeSpan
+
+ The time in milliseconds each emitted particle should last for.
+
+ Default value is 1000 (one second).
+*/
+/*!
+ \qmlproperty int QtQuick.Particles2::Emitter::lifeSpanVariation
+
+ Particle lifespans will vary by up to this much in either direction.
+
+ Default value is 0.
+*/
+/*!
+ \qmlproperty int QtQuick.Particles2::Emitter::emitCap
+
+ The maximum number of particles at a time that this emitter will have alive.
+
+ This can be set as a performance optimization (when using burst and pulse) or
+ to stagger emissions. The default value is emitRate * lifeSpan in seconds, which
+ is the number of particles that would be alive at any one time given the default settings.
+*/
+/*!
+ \qmlproperty real QtQuick.Particles2::Emitter::size
+
+ The size in pixels of the particles at the start of their life.
+
+ Default value is 16.
+*/
+/*!
+ \qmlproperty real QtQuick.Particles2::Emitter::endSize
+
+ The size in pixels of the particles at the end of their life. Size will
+ be linearly interpolated during the life of the particle from this value and
+ size. If endSize is -1, then the size of the particle will remain constant at
+ the starting size.
+
+ Default value is -1.
+*/
+/*!
+ \qmlproperty real QtQuick.Particles2::Emitter::sizeVariation
+
+ The size of a particle can vary by this much up or down from size/endSize. The same
+ random addition is made to both size and endSize for a single particle.
+
+ Default value is 0.
+*/
+/*!
+ \qmlproperty StochasticDirection QtQuick.Particles2::Emitter::speed
+
+ The starting speed of the particles emitted.
+*/
+/*!
+ \qmlproperty StochasticDirection QtQuick.Particles2::Emitter::acceleration
+
+ The starting acceleraton of the particles emitted.
+*/
+/*!
+ \qmlproperty qreal QtQuick.Particles2::Emitter::speedFromMovement
+
+ If this value is non-zero, then any movement of the emitter will provide additional
+ starting velocity to the particles based on the movement. The additional vector will be the
+ same angle as the emitter's movement, with a magnitude that is the magnitude of the emitters
+ movement multiplied by speedFromMovement.
+
+ Default value is 0.
+*/
+
QSGParticleEmitter::QSGParticleEmitter(QSGItem *parent) :
QSGItem(parent)
, m_particlesPerSecond(10)
@@ -58,6 +182,11 @@ QSGParticleEmitter::QSGParticleEmitter(QSGItem *parent) :
, m_particleSizeVariation(0)
, m_maxParticleCount(-1)
, m_burstLeft(0)
+ , m_speed_from_movement(0)
+ , m_particle_count(0)
+ , m_reset_last(true)
+ , m_last_timestamp(0)
+ , m_last_emission(0)
{
//TODO: Reset speed/acc back to null vector? Or allow null pointer?
@@ -83,11 +212,6 @@ void QSGParticleEmitter::componentComplete()
qWarning() << "Emitter created without a particle system specified";//TODO: useful QML warnings, like line number?
QSGItem::componentComplete();
}
-void QSGParticleEmitter::emitWindow(int timeStamp)
-{
- Q_UNUSED(timeStamp);
-}
-
void QSGParticleEmitter::setEmitting(bool arg)
{
@@ -155,4 +279,140 @@ int QSGParticleEmitter::particleCount() const
return m_particlesPerSecond*((m_particleDuration+m_particleDurationVariation)/1000.0);
}
+void QSGParticleEmitter::setSpeedFromMovement(qreal t)
+{
+ if (t == m_speed_from_movement)
+ return;
+ m_speed_from_movement = t;
+ emit speedFromMovementChanged();
+}
+
+void QSGParticleEmitter::emitWindow(int timeStamp)
+{
+ if (m_system == 0)
+ return;
+ if ((!m_emitting || !m_particlesPerSecond)&& !m_burstLeft && m_burstQueue.isEmpty()){
+ m_reset_last = true;
+ return;
+ }
+
+ if (m_reset_last) {
+ m_last_emitter = m_last_last_emitter = QPointF(x(), y());
+ m_last_timestamp = timeStamp/1000.;
+ m_last_emission = m_last_timestamp;
+ m_reset_last = false;
+ }
+
+ if (m_burstLeft){
+ m_burstLeft -= timeStamp - m_last_timestamp * 1000.;
+ if (m_burstLeft < 0){
+ if (!m_emitting)
+ timeStamp += m_burstLeft;
+ m_burstLeft = 0;
+ }
+ }
+
+ qreal time = timeStamp / 1000.;
+
+ qreal particleRatio = 1. / m_particlesPerSecond;
+ qreal pt = m_last_emission;
+
+ qreal opt = pt; // original particle time
+ qreal dt = time - m_last_timestamp; // timestamp delta...
+ if (!dt)
+ dt = 0.000001;
+
+ // emitter difference since last...
+ qreal dex = (x() - m_last_emitter.x());
+ qreal dey = (y() - m_last_emitter.y());
+
+ qreal ax = (m_last_last_emitter.x() + m_last_emitter.x()) / 2;
+ qreal bx = m_last_emitter.x();
+ qreal cx = (x() + m_last_emitter.x()) / 2;
+ qreal ay = (m_last_last_emitter.y() + m_last_emitter.y()) / 2;
+ qreal by = m_last_emitter.y();
+ qreal cy = (y() + m_last_emitter.y()) / 2;
+
+ qreal sizeAtEnd = m_particleEndSize >= 0 ? m_particleEndSize : m_particleSize;
+ qreal emitter_x_offset = m_last_emitter.x() - x();
+ qreal emitter_y_offset = m_last_emitter.y() - y();
+ if (!m_burstQueue.isEmpty() && !m_burstLeft && !m_emitting)//'outside time' emissions only
+ pt = time;
+ while (pt < time || !m_burstQueue.isEmpty()) {
+ //int pos = m_last_particle % m_particle_count;
+ QSGParticleData* datum = m_system->newDatum(m_system->m_groupIds[m_particle]);
+ if (datum){//actually emit(otherwise we've been asked to skip this one)
+ datum->e = this;//###useful?
+ qreal t = 1 - (pt - opt) / dt;
+ qreal vx =
+ - 2 * ax * (1 - t)
+ + 2 * bx * (1 - 2 * t)
+ + 2 * cx * t;
+ qreal vy =
+ - 2 * ay * (1 - t)
+ + 2 * by * (1 - 2 * t)
+ + 2 * cy * t;
+
+
+ // Particle timestamp
+ datum->t = pt;
+ datum->lifeSpan = //TODO:Promote to base class?
+ (m_particleDuration
+ + ((rand() % ((m_particleDurationVariation*2) + 1)) - m_particleDurationVariation))
+ / 1000.0;
+
+ // Particle position
+ QRectF boundsRect;
+ if (!m_burstQueue.isEmpty()){
+ boundsRect = QRectF(m_burstQueue.first().second.x() - x(), m_burstQueue.first().second.y() - y(),
+ width(), height());
+ } else {
+ boundsRect = QRectF(emitter_x_offset + dex * (pt - opt) / dt, emitter_y_offset + dey * (pt - opt) / dt
+ , width(), height());
+ }
+ QPointF newPos = effectiveExtruder()->extrude(boundsRect);
+ datum->x = newPos.x();
+ datum->y = newPos.y();
+
+ // Particle speed
+ const QPointF &speed = m_speed->sample(newPos);
+ datum->vx = speed.x()
+ + m_speed_from_movement * vx;
+ datum->vy = speed.y()
+ + m_speed_from_movement * vy;
+
+ // Particle acceleration
+ const QPointF &accel = m_acceleration->sample(newPos);
+ datum->ax = accel.x();
+ datum->ay = accel.y();
+
+ // Particle size
+ float sizeVariation = -m_particleSizeVariation
+ + rand() / float(RAND_MAX) * m_particleSizeVariation * 2;
+
+ float size = qMax((qreal)0.0 , m_particleSize + sizeVariation);
+ float endSize = qMax((qreal)0.0 , sizeAtEnd + sizeVariation);
+
+ datum->size = size;// * float(m_emitting);
+ datum->endSize = endSize;// * float(m_emitting);
+
+ m_system->emitParticle(datum);
+ }
+ if (m_burstQueue.isEmpty()){
+ pt += particleRatio;
+ }else{
+ m_burstQueue.first().first--;
+ if (m_burstQueue.first().first <= 0)
+ m_burstQueue.pop_front();
+ }
+ }
+ m_last_emission = pt;
+
+ m_last_last_last_emitter = m_last_last_emitter;
+ m_last_last_emitter = m_last_emitter;
+ m_last_emitter = QPointF(x(), y());
+ m_last_timestamp = time;
+}
+
+
QT_END_NAMESPACE
diff --git a/src/declarative/particles/qsgparticleemitter_p.h b/src/declarative/particles/qsgparticleemitter_p.h
index 9cf130d40d..0b0fe9197e 100644
--- a/src/declarative/particles/qsgparticleemitter_p.h
+++ b/src/declarative/particles/qsgparticleemitter_p.h
@@ -76,6 +76,8 @@ class QSGParticleEmitter : public QSGItem
Q_PROPERTY(QSGStochasticDirection *speed READ speed WRITE setSpeed NOTIFY speedChanged)
Q_PROPERTY(QSGStochasticDirection *acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged)
+ Q_PROPERTY(qreal speedFromMovement READ speedFromMovement WRITE setSpeedFromMovement NOTIFY speedFromMovementChanged)
+
public:
explicit QSGParticleEmitter(QSGItem *parent = 0);
virtual ~QSGParticleEmitter();
@@ -111,6 +113,8 @@ public:
return m_particleDurationVariation;
}
+ qreal speedFromMovement() const { return m_speed_from_movement; }
+ void setSpeedFromMovement(qreal s);
virtual void componentComplete();
signals:
void particlesPerSecondChanged(qreal);
@@ -138,6 +142,8 @@ signals:
void maxParticleCountChanged(int arg);
void particleCountChanged();
+ void speedFromMovementChanged();
+
public slots:
void pulse(qreal seconds);
void burst(int num);
@@ -293,8 +299,22 @@ protected:
int m_burstLeft;//TODO: Rename to pulse
QList<QPair<int, QPointF > > m_burstQueue;
int m_maxParticleCount;
+
+ //Used in default implementation, but might be useful
+ qreal m_speed_from_movement;
+
+ int m_particle_count;
+ bool m_reset_last;
+ qreal m_last_timestamp;
+ qreal m_last_emission;
+
+ QPointF m_last_emitter;
+ QPointF m_last_last_emitter;
+ QPointF m_last_last_last_emitter;
+
private:
QSGStochasticDirection m_nullVector;
+ qreal m_speedFromMovement;
};
QT_END_NAMESPACE
diff --git a/src/declarative/particles/qsgparticlesmodule.cpp b/src/declarative/particles/qsgparticlesmodule.cpp
index 1bb06eae35..f87115cba5 100644
--- a/src/declarative/particles/qsgparticlesmodule.cpp
+++ b/src/declarative/particles/qsgparticlesmodule.cpp
@@ -42,7 +42,6 @@
#include "qsgangleddirection_p.h"
#include "qsgcustomparticle_p.h"
#include "qsgellipseextruder_p.h"
-#include "qsgemitter_p.h"
#include "qsgfollowemitter_p.h"
#include "qsgfriction_p.h"
#include "qsggravity_p.h"
@@ -75,12 +74,6 @@ QT_BEGIN_NAMESPACE
void QSGParticlesModule::defineModule()
{
const char* uri = "QtQuick.Particles";
- //Debugging only exposition
- qmlRegisterType<QSGParticlePainter>(uri, 2, 0, "ParticlePainter");
- qmlRegisterType<QSGParticleEmitter>(uri, 2, 0, "ParticleEmitter");
- qmlRegisterType<QSGParticleExtruder>(uri, 2, 0, "ParticleExtruder");
- qmlRegisterType<QSGStochasticDirection>(uri, 2, 0, "NullVector");
- //Probably should be nocreate types
qmlRegisterType<QSGParticleSystem>(uri, 2, 0, "ParticleSystem");
@@ -89,7 +82,7 @@ void QSGParticlesModule::defineModule()
qmlRegisterType<QSGItemParticle>(uri, 2, 0, "ItemParticle");
qmlRegisterType<QSGModelParticle>(uri, 2, 0, "ModelParticle");
- qmlRegisterType<QSGBasicEmitter>(uri, 2, 0, "Emitter");//TODO: Rename BasicEmitter?
+ qmlRegisterType<QSGParticleEmitter>(uri, 2, 0, "Emitter");
qmlRegisterType<QSGCustomEmitter>(uri, 2, 0, "CustomEmitter");
qmlRegisterType<QSGFollowEmitter>(uri, 2, 0, "FollowEmitter");
@@ -112,6 +105,11 @@ void QSGParticlesModule::defineModule()
qmlRegisterType<QSGSpriteGoalAffector>(uri, 2, 0, "SpriteGoal");
qmlRegisterType<QSGTurbulenceAffector>(uri, 2, 0 , "Turbulence");
qmlRegisterType<QSGTargetAffector>(uri, 2, 0 , "Target");
+
+ //Exposed just for completeness
+ qmlRegisterType<QSGParticlePainter>(uri, 2, 0, "ParticlePainter");
+ qmlRegisterType<QSGParticleExtruder>(uri, 2, 0, "ParticleExtruder");
+ qmlRegisterType<QSGStochasticDirection>(uri, 2, 0, "NullVector");
}
QT_END_NAMESPACE