1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#ifndef QQUICK3DPPARTICLESYSTEM_H
5#define QQUICK3DPPARTICLESYSTEM_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtQuick3DParticles/qtquick3dparticlesglobal.h>
19#include <QtQuick3D/private/qquick3dnode_p.h>
20#include <QtQuick3D/private/qquick3ddefaultmaterial_p.h>
21#include <QtQuick3D/private/qquick3dprincipledmaterial_p.h>
22#include <QtQuick3D/private/qquick3dloader_p.h>
23#include <QtQuick3DParticles/private/qquick3dparticlesystemlogging_p.h>
24#include <QtQuick3DParticles/private/qquick3dparticlerandomizer_p.h>
25#include <QtQuick3DParticles/private/qquick3dparticledata_p.h>
26#include <QElapsedTimer>
27#include <QVector>
28#include <QList>
29#include <QHash>
30#include <QPointer>
31#include <QAbstractAnimation>
32#include <QtQml/qqml.h>
33#include <QElapsedTimer>
34#include <QTimer>
35
36QT_BEGIN_NAMESPACE
37
38class QQuick3DParticleSpriteParticle;
39class QQuick3DParticleModelParticle;
40class QQuick3DParticleModelBlendParticle;
41class QQuick3DParticleEmitter;
42class QQuick3DParticleTrailEmitter;
43class QQuick3DParticleAffector;
44class QQuick3DParticleStatelessAffector;
45
46class QQuick3DParticle;
47class QQuick3DParticleSystemAnimation;
48class QQuick3DParticleSystemUpdate;
49class QQuick3DParticleInstanceTable;
50
51class Q_QUICK3DPARTICLES_EXPORT QQuick3DParticleSystem : public QQuick3DNode
52{
53 Q_OBJECT
54 Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged)
55 Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged)
56 Q_PROPERTY(int startTime READ startTime WRITE setStartTime NOTIFY startTimeChanged)
57 Q_PROPERTY(int time READ time WRITE setTime NOTIFY timeChanged)
58 Q_PROPERTY(bool useRandomSeed READ useRandomSeed WRITE setUseRandomSeed NOTIFY useRandomSeedChanged)
59 Q_PROPERTY(int seed READ seed WRITE setSeed NOTIFY seedChanged)
60 Q_PROPERTY(bool logging READ logging WRITE setLogging NOTIFY loggingChanged)
61 Q_PROPERTY(QQuick3DParticleSystemLogging *loggingData READ loggingData NOTIFY loggingDataChanged)
62 QML_NAMED_ELEMENT(ParticleSystem3D)
63 QML_ADDED_IN_VERSION(6, 2)
64
65public:
66 QQuick3DParticleSystem(QQuick3DNode *parent = nullptr);
67 ~QQuick3DParticleSystem() override;
68
69 bool isRunning() const;
70 bool isPaused() const;
71 int startTime() const;
72 int time() const;
73 bool useRandomSeed() const;
74 int seed() const;
75 // Return the total amount of particles
76 int particleCount() const;
77 bool logging() const;
78 QQuick3DParticleSystemLogging *loggingData() const;
79
80 // Registering of different components into system
81 void registerParticle(QQuick3DParticle *particle);
82 void unRegisterParticle(QQuick3DParticle *particle);
83 void registerParticleEmitter(QQuick3DParticleEmitter* e);
84 void unRegisterParticleEmitter(QQuick3DParticleEmitter* e);
85 void registerParticleAffector(QQuick3DParticleAffector* a);
86 void unRegisterParticleAffector(QQuick3DParticleAffector* a);
87
88 void updateCurrentTime(int currentTime);
89
90 QPRand *rand();
91 bool isShared(const QQuick3DParticle *particle) const;
92 int currentTime() const;
93
94 struct TrailEmits {
95 QQuick3DParticleTrailEmitter *emitter = nullptr;
96 int amount = 0;
97 };
98
99 Q_INVOKABLE void reset();
100
101public Q_SLOTS:
102 void setRunning(bool running);
103 void setPaused(bool paused);
104 void setStartTime(int startTime);
105 void setTime(int time);
106 void setUseRandomSeed(bool randomize);
107 void setSeed(int seed);
108 void setLogging(bool logging);
109
110 void setEditorTime(int time);
111
112Q_SIGNALS:
113 void runningChanged();
114 void pausedChanged();
115 void timeChanged();
116 void startTimeChanged();
117 void useRandomSeedChanged();
118 void seedChanged();
119 void loggingChanged();
120 void loggingDataChanged();
121
122protected:
123 void componentComplete() override;
124
125private:
126 void registerParticleModel(QQuick3DParticleModelParticle* m);
127 void registerParticleSprite(QQuick3DParticleSpriteParticle* m);
128 void updateLoggingData();
129 void resetLoggingVariables();
130 void doSeedRandomization();
131 void refresh();
132 void markDirty();
133 void processModelParticle(QQuick3DParticleModelParticle *modelParticle, const QVector<TrailEmits> &trailEmits, float timeS);
134 void processSpriteParticle(QQuick3DParticleSpriteParticle *spriteParticle, const QVector<TrailEmits> &trailEmits, float timeS);
135 void processModelBlendParticle(QQuick3DParticleModelBlendParticle *particle, const QVector<TrailEmits> &trailEmits, float timeS);
136 void processParticleCommon(QQuick3DParticleDataCurrent &currentData, const QQuick3DParticleData *d, float particleTimeS);
137 void processParticleFadeInOut(QQuick3DParticleDataCurrent &currentData, const QQuick3DParticle *particle, float particleTimeS, float particleTimeLeftS);
138 void processParticleAlignment(QQuick3DParticleDataCurrent &currentData, const QQuick3DParticle *particle, const QQuick3DParticleData *d);
139 static bool isGloballyDisabled();
140 static bool isEditorModeOn();
141
142private:
143 friend class QQuick3DParticleEmitter;
144 friend class QQuick3DParticleTrailEmitter;
145 friend class QQuick3DParticleSystemUpdate;
146 friend class QQuick3DParticleSystemAnimation;
147 friend class QQuick3DParticleModelBlendParticle;
148
149 bool m_running;
150 bool m_paused;
151 bool m_initialized;
152 bool m_componentComplete;
153 // This animation runs the system, progressing time with pause, continue etc.
154 QQuick3DParticleSystemAnimation *m_animation = nullptr;
155 // This animation handles system dirty updates and runs always.
156 // It makes sure that updates are done in sync with other animations and only once per frame.
157 QQuick3DParticleSystemUpdate *m_updateAnimation = nullptr;
158
159 QList<QQuick3DParticle *> m_particles;
160 QList<QQuick3DParticleEmitter *> m_emitters;
161 QList<QQuick3DParticleTrailEmitter *> m_trailEmitters;
162 QList<QQuick3DParticleAffector *> m_affectors;
163 QMap<QQuick3DParticleAffector *, QMetaObject::Connection> m_connections;
164
165 int m_startTime = 0;
166 // Current time in ms
167 int m_time = 0;
168 int m_currentTime = 0;
169
170 // This overrides the time when editor mode is on
171 int m_editorTime = 0;
172
173 QElapsedTimer m_perfTimer;
174 QTimer m_loggingTimer;
175 qint64 m_timeAnimation = 0;
176 int m_particlesMax = 0;
177 int m_particlesUsed = 0;
178 int m_updates = 0;
179 bool m_useRandomSeed = true;
180 int m_seed = 0;
181 bool m_logging;
182 QQuick3DParticleSystemLogging *m_loggingData = nullptr;
183 QPRand m_rand;
184 int m_particleIdIndex = 0;
185};
186
187class QQuick3DParticleSystemAnimation : public QAbstractAnimation
188{
189 Q_OBJECT
190public:
191 QQuick3DParticleSystemAnimation(QQuick3DParticleSystem *system)
192 : QAbstractAnimation(static_cast<QObject *>(system)), m_system(system)
193 { }
194protected:
195 void updateCurrentTime(int t) override
196 {
197 // Keep the time property up-to-date
198 if (!m_system->isEditorModeOn() && !m_system->isGloballyDisabled())
199 m_system->setTime(t);
200
201 m_system->updateCurrentTime(currentTime: t + m_system->startTime());
202 }
203
204 int duration() const override
205 {
206 return -1;
207 }
208
209private:
210 QQuick3DParticleSystem *m_system;
211};
212
213class QQuick3DParticleSystemUpdate : public QAbstractAnimation
214{
215 Q_OBJECT
216public:
217 QQuick3DParticleSystemUpdate(QQuick3DParticleSystem *system)
218 : QAbstractAnimation(static_cast<QObject *>(system)), m_system(system)
219 { }
220
221 void setDirty(bool dirty)
222 {
223 m_dirty = dirty;
224 }
225
226protected:
227 void updateCurrentTime(int t) override
228 {
229 Q_UNUSED(t);
230 if (m_dirty)
231 m_system->refresh();
232 }
233
234 int duration() const override
235 {
236 return -1;
237 }
238
239private:
240 QQuick3DParticleSystem *m_system;
241 bool m_dirty = false;
242};
243
244QT_END_NAMESPACE
245
246#endif // QQUICK3DPPARTICLESYSTEM_H
247
248
249

source code of qtquick3d/src/quick3dparticles/qquick3dparticlesystem_p.h