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
qssgmesh_p.h
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// Qt-Security score:critical reason:data-parser
4
5
6#ifndef QSSGMESHUTILITIES_P_H
7#define QSSGMESHUTILITIES_P_H
8
9//
10// W A R N I N G
11// -------------
12//
13// This file is not part of the Qt API. It exists purely as an
14// implementation detail. This header file may change from version to
15// version without notice, or even be removed.
16//
17// We mean it.
18//
19
20#include <QtQuick3DUtils/private/qtquick3dutilsglobal_p.h>
21
22#include <QtQuick3DUtils/private/qssgbounds3_p.h>
23
24#include <QtQuick3DUtils/private/qssgrenderbasetypes_p.h>
25
26#include <QtCore/qstring.h>
27#include <QtCore/qbytearray.h>
28#include <QtCore/qiodevice.h>
29#include <QtCore/qlist.h>
30#include <QtCore/qmap.h>
31
32#include <QtGui/qvectornd.h>
33
34QT_BEGIN_NAMESPACE
35
36struct QSSGRenderVertexBufferEntry
37{
38 QByteArray m_name;
39 /** Datatype of the this entry points to in the buffer */
40 QSSGRenderComponentType m_componentType;
41 /** Number of components of each data member. 1,2,3, or 4. Don't be stupid.*/
42 quint32 m_numComponents;
43 /** Offset from the beginning of the buffer of the first item */
44 quint32 m_firstItemOffset;
45
46 QSSGRenderVertexBufferEntry(const QByteArray &nm,
47 QSSGRenderComponentType type,
48 quint32 numComponents,
49 quint32 firstItemOffset = 0)
50 : m_name(nm), m_componentType(type), m_numComponents(numComponents), m_firstItemOffset(firstItemOffset)
51 {
52 }
53
54 QSSGRenderVertexBufferEntry()
55 : m_componentType(QSSGRenderComponentType::Float32), m_numComponents(0), m_firstItemOffset(0)
56 {
57 }
58
59 QSSGRenderVertexBufferEntry(const QSSGRenderVertexBufferEntry &inOther)
60 : m_name(inOther.m_name)
61 , m_componentType(inOther.m_componentType)
62 , m_numComponents(inOther.m_numComponents)
63 , m_firstItemOffset(inOther.m_firstItemOffset)
64 {
65 }
66
67 QSSGRenderVertexBufferEntry &operator=(const QSSGRenderVertexBufferEntry &inOther)
68 {
69 if (this != &inOther) {
70 m_name = inOther.m_name;
71 m_componentType = inOther.m_componentType;
72 m_numComponents = inOther.m_numComponents;
73 m_firstItemOffset = inOther.m_firstItemOffset;
74 }
75 return *this;
76 }
77};
78
79namespace QSSGMesh {
80
81struct AssetVertexEntry;
82struct AssetMeshSubset;
83struct RuntimeMeshData;
84struct AssetLodEntry;
85
86class Q_QUICK3DUTILS_EXPORT Mesh
87{
88public:
92
106
112
117
123
128
129 struct Lod {
132 float distance = 0.0f;
133 };
134
143
144 // can just return by value (big data is all implicitly shared)
148 QVector<Subset> subsets() const { return m_subsets; }
149
150 // id 0 == first, otherwise has to match
151 static Mesh loadMesh(QIODevice *device, quint32 id = 0);
152
154
160
162 QString *error);
163
164 bool isValid() const { return !m_subsets.isEmpty(); }
165
166 DrawMode drawMode() const { return m_drawMode; }
167 Winding winding() const { return m_winding; }
168
169 // id 0 == generate new id; otherwise uses it as-is, and must be an unused one
170 quint32 save(QIODevice *device, quint32 id = 0) const;
171
172 bool hasLightmapUVChannel() const;
174
175private:
182 friend struct MeshInternal;
183};
184
185struct Q_QUICK3DUTILS_EXPORT AssetVertexEntry // for asset importer plugins (Assimp, FBX)
186{
191 qint32 morphTargetId = -1; // -1 menas that this entry belongs to the original mesh.
192};
193
194struct Q_QUICK3DUTILS_EXPORT AssetMeshSubset // for asset importer plugins (Assimp, FBX)
195{
203};
204
205struct Q_QUICK3DUTILS_EXPORT RuntimeMeshData // for custom geometry (QQuick3DGeometry, QSSGRenderGeometry)
206{
207 struct Attribute {
208 enum Semantic {
210 PositionSemantic, // attr_pos
211 NormalSemantic, // attr_norm
212 TexCoordSemantic, // attr_uv0
213 TangentSemantic, // attr_textan
214 BinormalSemantic, // attr_binormal
215 JointSemantic, // attr_joints
216 WeightSemantic, // attr_weights
217 ColorSemantic, // attr_color
218 TexCoord1Semantic, // attr_uv1
220 };
221
224 int offset = 0;
225
226 int componentCount() const {
227 switch (semantic) {
228 case IndexSemantic: return 1;
229 case PositionSemantic: return 3;
230 case NormalSemantic: return 3;
231 case TexCoord0Semantic: return 2;
232 case TexCoord1Semantic: return 2;
233 case TangentSemantic: return 3;
234 case BinormalSemantic: return 3;
235 case JointSemantic: return 4;
236 case WeightSemantic: return 4;
237 case ColorSemantic: return 4;
238 }
240 }
241 };
242
248
249 static const int MAX_ATTRIBUTES = 16;
250 static const int MAX_TARGET_ATTRIBUTES = 32;
251
252 void clear()
253 {
255 clearTarget();
256 }
266 {
269 }
270
275
281 int m_stride = 0;
282};
283
284struct Q_QUICK3DUTILS_EXPORT MeshInternal
285{
290 static const quint32 FILE_ID = 555777497;
291 static const quint32 FILE_VERSION = 1;
292 bool isValid() const {
293 return fileId == FILE_ID && fileVersion == FILE_VERSION;
294 }
296 return { FILE_ID, FILE_VERSION, {} };
297 }
298 };
299
305
306 static const quint32 FILE_ID = 3365961549;
307
308 // Version 3 and 4 is only different in the "offset" values that are
309 // all zeroes in version 4 because they are not used by the new mesh
310 // reader. So to support both with the new loader, no branching is
311 // needed at all, it just needs to accept both versions.
313 // Version 5 differs from 4 with the added lightmapSizeHint per subset.
314 // This needs branching in the deserializer.
315 // Version 6 differs from 5 with additional lodCount per subset as well
316 // as a list of Level of Detail data after the subset names.
317 // Version 7 will split the morph target data
318 static const quint32 FILE_VERSION = 7;
319
321 return { FILE_ID, FILE_VERSION, 0, 0 };
322 }
323
324 bool isValid() const {
325 return fileId == FILE_ID
328 }
329
330 bool hasLightmapSizeHint() const {
331 return fileVersion >= 5;
332 }
333
334 bool hasLodDataHint() const {
335 return fileVersion >= 6;
336 }
337
339 return fileVersion >= 7;
340 }
341 };
342
365
366 struct Subset {
374
377 // Only as many units as were actually read, less the terminator.
379 if (units > 0)
380 subset.name = QString::fromUtf16(reinterpret_cast<const char16_t *>(rawNameUtf16.constData()), units - 1);
387 return subset;
388 }
389 };
390
396
398
399 static const char *getPositionAttrName() { return "attr_pos"; }
400 static const char *getNormalAttrName() { return "attr_norm"; }
401 static const char *getUV0AttrName() { return "attr_uv0"; }
402 static const char *getUV1AttrName() { return "attr_uv1"; }
403 static const char *getLightmapUVAttrName() { return "attr_lightmapuv"; }
404 static const char *getTexTanAttrName() { return "attr_textan"; }
405 static const char *getTexBinormalAttrName() { return "attr_binormal"; }
406 static const char *getColorAttrName() { return "attr_color"; }
407 static const char *getJointAttrName() { return "attr_joints"; }
408 static const char *getWeightAttrName() { return "attr_weights"; }
409
417};
418
419size_t Q_QUICK3DUTILS_EXPORT simplifyMesh(unsigned int* destination,
420 const unsigned int* indices,
422 const float* vertexPositions,
426 float targetError,
427 unsigned int options,
428 float* resultError);
429
430float Q_QUICK3DUTILS_EXPORT simplifyScale(const float* vertexPositions,
433
434void Q_QUICK3DUTILS_EXPORT optimizeVertexCache(unsigned int* destination,
435 const unsigned int* indices,
438
439// A vertex attribute stream for welding; mirrors meshopt_Stream
446
447// The largest number of attribute streams generateVertexRemap() accepts
449
450// Builds a remap table that welds bitwise-identical vertices across all
451// given attribute streams, returning the unique vertex count. streamCount
452// must be between 1 and maxVertexStreams, and every stream's elementSize
453// must be no larger than its stride.
454size_t Q_QUICK3DUTILS_EXPORT generateVertexRemap(unsigned int *destination,
455 const unsigned int *indices,
460
461void Q_QUICK3DUTILS_EXPORT remapVertexBuffer(void *destination,
462 const void *vertices,
465 const unsigned int *remap);
466
467void Q_QUICK3DUTILS_EXPORT remapIndexBuffer(unsigned int *destination,
468 const unsigned int *indices,
470 const unsigned int *remap);
471
473{
474 float distance = 0.0f;
476};
477
483
484// Generates simplified index buffers (levels of detail) for a triangle mesh,
485// returned from smallest to largest index count. When normals are
486// recalculated, vertices whose new normal deviates more than
487// normalSplitAngle from the original are split: the returned LOD indexes
488// reference new vertices starting at positions.size(), and the caller must
489// append a copy of each reported source vertex with the given normal, in
490// order. splitVertices is cleared on entry, so it always describes only the
491// call that produced it.
492//
493// Passing 0.0 for both angles disables normal recalculation, which is also
494// what happens when normals is empty. Otherwise normals must be the same
495// length as positions. Note that preserving the normals this way also keeps
496// vertices that only differ in their normal from being welded together, so a
497// mesh with hard edges yields fewer levels, or none at all.
498QVector<MeshLevelOfDetail> Q_QUICK3DUTILS_EXPORT generateMeshLevelsOfDetail(
500 const QVector<QVector3D> &normals,
501 const QVector<quint32> &indexes,
503 float normalMergeAngle = 60.0f,
504 float normalSplitAngle = 25.0f);
505
506} // namespace QSSGMesh
507
508QT_END_NAMESPACE
509
510#endif // QSSGMESHUTILITIES_P_H
float simplifyScale(const float *vertexPositions, size_t vertexCount, size_t vertexPositionsStride)
static const size_t MESH_STRUCT_SIZE
Definition qssgmesh.cpp:34
void remapVertexBuffer(void *destination, const void *vertices, size_t vertexCount, size_t vertexSize, const unsigned int *remap)
static bool isKnownComponentType(quint32 value)
Definition qssgmesh.cpp:55
static const size_t SUBSET_STRUCT_SIZE_V3_V4
Definition qssgmesh.cpp:40
static const size_t VERTEX_BUFFER_ENTRY_STRUCT_SIZE
Definition qssgmesh.cpp:37
static const size_t MULTI_ENTRY_STRUCT_SIZE
Definition qssgmesh.cpp:28
static const size_t SUBSET_STRUCT_SIZE_V6
Definition qssgmesh.cpp:44
size_t simplifyMesh(unsigned int *destination, const unsigned int *indices, size_t indexCount, const float *vertexPositions, size_t vertexCount, size_t vertexPositionsStride, size_t targetIndexCount, float targetError, unsigned int options, float *resultError)
static const size_t JOINT_STRUCT_SIZE
Definition qssgmesh.cpp:50
static const size_t MULTI_HEADER_STRUCT_SIZE
Definition qssgmesh.cpp:25
size_t generateVertexRemap(unsigned int *destination, const unsigned int *indices, size_t indexCount, size_t vertexCount, const MeshVertexStream *streams, size_t streamCount)
static const size_t LOD_STRUCT_SIZE
Definition qssgmesh.cpp:47
void optimizeVertexCache(unsigned int *destination, const unsigned int *indices, size_t indexCount, size_t vertexCount)
static const size_t MESH_HEADER_STRUCT_SIZE
Definition qssgmesh.cpp:31
static const size_t SUBSET_STRUCT_SIZE_V5
Definition qssgmesh.cpp:42
static quint32 getAlignedOffset(quint32 offset, quint32 align)
Definition qssgmesh.cpp:840
void remapIndexBuffer(unsigned int *destination, const unsigned int *indices, size_t indexCount, const unsigned int *remap)
constexpr size_t maxVertexStreams
Definition qssgmesh_p.h:448
static bool canRead(QIODevice *device, quint64 count, quint64 itemSize)
Definition qssgmesh.cpp:76
QVector< MeshLevelOfDetail > generateMeshLevelsOfDetail(const QVector< QVector3D > &positions, const QVector< QVector3D > &normals, const QVector< quint32 > &indexes, QVector< MeshVertexSplit > &splitVertices, float normalMergeAngle, float normalSplitAngle)
QVector< quint32 > indexes
Definition qssgmesh_p.h:475