11QSSGLightmapUVGeneratorResult QSSGLightmapUVGenerator::run(
const QByteArray &positions,
12 const QByteArray &normals,
13 const QByteArray &uv0,
14 const QByteArray &index,
15 QSSGMesh::Mesh::ComponentType indexComponentType,
18 QSSGLightmapUVGeneratorResult result;
20 xatlas::MeshDecl meshInfo;
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;
27 qWarning(
"Lightmap UV generator: Unknown index type %d; cannot generate",
28 int(indexComponentType));
32 const quint32 indexComponentByteSize = QSSGMesh::MeshInternal::byteSizeForComponentType(indexComponentType);
33 const quint32 indexCount = index.size() / indexComponentByteSize;
35 meshInfo.indexCount = indexCount;
36 meshInfo.indexData = index.constData();
38 const quint32 positionStride = 3 *
sizeof(
float);
39 const quint32 normalStride = 3 *
sizeof(
float);
40 const quint32 uvStride = 2 *
sizeof(
float);
42 meshInfo.vertexCount = positions.size() / positionStride;
43 meshInfo.vertexPositionData = positions.data();
44 meshInfo.vertexPositionStride = positionStride;
46 if (!normals.isEmpty()) {
47 meshInfo.vertexNormalData = normals.constData();
48 meshInfo.vertexNormalStride = normalStride;
50 meshInfo.vertexNormalData =
nullptr;
51 meshInfo.vertexNormalStride = 0;
55 meshInfo.vertexUvData = uv0.constData();
56 meshInfo.vertexUvStride = uvStride;
58 meshInfo.vertexUvData =
nullptr;
59 meshInfo.vertexUvStride = 0;
62 xatlas::PackOptions packOptions;
63 packOptions.maxChartSize = 4096;
64 packOptions.padding = 1;
65 packOptions.resolution = 0;
66 packOptions.texelsPerUnit = texelsPerUnit;
67 packOptions.blockAlign =
true;
69 xatlas::ChartOptions chartOptions;
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);
78 xatlas::Generate(atlas, chartOptions, packOptions);
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);
87 result.lightmapWidth = textureWidth;
88 result.lightmapHeight = textureHeight;
90 const xatlas::Mesh &output = atlas->meshes[0];
91 result.lightmapUVChannel.resize(output.vertexCount * uvStride);
92 result.vertexMap.resize(output.vertexCount);
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);
100 result.vertexMap[i] = output.vertexArray[i].xref;
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];
108 xatlas::Destroy(atlas);