summaryrefslogtreecommitdiffstats
path: root/src/imports/particles/followemitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/imports/particles/followemitter.cpp')
-rw-r--r--src/imports/particles/followemitter.cpp121
1 files changed, 89 insertions, 32 deletions
diff --git a/src/imports/particles/followemitter.cpp b/src/imports/particles/followemitter.cpp
index ae00e0a2d4..825b9ea69f 100644
--- a/src/imports/particles/followemitter.cpp
+++ b/src/imports/particles/followemitter.cpp
@@ -1,21 +1,57 @@
+/****************************************************************************
+**
+** 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
#include "followemitter.h"
#include "particle.h"
#include <cmath>
QT_BEGIN_NAMESPACE
+
FollowEmitter::FollowEmitter(QSGItem *parent) :
ParticleEmitter(parent)
- , m_particleSize(16)
- , m_particleEndSize(-1)
- , m_particleSizeVariation(0)
- , m_xSpeed(0)
- , m_ySpeed(0)
- , m_xSpeedVariation(0)
- , m_ySpeedVariation(0)
- , m_xAccel(0)
- , m_yAccel(0)
- , m_xAccelVariation(0)
- , m_yAccelVariation(0)
, m_lastTimeStamp(0)
+ , m_emitterXVariation(0)
+ , m_emitterYVariation(0)
+ , m_followCount(0)
+ , m_emissionExtruder(0)
+ , m_defaultEmissionExtruder(new ParticleExtruder(this))
{
connect(this, SIGNAL(followChanged(QString)),
this, SLOT(recalcParticlesPerSecond()));
@@ -34,18 +70,26 @@ void FollowEmitter::recalcParticlesPerSecond(){
}else{
setParticlesPerSecond(m_particlesPerParticlePerSecond * m_followCount);
m_lastEmission.resize(m_followCount);
+ m_lastEmission.fill(0);
}
}
+void FollowEmitter::reset()
+{
+ m_followCount = 0;
+}
+
void FollowEmitter::emitWindow(int timeStamp)
{
if (m_system == 0)
return;
- if(!m_emitting && !m_burstLeft)
+ if(!m_emitting && !m_burstLeft && !m_emitLeft)
return;
if(m_followCount != m_system->m_groupData[m_system->m_groupIds[m_follow]]->size){
+ qreal oldPPS = m_particlesPerSecond;
recalcParticlesPerSecond();
- return;//system may need to update
+ if(m_particlesPerSecond != oldPPS)
+ return;//system may need to update
}
if(m_burstLeft){
@@ -61,24 +105,32 @@ void FollowEmitter::emitWindow(int timeStamp)
qreal pt;
//Have to map it into this system, because particlesystem automaps it back
- QPointF offset = this->mapFromItem(m_system, QPointF(0, 0));
- float sizeAtEnd = m_particleEndSize >= 0 ? m_particleEndSize : m_particleSize;
+ QPointF offset = m_system->mapFromItem(this, QPointF(0, 0));
+ qreal sizeAtEnd = m_particleEndSize >= 0 ? m_particleEndSize : m_particleSize;
int gId = m_system->m_groupIds[m_follow];
int gId2 = m_system->m_groupIds[m_particle];
for(int i=0; i<m_system->m_groupData[gId]->size; i++){
pt = m_lastEmission[i];
ParticleData* d = m_system->m_data[i + m_system->m_groupData[gId]->start];
- if(!d)
+ if(!d || !d->stillAlive())
continue;
if(pt < d->pv.t)
pt = d->pv.t;
- if(!QRect(offset.x(), offset.y(), width(), height()).contains(d->curX(), d->curY())){
+
+ if(!effectiveExtruder()->contains(QRectF(offset.x(), offset.y(), width(), height()),QPointF(d->curX(), d->curY()))){
m_lastEmission[i] = time;//jump over this time period without emitting, because it's outside
continue;
}
- while(pt < time){
+ while(pt < time || m_emitLeft){
ParticleData* datum = m_system->newDatum(gId2);
+ if(!datum){//skip this emission
+ if(m_emitLeft)
+ --m_emitLeft;
+ else
+ pt += particleRatio;
+ continue;
+ }
datum->e = this;//###useful?
ParticleVertex &p = datum->pv;
@@ -92,18 +144,20 @@ void FollowEmitter::emitWindow(int timeStamp)
// Particle position
qreal followT = pt - d->pv.t;
qreal followT2 = followT * followT * 0.5;
- qreal sizeOffset = d->pv.size/2;//TODO: Current size
+ qreal sizeOffset = d->pv.size/2;//TODO: Current size? As an option
//TODO: Set variations
-// QRectF boundsRect(d->pv.x + d->pv.sx * followT + d->pv.ax * followT2 + offset.x() - m_emitterXVariation/2,
-// d->pv.y + d->pv.sy * followT + d->pv.ay * followT2 + offset.y() - m_emitterYVariation/2,
-// m_emitterXVariation,
-// m_emitterYVariation);
- QRectF boundsRect(d->pv.x + d->pv.sx * followT + d->pv.ax * followT2 + offset.x() - sizeOffset,
- d->pv.y + d->pv.sy * followT + d->pv.ay * followT2 + offset.y() - sizeOffset,
- sizeOffset*2,
- sizeOffset*2);
-
- const QPointF &newPos = effectiveExtruder()->extrude(boundsRect);
+ //Subtract offset, because PS expects this in emitter coordinates
+ QRectF boundsRect(d->pv.x - offset.x() + d->pv.sx * followT + d->pv.ax * followT2 - m_emitterXVariation/2,
+ d->pv.y - offset.y() + d->pv.sy * followT + d->pv.ay * followT2 - m_emitterYVariation/2,
+ m_emitterXVariation,
+ m_emitterYVariation);
+// QRectF boundsRect(d->pv.x + d->pv.sx * followT + d->pv.ax * followT2 + offset.x() - sizeOffset,
+// d->pv.y + d->pv.sy * followT + d->pv.ay * followT2 + offset.y() - sizeOffset,
+// sizeOffset*2,
+// sizeOffset*2);
+
+ ParticleExtruder* effectiveEmissionExtruder = m_emissionExtruder ? m_emissionExtruder : m_defaultEmissionExtruder;
+ const QPointF &newPos = effectiveEmissionExtruder->extrude(boundsRect);
p.x = newPos.x();
p.y = newPos.y();
@@ -121,13 +175,16 @@ void FollowEmitter::emitWindow(int timeStamp)
float sizeVariation = -m_particleSizeVariation
+ rand() / float(RAND_MAX) * m_particleSizeVariation * 2;
- float size = m_particleSize + sizeVariation;
- float endSize = sizeAtEnd + sizeVariation;
+ float size = qMax((qreal)0.0, m_particleSize + sizeVariation);
+ float endSize = qMax((qreal)0.0, sizeAtEnd + sizeVariation);
p.size = size * float(m_emitting);
p.endSize = endSize * float(m_emitting);
- pt += particleRatio;
+ if(m_emitLeft)
+ --m_emitLeft;
+ else
+ pt += particleRatio;
m_system->emitParticle(datum);
}
m_lastEmission[i] = pt;