Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qquick3dparticlemodelparticle.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
5
7
20 : QQuick3DParticle(parent)
21 , m_initialScale(1.0f, 1.0f, 1.0f)
22{
24 handleMaxAmountChanged(m_maxAmount);
25 });
27 handleSortModeChanged(sortMode());
28 });
29}
30
31void QQuick3DParticleModelParticle::handleMaxAmountChanged(int amount)
32{
33 if (m_particleData.size() == amount)
34 return;
35
36 m_particleData.resize(amount);
38}
39
66{
67 return m_delegate.data();
68}
69
71{
72 if (delegate == m_delegate)
73 return;
74 m_delegate = delegate;
75
76 regenerate();
78}
79
81{
82 struct SortData
83 {
84 float age;
85 int index;
86 };
87
88public:
90 void clear() { m_instances.clear(); m_sortData.clear(); }
91 void commit() { sort(); markDirty(); }
93 const QVector3D &scale,
94 const QVector3D &eulerRotation,
95 const QColor &color,
96 float age) {
97 auto entry = calculateTableEntry(position, scale, eulerRotation, color);
98 m_instances.append(reinterpret_cast<char *>(&entry), sizeof(InstanceTableEntry));
99 if (m_ageSorting)
100 m_sortData.append({age, int(m_instances.size() / sizeof(InstanceTableEntry))});
101 }
102 void setSorting(bool enable, bool inverted = false)
103 {
104 m_ageSorting = enable;
105 m_inverted = inverted;
106 }
107protected:
109 {
110 if (instanceCount)
111 *instanceCount = int(m_instances.size() / sizeof(InstanceTableEntry));
112
113 if (!m_ageSorting)
114 return m_instances;
115 return m_sortedInstances;
116 }
117 void sort()
118 {
119 if (!m_ageSorting)
120 return;
121
122 if (m_inverted) {
123 std::sort(m_sortData.begin(), m_sortData.end(), [&](const SortData &a, const SortData &b) {
124 return a.age < b.age;
125 });
126 } else {
127 std::sort(m_sortData.begin(), m_sortData.end(), [&](const SortData &a, const SortData &b) {
128 return a.age > b.age;
129 });
130 }
131 m_sortedInstances.resize(m_instances.size());
132 const InstanceTableEntry *src = reinterpret_cast<InstanceTableEntry *>(m_instances.data());
133 InstanceTableEntry *dst = reinterpret_cast<InstanceTableEntry *>(m_sortedInstances.data());
134 for (auto &e : m_sortData)
135 *dst++ = src[e.index];
136 }
137
138private:
139 QList<SortData> m_sortData;
140 QByteArray m_instances;
141 QByteArray m_sortedInstances;
142 bool m_ageSorting = false;
143 bool m_inverted = false;
144};
145
146void QQuick3DParticleModelParticle::handleSortModeChanged(QQuick3DParticle::SortMode mode)
147{
148 if (m_instanceTable) {
150 m_instanceTable->setSorting(true, mode == QQuick3DParticle::SortNewest);
151 else
152 m_instanceTable->setSorting(false);
154 }
155}
156
201{
202 return m_instanceTable;
203}
204
205void QQuick3DParticleModelParticle::clearInstanceTable()
206{
207 if (m_instanceTable)
208 m_instanceTable->clear();
209}
210
211void QQuick3DParticleModelParticle::addInstance(const QVector3D &position, const QVector3D &scale, const QVector3D &eulerRotation, const QColor &color, float age)
212{
213 if (m_instanceTable)
214 m_instanceTable->addInstance(position, scale, eulerRotation, color, age);
215}
216
217void QQuick3DParticleModelParticle::commitInstance()
218{
219 if (m_instanceTable) {
220 m_instanceTable->setHasTransparency(hasTransparency());
221 m_instanceTable->commit();
222 }
223}
224
225static void setInstancing(QQuick3DNode *node, QQuick3DInstancing *instanceTable, float bias)
226{
227 auto *asModel = qobject_cast<QQuick3DModel *>(node);
228 if (asModel) {
229 asModel->setInstancing(instanceTable);
230 asModel->setDepthBias(bias);
231 }
232 const auto children = node->childItems();
233 for (auto *child : children) {
234 auto *childNode = qobject_cast<QQuick3DNode *>(child);
235 if (childNode)
236 setInstancing(childNode, instanceTable, bias);
237 }
238}
239
240void QQuick3DParticleModelParticle::updateDepthBias(float bias)
241{
242 setInstancing(m_node, m_instanceTable, bias);
243}
244
245void QQuick3DParticleModelParticle::regenerate()
246{
247 delete m_node;
248 m_node = nullptr;
249
250 if (!isComponentComplete())
251 return;
252
253 if (!m_instanceTable) {
254 m_instanceTable = new QQuick3DParticleInstanceTable();
255 m_instanceTable->setParent(this);
256 m_instanceTable->setParentItem(this);
258 } else {
259 m_instanceTable->clear();
260 }
261
262 if (m_delegate.isNull())
263 return;
264
265 auto *obj = m_delegate->create(m_delegate->creationContext());
266
267 m_node = qobject_cast<QQuick3DNode *>(obj);
268 if (m_node) {
269 setInstancing(m_node, m_instanceTable, depthBias());
270 auto *particleSystem = system();
271 m_node->setParent(particleSystem);
272 m_node->setParentItem(particleSystem);
273 } else {
274 delete obj;
275 }
276}
277
279{
280 if (!system() && qobject_cast<QQuick3DParticleSystem *>(parentItem()))
281 setSystem(qobject_cast<QQuick3DParticleSystem *>(parentItem()));
282
284 regenerate();
285}
286
287void QQuick3DParticleModelParticle::itemChange(QQuick3DObject::ItemChange change, const QQuick3DObject::ItemChangeData &value)
288{
290 if (change == ItemParentHasChanged)
291 regenerate();
292}
293
\inmodule QtCore
Definition qbytearray.h:57
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
Definition qbytearray.h:611
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
Definition qbytearray.h:494
void clear()
Clears the contents of the byte array and makes it null.
void resize(qsizetype size)
Sets the size of the byte array to size bytes.
QByteArray & append(char c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
qsizetype size() const noexcept
Definition qlist.h:397
QList< T > & fill(parameter_type t, qsizetype size=-1)
Definition qlist.h:903
iterator end()
Definition qlist.h:626
iterator begin()
Definition qlist.h:625
void resize(qsizetype size)
Definition qlist.h:403
void append(parameter_type t)
Definition qlist.h:458
void clear()
Definition qlist.h:434
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
void setParent(QObject *parent)
Makes the object a child of parent.
Definition qobject.cpp:2195
T * data() const noexcept
Definition qpointer.h:73
bool isNull() const noexcept
Definition qpointer.h:84
The QQmlComponent class encapsulates a QML component definition.
QQmlContext * creationContext() const
Returns the QQmlContext the component was created in.
virtual QObject * create(QQmlContext *context=nullptr)
Create an object instance from this component, within the specified context.
\inmodule QtQuick3D \inherits QQuick3DObject
void setHasTransparency(bool hasTransparency)
void markDirty()
Mark that the instance data has changed and must be uploaded again.
void setDepthSortingEnabled(bool enabled)
static InstanceTableEntry calculateTableEntry(const QVector3D &position, const QVector3D &scale, const QVector3D &eulerRotation, const QColor &color, const QVector4D &customData={})
Converts the position scale eulerRotation color and customData to the instance table format expected ...
void setParentItem(QQuick3DObject *parentItem)
virtual void itemChange(ItemChange, const ItemChangeData &)
bool isComponentComplete() const
QByteArray getInstanceBuffer(int *instanceCount) override
Implement this function to return the contents of the instance table.
void setSorting(bool enable, bool inverted=false)
void addInstance(const QVector3D &position, const QVector3D &scale, const QVector3D &eulerRotation, const QColor &color, float age)
void setDelegate(QQmlComponent *delegate)
void itemChange(ItemChange change, const ItemChangeData &value) override
QQuick3DParticleModelParticle(QQuick3DNode *parent=nullptr)
\qmltype ModelParticle3D \inherits Particle3D \inqmlmodule QtQuick3D.Particles3D
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
float depthBias() const
void sortModeChanged()
void maxAmountChanged()
QList< QQuick3DParticleData > m_particleData
void setSystem(QQuick3DParticleSystem *system)
QQuick3DParticleSystem * system() const
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
The QVector3D class represents a vector or vertex in 3D space.
Definition qvectornd.h:171
Combined button and popup list for selecting options.
static int instanceCount
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLboolean GLboolean GLboolean b
GLenum mode
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint index
[2]
GLenum src
GLuint color
[2]
GLenum GLenum dst
GLboolean enable
GLhandleARB obj
[2]
GLuint entry
GLfloat bias
GLenum GLenum GLenum GLenum GLenum scale
static void setInstancing(QQuick3DNode *node, QQuick3DInstancing *instanceTable, float bias)
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
#define Q_EMIT
#define emit
QLayoutItem * child
[0]