1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the Declarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #ifndef PARTICLESYSTEM_H
43 #define PARTICLESYSTEM_H
46 #include <QElapsedTimer>
50 #include <QSignalMapper>
51 #include <QtDeclarative/private/qsgsprite_p.h>
52 #include <QAbstractAnimation>
53 #include <QtDeclarative/qdeclarative.h>
54 #include <private/qv8engine_p.h> //For QDeclarativeV8Handle
60 QT_MODULE(Declarative)
62 class QSGParticleSystem;
63 class QSGParticleAffector;
64 class QSGParticleEmitter;
65 class QSGParticlePainter;
66 class QSGParticleData;
67 class QSGParticleSystemAnimation;
68 class QSGSpriteEngine;
70 class QSGV8ParticleData;
72 struct QSGParticleDataHeapNode{
74 QSet<QSGParticleData*> data;//Set ptrs instead?
77 class QSGParticleDataHeap {
78 //Idea is to do a binary heap, but which also stores a set of int,Node* so that if the int already exists, you can
79 //add it to the data* list. Pops return the whole list at once.
81 QSGParticleDataHeap();
82 void insert(QSGParticleData* data);
86 QSet<QSGParticleData*> pop();
90 bool contains(QSGParticleData*);//O(n), for debugging purposes only
98 QSGParticleDataHeapNode m_tmp;
99 QVector<QSGParticleDataHeapNode> m_data;
100 QHash<int,int> m_lookups;
103 class QSGParticleGroupData{
105 QSGParticleGroupData(int id, QSGParticleSystem* sys);
106 ~QSGParticleGroupData();
111 void setSize(int newSize);
114 QSet<QSGParticlePainter*> painters;
116 //TODO: Refactor particle data list out into a separate class
117 QVector<QSGParticleData*> data;
118 QSGParticleDataHeap dataHeap;
119 QSet<int> reusableIndexes;
122 void kill(QSGParticleData* d);
124 //After calling this, initialize, then call prepareRecycler(d)
125 QSGParticleData* newDatum(bool respectsLimits);
127 //TODO: Find and clean up those that don't get added to the recycler (currently they get lost)
128 void prepareRecycler(QSGParticleData* d);
132 QSGParticleSystem* m_system;
142 class QSGParticleData{
144 //TODO: QObject like memory management (without the cost, just attached to system)
145 QSGParticleData(QSGParticleSystem* sys);
147 //Convenience functions for working backwards, because parameters are from the start of particle life
148 //If setting multiple parameters at once, doing the conversion yourself will be faster.
150 //sets the x accleration without affecting the instantaneous x velocity or position
151 void setInstantaneousAX(qreal ax);
152 //sets the x velocity without affecting the instantaneous x postion
153 void setInstantaneousVX(qreal vx);
154 //sets the instantaneous x postion
155 void setInstantaneousX(qreal x);
156 //sets the y accleration without affecting the instantaneous y velocity or position
157 void setInstantaneousAY(qreal ay);
158 //sets the y velocity without affecting the instantaneous y postion
159 void setInstantaneousVY(qreal vy);
160 //sets the instantaneous Y postion
161 void setInstantaneousY(qreal y);
163 //TODO: Slight caching?
166 qreal curAX() const { return ax; }
169 qreal curAY() const { return ay; }
172 QSGParticleEmitter* e;//### Needed?
173 QSGParticleSystem* system;
177 //General Position Stuff
189 //Other stuff, now universally shared
197 float autoRotate;//Assume that GPUs prefer floats to bools
210 void clone(const QSGParticleData& other);//Not =, leaves meta-data like index
211 QDeclarativeV8Handle v8Value();
213 QSGV8ParticleData* v8Datum;
216 class QSGParticleSystem : public QSGItem
219 Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged)
220 Q_PROPERTY(int startTime READ startTime WRITE setStartTime NOTIFY startTimeChanged)
221 Q_PROPERTY(QDeclarativeListProperty<QSGSprite> particleStates READ particleStates)
224 explicit QSGParticleSystem(QSGItem *parent = 0);
225 ~QSGParticleSystem();
226 QDeclarativeListProperty<QSGSprite> particleStates();
228 //TODO: Hook up running and temporal manipulators to the animation
229 bool isRunning() const
234 int startTime() const
239 int count(){ return m_particle_count; }
243 void systemInitialized();
244 void runningChanged(bool arg);
246 void startTimeChanged(int arg);
251 void setRunning(bool arg);
254 void setStartTime(int arg)
259 void fastForward(int ms)
264 virtual int duration() const { return -1; }
267 //This one only once per frame (effectively)
268 void componentComplete();
271 void emittersChanged();
272 void loadPainter(QObject* p);
273 void createEngine(); //### method invoked by sprite list changing (in engine.h) - pretty nasty
274 void particleStateChange(int idx);
276 public://###but only really for related class usage. Perhaps we should all be friends?
277 //These can be called multiple times per frame, performance critical
278 void emitParticle(QSGParticleData* p);
279 QSGParticleData* newDatum(int groupId, bool respectLimits = true, int sysIdx = -1);//TODO: implement respectLimits in emitters (which means interacting with maxCount?)
280 void finishNewDatum(QSGParticleData*);
281 void moveGroups(QSGParticleData *d, int newGIdx);
282 int nextSystemIndex();
284 //This one only once per painter per frame
285 int systemSync(QSGParticlePainter* p);
287 QSet<QSGParticleData*> m_needsReset;
288 QVector<QSGParticleData*> m_bySysIdx; //Another reference to the data (data owned by group), but by sysIdx
289 QHash<QString, int> m_groupIds;
290 QHash<int, QSGParticleGroupData*> m_groupData;
291 QSGSpriteEngine* m_spriteEngine;
296 void registerParticlePainter(QSGParticlePainter* p);
297 void registerParticleEmitter(QSGParticleEmitter* e);
298 void registerParticleAffector(QSGParticleAffector* a);
300 int m_particle_count;
301 static void stateRedirect(QDeclarativeListProperty<QObject> *prop, QObject *value);//From QSGSprite
303 void initializeSystem();
305 QList<QPointer<QSGParticleEmitter> > m_emitters;
306 QList<QPointer<QSGParticleAffector> > m_affectors;
307 QList<QPointer<QSGParticlePainter> > m_particlePainters;
308 QList<QPointer<QSGParticlePainter> > m_syncList;
312 QSet<int> m_reusableIndexes;
313 bool m_componentComplete;
314 QList<QSGSprite*> m_states;
316 QSignalMapper m_painterMapper;
317 QSignalMapper m_emitterMapper;
318 friend class QSGParticleSystemAnimation;
319 void updateCurrentTime( int currentTime );
320 QSGParticleSystemAnimation* m_animation;
323 // Internally, this animation drives all the timing. Painters sync up in their updatePaintNode
324 class QSGParticleSystemAnimation : public QAbstractAnimation
328 QSGParticleSystemAnimation(QSGParticleSystem* system)
329 : QAbstractAnimation(static_cast<QObject*>(system)), m_system(system)
332 virtual void updateCurrentTime( int t )
334 m_system->updateCurrentTime(t);
337 virtual int duration() const
343 QSGParticleSystem* m_system;
351 #endif // PARTICLESYSTEM_H