Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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
230
236
241
246{
247 const Q_D(QQuick3DGeometry);
248 return d->m_vertexBuffer;
249}
250
256QByteArray QQuick3DGeometry::targetData() const
257{
258 const Q_D(QQuick3DGeometry);
259 return d->m_targetBuffer;
260}
261
266{
267 const Q_D(QQuick3DGeometry);
268 return d->m_indexBuffer;
269}
270
277{
278 const Q_D(QQuick3DGeometry);
279 return d->m_attributeCount;
280}
281
288{
289 const Q_D(QQuick3DGeometry);
290 return d->m_attributes[index];
291}
292
299int QQuick3DGeometry::targetAttributeCount() const
300{
301 const Q_D(QQuick3DGeometry);
302 return d->m_targetAttributeCount;
303}
304
312QQuick3DGeometry::TargetAttribute QQuick3DGeometry::targetAttribute(int index) const
313{
314 const Q_D(QQuick3DGeometry);
315 return d->m_targetAttributes[index];
316}
317
324{
325 const Q_D(QQuick3DGeometry);
326 return d->m_primitiveType;
327}
328
335{
336 const Q_D(QQuick3DGeometry);
337 return d->m_min;
338}
339
346{
347 const Q_D(QQuick3DGeometry);
348 return d->m_max;
349}
350
356int QQuick3DGeometry::stride() const
357{
358 const Q_D(QQuick3DGeometry);
359 return d->m_stride;
360}
361
366
376{
377 Q_D(QQuick3DGeometry);
378 d->m_vertexBuffer = data;
379 d->m_geometryChanged = true;
380}
381
397{
398 Q_D(QQuick3DGeometry);
399 if (offset >= d->m_vertexBuffer.size())
400 return;
401
402 const size_t len = qMin(d->m_vertexBuffer.size() - offset, data.size());
403 memcpy(d->m_vertexBuffer.data() + offset, data.data(), len);
404
405 d->m_geometryChanged = true;
406}
407
416void QQuick3DGeometry::setTargetData(const QByteArray &data)
417{
418 Q_D(QQuick3DGeometry);
419 d->m_targetBuffer = data;
420 d->m_targetChanged = true;
421}
422
439void QQuick3DGeometry::setTargetData(int offset, const QByteArray &data)
440{
441 Q_D(QQuick3DGeometry);
442 if (offset >= d->m_targetBuffer.size())
443 return;
444
445 const size_t len = qMin(d->m_targetBuffer.size() - offset, data.size());
446 memcpy(d->m_targetBuffer.data() + offset, data.data(), len);
447
448 d->m_targetChanged = true;
449}
450
457{
458 Q_D(QQuick3DGeometry);
459 d->m_indexBuffer = data;
460 d->m_geometryChanged = true;
461}
462
478{
479 Q_D(QQuick3DGeometry);
480 if (offset >= d->m_indexBuffer.size())
481 return;
482
483 const size_t len = qMin(d->m_indexBuffer.size() - offset, data.size());
484 memcpy(d->m_indexBuffer.data() + offset, data.data(), len);
485
486 d->m_geometryChanged = true;
487}
488
504{
505 Q_D(QQuick3DGeometry);
506 if (stride != d->m_stride) {
507 d->m_stride = stride;
508 d->m_geometryChanged = true;
509 }
510}
511
517{
518 Q_D(QQuick3DGeometry);
519 d->m_max = max;
520 d->m_min = min;
521 d->m_geometryBoundsChanged = true;
522}
523
549{
550 Q_D(QQuick3DGeometry);
551 if (d->m_primitiveType != type) {
552 d->m_primitiveType = type;
553 d->m_geometryChanged = true;
554 }
555}
556
609 Attribute::ComponentType componentType)
610{
611 Q_D(QQuick3DGeometry);
616 if (d->m_attributeCount >= QQuick3DGeometryPrivate::MAX_ATTRIBUTE_COUNT)
617 return;
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;
623 } else {
624 if (d->m_targetAttributeCount >= QQuick3DGeometryPrivate::MAX_TARGET_ATTRIBUTE_COUNT)
625 return;
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;
629 // m_stride and m_vertexBuffer will be used for targetBuffer.
630 d->m_targetAttributeCount++;
631 d->m_targetChanged = true;
632 d->m_usesOldTargetSemantics = true;
633 }
634}
635
645{
646 Q_D(QQuick3DGeometry);
647 if (d->m_attributeCount >= QQuick3DGeometryPrivate::MAX_ATTRIBUTE_COUNT)
648 return;
649 d->m_attributes[d->m_attributeCount++] = attribute;
650 d->m_geometryChanged = true;
651}
652
674void QQuick3DGeometry::addTargetAttribute(quint32 targetId,
675 Attribute::Semantic semantic, int offset,
676 int stride)
677{
678 Q_D(QQuick3DGeometry);
679 if (d->m_targetAttributeCount >= QQuick3DGeometryPrivate::MAX_TARGET_ATTRIBUTE_COUNT)
680 return;
684 return;
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;
691}
692
702void QQuick3DGeometry::addTargetAttribute(const TargetAttribute &attribute)
703{
704 Q_D(QQuick3DGeometry);
705 if (d->m_targetAttributeCount >= QQuick3DGeometryPrivate::MAX_TARGET_ATTRIBUTE_COUNT)
706 return;
707 if (attribute.attr.semantic == Attribute::IndexSemantic ||
708 attribute.attr.semantic == Attribute::JointSemantic ||
709 attribute.attr.semantic == Attribute::WeightSemantic)
710 return;
711 d->m_targetAttributes[d->m_targetAttributeCount++] = attribute;
712 d->m_targetChanged = true;
713}
714
719{
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;
730 d->m_min = {};
731 d->m_max = {};
732}
733
737int QQuick3DGeometry::subsetCount() const
738{
739 Q_D(const QQuick3DGeometry);
740 return d->m_subsets.size();
741}
742
748QVector3D QQuick3DGeometry::subsetBoundsMin(int subset) const
749{
750 Q_D(const QQuick3DGeometry);
751 if (subset >= 0 && subset < d->m_subsets.size())
752 return d->m_subsets[subset].boundsMin;
753 return {};
754}
755
761QVector3D QQuick3DGeometry::subsetBoundsMax(int subset) const
762{
763 Q_D(const QQuick3DGeometry);
764 if (subset >= 0 && subset < d->m_subsets.size())
765 return d->m_subsets[subset].boundsMax;
766 return {};
767}
768
774int QQuick3DGeometry::subsetOffset(int subset) const
775{
776 Q_D(const QQuick3DGeometry);
777 if (subset >= 0 && subset < d->m_subsets.size())
778 return d->m_subsets[subset].offset;
779 return 0;
780}
781
787int QQuick3DGeometry::subsetCount(int subset) const
788{
789 Q_D(const QQuick3DGeometry);
790 if (subset >= 0 && subset < d->m_subsets.size())
791 return d->m_subsets[subset].count;
792 return 0;
793}
794
798QString QQuick3DGeometry::subsetName(int subset) const
799{
800 Q_D(const QQuick3DGeometry);
801 if (subset >= 0 && subset < d->m_subsets.size())
802 return d->m_subsets[subset].name;
803 return {};
804}
805
817void QQuick3DGeometry::addSubset(int offset, int count, const QVector3D &boundsMin, const QVector3D &boundsMax, const QString &name)
818{
819 Q_D(QQuick3DGeometry);
820 d->m_subsets.append({name, boundsMin, boundsMax, quint32(offset), quint32(count)});
821 d->m_geometryChanged = true;
822}
823
825{
826 switch (t) {
828 return QSSGMesh::Mesh::DrawMode::Points;
830 return QSSGMesh::Mesh::DrawMode::LineStrip;
832 return QSSGMesh::Mesh::DrawMode::Lines;
834 return QSSGMesh::Mesh::DrawMode::TriangleStrip;
836 return QSSGMesh::Mesh::DrawMode::TriangleFan;
838 return QSSGMesh::Mesh::DrawMode::Triangles;
839 }
840
841 Q_UNREACHABLE_RETURN(QSSGMesh::Mesh::DrawMode::Triangles);
842}
843
845{
846 switch (s) {
875 }
876
878}
879
881{
882 switch (t) {
884 return QSSGMesh::Mesh::ComponentType::UnsignedInt16;
886 return QSSGMesh::Mesh::ComponentType::UnsignedInt32;
888 return QSSGMesh::Mesh::ComponentType::Int32;
890 return QSSGMesh::Mesh::ComponentType::Float32;
891 }
892
893 Q_UNREACHABLE_RETURN(QSSGMesh::Mesh::ComponentType::Float32);
894}
895
900{
901 Q_D(QQuick3DGeometry);
902 if (!node) {
903 markAllDirty();
904 node = new QSSGRenderGeometry();
906 }
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);
913 // If there is vertex data but no stride is set, the user likely forgot to set the 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,
924 componentType);
925 if (d->m_attributes[i].semantic == Attribute::IndexSemantic) {
926 if (componentType != QSSGMesh::Mesh::ComponentType::UnsignedInt16
927 && componentType != QSSGMesh::Mesh::ComponentType::UnsignedInt32)
928 {
929 qWarning("Index data can only be uint16 or uint32");
930 }
931 indexBufferComponentSize = QSSGMesh::MeshInternal::byteSizeForComponentType(componentType);
932 } else if (componentType == QSSGMesh::Mesh::ComponentType::UnsignedInt16) {
933 qWarning("Attributes cannot be uint16, only index data");
934 }
935 }
936 if (!d->m_indexBuffer.isEmpty() && !indexBufferComponentSize) {
937 qWarning("IndexData has been set, but no index attribute found.");
938 geometry->setIndexData({});
939 }
940 // Implicitely add subset if none set for backwards compatibility
941 if (d->m_subsets.isEmpty()) {
942 quint32 offset = 0;
943 quint32 count = 0;
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);
949 } else {
950 for (auto &s : d->m_subsets)
951 geometry->addSubset(s.offset, s.count, s.boundsMin, s.boundsMax, s.name);
952 }
953 d->m_geometryChanged = false;
954 emit geometryChanged();
955 }
956 if (d->m_geometryBoundsChanged) {
957 geometry->setBounds(d->m_min, d->m_max);
959 d->m_geometryBoundsChanged = false;
960 }
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);
969 }
970 d->m_targetChanged = false;
971 }
972
974
975 return node;
976}
977
994
996{
997 switch (ctype) {
998 case QSSGMesh::Mesh::ComponentType::Float32:
1000 case QSSGMesh::Mesh::ComponentType::Int32:
1002 case QSSGMesh::Mesh::ComponentType::UnsignedInt16:
1004 case QSSGMesh::Mesh::ComponentType::UnsignedInt32:
1006
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:
1014 default:
1015 Q_ASSERT_X(0, "Incorrect datatype", "QQuick3DGeometryPrivate::toComponentType");
1016 break;
1017 }
1019}
1020
\inmodule QtCore
Definition qbytearray.h:57
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:129
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:166
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
GLuint index
[2]
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
const void GLsizei GLsizei stride
GLenum type
GLenum GLuint GLintptr offset
GLuint name
GLdouble s
[6]
Definition qopenglext.h:235
GLdouble GLdouble t
Definition qopenglext.h:243
GLenum GLsizei len
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:50
static quint32 byteSizeForComponentType(Mesh::ComponentType componentType)
Definition qssgmesh_p.h:390
static const char * getNormalAttrName()
Definition qssgmesh_p.h:393
static const char * getUV1AttrName()
Definition qssgmesh_p.h:395
static const char * getTexBinormalAttrName()
Definition qssgmesh_p.h:398
static const char * getPositionAttrName()
Definition qssgmesh_p.h:392
static const char * getTexTanAttrName()
Definition qssgmesh_p.h:397
static const char * getColorAttrName()
Definition qssgmesh_p.h:399
static const char * getJointAttrName()
Definition qssgmesh_p.h:400
static const char * getUV0AttrName()
Definition qssgmesh_p.h:394
static const char * getWeightAttrName()
Definition qssgmesh_p.h:401
Definition moc.h:23