341 QVector<QVector3D> indicedPositions;
342 QVector<QVector3D> positions;
343 if (QQuick3DGeometry *geometry = model->geometry()) {
344 bool hasIndexBuffer =
false;
345 QQuick3DGeometry::Attribute::ComponentType indexBufferFormat;
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;
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) {
363 memcpy(v, data + posOffset + i,
sizeof(v));
365 positions.append(matrix->mapVector(QVector3D(v[0], v[1], v[2])));
367 positions.append(QVector3D(v[0], v[1], v[2]));
369 if (hasIndexBuffer) {
370 const auto &data = geometry->indexData();
372 if (indexBufferFormat == QQuick3DGeometry::Attribute::U16Type)
374 for (
int i = 0; i < data.size(); i += indexSize) {
376 memcpy(&index, data + i, indexSize);
377 if (positions.size() > index)
378 indicedPositions.append(positions[index]);
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(
"#")));
388 src = QQmlFile::urlToLocalFileOrQrc(context->resolvedUrl(model->source()));
390 QSSGMesh::Mesh mesh = loadModelShapeMesh(src);
391 if (mesh.isValid() && mesh.drawMode() == QSSGMesh::Mesh::DrawMode::Triangles) {
392 auto entries = mesh.vertexBuffer().entries;
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;
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) {
411 memcpy(v, data + posOffset + i,
sizeof(v));
413 positions.append(matrix->map(QVector3D(v[0], v[1], v[2])));
415 positions.append(QVector3D(v[0], v[1], v[2]));
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) {
421 memcpy(&index, indexData + i, indexSize);
422 if (positions.size() > index)
423 indicedPositions.append(positions[index]);
428 if (!indicedPositions.empty())
429 return indicedPositions;
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]
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)