1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#ifndef QQUICK3DSPRITEPARTICLE_H
5#define QQUICK3DSPRITEPARTICLE_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 <QColor>
19#include <QVector4D>
20#include <QtQml/QQmlListProperty>
21
22#include <QtQuick3DParticles/private/qquick3dparticle_p.h>
23#include <QtQuick3DParticles/private/qquick3dparticlesystem_p.h>
24#include <QtQuick3DParticles/private/qquick3dparticledata_p.h>
25#include <QtQuick3DParticles/private/qquick3dparticlespritesequence_p.h>
26#include <QtQuick3D/private/qquick3dabstractlight_p.h>
27#include <QtQuick3DRuntimeRender/private/qssgrenderparticles_p.h>
28
29QT_BEGIN_NAMESPACE
30
31class Q_QUICK3DPARTICLES_EXPORT QQuick3DParticleSpriteParticle : public QQuick3DParticle
32{
33 Q_OBJECT
34 Q_PROPERTY(BlendMode blendMode READ blendMode WRITE setBlendMode NOTIFY blendModeChanged)
35 Q_PROPERTY(QQuick3DTexture *sprite READ sprite WRITE setSprite NOTIFY spriteChanged)
36 Q_PROPERTY(QQuick3DParticleSpriteSequence *spriteSequence READ spriteSequence WRITE setSpriteSequence NOTIFY spriteSequenceChanged)
37 Q_PROPERTY(bool billboard READ billboard WRITE setBillboard NOTIFY billboardChanged)
38 Q_PROPERTY(float particleScale READ particleScale WRITE setParticleScale NOTIFY particleScaleChanged)
39 Q_PROPERTY(QQuick3DTexture *colorTable READ colorTable WRITE setColorTable NOTIFY colorTableChanged)
40 Q_PROPERTY(QQmlListProperty<QQuick3DAbstractLight> lights READ lights NOTIFY lightsChanged REVISION(6, 3))
41 Q_PROPERTY(float offsetX READ offsetX WRITE setOffsetX NOTIFY offsetXChanged REVISION(6, 3))
42 Q_PROPERTY(float offsetY READ offsetY WRITE setOffsetY NOTIFY offsetYChanged REVISION(6, 3))
43 Q_PROPERTY(bool castsReflections READ castsReflections WRITE setCastsReflections NOTIFY castsReflectionsChanged REVISION(6, 4))
44 QML_NAMED_ELEMENT(SpriteParticle3D)
45 QML_ADDED_IN_VERSION(6, 2)
46
47public:
48 enum BlendMode { SourceOver = 0, Screen, Multiply };
49 Q_ENUM(BlendMode)
50
51 QQuick3DParticleSpriteParticle(QQuick3DNode *parent = nullptr);
52 ~QQuick3DParticleSpriteParticle() override;
53
54 BlendMode blendMode() const;
55 QQuick3DTexture *sprite() const;
56 QQuick3DParticleSpriteSequence *spriteSequence() const;
57 bool billboard() const;
58 float particleScale() const;
59 QQuick3DTexture *colorTable() const;
60 Q_REVISION(6, 3) QQmlListProperty<QQuick3DAbstractLight> lights();
61 float offsetX() const;
62 float offsetY() const;
63 Q_REVISION(6, 4) bool castsReflections() const;
64
65public Q_SLOTS:
66 void setBlendMode(QQuick3DParticleSpriteParticle::BlendMode blendMode);
67 void setSprite(QQuick3DTexture *sprite);
68 void setSpriteSequence(QQuick3DParticleSpriteSequence *spriteSequence);
69 void setBillboard(bool billboard);
70 void setParticleScale(float scale);
71 void setColorTable(QQuick3DTexture *colorTable);
72 void setOffsetX(float value);
73 void setOffsetY(float value);
74 Q_REVISION(6, 4) void setCastsReflections(bool castsReflections);
75
76Q_SIGNALS:
77 void blendModeChanged();
78 void spriteChanged();
79 void spriteSequenceChanged();
80 void billboardChanged();
81 void particleScaleChanged();
82 void colorTableChanged();
83 Q_REVISION(6, 3) void lightsChanged();
84 Q_REVISION(6, 3) void offsetXChanged();
85 Q_REVISION(6, 3) void offsetYChanged();
86 Q_REVISION(6, 4) void castsReflectionsChanged();
87
88protected:
89 void itemChange(ItemChange, const ItemChangeData &) override;
90 void reset() override;
91 void componentComplete() override;
92 int nextCurrentIndex(const QQuick3DParticleEmitter *emitter) override;
93 virtual void setParticleData(int particleIndex,
94 const QVector3D &position,
95 const QVector3D &rotation,
96 const QVector4D &color,
97 float size, float age,
98 float animationFrame);
99 virtual void resetParticleData(int particleIndex);
100 virtual void commitParticles(float);
101 void setDepthBias(float bias) override
102 {
103 QQuick3DParticle::setDepthBias(bias);
104 markNodesDirty();
105 }
106
107private Q_SLOTS:
108 void onLightDestroyed(QObject *object);
109
110public:
111 friend class QQuick3DParticleSystem;
112 friend class QQuick3DParticleEmitter;
113 friend class QQuick3DParticleSpriteSequence;
114
115 enum FeatureLevel
116 {
117 Simple = 0,
118 Mapped,
119 Animated,
120 SimpleVLight,
121 MappedVLight,
122 AnimatedVLight
123 };
124
125 struct SpriteParticleData
126 {
127 QVector3D position;
128 QVector3D rotation;
129 QVector4D color;
130 float size = 0.0f;
131 float age = 0.0f;
132 float animationFrame = -1.0f;
133 int emitterIndex = -1;
134 };
135
136 class ParticleUpdateNode : public QQuick3DNode
137 {
138 public:
139 ParticleUpdateNode(QQuick3DNode *parent = nullptr)
140 : QQuick3DNode(parent)
141 {
142 }
143 QSSGRenderGraphObject *updateSpatialNode(QSSGRenderGraphObject *node) override;
144 QQuick3DParticleSpriteParticle *m_particle = nullptr;
145 bool m_nodeDirty = true;
146 };
147 friend class ParticleUpdateNode;
148
149 struct PerEmitterData
150 {
151 ParticleUpdateNode *particleUpdateNode = nullptr;
152 int particleCount = 0;
153 int emitterIndex = -1;
154 const QQuick3DParticleEmitter *emitter = nullptr;
155 };
156
157 PerEmitterData &perEmitterData(const QQuick3DNode *updateNode);
158 PerEmitterData &perEmitterData(int emitterIndex);
159 QSSGRenderGraphObject *updateParticleNode(const ParticleUpdateNode *updateNode, QSSGRenderGraphObject *node);
160
161protected:
162 virtual void handleMaxAmountChanged(int amount);
163 virtual void handleSystemChanged(QQuick3DParticleSystem *system);
164 void updateNodes();
165 void deleteNodes();
166 void markNodesDirty();
167
168 QMap<const QQuick3DParticleEmitter *, PerEmitterData> m_perEmitterData;
169 QVector<SpriteParticleData> m_spriteParticleData;
170 int m_nextEmitterIndex = 0;
171 FeatureLevel m_featureLevel = FeatureLevel::Simple;
172
173private:
174 static QSSGRenderParticles::FeatureLevel mapFeatureLevel(QQuick3DParticleSpriteParticle::FeatureLevel level);
175
176 void updateParticleBuffer(ParticleUpdateNode *updateNode, QSSGRenderGraphObject *node);
177 void updateAnimatedParticleBuffer(ParticleUpdateNode *updateNode, QSSGRenderGraphObject *node);
178 void updateSceneManager(QQuick3DSceneManager *window);
179
180
181 // Call this whenever features which may affect the level change
182 void updateFeatureLevel();
183
184 QHash<QByteArray, QMetaObject::Connection> m_connections;
185 PerEmitterData n_noPerEmitterData;
186 BlendMode m_blendMode = SourceOver;
187 QQuick3DTexture *m_sprite = nullptr;
188 QQuick3DTexture *m_colorTable = nullptr;
189 float m_particleScale = 5.0f;
190 bool m_billboard = false;
191 bool m_useAnimatedParticle = false;
192
193 // Lights
194 Q_REVISION(6, 3) static void qmlAppendLight(QQmlListProperty<QQuick3DAbstractLight> *list, QQuick3DAbstractLight *light);
195 Q_REVISION(6, 3) static QQuick3DAbstractLight *qmlLightAt(QQmlListProperty<QQuick3DAbstractLight> *list, qsizetype index);
196 Q_REVISION(6, 3) static qsizetype qmlLightsCount(QQmlListProperty<QQuick3DAbstractLight> *list);
197 Q_REVISION(6, 3) static void qmlClearLights(QQmlListProperty<QQuick3DAbstractLight> *list);
198 QVector<QQuick3DAbstractLight *> m_lights;
199 QVector3D m_offset = {};
200 bool m_castsReflections = true;
201};
202
203QT_END_NAMESPACE
204
205#endif
206
207

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