aboutsummaryrefslogtreecommitdiffstats
path: root/src/imports/particles
diff options
context:
space:
mode:
Diffstat (limited to 'src/imports/particles')
-rw-r--r--src/imports/particles/followemitter.cpp123
-rw-r--r--src/imports/particles/killaffector.cpp6
-rw-r--r--src/imports/particles/particleemitter.cpp3
-rw-r--r--src/imports/particles/particleemitter.h7
-rw-r--r--src/imports/particles/trailsemitter.cpp130
5 files changed, 139 insertions, 130 deletions
diff --git a/src/imports/particles/followemitter.cpp b/src/imports/particles/followemitter.cpp
index 9e1ec7bbd2..17a544f62d 100644
--- a/src/imports/particles/followemitter.cpp
+++ b/src/imports/particles/followemitter.cpp
@@ -84,7 +84,7 @@ void FollowEmitter::emitWindow(int timeStamp)
{
if (m_system == 0)
return;
- if(!m_emitting && !m_burstLeft && !m_emitLeft)
+ if(!m_emitting && !m_burstLeft && m_burstQueue.isEmpty())
return;
if(m_followCount != m_system->m_groupData[m_system->m_groupIds[m_follow]]->size){
qreal oldPPS = m_particlesPerSecond;
@@ -123,70 +123,69 @@ void FollowEmitter::emitWindow(int timeStamp)
m_lastEmission[i] = time;//jump over this time period without emitting, because it's outside
continue;
}
- while(pt < time || m_emitLeft){
+ while(pt < time || !m_burstQueue.isEmpty()){
ParticleData* datum = m_system->newDatum(gId2);
- if(!datum){//skip this emission
- if(m_emitLeft)
- --m_emitLeft;
- else
- pt += particleRatio;
- continue;
+ if(datum){//else, skip this emission
+ datum->e = this;//###useful?
+ ParticleVertex &p = datum->pv;
+
+ // Particle timestamp
+ p.t = pt;
+ p.lifeSpan =
+ (m_particleDuration
+ + ((rand() % ((m_particleDurationVariation*2) + 1)) - m_particleDurationVariation))
+ / 1000.0;
+
+ // Particle position
+ // Note that burst location doesn't get used for follow emitter
+ qreal followT = pt - d->pv.t;
+ qreal followT2 = followT * followT * 0.5;
+ qreal sizeOffset = d->pv.size/2;//TODO: Current size? As an option
+ //TODO: Set variations
+ //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();
+
+ // Particle speed
+ const QPointF &speed = m_speed->sample(newPos);
+ p.sx = speed.x();
+ p.sy = speed.y();
+
+ // Particle acceleration
+ const QPointF &accel = m_acceleration->sample(newPos);
+ p.ax = accel.x();
+ p.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);
+
+ p.size = size * float(m_emitting);
+ p.endSize = endSize * float(m_emitting);
+
+ m_system->emitParticle(datum);
}
- datum->e = this;//###useful?
- ParticleVertex &p = datum->pv;
-
- // Particle timestamp
- p.t = pt;
- p.lifeSpan =
- (m_particleDuration
- + ((rand() % ((m_particleDurationVariation*2) + 1)) - m_particleDurationVariation))
- / 1000.0;
-
- // Particle position
- qreal followT = pt - d->pv.t;
- qreal followT2 = followT * followT * 0.5;
- qreal sizeOffset = d->pv.size/2;//TODO: Current size? As an option
- //TODO: Set variations
- //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();
-
- // Particle speed
- const QPointF &speed = m_speed->sample(newPos);
- p.sx = speed.x();
- p.sy = speed.y();
-
- // Particle acceleration
- const QPointF &accel = m_acceleration->sample(newPos);
- p.ax = accel.x();
- p.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);
-
- p.size = size * float(m_emitting);
- p.endSize = endSize * float(m_emitting);
-
- if(m_emitLeft)
- --m_emitLeft;
- else
+ if(!m_burstQueue.isEmpty()){
+ m_burstQueue.first().first--;
+ if(m_burstQueue.first().first <= 0)
+ m_burstQueue.pop_front();
+ }else{
pt += particleRatio;
- m_system->emitParticle(datum);
+ }
}
m_lastEmission[i] = pt;
}
diff --git a/src/imports/particles/killaffector.cpp b/src/imports/particles/killaffector.cpp
index 1af77918c5..c98a2f44e2 100644
--- a/src/imports/particles/killaffector.cpp
+++ b/src/imports/particles/killaffector.cpp
@@ -51,7 +51,9 @@ KillAffector::KillAffector(QSGItem *parent) :
bool KillAffector::affectParticle(ParticleData *d, qreal dt)
{
Q_UNUSED(dt);
- d->pv.t -= d->pv.lifeSpan;
- return true;
+ if(d->stillAlive()){
+ d->pv.t -= d->pv.lifeSpan + 1;
+ return true;
+ }
}
QT_END_NAMESPACE
diff --git a/src/imports/particles/particleemitter.cpp b/src/imports/particles/particleemitter.cpp
index f490ed643e..dd7d73749b 100644
--- a/src/imports/particles/particleemitter.cpp
+++ b/src/imports/particles/particleemitter.cpp
@@ -57,7 +57,6 @@ ParticleEmitter::ParticleEmitter(QSGItem *parent) :
, m_particleSizeVariation(0)
, m_maxParticleCount(-1)
, m_burstLeft(0)
- , m_emitLeft(0)
{
//TODO: Reset speed/acc back to null vector? Or allow null pointer?
@@ -117,7 +116,7 @@ void ParticleEmitter::burst(int num)
{
if(!particleCount())
qWarning() << "burst called on an emitter with a particle count of zero";
- m_emitLeft += num;
+ m_burstQueue << qMakePair(num, QPointF(x(), y()));
}
void ParticleEmitter::setMaxParticleCount(int arg)
diff --git a/src/imports/particles/particleemitter.h b/src/imports/particles/particleemitter.h
index 61994e52fa..e272ae51ab 100644
--- a/src/imports/particles/particleemitter.h
+++ b/src/imports/particles/particleemitter.h
@@ -48,6 +48,9 @@
#include "particleextruder.h"
#include "varyingvector.h"
+#include <QList>
+#include <QPair>
+#include <QPointF>
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
@@ -287,8 +290,8 @@ protected:
qreal m_particleEndSize;
qreal m_particleSizeVariation;
- int m_burstLeft;
- int m_emitLeft;
+ int m_burstLeft;//TODO: Rename to pulse
+ QList<QPair<int, QPointF > > m_burstQueue;
int m_maxParticleCount;
private:
VaryingVector m_nullVector;
diff --git a/src/imports/particles/trailsemitter.cpp b/src/imports/particles/trailsemitter.cpp
index 2355670801..41635a4299 100644
--- a/src/imports/particles/trailsemitter.cpp
+++ b/src/imports/particles/trailsemitter.cpp
@@ -72,7 +72,7 @@ void TrailsEmitter::emitWindow(int timeStamp)
{
if (m_system == 0)
return;
- if((!m_emitting || !m_particlesPerSecond)&& !m_burstLeft && !m_emitLeft){
+ if((!m_emitting || !m_particlesPerSecond)&& !m_burstLeft && m_burstQueue.isEmpty()){
m_reset_last = true;
return;
}
@@ -92,6 +92,7 @@ void TrailsEmitter::emitWindow(int timeStamp)
m_burstLeft = 0;
}
}
+
qreal time = timeStamp / 1000.;
qreal particleRatio = 1. / m_particlesPerSecond;
@@ -116,71 +117,76 @@ void TrailsEmitter::emitWindow(int timeStamp)
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();
- while (pt < time || m_emitLeft) {
+ 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;
ParticleData* datum = m_system->newDatum(m_system->m_groupIds[m_particle]);
- if(!datum){//skip this emission
- if(!m_emitLeft)
- pt += particleRatio;
- else
- --m_emitLeft;
- continue;
+ if(datum){//actually emit(otherwise we've been asked to skip this one)
+ datum->e = this;//###useful?
+ ParticleVertex &p = datum->pv;
+ 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
+ p.t = pt;
+ p.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);
+ p.x = newPos.x();
+ p.y = newPos.y();
+
+ // Particle speed
+ const QPointF &speed = m_speed->sample(newPos);
+ p.sx = speed.x()
+ + m_speed_from_movement * vx;
+ p.sy = speed.y()
+ + m_speed_from_movement * vy;
+
+ // Particle acceleration
+ const QPointF &accel = m_acceleration->sample(newPos);
+ p.ax = accel.x();
+ p.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);
+
+ p.size = size;// * float(m_emitting);
+ p.endSize = endSize;// * float(m_emitting);
+
+ m_system->emitParticle(datum);
}
- datum->e = this;//###useful?
- ParticleVertex &p = datum->pv;
- 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
- p.t = pt;
- p.lifeSpan = //TODO:Promote to base class?
- (m_particleDuration
- + ((rand() % ((m_particleDurationVariation*2) + 1)) - m_particleDurationVariation))
- / 1000.0;
-
- // Particle position
- QRectF boundsRect(emitter_x_offset + dex * (pt - opt) / dt, emitter_y_offset + dey * (pt - opt) / dt
- , width(), height());
- QPointF newPos = effectiveExtruder()->extrude(boundsRect);
- p.x = newPos.x();
- p.y = newPos.y();
-
- // Particle speed
- const QPointF &speed = m_speed->sample(newPos);
- p.sx = speed.x()
- + m_speed_from_movement * vx;
- p.sy = speed.y()
- + m_speed_from_movement * vy;
-
- // Particle acceleration
- const QPointF &accel = m_acceleration->sample(newPos);
- p.ax = accel.x();
- p.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);
-
- p.size = size;// * float(m_emitting);
- p.endSize = endSize;// * float(m_emitting);
-
- if(!m_emitLeft)
+ if(m_burstQueue.isEmpty()){
pt += particleRatio;
- else
- --m_emitLeft;
-
- m_system->emitParticle(datum);
+ }else{
+ m_burstQueue.first().first--;
+ if(m_burstQueue.first().first <= 0)
+ m_burstQueue.pop_front();
+ }
}
m_last_emission = pt;