From: Alan Alpert Date: Thu, 11 Aug 2011 09:36:07 +0000 (+1000) Subject: Refactor BasicEmitter into Emitter X-Git-Tag: qt-v5.0.0-alpha1~1934 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5db92f1f1cacd25791abe6a4e6c6509fdd329e06;p=profile%2Fivi%2Fqtdeclarative.git 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 Reviewed-by: Alan Alpert --- diff --git a/src/declarative/particles/particles.pri b/src/declarative/particles/particles.pri index 582e1d3..1fc5783 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 10d59df..0000000 --- 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 f61da15..0000000 --- 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 //FIXME -#include - -#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 0d4e7f7..a074f44 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 dfd1618..c1d6e5e 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 9cf130d..0b0fe91 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 > 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 1bb06ea..f87115c 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(uri, 2, 0, "ParticlePainter"); - qmlRegisterType(uri, 2, 0, "ParticleEmitter"); - qmlRegisterType(uri, 2, 0, "ParticleExtruder"); - qmlRegisterType(uri, 2, 0, "NullVector"); - //Probably should be nocreate types qmlRegisterType(uri, 2, 0, "ParticleSystem"); @@ -89,7 +82,7 @@ void QSGParticlesModule::defineModule() qmlRegisterType(uri, 2, 0, "ItemParticle"); qmlRegisterType(uri, 2, 0, "ModelParticle"); - qmlRegisterType(uri, 2, 0, "Emitter");//TODO: Rename BasicEmitter? + qmlRegisterType(uri, 2, 0, "Emitter"); qmlRegisterType(uri, 2, 0, "CustomEmitter"); qmlRegisterType(uri, 2, 0, "FollowEmitter"); @@ -112,6 +105,11 @@ void QSGParticlesModule::defineModule() qmlRegisterType(uri, 2, 0, "SpriteGoal"); qmlRegisterType(uri, 2, 0 , "Turbulence"); qmlRegisterType(uri, 2, 0 , "Target"); + + //Exposed just for completeness + qmlRegisterType(uri, 2, 0, "ParticlePainter"); + qmlRegisterType(uri, 2, 0, "ParticleExtruder"); + qmlRegisterType(uri, 2, 0, "NullVector"); } QT_END_NAMESPACE