11
12
13
14
15
16
17
18
19
21QQuick3DParticleModelParticle::QQuick3DParticleModelParticle(QQuick3DNode *parent)
22 : QQuick3DParticle(parent)
23 , m_initialScale(1.0f, 1.0f, 1.0f)
25 QObject::connect(
this, &QQuick3DParticle::maxAmountChanged,
this, [
this]() {
26 handleMaxAmountChanged(m_maxAmount);
28 QObject::connect(
this, &QQuick3DParticle::sortModeChanged,
this, [
this]() {
29 handleSortModeChanged(sortMode());
33void QQuick3DParticleModelParticle::handleMaxAmountChanged(
int amount)
35 if (m_particleData.size() == amount)
38 m_particleData.resize(amount);
39 m_particleData.fill({});
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
73QQmlComponent *QQuick3DParticleModelParticle::delegate()
const
75 return m_delegate.data();
78void QQuick3DParticleModelParticle::setDelegate(QQmlComponent *delegate)
80 if (delegate == m_delegate)
82 m_delegate = delegate;
85 Q_EMIT delegateChanged();
98 void clear() { m_instances.clear(); m_sortData.clear(); }
101 const QVector3D &scale,
102 const QVector3D &eulerRotation,
105 auto entry = calculateTableEntry(position, scale, eulerRotation, color);
106 m_instances.append(
reinterpret_cast<
char *>(&entry),
sizeof(InstanceTableEntry));
108 m_sortData.append({age,
int(m_instances.size() /
sizeof(InstanceTableEntry))});
112 m_ageSorting = enable;
113 m_inverted = inverted;
119 *instanceCount =
int(m_instances.size() /
sizeof(InstanceTableEntry));
123 return m_sortedInstances;
131 std::sort(m_sortData.begin(), m_sortData.end(), [&](
const SortData &a,
const SortData &b) {
132 return a.age < b.age;
135 std::sort(m_sortData.begin(), m_sortData.end(), [&](
const SortData &a,
const SortData &b) {
136 return a.age > b.age;
139 m_sortedInstances.resize(m_instances.size());
140 const InstanceTableEntry *src =
reinterpret_cast<InstanceTableEntry *>(m_instances.data());
141 InstanceTableEntry *dst =
reinterpret_cast<InstanceTableEntry *>(m_sortedInstances.data());
142 for (
auto &e : m_sortData)
143 *dst++ = src[e.index];
147 QList<SortData> m_sortData;
148 QByteArray m_instances;
149 QByteArray m_sortedInstances;
150 bool m_ageSorting =
false;
151 bool m_inverted =
false;
154void QQuick3DParticleModelParticle::handleSortModeChanged(QQuick3DParticle::SortMode mode)
156 if (m_instanceTable) {
157 if (mode == QQuick3DParticle::SortNewest || mode == QQuick3DParticle::SortOldest)
158 m_instanceTable->setSorting(
true, mode == QQuick3DParticle::SortNewest);
160 m_instanceTable->setSorting(
false);
161 m_instanceTable->setDepthSortingEnabled(mode == QQuick3DParticle::SortDistance);
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
208QQuick3DInstancing *QQuick3DParticleModelParticle::instanceTable()
const
210 return m_instanceTable;
213void QQuick3DParticleModelParticle::clearInstanceTable()
216 m_instanceTable->clear();
219void QQuick3DParticleModelParticle::addInstance(
const QVector3D &position,
const QVector3D &scale,
const QVector3D &eulerRotation,
const QColor &color,
float age)
222 m_instanceTable->addInstance(position, scale, eulerRotation, color, age);
225void QQuick3DParticleModelParticle::commitInstance()
227 if (m_instanceTable) {
228 m_instanceTable->setHasTransparency(hasTransparency());
229 m_instanceTable->commit();
233static void setInstancing(QQuick3DNode *node, QQuick3DInstancing *instanceTable,
float bias)
235 auto *asModel = qobject_cast<QQuick3DModel *>(node);
237 asModel->setInstancing(instanceTable);
238 asModel->setDepthBias(bias);
240 const auto children = node->childItems();
241 for (
auto *child : children) {
242 auto *childNode = qobject_cast<QQuick3DNode *>(child);
244 setInstancing(childNode, instanceTable, bias);
248void QQuick3DParticleModelParticle::updateDepthBias(
float bias)
250 setInstancing(m_node, m_instanceTable, bias);
253void QQuick3DParticleModelParticle::regenerate()
258 if (!isComponentComplete() || !parentItem())
261 if (!m_instanceTable) {
262 m_instanceTable =
new QQuick3DParticleInstanceTable();
263 m_instanceTable->setParent(
this);
264 m_instanceTable->setParentItem(
this);
265 emit instanceTableChanged();
267 m_instanceTable->clear();
270 if (m_delegate.isNull())
273 auto *obj = m_delegate->create(m_delegate->creationContext());
275 m_node = qobject_cast<QQuick3DNode *>(obj);
277 setInstancing(m_node, m_instanceTable, depthBias());
278 auto *particleSystem = system();
279 m_node->setParent(particleSystem);
280 m_node->setParentItem(particleSystem);
286void QQuick3DParticleModelParticle::componentComplete()
288 if (!system() && qobject_cast<QQuick3DParticleSystem *>(parentItem()))
289 setSystem(qobject_cast<QQuick3DParticleSystem *>(parentItem()));
291 QQuick3DParticle::componentComplete();
295void QQuick3DParticleModelParticle::itemChange(QQuick3DObject::ItemChange change,
const QQuick3DObject::ItemChangeData &value)
297 QQuick3DObject::itemChange(change, value);
298 if (change == ItemParentHasChanged)
QByteArray getInstanceBuffer(int *instanceCount) override
Implement this function to return the contents of the instance table.
void setSorting(bool enable, bool inverted=false)
QQuick3DParticleInstanceTable()
void addInstance(const QVector3D &position, const QVector3D &scale, const QVector3D &eulerRotation, const QColor &color, float age)
Combined button and popup list for selecting options.
static void setInstancing(QQuick3DNode *node, QQuick3DInstancing *instanceTable, float bias)