6#include <QtQuick3DUtils/private/qssgutils_p.h>
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
225QQuick3DGeometryPrivate::QQuick3DGeometryPrivate()
226 : QQuick3DObjectPrivate(QQuick3DObjectPrivate::Type::Geometry)
231QQuick3DGeometry::QQuick3DGeometry(QQuick3DObject *parent)
232 : QQuick3DObject(*
new QQuick3DGeometryPrivate, parent)
237QQuick3DGeometry::~QQuick3DGeometry()
243
244
245QByteArray QQuick3DGeometry::vertexData()
const
247 const Q_D(QQuick3DGeometry);
248 return d->m_vertexBuffer;
252
253
254
255
256QByteArray QQuick3DGeometry::targetData()
const
258 const Q_D(QQuick3DGeometry);
259 return d->m_targetBuffer;
263
264
265QByteArray QQuick3DGeometry::indexData()
const
267 const Q_D(QQuick3DGeometry);
268 return d->m_indexBuffer;
272
273
274
275
276int QQuick3DGeometry::attributeCount()
const
278 const Q_D(QQuick3DGeometry);
279 return d->m_attributeCount;
283
284
285
286
287QQuick3DGeometry::Attribute QQuick3DGeometry::attribute(
int index)
const
289 const Q_D(QQuick3DGeometry);
290 return d->m_attributes[index];
294
295
296
297
298
299int QQuick3DGeometry::targetAttributeCount()
const
301 const Q_D(QQuick3DGeometry);
302 return d->m_targetAttributeCount;
306
307
308
309
310
311
312QQuick3DGeometry::TargetAttribute QQuick3DGeometry::targetAttribute(
int index)
const
314 const Q_D(QQuick3DGeometry);
315 return d->m_targetAttributes[index];
319
320
321
322
323QQuick3DGeometry::PrimitiveType QQuick3DGeometry::primitiveType()
const
325 const Q_D(QQuick3DGeometry);
326 return d->m_primitiveType;
330
331
332
333
334QVector3D QQuick3DGeometry::boundsMin()
const
336 const Q_D(QQuick3DGeometry);
341
342
343
344
345QVector3D QQuick3DGeometry::boundsMax()
const
347 const Q_D(QQuick3DGeometry);
352
353
354
355
356int QQuick3DGeometry::stride()
const
358 const Q_D(QQuick3DGeometry);
362void QQuick3DGeometry::markAllDirty()
364 QQuick3DObject::markAllDirty();
368
369
370
371
372
373
374
375void QQuick3DGeometry::setVertexData(
const QByteArray &data)
377 Q_D(QQuick3DGeometry);
378 d->m_vertexBuffer = data;
379 d->m_geometryChanged =
true;
383
384
385
386
387
388
389
390
391
392
393
394
395
396void QQuick3DGeometry::setVertexData(
int offset,
const QByteArray &data)
398 Q_D(QQuick3DGeometry);
399 if (offset >= d->m_vertexBuffer.size())
402 const size_t len = qMin(d->m_vertexBuffer.size() - offset, data.size());
403 memcpy(d->m_vertexBuffer.data() + offset, data.data(), len);
405 d->m_geometryChanged =
true;
409
410
411
412
413
414
415
416void QQuick3DGeometry::setTargetData(
const QByteArray &data)
418 Q_D(QQuick3DGeometry);
419 d->m_targetBuffer = data;
420 d->m_targetChanged =
true;
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439void QQuick3DGeometry::setTargetData(
int offset,
const QByteArray &data)
441 Q_D(QQuick3DGeometry);
442 if (offset >= d->m_targetBuffer.size())
445 const size_t len = qMin(d->m_targetBuffer.size() - offset, data.size());
446 memcpy(d->m_targetBuffer.data() + offset, data.data(), len);
448 d->m_targetChanged =
true;
452
453
454
455
456void QQuick3DGeometry::setIndexData(
const QByteArray &data)
458 Q_D(QQuick3DGeometry);
459 d->m_indexBuffer = data;
460 d->m_geometryChanged =
true;
464
465
466
467
468
469
470
471
472
473
474
475
476
477void QQuick3DGeometry::setIndexData(
int offset,
const QByteArray &data)
479 Q_D(QQuick3DGeometry);
480 if (offset >= d->m_indexBuffer.size())
483 const size_t len = qMin(d->m_indexBuffer.size() - offset, data.size());
484 memcpy(d->m_indexBuffer.data() + offset, data.data(), len);
486 d->m_geometryChanged =
true;
490
491
492
493
494
495
496
497
498
499
500
501
502
503void QQuick3DGeometry::setStride(
int stride)
505 Q_D(QQuick3DGeometry);
506 if (stride != d->m_stride) {
507 d->m_stride = stride;
508 d->m_geometryChanged =
true;
513
514
515
516void QQuick3DGeometry::setBounds(
const QVector3D &min,
const QVector3D &max)
518 Q_D(QQuick3DGeometry);
521 d->m_geometryBoundsChanged =
true;
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548void QQuick3DGeometry::setPrimitiveType(PrimitiveType type)
550 Q_D(QQuick3DGeometry);
551 if (d->m_primitiveType != type) {
552 d->m_primitiveType = type;
553 d->m_geometryChanged =
true;
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608void QQuick3DGeometry::addAttribute(Attribute::Semantic semantic,
int offset,
609 Attribute::ComponentType componentType)
611 Q_D(QQuick3DGeometry);
612 if (semantic != Attribute::TargetPositionSemantic
613 && semantic != Attribute::TargetNormalSemantic
614 && semantic != Attribute::TargetTangentSemantic
615 && semantic != Attribute::TargetBinormalSemantic) {
616 if (d->m_attributeCount >= QQuick3DGeometryPrivate::MAX_ATTRIBUTE_COUNT)
618 d->m_attributes[d->m_attributeCount].semantic = semantic;
619 d->m_attributes[d->m_attributeCount].offset = offset;
620 d->m_attributes[d->m_attributeCount].componentType = componentType;
621 d->m_attributeCount++;
622 d->m_geometryChanged =
true;
624 if (d->m_targetAttributeCount >= QQuick3DGeometryPrivate::MAX_TARGET_ATTRIBUTE_COUNT)
626 d->m_targetAttributes[d->m_targetAttributeCount].targetId = 0;
627 d->m_targetAttributes[d->m_targetAttributeCount].attr.semantic = semantic;
628 d->m_targetAttributes[d->m_targetAttributeCount].attr.offset = offset;
630 d->m_targetAttributeCount++;
631 d->m_targetChanged =
true;
632 d->m_usesOldTargetSemantics =
true;
637
638
639
640
641
642
643
644void QQuick3DGeometry::addAttribute(
const Attribute &attribute)
646 Q_D(QQuick3DGeometry);
647 if (d->m_attributeCount >= QQuick3DGeometryPrivate::MAX_ATTRIBUTE_COUNT)
649 d->m_attributes[d->m_attributeCount++] = attribute;
650 d->m_geometryChanged =
true;
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674void QQuick3DGeometry::addTargetAttribute(quint32 targetId,
675 Attribute::Semantic semantic,
int offset,
678 Q_D(QQuick3DGeometry);
679 if (d->m_targetAttributeCount >= QQuick3DGeometryPrivate::MAX_TARGET_ATTRIBUTE_COUNT)
681 if (semantic == Attribute::IndexSemantic
682 || semantic == Attribute::JointSemantic
683 || semantic == Attribute::WeightSemantic)
685 d->m_targetAttributes[d->m_targetAttributeCount].targetId = targetId;
686 d->m_targetAttributes[d->m_targetAttributeCount].attr.semantic = semantic;
687 d->m_targetAttributes[d->m_targetAttributeCount].attr.offset = offset;
688 d->m_targetAttributes[d->m_targetAttributeCount].stride = stride;
689 d->m_targetAttributeCount++;
690 d->m_targetChanged =
true;
694
695
696
697
698
699
700
701
702void QQuick3DGeometry::addTargetAttribute(
const TargetAttribute &attribute)
704 Q_D(QQuick3DGeometry);
705 if (d->m_targetAttributeCount >= QQuick3DGeometryPrivate::MAX_TARGET_ATTRIBUTE_COUNT)
707 if (attribute.attr.semantic == Attribute::IndexSemantic ||
708 attribute.attr.semantic == Attribute::JointSemantic ||
709 attribute.attr.semantic == Attribute::WeightSemantic)
711 d->m_targetAttributes[d->m_targetAttributeCount++] = attribute;
712 d->m_targetChanged =
true;
716
717
718void QQuick3DGeometry::clear()
720 Q_D(QQuick3DGeometry);
721 d->m_vertexBuffer.clear();
722 d->m_targetBuffer.clear();
723 d->m_indexBuffer.clear();
724 d->m_attributeCount = 0;
725 d->m_targetAttributeCount = 0;
726 d->m_subsets.clear();
727 d->m_primitiveType = PrimitiveType::Triangles;
728 d->m_geometryChanged =
true;
729 d->m_targetChanged =
true;
735
736
737int QQuick3DGeometry::subsetCount()
const
739 Q_D(
const QQuick3DGeometry);
740 return d->m_subsets.size();
744
745
746
747
748QVector3D QQuick3DGeometry::subsetBoundsMin(
int subset)
const
750 Q_D(
const QQuick3DGeometry);
751 if (subset >= 0 && subset < d->m_subsets.size())
752 return d->m_subsets[subset].boundsMin;
757
758
759
760
761QVector3D QQuick3DGeometry::subsetBoundsMax(
int subset)
const
763 Q_D(
const QQuick3DGeometry);
764 if (subset >= 0 && subset < d->m_subsets.size())
765 return d->m_subsets[subset].boundsMax;
770
771
772
773
774int QQuick3DGeometry::subsetOffset(
int subset)
const
776 Q_D(
const QQuick3DGeometry);
777 if (subset >= 0 && subset < d->m_subsets.size())
778 return d->m_subsets[subset].offset;
783
784
785
786
787int QQuick3DGeometry::subsetCount(
int subset)
const
789 Q_D(
const QQuick3DGeometry);
790 if (subset >= 0 && subset < d->m_subsets.size())
791 return d->m_subsets[subset].count;
796
797
798QString QQuick3DGeometry::subsetName(
int subset)
const
800 Q_D(
const QQuick3DGeometry);
801 if (subset >= 0 && subset < d->m_subsets.size())
802 return d->m_subsets[subset].name;
807
808
809
810
811
812
813
814
815
816
817void QQuick3DGeometry::addSubset(
int offset,
int count,
const QVector3D &boundsMin,
const QVector3D &boundsMax,
const QString &name)
819 Q_D(QQuick3DGeometry);
820 d->m_subsets.append({name, boundsMin, boundsMax, quint32(offset), quint32(count)});
821 d->m_geometryChanged =
true;
827 case QQuick3DGeometry::PrimitiveType::Points:
828 return QSSGMesh::Mesh::DrawMode::Points;
829 case QQuick3DGeometry::PrimitiveType::LineStrip:
830 return QSSGMesh::Mesh::DrawMode::LineStrip;
831 case QQuick3DGeometry::PrimitiveType::Lines:
832 return QSSGMesh::Mesh::DrawMode::Lines;
833 case QQuick3DGeometry::PrimitiveType::TriangleStrip:
834 return QSSGMesh::Mesh::DrawMode::TriangleStrip;
835 case QQuick3DGeometry::PrimitiveType::TriangleFan:
836 return QSSGMesh::Mesh::DrawMode::TriangleFan;
837 case QQuick3DGeometry::PrimitiveType::Triangles:
838 return QSSGMesh::Mesh::DrawMode::Triangles;
841 Q_UNREACHABLE_RETURN(QSSGMesh::Mesh::DrawMode::Triangles);
847 case QQuick3DGeometry::Attribute::IndexSemantic:
848 return QSSGMesh::RuntimeMeshData::Attribute::IndexSemantic;
849 case QQuick3DGeometry::Attribute::PositionSemantic:
850 return QSSGMesh::RuntimeMeshData::Attribute::PositionSemantic;
851 case QQuick3DGeometry::Attribute::NormalSemantic:
852 return QSSGMesh::RuntimeMeshData::Attribute::NormalSemantic;
853 case QQuick3DGeometry::Attribute::TexCoord0Semantic:
854 return QSSGMesh::RuntimeMeshData::Attribute::TexCoord0Semantic;
855 case QQuick3DGeometry::Attribute::TexCoord1Semantic:
856 return QSSGMesh::RuntimeMeshData::Attribute::TexCoord1Semantic;
857 case QQuick3DGeometry::Attribute::TangentSemantic:
858 return QSSGMesh::RuntimeMeshData::Attribute::TangentSemantic;
859 case QQuick3DGeometry::Attribute::BinormalSemantic:
860 return QSSGMesh::RuntimeMeshData::Attribute::BinormalSemantic;
861 case QQuick3DGeometry::Attribute::JointSemantic:
862 return QSSGMesh::RuntimeMeshData::Attribute::JointSemantic;
863 case QQuick3DGeometry::Attribute::WeightSemantic:
864 return QSSGMesh::RuntimeMeshData::Attribute::WeightSemantic;
865 case QQuick3DGeometry::Attribute::ColorSemantic:
866 return QSSGMesh::RuntimeMeshData::Attribute::ColorSemantic;
867 case QQuick3DGeometry::Attribute::TargetPositionSemantic:
868 return QSSGMesh::RuntimeMeshData::Attribute::PositionSemantic;
869 case QQuick3DGeometry::Attribute::TargetNormalSemantic:
870 return QSSGMesh::RuntimeMeshData::Attribute::NormalSemantic;
871 case QQuick3DGeometry::Attribute::TargetTangentSemantic:
872 return QSSGMesh::RuntimeMeshData::Attribute::TangentSemantic;
873 case QQuick3DGeometry::Attribute::TargetBinormalSemantic:
874 return QSSGMesh::RuntimeMeshData::Attribute::BinormalSemantic;
877 Q_UNREACHABLE_RETURN(QSSGMesh::RuntimeMeshData::Attribute::PositionSemantic);
883 case QQuick3DGeometry::Attribute::U16Type:
884 return QSSGMesh::Mesh::ComponentType::UnsignedInt16;
885 case QQuick3DGeometry::Attribute::U32Type:
886 return QSSGMesh::Mesh::ComponentType::UnsignedInt32;
887 case QQuick3DGeometry::Attribute::I32Type:
888 return QSSGMesh::Mesh::ComponentType::Int32;
889 case QQuick3DGeometry::Attribute::F32Type:
890 return QSSGMesh::Mesh::ComponentType::Float32;
893 Q_UNREACHABLE_RETURN(QSSGMesh::Mesh::ComponentType::Float32);
897
898
899QSSGRenderGraphObject *QQuick3DGeometry::updateSpatialNode(QSSGRenderGraphObject *node)
901 Q_D(QQuick3DGeometry);
904 node =
new QSSGRenderGeometry();
905 emit geometryNodeDirty();
907 QQuick3DObject::updateSpatialNode(node);
908 QSSGRenderGeometry *geometry =
static_cast<QSSGRenderGeometry *>(node);
909 if (d->m_geometryChanged) {
910 geometry->clearVertexAndIndex();
911 geometry->setBounds(d->m_min, d->m_max);
912 geometry->setStride(d->m_stride);
914 if (d->m_stride < 1 && !d->m_vertexBuffer.isEmpty())
915 qWarning(
"%d is an invalid stride, was QQuick3DGeometry::setStride() called?", d->m_stride);
916 geometry->setIndexData(d->m_indexBuffer);
917 geometry->setVertexData(d->m_vertexBuffer);
918 geometry->setPrimitiveType(mapPrimitiveType(d->m_primitiveType));
919 quint32 indexBufferComponentSize = 0;
920 for (
int i = 0; i < d->m_attributeCount; ++i) {
921 const auto componentType = mapComponentType(d->m_attributes[i].componentType);
922 geometry->addAttribute(mapSemantic(d->m_attributes[i].semantic),
923 d->m_attributes[i].offset,
925 if (d->m_attributes[i].semantic == Attribute::IndexSemantic) {
926 if (componentType != QSSGMesh::Mesh::ComponentType::UnsignedInt16
927 && componentType != QSSGMesh::Mesh::ComponentType::UnsignedInt32)
929 qWarning(
"Index data can only be uint16 or uint32");
931 indexBufferComponentSize = QSSGMesh::MeshInternal::byteSizeForComponentType(componentType);
932 }
else if (componentType == QSSGMesh::Mesh::ComponentType::UnsignedInt16) {
933 qWarning(
"Attributes cannot be uint16, only index data");
936 if (!d->m_indexBuffer.isEmpty() && !indexBufferComponentSize) {
937 qWarning(
"IndexData has been set, but no index attribute found.");
938 geometry->setIndexData({});
941 if (d->m_subsets.isEmpty()) {
944 if (!d->m_indexBuffer.isEmpty() && indexBufferComponentSize)
945 count = d->m_indexBuffer.size() / indexBufferComponentSize;
946 else if (d->m_stride)
947 count = d->m_vertexBuffer.size() / d->m_stride;
948 geometry->addSubset(offset, count, d->m_min, d->m_max);
950 for (
auto &s : d->m_subsets)
951 geometry->addSubset(s.offset, s.count, s.boundsMin, s.boundsMax, s.name);
953 d->m_geometryChanged =
false;
954 emit geometryChanged();
956 if (d->m_geometryBoundsChanged) {
957 geometry->setBounds(d->m_min, d->m_max);
958 emit geometryNodeDirty();
959 d->m_geometryBoundsChanged =
false;
961 if (d->m_targetChanged) {
962 geometry->clearTarget();
963 geometry->setTargetData(d->m_usesOldTargetSemantics ? d->m_vertexBuffer : d->m_targetBuffer);
964 for (
int i = 0; i < d->m_targetAttributeCount; ++i) {
965 geometry->addTargetAttribute(d->m_targetAttributes[i].targetId,
966 mapSemantic(d->m_targetAttributes[i].attr.semantic),
967 d->m_targetAttributes[i].attr.offset,
968 d->m_usesOldTargetSemantics ? d->m_stride : d->m_targetAttributes[i].stride);
970 d->m_targetChanged =
false;
973 DebugViewHelpers::ensureDebugObjectName(geometry,
this);
978QQuick3DGeometry::Attribute::Semantic QQuick3DGeometryPrivate::semanticFromName(
const QByteArray &name)
980 static QMap<
const QByteArray, QQuick3DGeometry::Attribute::Semantic> semanticMap;
981 if (semanticMap.isEmpty()) {
982 semanticMap[QSSGMesh::MeshInternal::getPositionAttrName()] = QQuick3DGeometry::Attribute::PositionSemantic;
983 semanticMap[QSSGMesh::MeshInternal::getNormalAttrName()] = QQuick3DGeometry::Attribute::NormalSemantic;
984 semanticMap[QSSGMesh::MeshInternal::getUV0AttrName()] = QQuick3DGeometry::Attribute::TexCoord0Semantic;
985 semanticMap[QSSGMesh::MeshInternal::getUV1AttrName()] = QQuick3DGeometry::Attribute::TexCoord1Semantic;
986 semanticMap[QSSGMesh::MeshInternal::getTexTanAttrName()] = QQuick3DGeometry::Attribute::TangentSemantic;
987 semanticMap[QSSGMesh::MeshInternal::getTexBinormalAttrName()] = QQuick3DGeometry::Attribute::BinormalSemantic;
988 semanticMap[QSSGMesh::MeshInternal::getColorAttrName()] = QQuick3DGeometry::Attribute::ColorSemantic;
989 semanticMap[QSSGMesh::MeshInternal::getWeightAttrName()] = QQuick3DGeometry::Attribute::WeightSemantic;
990 semanticMap[QSSGMesh::MeshInternal::getJointAttrName()] = QQuick3DGeometry::Attribute::JointSemantic;
992 return semanticMap[name];
995QQuick3DGeometry::Attribute::ComponentType QQuick3DGeometryPrivate::toComponentType(QSSGMesh::Mesh::ComponentType ctype)
998 case QSSGMesh::Mesh::ComponentType::Float32:
999 return QQuick3DGeometry::Attribute::F32Type;
1000 case QSSGMesh::Mesh::ComponentType::Int32:
1001 return QQuick3DGeometry::Attribute::I32Type;
1002 case QSSGMesh::Mesh::ComponentType::UnsignedInt16:
1003 return QQuick3DGeometry::Attribute::U16Type;
1004 case QSSGMesh::Mesh::ComponentType::UnsignedInt32:
1005 return QQuick3DGeometry::Attribute::U32Type;
1007 case QSSGMesh::Mesh::ComponentType::Float16:
1008 case QSSGMesh::Mesh::ComponentType::Float64:
1009 case QSSGMesh::Mesh::ComponentType::UnsignedInt8:
1010 case QSSGMesh::Mesh::ComponentType::Int8:
1011 case QSSGMesh::Mesh::ComponentType::Int16:
1012 case QSSGMesh::Mesh::ComponentType::UnsignedInt64:
1013 case QSSGMesh::Mesh::ComponentType::Int64:
1015 Q_ASSERT_X(0,
"Incorrect datatype",
"QQuick3DGeometryPrivate::toComponentType");
1018 return QQuick3DGeometry::Attribute::F32Type;
static QSSGMesh::Mesh::DrawMode mapPrimitiveType(QQuick3DGeometry::PrimitiveType t)
static QSSGMesh::RuntimeMeshData::Attribute::Semantic mapSemantic(QQuick3DGeometry::Attribute::Semantic s)
static QSSGMesh::Mesh::ComponentType mapComponentType(QQuick3DGeometry::Attribute::ComponentType t)