summaryrefslogtreecommitdiffstats
path: root/src/imports/particles/particlesystem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/imports/particles/particlesystem.cpp')
-rw-r--r--src/imports/particles/particlesystem.cpp95
1 files changed, 80 insertions, 15 deletions
diff --git a/src/imports/particles/particlesystem.cpp b/src/imports/particles/particlesystem.cpp
index cfc8db428f..1cb7d110ee 100644
--- a/src/imports/particles/particlesystem.cpp
+++ b/src/imports/particles/particlesystem.cpp
@@ -1,10 +1,52 @@
+/****************************************************************************
+**
+** 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 "particlesystem.h"
-#include <node.h>
+#include <qsgnode.h>
#include "particleemitter.h"
#include "particleaffector.h"
#include "particle.h"
#include <cmath>
#include <QDebug>
+
QT_BEGIN_NAMESPACE
ParticleData::ParticleData()
@@ -25,30 +67,30 @@ ParticleData::ParticleData()
}
ParticleSystem::ParticleSystem(QSGItem *parent) :
- QSGItem(parent), m_running(true) , m_startTime(0)
+ QSGItem(parent), m_particle_count(0), m_running(true) , m_startTime(0), m_overwrite(true)
{
m_groupIds = QHash<QString, int>();
}
void ParticleSystem::registerParticleType(ParticleType* p)
{
- m_particles << p;//###Set or uniqueness checking?
+ m_particles << QPointer<ParticleType>(p);//###Set or uniqueness checking?
reset();
}
void ParticleSystem::registerParticleEmitter(ParticleEmitter* e)
{
- m_emitters << e;//###How to get them out?
- connect(e, SIGNAL(particlesPerSecondChanged(qreal)),
+ m_emitters << QPointer<ParticleEmitter>(e);//###How to get them out?
+ connect(e, SIGNAL(particleCountChanged()),
this, SLOT(countChanged()));
- connect(e, SIGNAL(particleDurationChanged(int)),
+ connect(e, SIGNAL(particleChanged(QString)),
this, SLOT(countChanged()));
reset();
}
void ParticleSystem::registerParticleAffector(ParticleAffector* a)
{
- m_affectors << a;
+ m_affectors << QPointer<ParticleAffector>(a);
//reset();//TODO: Slim down the huge batch of resets at the start
}
@@ -112,7 +154,7 @@ void ParticleSystem::initializeSystem()
m_groupIds.insert(e->particle(), id);
m_groupData.insert(id, gd);
}
- m_groupData[m_groupIds[e->particle()]]->size += ceil(e->particlesPerSecond()*((e->particleDuration()+e->particleDurationVariation())/1000.0));
+ m_groupData[m_groupIds[e->particle()]]->size += e->particleCount();
}
for(QHash<int, GroupData*>::iterator iter = m_groupData.begin(); iter != m_groupData.end(); iter++){
@@ -148,6 +190,12 @@ void ParticleSystem::initializeSystem()
void ParticleSystem::reset()
{
+ //Clear guarded pointers which have been deleted
+ int cleared = 0;
+ cleared += m_emitters.removeAll(0);
+ cleared += m_particles.removeAll(0);
+ cleared += m_affectors.removeAll(0);
+ //qDebug() << "Reset" << m_emitters.count() << m_particles.count() << "Cleared" << cleared;
foreach(ParticleType* p, m_particles)
p->reset();
foreach(ParticleEmitter* e, m_emitters)
@@ -166,9 +214,13 @@ ParticleData* ParticleSystem::newDatum(int groupId)
if( m_groupData[groupId]->nextIdx >= m_groupData[groupId]->size)
m_groupData[groupId]->nextIdx = 0;
+ Q_ASSERT(nextIdx < m_data.size());
ParticleData* ret;
- if(m_data[nextIdx]){//Recycle, it's faster. //###Reset?
+ if(m_data[nextIdx]){//Recycle, it's faster.
ret = m_data[nextIdx];
+ if(!m_overwrite && ret->stillAlive()){
+ return 0;//Artificial longevity (or too fast emission) means this guy hasn't died. To maintain count, don't emit a new one
+ }//###Reset?
}else{
ret = new ParticleData;
m_data[nextIdx] = ret;
@@ -191,10 +243,11 @@ void ParticleSystem::emitParticle(ParticleData* pd)
}
foreach(ParticleAffector *a, m_affectors)
- if(a->m_needsReset)
+ if(a && a->m_needsReset)
a->reset(pd->systemIndex);
foreach(ParticleType* p, m_groupData[pd->group]->types)
- p->load(pd);
+ if(p)
+ p->load(pd);
}
@@ -216,12 +269,15 @@ uint ParticleSystem::systemSync(ParticleType* p)
dt = time - dt;
m_needsReset.clear();
foreach(ParticleEmitter* emitter, m_emitters)
- emitter->emitWindow(m_timeInt);
+ if(emitter)
+ emitter->emitWindow(m_timeInt);
foreach(ParticleAffector* a, m_affectors)
- a->affectSystem(dt);
+ if(a)
+ a->affectSystem(dt);
foreach(ParticleData* d, m_needsReset)
foreach(ParticleType* p, m_groupData[d->group]->types)
- p->reload(d);
+ if(p && d)
+ p->reload(d);
}
m_syncList << p;
return m_timeInt;
@@ -322,6 +378,15 @@ void ParticleData::debugDump()
<< "Pos: " << pv.x << "," << pv.y
<< "Vel: " << pv.sx << "," << pv.sy
<< "Acc: " << pv.ax << "," << pv.ay
- << "Time: " << pv.t;// << "," << (system->m_timeInt / 1000.0);
+ << "Size: " << pv.size << "," << pv.endSize
+ << "Time: " << pv.t << "," <<pv.lifeSpan;
+}
+
+bool ParticleData::stillAlive()
+{
+ if(!system)
+ return false;
+ return (pv.t + pv.lifeSpan) > (system->m_timeInt/1000.0);
}
+
QT_END_NAMESPACE