Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qquick3dgeometry.cpp
Go to the documentation of this file.
1// Copyright (C) 2019 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
6#include <QtQuick3DUtils/private/qssgutils_p.h>
7
224
227{
228
229}
230
233{
234
235}
236
238{
239
240}
241
246{
247 const Q_D(QQuick3DGeometry);
248 return d->m_vertexBuffer;
249}
250
254QByteArray QQuick3DGeometry::targetData() const
255{
256 const Q_D(QQuick3DGeometry);
257 return d->m_targetBuffer;
258}
259
264{
265 const Q_D(QQuick3DGeometry);
266 return d->m_indexBuffer;
267}
268
275{
276 const Q_D(QQuick3DGeometry);
277 return d->m_attributeCount;
278}
279
286{
287 const Q_D(QQuick3DGeometry);
288 return d->m_attributes[index];
289}
290
296int QQuick3DGeometry::targetAttributeCount() const
297{
298 const Q_D(QQuick3DGeometry);
299 return d->m_targetAttributeCount;
300}
301
307QQuick3DGeometry::TargetAttribute QQuick3DGeometry::targetAttribute(int index) const
308{
309 const Q_D(QQuick3DGeometry);
310 return d->m_targetAttributes[index];
311}
312
319{
320 const Q_D(QQuick3DGeometry);
321 return d->m_primitiveType;
322}
323
330{
331 const Q_D(QQuick3DGeometry);
332 return d->m_min;
333}
334
341{
342 const Q_D(QQuick3DGeometry);
343 return d->m_max;
344}
345
351int QQuick3DGeometry::stride() const
352{
353 const Q_D(QQuick3DGeometry);
354 return d->m_stride;
355}
356
358{
360}
361
371{
372 Q_D(QQuick3DGeometry);
373 d->m_vertexBuffer = data;
374 d->m_geometryChanged = true;
375}
376
392{
393 Q_D(QQuick3DGeometry);
394 if (offset >= d->m_vertexBuffer.size())
395 return;
396
397 const size_t len = qMin(d->m_vertexBuffer.size() - offset, data.size());
398 memcpy(d->m_vertexBuffer.data() + offset, data.data(), len);
399
400 d->m_geometryChanged = true;
401}
402
409void QQuick3DGeometry::setTargetData(const QByteArray &data)
410{
411 Q_D(QQuick3DGeometry);
412 d->m_targetBuffer = data;
413 d->m_targetChanged = true;
414}
415
430void QQuick3DGeometry::setTargetData(int offset, const QByteArray &data)
431{
432 Q_D(QQuick3DGeometry);
433 if (offset >= d->m_targetBuffer.size())
434 return;
435
436 const size_t len = qMin(d->m_targetBuffer.size() - offset, data.size());
437 memcpy(d->m_targetBuffer.data() + offset, data.data(), len);
438
439 d->m_targetChanged = true;
440}
441
448{
449 Q_D(QQuick3DGeometry);
450 d->m_indexBuffer = data;
451 d->m_geometryChanged = true;
452}
453
469{
470 Q_D(QQuick3DGeometry);
471 if (offset >= d->m_indexBuffer.size())
472 return;
473
474 const size_t len = qMin(d->m_indexBuffer.size() - offset, data.size());
475 memcpy(d->m_indexBuffer.data() + offset, data.data(), len);
476
477 d->m_geometryChanged = true;
478}
479
495{
496 Q_D(QQuick3DGeometry);
497 if (stride != d->m_stride) {
498 d->m_stride = stride;
499 d->m_geometryChanged = true;
500 }
501}
502
508{
509 Q_D(QQuick3DGeometry);
510 d->m_max = max;
511 d->m_min = min;
512 d->m_geometryBoundsChanged = true;
513}
514
540{
541 Q_D(QQuick3DGeometry);
542 if (d->m_primitiveType != type) {
543 d->m_primitiveType = type;
544 d->m_geometryChanged = true;
545 }
546}
547
600 Attribute::ComponentType componentType)
601{
602 Q_D(QQuick3DGeometry);
607 if (d->m_attributeCount >= QQuick3DGeometryPrivate::MAX_ATTRIBUTE_COUNT)
608 return;
609 d->m_attributes[d->m_attributeCount].semantic = semantic;
610 d->m_attributes[d->m_attributeCount].offset = offset;
611 d->m_attributes[d->m_attributeCount].componentType = componentType;
612 d->m_attributeCount++;
613 d->m_geometryChanged = true;
614 } else {
615 if (d->m_targetAttributeCount >= QQuick3DGeometryPrivate::MAX_TARGET_ATTRIBUTE_COUNT)
616 return;
617 d->m_targetAttributes[d->m_targetAttributeCount].targetId = 0;
618 d->m_targetAttributes[d->m_targetAttributeCount].attr.semantic = semantic;
619 d->m_targetAttributes[d->m_targetAttributeCount].attr.offset = offset;
620 // m_stride and m_vertexBuffer will be used for targetBuffer.
621 d->m_targetAttributeCount++;
622 d->m_targetChanged = true;
623 d->m_usesOldTargetSemantics = true;
624 }
625}
626
636{
637 Q_D(QQuick3DGeometry);
638 if (d->m_attributeCount >= QQuick3DGeometryPrivate::MAX_ATTRIBUTE_COUNT)
639 return;
640 d->m_attributes[d->m_attributeCount++] = attribute;
641 d->m_geometryChanged = true;
642}
643
663void QQuick3DGeometry::addTargetAttribute(quint32 targetId,
664 Attribute::Semantic semantic, int offset,
665 int stride)
666{
667 Q_D(QQuick3DGeometry);
668 if (d->m_targetAttributeCount >= QQuick3DGeometryPrivate::MAX_TARGET_ATTRIBUTE_COUNT)
669 return;
673 return;
674 d->m_targetAttributes[d->m_targetAttributeCount].targetId = targetId;
675 d->m_targetAttributes[d->m_targetAttributeCount].attr.semantic = semantic;
676 d->m_targetAttributes[d->m_targetAttributeCount].attr.offset = offset;
677 d->m_targetAttributes[d->m_targetAttributeCount].stride = stride;
678 d->m_targetAttributeCount++;
679 d->m_targetChanged = true;
680}
681
690void QQuick3DGeometry::addTargetAttribute(const TargetAttribute &attribute)
691{
692 Q_D(QQuick3DGeometry);
693 if (d->m_targetAttributeCount >= QQuick3DGeometryPrivate::MAX_TARGET_ATTRIBUTE_COUNT)
694 return;
695 if (attribute.attr.semantic == Attribute::IndexSemantic ||
696 attribute.attr.semantic == Attribute::JointSemantic ||
697 attribute.attr.semantic == Attribute::WeightSemantic)
698 return;
699 d->m_targetAttributes[d->m_targetAttributeCount++] = attribute;
700 d->m_targetChanged = true;
701}
702
707{
708 Q_D(QQuick3DGeometry);
709 d->m_vertexBuffer.clear();
710 d->m_targetBuffer.clear();
711 d->m_indexBuffer.clear();
712 d->m_attributeCount = 0;
713 d->m_targetAttributeCount = 0;
714 d->m_subsets.clear();
715 d->m_primitiveType = PrimitiveType::Triangles;
716 d->m_geometryChanged = true;
717 d->m_targetChanged = true;
718 d->m_min = {};
719 d->m_max = {};
720}
721
725int QQuick3DGeometry::subsetCount() const
726{
727 Q_D(const QQuick3DGeometry);
728 return d->m_subsets.size();
729}
730
736QVector3D QQuick3DGeometry::subsetBoundsMin(int subset) const
737{
738 Q_D(const QQuick3DGeometry);
739 if (subset >= 0 && subset < d->m_subsets.size())
740 return d->m_subsets[subset].boundsMin;
741 return {};
742}
743
749QVector3D QQuick3DGeometry::subsetBoundsMax(int subset) const
750{
751 Q_D(const QQuick3DGeometry);
752 if (subset >= 0 && subset < d->m_subsets.size())
753 return d->m_subsets[subset].boundsMax;
754 return {};
755}
756
762int QQuick3DGeometry::subsetOffset(int subset) const
763{
764 Q_D(const QQuick3DGeometry);
765 if (subset >= 0 && subset < d->m_subsets.size())
766 return d->m_subsets[subset].offset;
767 return 0;
768}
769
775int QQuick3DGeometry::subsetCount(int subset) const
776{
777 Q_D(const QQuick3DGeometry);
778 if (subset >= 0 && subset < d->m_subsets.size())
779 return d->m_subsets[subset].count;
780 return 0;
781}
782
786QString QQuick3DGeometry::subsetName(int subset) const
787{
788 Q_D(const QQuick3DGeometry);
789 if (subset >= 0 && subset < d->m_subsets.size())
790 return d->m_subsets[subset].name;
791 return {};
792}
793
805void QQuick3DGeometry::addSubset(int offset, int count, const QVector3D &boundsMin, const QVector3D &boundsMax, const QString &name)
806{
807 Q_D(QQuick3DGeometry);
808 d->m_subsets.append({name, boundsMin, boundsMax, quint32(offset), quint32(count)});
809 d->m_geometryChanged = true;
810}
811
813{
814 switch (t) {
816 return QSSGMesh::Mesh::DrawMode::Points;
818 return QSSGMesh::Mesh::DrawMode::LineStrip;
820 return QSSGMesh::Mesh::DrawMode::Lines;
822 return QSSGMesh::Mesh::DrawMode::TriangleStrip;
824 return QSSGMesh::Mesh::DrawMode::TriangleFan;
826 return QSSGMesh::Mesh::DrawMode::Triangles;
827 }
828
829 Q_UNREACHABLE_RETURN(QSSGMesh::Mesh::DrawMode::Triangles);
830}
831
833{
834 switch (s) {
863 }
864
866}
867
869{
870 switch (t) {
872 return QSSGMesh::Mesh::ComponentType::UnsignedInt16;
874 return QSSGMesh::Mesh::ComponentType::UnsignedInt32;
876 return QSSGMesh::Mesh::ComponentType::Int32;
878 return QSSGMesh::Mesh::ComponentType::Float32;
879 }
880
881 Q_UNREACHABLE_RETURN(QSSGMesh::Mesh::ComponentType::Float32);
882}
883
888{
889 Q_D(QQuick3DGeometry);
890 if (!node) {
891 markAllDirty();
892 node = new QSSGRenderGeometry();
894 }
896 QSSGRenderGeometry *geometry = static_cast<QSSGRenderGeometry *>(node);
897 if (d->m_geometryChanged) {
898 geometry->clearVertexAndIndex();
899 geometry->setBounds(d->m_min, d->m_max);
900 geometry->setStride(d->m_stride);
901 // If there is vertex data but no stride is set, the user likely forgot to set the stride.
902 if (d->m_stride < 1 && !d->m_vertexBuffer.isEmpty())
903 qWarning("%d is an invalid stride, was QQuick3DGeometry::setStride() called?", d->m_stride);
904 geometry->setIndexData(d->m_indexBuffer);
905 geometry->setVertexData(d->m_vertexBuffer);
906 geometry->setPrimitiveType(mapPrimitiveType(d->m_primitiveType));
907 quint32 indexBufferComponentSize = 0;
908 for (int i = 0; i < d->m_attributeCount; ++i) {
909 const auto componentType = mapComponentType(d->m_attributes[i].componentType);
910 geometry->addAttribute(mapSemantic(d->m_attributes[i].semantic),
911 d->m_attributes[i].offset,
912 componentType);
913 if (d->m_attributes[i].semantic == Attribute::IndexSemantic) {
914 if (componentType != QSSGMesh::Mesh::ComponentType::UnsignedInt16
915 && componentType != QSSGMesh::Mesh::ComponentType::UnsignedInt32)
916 {
917 qWarning("Index data can only be uint16 or uint32");
918 }
919 indexBufferComponentSize = QSSGMesh::MeshInternal::byteSizeForComponentType(componentType);
920 } else if (componentType == QSSGMesh::Mesh::ComponentType::UnsignedInt16) {
921 qWarning("Attributes cannot be uint16, only index data");
922 }
923 }
924 if (!d->m_indexBuffer.isEmpty() && !indexBufferComponentSize) {
925 qWarning("IndexData has been set, but no index attribute found.");
926 geometry->setIndexData({});
927 }
928 // Implicitely add subset if none set for backwards compatibility
929 if (d->m_subsets.isEmpty()) {
930 quint32 offset = 0;
931 quint32 count = 0;
932 if (!d->m_indexBuffer.isEmpty() && indexBufferComponentSize)
933 count = d->m_indexBuffer.size() / indexBufferComponentSize;
934 else if (d->m_stride)
935 count = d->m_vertexBuffer.size() / d->m_stride;
936 geometry->addSubset(offset, count, d->m_min, d->m_max);
937 } else {
938 for (auto &s : d->m_subsets)
939 geometry->addSubset(s.offset, s.count, s.boundsMin, s.boundsMax, s.name);
940 }
941 d->m_geometryChanged = false;
942 }
943 if (d->m_geometryBoundsChanged) {
944 geometry->setBounds(d->m_min, d->m_max);
946 d->m_geometryBoundsChanged = false;
947 }
948 if (d->m_targetChanged) {
949 geometry->clearTarget();
950 geometry->setTargetData(d->m_usesOldTargetSemantics ? d->m_vertexBuffer : d->m_targetBuffer);
951 for (int i = 0; i < d->m_targetAttributeCount; ++i) {
952 geometry->addTargetAttribute(d->m_targetAttributes[i].targetId,
953 mapSemantic(d->m_targetAttributes[i].attr.semantic),
954 d->m_targetAttributes[i].attr.offset,
955 d->m_usesOldTargetSemantics ? d->m_stride : d->m_targetAttributes[i].stride);
956 }
957 d->m_targetChanged = false;
958 }
959
961
962 return node;
963}
964
966{
968 if (semanticMap.isEmpty()) {
978 }
979 return semanticMap[name];
980}
981
983{
984 switch (ctype) {
985 case QSSGMesh::Mesh::ComponentType::Float32:
987 case QSSGMesh::Mesh::ComponentType::Int32:
989 case QSSGMesh::Mesh::ComponentType::UnsignedInt16:
991 case QSSGMesh::Mesh::ComponentType::UnsignedInt32:
993
994 case QSSGMesh::Mesh::ComponentType::Float16:
995 case QSSGMesh::Mesh::ComponentType::Float64:
996 case QSSGMesh::Mesh::ComponentType::UnsignedInt8:
997 case QSSGMesh::Mesh::ComponentType::Int8:
998 case QSSGMesh::Mesh::ComponentType::Int16:
999 case QSSGMesh::Mesh::ComponentType::UnsignedInt64:
1000 case QSSGMesh::Mesh::ComponentType::Int64:
1001 default:
1002 Q_ASSERT_X(0, "Incorrect datatype", "QQuick3DGeometryPrivate::toComponentType");
1003 break;
1004 }
1006}
1007
\inmodule QtCore
Definition qbytearray.h:57
Definition qmap.h:186
bool isEmpty() const
Definition qmap.h:268
static const int MAX_ATTRIBUTE_COUNT
static const int MAX_TARGET_ATTRIBUTE_COUNT
static QQuick3DGeometry::Attribute::Semantic semanticFromName(const QByteArray &name)
static QQuick3DGeometry::Attribute::ComponentType toComponentType(QSSGMesh::Mesh::ComponentType componentType)
\qmltype Geometry \inherits Object3D \inqmlmodule QtQuick3D \instantiates QQuick3DGeometry
Attribute::Semantic int int stride
Returns the byte stride of the vertex buffer.
void setPrimitiveType(PrimitiveType type)
Sets the primitive type used for rendering to type.
int attributeCount() const
Returns the number of attributes defined for this geometry.
void setStride(int stride)
Sets the stride of the vertex buffer to stride, measured in bytes.
void addAttribute(Attribute::Semantic semantic, int offset, Attribute::ComponentType componentType)
Adds vertex attribute description.
QQuick3DGeometry(QQuick3DObject *parent=nullptr)
void setVertexData(const QByteArray &data)
Sets the vertex buffer data.
int const QVector3D const QVector3D & boundsMax
Returns the maximum coordinate of the bounding volume.
int const QVector3D & boundsMin
Returns the minimum coordinate of the bounding volume.
PrimitiveType primitiveType() const
Returns the primitive type used when rendering.
Attribute attribute(int index) const
Returns attribute definition number index.
Attribute::Semantic int offset
int const QVector3D const QVector3D const QString & name
void markAllDirty() override
const QByteArray & data
void clear()
Resets the geometry to its initial state, clearing previously set vertex and index data as well as at...
void geometryNodeDirty()
void setBounds(const QVector3D &min, const QVector3D &max)
Sets the bounding volume of the geometry to the cube defined by the points min and max.
QByteArray vertexData() const
Returns the vertex buffer data set by setVertexData.
QByteArray indexData() const
Returns the index buffer data.
QSSGRenderGraphObject * updateSpatialNode(QSSGRenderGraphObject *node) override
Attribute::Semantic semantic
void setIndexData(const QByteArray &data)
Sets the index buffer to data.
\qmltype Object3D \inqmlmodule QtQuick3D \instantiates QQuick3DObject \inherits QtObject
virtual QSSGRenderGraphObject * updateSpatialNode(QSSGRenderGraphObject *node)
virtual void markAllDirty()
void setBounds(const QVector3D &min, const QVector3D &max)
void setStride(int stride)
void addAttribute(QSSGMesh::RuntimeMeshData::Attribute::Semantic semantic, int offset, QSSGMesh::Mesh::ComponentType componentType)
void setVertexData(const QByteArray &data)
void setPrimitiveType(QSSGMesh::Mesh::DrawMode type)
void addSubset(quint32 offset, quint32 count, const QVector3D &boundsMin, const QVector3D &boundsMax, const QString &name={})
void setIndexData(const QByteArray &data)
void setTargetData(const QByteArray &data)
void addTargetAttribute(quint32 targetId, QSSGMesh::RuntimeMeshData::Attribute::Semantic semantic, int offset, int stride=0)
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
The QVector3D class represents a vector or vertex in 3D space.
Definition qvectornd.h:171
void ensureDebugObjectName(T *node, QObject *src)
Combined button and popup list for selecting options.
EGLOutputLayerEXT EGLint attribute
#define qWarning
Definition qlogging.h:162
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
GLuint index
[2]
GLenum GLenum GLsizei count
const void GLsizei GLsizei stride
GLenum type
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLintptr offset
GLuint name
GLenum GLsizei len
GLdouble GLdouble t
Definition qopenglext.h:243
GLdouble s
[6]
Definition qopenglext.h:235
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)
#define Q_ASSERT_X(cond, x, msg)
Definition qrandom.cpp:48
QSSGRenderComponentType
#define emit
unsigned int quint32
Definition qtypes.h:45
static quint32 byteSizeForComponentType(Mesh::ComponentType componentType)
Definition qssgmesh_p.h:347
static const char * getNormalAttrName()
Definition qssgmesh_p.h:350
static const char * getUV1AttrName()
Definition qssgmesh_p.h:352
static const char * getTexBinormalAttrName()
Definition qssgmesh_p.h:355
static const char * getPositionAttrName()
Definition qssgmesh_p.h:349
static const char * getTexTanAttrName()
Definition qssgmesh_p.h:354
static const char * getColorAttrName()
Definition qssgmesh_p.h:356
static const char * getJointAttrName()
Definition qssgmesh_p.h:357
static const char * getUV0AttrName()
Definition qssgmesh_p.h:351
static const char * getWeightAttrName()
Definition qssgmesh_p.h:358
Definition moc.h:24
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent