Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquick3dparticleutils.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// Qt-Security score:significant reason:default
4
5
7#include <QtQuick3D/private/qquick3dnode_p.h>
8#include <QtQuick3D/private/qquick3dmodel_p.h>
9
10#include <QtQuick3DRuntimeRender/private/qssgrenderbuffermanager_p.h>
11
12#include <QtQuick3D/QQuick3DGeometry>
13#include <QtGui/qquaternion.h>
14#include <QtCore/qdir.h>
15
16#include <iterator>
17
18QT_BEGIN_NAMESPACE
19
20Q_CONSTINIT const float qt_quick3d_sine_table[] = {
21 float(0.0),
22 float(0.024541228522912288),
23 float(0.049067674327418015),
24 float(0.073564563599667426),
25 float(0.098017140329560604),
26 float(0.1224106751992162),
27 float(0.14673047445536175),
28 float(0.17096188876030122),
29 float(0.19509032201612825),
30 float(0.2191012401568698),
31 float(0.24298017990326387),
32 float(0.26671275747489837),
33 float(0.29028467725446233),
34 float(0.31368174039889152),
35 float(0.33688985339222005),
36 float(0.35989503653498811),
37 float(0.38268343236508978),
38 float(0.40524131400498986),
39 float(0.42755509343028208),
40 float(0.44961132965460654),
41 float(0.47139673682599764),
42 float(0.49289819222978404),
43 float(0.51410274419322166),
44 float(0.53499761988709715),
45 float(0.55557023301960218),
46 float(0.57580819141784534),
47 float(0.59569930449243336),
48 float(0.61523159058062682),
49 float(0.63439328416364549),
50 float(0.65317284295377676),
51 float(0.67155895484701833),
52 float(0.68954054473706683),
53 float(0.70710678118654746),
54 float(0.72424708295146689),
55 float(0.74095112535495911),
56 float(0.75720884650648446),
57 float(0.77301045336273699),
58 float(0.78834642762660623),
59 float(0.80320753148064483),
60 float(0.81758481315158371),
61 float(0.83146961230254524),
62 float(0.84485356524970701),
63 float(0.85772861000027212),
64 float(0.87008699110871135),
65 float(0.88192126434835494),
66 float(0.89322430119551532),
67 float(0.90398929312344334),
68 float(0.91420975570353069),
69 float(0.92387953251128674),
70 float(0.93299279883473885),
71 float(0.94154406518302081),
72 float(0.94952818059303667),
73 float(0.95694033573220894),
74 float(0.96377606579543984),
75 float(0.97003125319454397),
76 float(0.97570213003852857),
77 float(0.98078528040323043),
78 float(0.98527764238894122),
79 float(0.98917650996478101),
80 float(0.99247953459870997),
81 float(0.99518472667219682),
82 float(0.99729045667869021),
83 float(0.99879545620517241),
84 float(0.99969881869620425),
85 float(1.0),
86 float(0.99969881869620425),
87 float(0.99879545620517241),
88 float(0.99729045667869021),
89 float(0.99518472667219693),
90 float(0.99247953459870997),
91 float(0.98917650996478101),
92 float(0.98527764238894122),
93 float(0.98078528040323043),
94 float(0.97570213003852857),
95 float(0.97003125319454397),
96 float(0.96377606579543984),
97 float(0.95694033573220894),
98 float(0.94952818059303667),
99 float(0.94154406518302081),
100 float(0.93299279883473885),
101 float(0.92387953251128674),
102 float(0.91420975570353069),
103 float(0.90398929312344345),
104 float(0.89322430119551521),
105 float(0.88192126434835505),
106 float(0.87008699110871146),
107 float(0.85772861000027212),
108 float(0.84485356524970723),
109 float(0.83146961230254546),
110 float(0.81758481315158371),
111 float(0.80320753148064494),
112 float(0.78834642762660634),
113 float(0.7730104533627371),
114 float(0.75720884650648468),
115 float(0.74095112535495899),
116 float(0.72424708295146689),
117 float(0.70710678118654757),
118 float(0.68954054473706705),
119 float(0.67155895484701855),
120 float(0.65317284295377664),
121 float(0.63439328416364549),
122 float(0.61523159058062693),
123 float(0.59569930449243347),
124 float(0.57580819141784545),
125 float(0.55557023301960218),
126 float(0.53499761988709715),
127 float(0.51410274419322177),
128 float(0.49289819222978415),
129 float(0.47139673682599786),
130 float(0.44961132965460687),
131 float(0.42755509343028203),
132 float(0.40524131400498992),
133 float(0.38268343236508989),
134 float(0.35989503653498833),
135 float(0.33688985339222033),
136 float(0.31368174039889141),
137 float(0.29028467725446239),
138 float(0.26671275747489848),
139 float(0.24298017990326407),
140 float(0.21910124015687005),
141 float(0.19509032201612861),
142 float(0.17096188876030122),
143 float(0.1467304744553618),
144 float(0.12241067519921635),
145 float(0.098017140329560826),
146 float(0.073564563599667732),
147 float(0.049067674327417966),
148 float(0.024541228522912326),
149 float(0.0),
150 float(-0.02454122852291208),
151 float(-0.049067674327417724),
152 float(-0.073564563599667496),
153 float(-0.09801714032956059),
154 float(-0.1224106751992161),
155 float(-0.14673047445536158),
156 float(-0.17096188876030097),
157 float(-0.19509032201612836),
158 float(-0.2191012401568698),
159 float(-0.24298017990326382),
160 float(-0.26671275747489825),
161 float(-0.29028467725446211),
162 float(-0.31368174039889118),
163 float(-0.33688985339222011),
164 float(-0.35989503653498811),
165 float(-0.38268343236508967),
166 float(-0.40524131400498969),
167 float(-0.42755509343028181),
168 float(-0.44961132965460665),
169 float(-0.47139673682599764),
170 float(-0.49289819222978393),
171 float(-0.51410274419322155),
172 float(-0.53499761988709693),
173 float(-0.55557023301960196),
174 float(-0.57580819141784534),
175 float(-0.59569930449243325),
176 float(-0.61523159058062671),
177 float(-0.63439328416364527),
178 float(-0.65317284295377653),
179 float(-0.67155895484701844),
180 float(-0.68954054473706683),
181 float(-0.70710678118654746),
182 float(-0.72424708295146678),
183 float(-0.74095112535495888),
184 float(-0.75720884650648423),
185 float(-0.77301045336273666),
186 float(-0.78834642762660589),
187 float(-0.80320753148064505),
188 float(-0.81758481315158382),
189 float(-0.83146961230254524),
190 float(-0.84485356524970701),
191 float(-0.85772861000027201),
192 float(-0.87008699110871135),
193 float(-0.88192126434835494),
194 float(-0.89322430119551521),
195 float(-0.90398929312344312),
196 float(-0.91420975570353047),
197 float(-0.92387953251128652),
198 float(-0.93299279883473896),
199 float(-0.94154406518302081),
200 float(-0.94952818059303667),
201 float(-0.95694033573220882),
202 float(-0.96377606579543984),
203 float(-0.97003125319454397),
204 float(-0.97570213003852846),
205 float(-0.98078528040323032),
206 float(-0.98527764238894111),
207 float(-0.9891765099647809),
208 float(-0.99247953459871008),
209 float(-0.99518472667219693),
210 float(-0.99729045667869021),
211 float(-0.99879545620517241),
212 float(-0.99969881869620425),
213 float(-1.0),
214 float(-0.99969881869620425),
215 float(-0.99879545620517241),
216 float(-0.99729045667869021),
217 float(-0.99518472667219693),
218 float(-0.99247953459871008),
219 float(-0.9891765099647809),
220 float(-0.98527764238894122),
221 float(-0.98078528040323043),
222 float(-0.97570213003852857),
223 float(-0.97003125319454397),
224 float(-0.96377606579543995),
225 float(-0.95694033573220894),
226 float(-0.94952818059303679),
227 float(-0.94154406518302092),
228 float(-0.93299279883473907),
229 float(-0.92387953251128663),
230 float(-0.91420975570353058),
231 float(-0.90398929312344334),
232 float(-0.89322430119551532),
233 float(-0.88192126434835505),
234 float(-0.87008699110871146),
235 float(-0.85772861000027223),
236 float(-0.84485356524970723),
237 float(-0.83146961230254546),
238 float(-0.81758481315158404),
239 float(-0.80320753148064528),
240 float(-0.78834642762660612),
241 float(-0.77301045336273688),
242 float(-0.75720884650648457),
243 float(-0.74095112535495911),
244 float(-0.724247082951467),
245 float(-0.70710678118654768),
246 float(-0.68954054473706716),
247 float(-0.67155895484701866),
248 float(-0.65317284295377709),
249 float(-0.63439328416364593),
250 float(-0.61523159058062737),
251 float(-0.59569930449243325),
252 float(-0.57580819141784523),
253 float(-0.55557023301960218),
254 float(-0.53499761988709726),
255 float(-0.51410274419322188),
256 float(-0.49289819222978426),
257 float(-0.47139673682599792),
258 float(-0.44961132965460698),
259 float(-0.42755509343028253),
260 float(-0.40524131400499042),
261 float(-0.38268343236509039),
262 float(-0.359895036534988),
263 float(-0.33688985339222),
264 float(-0.31368174039889152),
265 float(-0.2902846772544625),
266 float(-0.26671275747489859),
267 float(-0.24298017990326418),
268 float(-0.21910124015687016),
269 float(-0.19509032201612872),
270 float(-0.17096188876030177),
271 float(-0.14673047445536239),
272 float(-0.12241067519921603),
273 float(-0.098017140329560506),
274 float(-0.073564563599667412),
275 float(-0.049067674327418091),
276 float(-0.024541228522912448)
277};
279
280QQuick3DNode *getSharedParentNode(QQuick3DNode *node, QQuick3DNode *system) {
281 QQuick3DNode *systemSharedParent = nullptr;
282 if (node && system) {
283 QVector<QQuick3DNode *> parents;
284 QQuick3DNode *parent = node->parentNode();
285 while (parent) {
286 parents.append(parent);
287 parent = parent->parentNode();
288 }
289
290 parent = system;
291 while (parent) {
292 if (parents.contains(parent)) {
293 systemSharedParent = parent;
294 break;
295 }
296 parent = parent->parentNode();
297 }
298 }
299 return systemSharedParent;
300}
301
302QMatrix4x4 calculateParticleTransform(const QQuick3DNode *parent, const QQuick3DNode *systemSharedParent)
303{
304 QMatrix4x4 transform = parent->sceneTransform();
305 if (systemSharedParent)
306 transform = systemSharedParent->sceneTransform().inverted() * transform;
307 return transform;
308}
309
310QQuaternion calculateParticleRotation(const QQuick3DNode *parent, const QQuick3DNode *systemSharedParent)
311{
312 QQuaternion rotation = parent->sceneRotation();
313 if (systemSharedParent)
314 rotation = systemSharedParent->sceneRotation().inverted() * rotation;
315 return rotation;
316}
317
318static QSSGMesh::Mesh loadModelShapeMesh(const QString &source)
319{
320 QString src = source;
321 if (source.startsWith(QLatin1Char('#'))) {
322 src = QSSGBufferManager::primitivePath(source);
323 src.prepend(QLatin1String(":/"));
324 }
325 src = QDir::cleanPath(src);
326 if (src.startsWith(QLatin1String("qrc:/")))
327 src = src.mid(3);
328 QSSGMesh::Mesh mesh;
329 QFileInfo fileInfo = QFileInfo(src);
330 if (fileInfo.exists()) {
331 QFile file(fileInfo.absoluteFilePath());
332 if (!file.open(QFile::ReadOnly))
333 return {};
334 mesh = QSSGMesh::Mesh::loadMesh(&file);
335 }
336 return mesh;
337}
338
339QList<QVector3D> positionsFromModel(QQuick3DModel *model, const QMatrix4x4 *matrix, QQmlContext *context)
340{
341 QVector<QVector3D> indicedPositions;
342 QVector<QVector3D> positions;
343 if (QQuick3DGeometry *geometry = model->geometry()) {
344 bool hasIndexBuffer = false;
345 QQuick3DGeometry::Attribute::ComponentType indexBufferFormat;
346 int posOffset = 0;
347 QQuick3DGeometry::Attribute::ComponentType posType = QQuick3DGeometry::Attribute::U16Type;
348 for (int i = 0; i < geometry->attributeCount(); ++i) {
349 auto attribute = geometry->attribute(i);
350 if (attribute.semantic == QQuick3DGeometry::Attribute::PositionSemantic) {
351 posOffset = attribute.offset;
352 posType = attribute.componentType;
353 } else if (attribute.semantic == QQuick3DGeometry::Attribute::IndexSemantic) {
354 hasIndexBuffer = true;
355 indexBufferFormat = attribute.componentType;
356 }
357 }
358 if (posType == QQuick3DGeometry::Attribute::F32Type) {
359 const auto &data = geometry->vertexData();
360 int stride = geometry->stride();
361 for (int i = 0; i < data.size(); i += stride) {
362 float v[3];
363 memcpy(v, data + posOffset + i, sizeof(v));
364 if (matrix)
365 positions.append(matrix->mapVector(QVector3D(v[0], v[1], v[2])));
366 else
367 positions.append(QVector3D(v[0], v[1], v[2]));
368 }
369 if (hasIndexBuffer) {
370 const auto &data = geometry->indexData();
371 int indexSize = 4;
372 if (indexBufferFormat == QQuick3DGeometry::Attribute::U16Type)
373 indexSize = 2;
374 for (int i = 0; i < data.size(); i += indexSize) {
375 qsizetype index = 0;
376 memcpy(&index, data + i, indexSize);
377 if (positions.size() > index)
378 indicedPositions.append(positions[index]);
379 }
380 }
381 }
382 } else {
383 QString src = model->source().toString();
384 if (context && !src.startsWith(QLatin1Char('#'))) {
385 if (src.contains(QStringLiteral("#")))
386 src = src.right(src.length() - src.lastIndexOf(QStringLiteral("#")));
387 else
388 src = QQmlFile::urlToLocalFileOrQrc(context->resolvedUrl(model->source()));
389 }
390 QSSGMesh::Mesh mesh = loadModelShapeMesh(src);
391 if (mesh.isValid() && mesh.drawMode() == QSSGMesh::Mesh::DrawMode::Triangles) {
392 auto entries = mesh.vertexBuffer().entries;
393 int posOffset = 0;
394 int posCount = 0;
395 // Just set 'posType' to something to avoid invalid 'maybe-uninitialized' warning
396 QSSGMesh::Mesh::ComponentType posType = QSSGMesh::Mesh::ComponentType::UnsignedInt8;
397 for (int i = 0; i < entries.size(); ++i) {
398 const char *nameStr = entries[i].name.constData();
399 if (!strcmp(nameStr, QSSGMesh::MeshInternal::getPositionAttrName())) {
400 posOffset = entries[i].offset;
401 posCount = entries[i].componentCount;
402 posType = entries[i].componentType;
403 break;
404 }
405 }
406 if (posCount == 3 && posType == QSSGMesh::Mesh::ComponentType::Float32) {
407 const auto &data = mesh.vertexBuffer().data;
408 int stride = mesh.vertexBuffer().stride;
409 for (int i = 0; i < data.size(); i += stride) {
410 float v[3];
411 memcpy(v, data + posOffset + i, sizeof(v));
412 if (matrix)
413 positions.append(matrix->map(QVector3D(v[0], v[1], v[2])));
414 else
415 positions.append(QVector3D(v[0], v[1], v[2]));
416 }
417 const auto &indexData = mesh.indexBuffer().data;
418 int indexSize = QSSGMesh::MeshInternal::byteSizeForComponentType(mesh.indexBuffer().componentType);
419 for (int i = 0; i < indexData.size(); i += indexSize) {
420 qsizetype index = 0;
421 memcpy(&index, indexData + i, indexSize);
422 if (positions.size() > index)
423 indicedPositions.append(positions[index]);
424 }
425 }
426 }
427 }
428 if (!indicedPositions.empty())
429 return indicedPositions;
430 return positions;
431}
432
433QT_END_NAMESPACE
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition qmatrix4x4.h:27
static QSSGMesh::Mesh loadModelShapeMesh(const QString &source)
QQuick3DNode * getSharedParentNode(QQuick3DNode *node, QQuick3DNode *system)
Q_QUICK3DPARTICLES_EXPORT const float qt_quick3d_sine_table[QT_QUICK3D_SINE_TABLE_SIZE]
#define QT_QUICK3D_SINE_TABLE_SIZE
QList< QVector3D > positionsFromModel(QQuick3DModel *model, const QMatrix4x4 *matrix, QQmlContext *context)
QMatrix4x4 calculateParticleTransform(const QQuick3DNode *parent, const QQuick3DNode *systemSharedParent)
QQuaternion calculateParticleRotation(const QQuick3DNode *parent, const QQuick3DNode *systemSharedParent)