9
10
11
12
13
14
15
16
17
19QQuick3DParticleModelParticle::QQuick3DParticleModelParticle(QQuick3DNode *parent)
20 : QQuick3DParticle(parent)
21 , m_initialScale(1.0f, 1.0f, 1.0f)
23 QObject::connect(
this, &QQuick3DParticle::maxAmountChanged,
this, [
this]() {
24 handleMaxAmountChanged(m_maxAmount);
26 QObject::connect(
this, &QQuick3DParticle::sortModeChanged,
this, [
this]() {
27 handleSortModeChanged(sortMode());
31void QQuick3DParticleModelParticle::handleMaxAmountChanged(
int amount)
33 if (m_particleData.size() == amount)
36 m_particleData.resize(amount);
37 m_particleData.fill({});
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65QQmlComponent *QQuick3DParticleModelParticle::delegate()
const
67 return m_delegate.data();
70void QQuick3DParticleModelParticle::setDelegate(QQmlComponent *delegate)
72 if (delegate == m_delegate)
74 m_delegate = delegate;
77 Q_EMIT delegateChanged();
90 void clear() { m_instances.clear(); m_sortData.clear(); }
93 const QVector3D &scale,
94 const QVector3D &eulerRotation,
97 auto entry = calculateTableEntry(position, scale, eulerRotation, color);
98 m_instances.append(
reinterpret_cast<
char *>(&entry),
sizeof(InstanceTableEntry));
100 m_sortData.append({age,
int(m_instances.size() /
sizeof(InstanceTableEntry))});
104 m_ageSorting = enable;
105 m_inverted = inverted;
111 *instanceCount =
int(m_instances.size() /
sizeof(InstanceTableEntry));
115 return m_sortedInstances;
123 std::sort(m_sortData.begin(), m_sortData.end(), [&](
const SortData &a,
const SortData &b) {
124 return a.age < b.age;
127 std::sort(m_sortData.begin(), m_sortData.end(), [&](
const SortData &a,
const SortData &b) {
128 return a.age > b.age;
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];
139 QList<SortData> m_sortData;
140 QByteArray m_instances;
141 QByteArray m_sortedInstances;
142 bool m_ageSorting =
false;
143 bool m_inverted =
false;
146void QQuick3DParticleModelParticle::handleSortModeChanged(QQuick3DParticle::SortMode mode)
148 if (m_instanceTable) {
149 if (mode == QQuick3DParticle::SortNewest || mode == QQuick3DParticle::SortOldest)
150 m_instanceTable->setSorting(
true, mode == QQuick3DParticle::SortNewest);
152 m_instanceTable->setSorting(
false);
153 m_instanceTable->setDepthSortingEnabled(mode == QQuick3DParticle::SortDistance);
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
200QQuick3DInstancing *QQuick3DParticleModelParticle::instanceTable()
const
202 return m_instanceTable;
205void QQuick3DParticleModelParticle::clearInstanceTable()
208 m_instanceTable->clear();
211void QQuick3DParticleModelParticle::addInstance(
const QVector3D &position,
const QVector3D &scale,
const QVector3D &eulerRotation,
const QColor &color,
float age)
214 m_instanceTable->addInstance(position, scale, eulerRotation, color, age);
217void QQuick3DParticleModelParticle::commitInstance()
219 if (m_instanceTable) {
220 m_instanceTable->setHasTransparency(hasTransparency());
221 m_instanceTable->commit();
225static void setInstancing(QQuick3DNode *node, QQuick3DInstancing *instanceTable,
float bias)
227 auto *asModel = qobject_cast<QQuick3DModel *>(node);
229 asModel->setInstancing(instanceTable);
230 asModel->setDepthBias(bias);
232 const auto children = node->childItems();
233 for (
auto *child : children) {
234 auto *childNode = qobject_cast<QQuick3DNode *>(child);
236 setInstancing(childNode, instanceTable, bias);
240void QQuick3DParticleModelParticle::updateDepthBias(
float bias)
242 setInstancing(m_node, m_instanceTable, bias);
245void QQuick3DParticleModelParticle::regenerate()
250 if (!isComponentComplete() || !parentItem())
253 if (!m_instanceTable) {
254 m_instanceTable =
new QQuick3DParticleInstanceTable();
255 m_instanceTable->setParent(
this);
256 m_instanceTable->setParentItem(
this);
257 emit instanceTableChanged();
259 m_instanceTable->clear();
262 if (m_delegate.isNull())
265 auto *obj = m_delegate->create(m_delegate->creationContext());
267 m_node = qobject_cast<QQuick3DNode *>(obj);
269 setInstancing(m_node, m_instanceTable, depthBias());
270 auto *particleSystem = system();
271 m_node->setParent(particleSystem);
272 m_node->setParentItem(particleSystem);
278void QQuick3DParticleModelParticle::componentComplete()
280 if (!system() && qobject_cast<QQuick3DParticleSystem *>(parentItem()))
281 setSystem(qobject_cast<QQuick3DParticleSystem *>(parentItem()));
283 QQuick3DParticle::componentComplete();
287void QQuick3DParticleModelParticle::itemChange(QQuick3DObject::ItemChange change,
const QQuick3DObject::ItemChangeData &value)
289 QQuick3DObject::itemChange(change, value);
290 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)
static void setInstancing(QQuick3DNode *node, QQuick3DInstancing *instanceTable, float bias)