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