9QSSGLightmapUVGeneratorResult QSSGLightmapUVGenerator::run(
const QByteArray &positions,
10 const QByteArray &normals,
11 const QByteArray &uv0,
12 const QByteArray &index,
13 QSSGMesh::Mesh::ComponentType indexComponentType,
16 QSSGLightmapUVGeneratorResult result;
18 xatlas::MeshDecl meshInfo;
20 if (indexComponentType == QSSGMesh::Mesh::ComponentType::UnsignedInt16) {
21 meshInfo.indexFormat = xatlas::IndexFormat::UInt16;
22 }
else if (indexComponentType == QSSGMesh::Mesh::ComponentType::UnsignedInt32) {
23 meshInfo.indexFormat = xatlas::IndexFormat::UInt32;
25 qWarning(
"Lightmap UV generator: Unknown index type %d; cannot generate",
26 int(indexComponentType));
30 const quint32 indexComponentByteSize = QSSGMesh::MeshInternal::byteSizeForComponentType(indexComponentType);
31 const quint32 indexCount = index.size() / indexComponentByteSize;
33 meshInfo.indexCount = indexCount;
34 meshInfo.indexData = index.constData();
36 const quint32 positionStride = 3 *
sizeof(
float);
37 const quint32 normalStride = 3 *
sizeof(
float);
38 const quint32 uvStride = 2 *
sizeof(
float);
40 meshInfo.vertexCount = positions.size() / positionStride;
41 meshInfo.vertexPositionData = positions.data();
42 meshInfo.vertexPositionStride = positionStride;
44 if (!normals.isEmpty()) {
45 meshInfo.vertexNormalData = normals.constData();
46 meshInfo.vertexNormalStride = normalStride;
48 meshInfo.vertexNormalData =
nullptr;
49 meshInfo.vertexNormalStride = 0;
53 meshInfo.vertexUvData = uv0.constData();
54 meshInfo.vertexUvStride = uvStride;
56 meshInfo.vertexUvData =
nullptr;
57 meshInfo.vertexUvStride = 0;
60 xatlas::PackOptions packOptions;
61 packOptions.maxChartSize = 4096;
62 packOptions.padding = 1;
63 packOptions.resolution = 0;
64 packOptions.texelsPerUnit = texelsPerUnit;
65 packOptions.blockAlign =
true;
67 xatlas::ChartOptions chartOptions;
69 xatlas::Atlas *atlas = xatlas::Create();
70 xatlas::AddMeshError err = xatlas::AddMesh(atlas, meshInfo, 1);
71 if (err != xatlas::AddMeshError::Success) {
72 qWarning(
"Failed to register mesh for UV unwrapping (error %d)",
int(err));
73 xatlas::Destroy(atlas);
76 xatlas::Generate(atlas, chartOptions, packOptions);
78 const uint32_t textureWidth = atlas->width;
79 const uint32_t textureHeight = atlas->height;
80 if (textureWidth == 0 || textureHeight == 0) {
81 qWarning(
"Texture size is empty, UV unwrapping failed");
82 xatlas::Destroy(atlas);
85 result.lightmapWidth = textureWidth;
86 result.lightmapHeight = textureHeight;
88 const xatlas::Mesh &output = atlas->meshes[0];
89 result.lightmapUVChannel.resize(output.vertexCount * uvStride);
90 result.vertexMap.resize(output.vertexCount);
92 float *uvPtr =
reinterpret_cast<
float *>(result.lightmapUVChannel.data());
93 for (uint32_t i = 0; i < output.vertexCount; ++i) {
94 const float u = output.vertexArray[i].uv[0] /
float(textureWidth);
95 const float v = output.vertexArray[i].uv[1] /
float(textureHeight);
98 result.vertexMap[i] = output.vertexArray[i].xref;
101 result.indexData.resize(output.indexCount *
sizeof(quint32));
102 quint32 *indexPtr =
reinterpret_cast<quint32 *>(result.indexData.data());
103 for (uint32_t i = 0; i < output.indexCount; ++i)
104 *indexPtr++ = output.indexArray[i];
106 xatlas::Destroy(atlas);