1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
4#ifndef QQUICK3DMODELBLENDPARTICLE_H
5#define QQUICK3DMODELBLENDPARTICLE_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 <QMatrix4x4>
21
22#include <QtQuick3DParticles/private/qquick3dparticle_p.h>
23#include <QtQuick3DParticles/private/qquick3dparticlesystem_p.h>
24#include <QtQuick3DParticles/private/qquick3dparticledata_p.h>
25#include <QtQuick3D/private/qquick3dmodel_p.h>
26#include <QtQuick3D/private/qquick3dgeometry_p.h>
27
28QT_BEGIN_NAMESPACE
29
30struct QSSGParticleBuffer;
31class Q_QUICK3DPARTICLES_EXPORT QQuick3DParticleModelBlendParticle : public QQuick3DParticle
32{
33 Q_OBJECT
34 Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)
35 Q_PROPERTY(QQuick3DNode *endNode READ endNode WRITE setEndNode NOTIFY endNodeChanged)
36 Q_PROPERTY(ModelBlendMode modelBlendMode READ modelBlendMode WRITE setModelBlendMode NOTIFY modelBlendModeChanged)
37 Q_PROPERTY(int endTime READ endTime WRITE setEndTime NOTIFY endTimeChanged)
38 Q_PROPERTY(QQuick3DNode *activationNode READ activationNode WRITE setActivationNode NOTIFY activationNodeChanged)
39 Q_PROPERTY(ModelBlendEmitMode emitMode READ emitMode WRITE setEmitMode NOTIFY emitModeChanged)
40 QML_NAMED_ELEMENT(ModelBlendParticle3D)
41 QML_ADDED_IN_VERSION(6, 2)
42
43public:
44 QQuick3DParticleModelBlendParticle(QQuick3DNode *parent = nullptr);
45 ~QQuick3DParticleModelBlendParticle() override;
46
47 enum ModelBlendMode
48 {
49 Explode,
50 Construct,
51 Transfer
52 };
53 Q_ENUM(ModelBlendMode)
54
55 enum ModelBlendEmitMode
56 {
57 Sequential,
58 Random,
59 Activation
60 };
61 Q_ENUM(ModelBlendEmitMode)
62
63 QQmlComponent *delegate() const;
64 QQuick3DNode *endNode() const;
65 ModelBlendMode modelBlendMode() const;
66 int endTime() const;
67 QQuick3DNode *activationNode() const;
68 ModelBlendEmitMode emitMode() const;
69
70public Q_SLOTS:
71 void setDelegate(QQmlComponent *setDelegate);
72 void setEndNode(QQuick3DNode *endNode);
73 void setEndTime(int endTime);
74 void setModelBlendMode(ModelBlendMode mode);
75 void setActivationNode(QQuick3DNode *activationNode);
76 void setEmitMode(ModelBlendEmitMode emitMode);
77
78Q_SIGNALS:
79 void delegateChanged();
80 void blendFactorChanged();
81 void endNodeChanged();
82 void modelBlendModeChanged();
83 void endTimeChanged();
84 void activationNodeChanged();
85 void emitModeChanged();
86
87protected:
88 void itemChange(ItemChange, const ItemChangeData &) override;
89 void reset() override;
90 bool lastParticle() const;
91 void doSetMaxAmount(int amount) override;
92 void componentComplete() override;
93 int nextCurrentIndex(const QQuick3DParticleEmitter *emitter) override;
94 void setParticleData(int particleIndex,
95 const QVector3D &position,
96 const QVector3D &rotation,
97 const QVector4D &color,
98 float size, float age);
99 QVector3D particleCenter(int particleIndex) const;
100 QVector3D particleEndPosition(int particleIndex) const;
101 QVector3D particleEndRotation(int particleIndex) const;
102 int randomIndex(int particleIndex);
103 void commitParticles()
104 {
105 markAllDirty();
106 update();
107 }
108
109private:
110 friend class QQuick3DParticleSystem;
111 friend class QQuick3DParticleEmitter;
112
113 struct TriangleParticleData
114 {
115 QVector3D position;
116 QVector3D rotation;
117 QVector3D center;
118 QVector4D color;
119 float age = 0.0f;
120 float size = 1.0f;
121 int emitterIndex = -1;
122 };
123
124 struct PerEmitterData
125 {
126 int particleCount = 0;
127 int emitterIndex = -1;
128 const QQuick3DParticleEmitter *emitter = nullptr;
129 };
130
131 QSSGRenderGraphObject *updateSpatialNode(QSSGRenderGraphObject *node) override;
132 void updateParticleBuffer(QSSGParticleBuffer *buffer, const QMatrix4x4 &sceneTransform);
133 void regenerate();
134 void updateParticles();
135 void handleEndNodeChanged();
136 PerEmitterData &perEmitterData(int emitterIndex);
137
138 QVector<TriangleParticleData> m_triangleParticleData;
139 QVector<QVector3D> m_centerData;
140 QHash<QByteArray, QMetaObject::Connection> m_connections;
141 QMap<const QQuick3DParticleEmitter *, PerEmitterData> m_perEmitterData;
142 QVector<int> m_randomParticles;
143 PerEmitterData n_noPerEmitterData;
144 int m_nextEmitterIndex = 0;
145 bool m_bufferUpdated = false;
146 QQmlComponent *m_delegate = nullptr;
147 QQuick3DModel *m_model = nullptr;
148 QQuick3DGeometry *m_modelGeometry = nullptr;
149 QQuick3DNode *m_endNode = nullptr;
150 QVector3D m_endNodePosition;
151 QVector3D m_endNodeRotation;
152 QVector3D m_endNodeScale;
153 QMatrix4x4 m_endRotationMatrix;
154 int m_particleCount = 0;
155 ModelBlendMode m_modelBlendMode = Explode;
156 int m_endTime = 0;
157 bool m_dataChanged = true;
158 ModelBlendEmitMode m_emitMode = Sequential;
159 QQuick3DNode *m_activationNode = nullptr;
160 float m_maxTriangleRadius = 0.f;
161};
162
163QT_END_NAMESPACE
164
165#endif
166

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