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
67QQmlComponent *QQuick3DParticleModelParticle::delegate()
const
69 return m_delegate.data();
72void QQuick3DParticleModelParticle::setDelegate(QQmlComponent *delegate)
74 if (delegate == m_delegate)
76 m_delegate = delegate;
79 Q_EMIT delegateChanged();
92 void clear() { m_instances.clear(); m_sortData.clear(); }
95 const QVector3D &scale,
96 const QVector3D &eulerRotation,
99 auto entry = calculateTableEntry(position, scale, eulerRotation, color);
100 m_instances.append(
reinterpret_cast<
char *>(&entry),
sizeof(InstanceTableEntry));
102 m_sortData.append({age,
int(m_instances.size() /
sizeof(InstanceTableEntry))});
106 m_ageSorting = enable;
107 m_inverted = inverted;
113 *instanceCount =
int(m_instances.size() /
sizeof(InstanceTableEntry));
117 return m_sortedInstances;
125 std::sort(m_sortData.begin(), m_sortData.end(), [&](
const SortData &a,
const SortData &b) {
126 return a.age < b.age;
129 std::sort(m_sortData.begin(), m_sortData.end(), [&](
const SortData &a,
const SortData &b) {
130 return a.age > b.age;
133 m_sortedInstances.resize(m_instances.size());
134 const InstanceTableEntry *src =
reinterpret_cast<InstanceTableEntry *>(m_instances.data());
135 InstanceTableEntry *dst =
reinterpret_cast<InstanceTableEntry *>(m_sortedInstances.data());
136 for (
auto &e : m_sortData)
137 *dst++ = src[e.index];
141 QList<SortData> m_sortData;
142 QByteArray m_instances;
143 QByteArray m_sortedInstances;
144 bool m_ageSorting =
false;
145 bool m_inverted =
false;
148void QQuick3DParticleModelParticle::handleSortModeChanged(QQuick3DParticle::SortMode mode)
150 if (m_instanceTable) {
151 if (mode == QQuick3DParticle::SortNewest || mode == QQuick3DParticle::SortOldest)
152 m_instanceTable->setSorting(
true, mode == QQuick3DParticle::SortNewest);
154 m_instanceTable->setSorting(
false);
155 m_instanceTable->setDepthSortingEnabled(mode == QQuick3DParticle::SortDistance);
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
202QQuick3DInstancing *QQuick3DParticleModelParticle::instanceTable()
const
204 return m_instanceTable;
207void QQuick3DParticleModelParticle::clearInstanceTable()
210 m_instanceTable->clear();
213void QQuick3DParticleModelParticle::addInstance(
const QVector3D &position,
const QVector3D &scale,
const QVector3D &eulerRotation,
const QColor &color,
float age)
216 m_instanceTable->addInstance(position, scale, eulerRotation, color, age);
219void QQuick3DParticleModelParticle::commitInstance()
221 if (m_instanceTable) {
222 m_instanceTable->setHasTransparency(hasTransparency());
223 m_instanceTable->commit();
227static void setInstancing(QQuick3DNode *node, QQuick3DInstancing *instanceTable,
float bias)
229 auto *asModel = qobject_cast<QQuick3DModel *>(node);
231 asModel->setInstancing(instanceTable);
232 asModel->setDepthBias(bias);
234 const auto children = node->childItems();
235 for (
auto *child : children) {
236 auto *childNode = qobject_cast<QQuick3DNode *>(child);
238 setInstancing(childNode, instanceTable, bias);
242void QQuick3DParticleModelParticle::updateDepthBias(
float bias)
244 setInstancing(m_node, m_instanceTable, bias);
247void QQuick3DParticleModelParticle::regenerate()
252 if (!isComponentComplete() || !parentItem())
255 if (!m_instanceTable) {
256 m_instanceTable =
new QQuick3DParticleInstanceTable();
257 m_instanceTable->setParent(
this);
258 m_instanceTable->setParentItem(
this);
259 emit instanceTableChanged();
261 m_instanceTable->clear();
264 if (m_delegate.isNull())
267 auto *obj = m_delegate->create(m_delegate->creationContext());
269 m_node = qobject_cast<QQuick3DNode *>(obj);
271 setInstancing(m_node, m_instanceTable, depthBias());
272 auto *particleSystem = system();
273 m_node->setParent(particleSystem);
274 m_node->setParentItem(particleSystem);
280void QQuick3DParticleModelParticle::componentComplete()
282 if (!system() && qobject_cast<QQuick3DParticleSystem *>(parentItem()))
283 setSystem(qobject_cast<QQuick3DParticleSystem *>(parentItem()));
285 QQuick3DParticle::componentComplete();
289void QQuick3DParticleModelParticle::itemChange(QQuick3DObject::ItemChange change,
const QQuick3DObject::ItemChangeData &value)
291 QQuick3DObject::itemChange(change, value);
292 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)