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
qssglightmapuvgenerator.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5
7#include "xatlas.h"
8
10
11QSSGLightmapUVGeneratorResult QSSGLightmapUVGenerator::run(const QByteArray &positions,
12 const QByteArray &normals,
13 const QByteArray &uv0,
14 const QByteArray &index,
15 QSSGMesh::Mesh::ComponentType indexComponentType,
16 float texelsPerUnit)
17{
18 QSSGLightmapUVGeneratorResult result;
19
20 xatlas::MeshDecl meshInfo;
21
22 if (indexComponentType == QSSGMesh::Mesh::ComponentType::UnsignedInt16) {
23 meshInfo.indexFormat = xatlas::IndexFormat::UInt16;
24 } else if (indexComponentType == QSSGMesh::Mesh::ComponentType::UnsignedInt32) {
25 meshInfo.indexFormat = xatlas::IndexFormat::UInt32;
26 } else {
27 qWarning("Lightmap UV generator: Unknown index type %d; cannot generate",
28 int(indexComponentType));
29 return result;
30 }
31
32 const quint32 indexComponentByteSize = QSSGMesh::MeshInternal::byteSizeForComponentType(indexComponentType);
33 const quint32 indexCount = index.size() / indexComponentByteSize;
34
35 meshInfo.indexCount = indexCount;
36 meshInfo.indexData = index.constData();
37
38 const quint32 positionStride = 3 * sizeof(float);
39 const quint32 normalStride = 3 * sizeof(float);
40 const quint32 uvStride = 2 * sizeof(float);
41
42 meshInfo.vertexCount = positions.size() / positionStride;
43 meshInfo.vertexPositionData = positions.data();
44 meshInfo.vertexPositionStride = positionStride;
45
46 if (!normals.isEmpty()) {
47 meshInfo.vertexNormalData = normals.constData();
48 meshInfo.vertexNormalStride = normalStride;
49 } else {
50 meshInfo.vertexNormalData = nullptr;
51 meshInfo.vertexNormalStride = 0;
52 }
53
54 if (!uv0.isEmpty()) {
55 meshInfo.vertexUvData = uv0.constData();
56 meshInfo.vertexUvStride = uvStride;
57 } else {
58 meshInfo.vertexUvData = nullptr;
59 meshInfo.vertexUvStride = 0;
60 }
61
62 xatlas::PackOptions packOptions;
63 packOptions.maxChartSize = 4096;
64 packOptions.padding = 1;
65 packOptions.resolution = 0;
66 packOptions.texelsPerUnit = texelsPerUnit;
67 packOptions.blockAlign = true;
68
69 xatlas::ChartOptions chartOptions;
70
71 xatlas::Atlas *atlas = xatlas::Create();
72 xatlas::AddMeshError err = xatlas::AddMesh(atlas, meshInfo, 1);
73 if (err != xatlas::AddMeshError::Success) {
74 qWarning("Failed to register mesh for UV unwrapping (error %d)", int(err));
75 xatlas::Destroy(atlas);
76 return result;
77 }
78 xatlas::Generate(atlas, chartOptions, packOptions);
79
80 const uint32_t textureWidth = atlas->width;
81 const uint32_t textureHeight = atlas->height;
82 if (textureWidth == 0 || textureHeight == 0) {
83 qWarning("Texture size is empty, UV unwrapping failed");
84 xatlas::Destroy(atlas);
85 return result;
86 }
87 result.lightmapWidth = textureWidth;
88 result.lightmapHeight = textureHeight;
89
90 const xatlas::Mesh &output = atlas->meshes[0];
91 result.lightmapUVChannel.resize(output.vertexCount * uvStride);
92 result.vertexMap.resize(output.vertexCount);
93
94 float *uvPtr = reinterpret_cast<float *>(result.lightmapUVChannel.data());
95 for (uint32_t i = 0; i < output.vertexCount; ++i) {
96 const float u = output.vertexArray[i].uv[0] / float(textureWidth);
97 const float v = output.vertexArray[i].uv[1] / float(textureHeight);
98 *uvPtr++ = u;
99 *uvPtr++ = v;
100 result.vertexMap[i] = output.vertexArray[i].xref;
101 }
102
103 result.indexData.resize(output.indexCount * sizeof(quint32));
104 quint32 *indexPtr = reinterpret_cast<quint32 *>(result.indexData.data());
105 for (uint32_t i = 0; i < output.indexCount; ++i)
106 *indexPtr++ = output.indexArray[i];
107
108 xatlas::Destroy(atlas);
109
110 return result;
111}
112
113QT_END_NAMESPACE
Combined button and popup list for selecting options.