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));
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;
45 meshInfo.vertexNormalData = normals.
constData();
46 meshInfo.vertexNormalStride = normalStride;
48 meshInfo.vertexNormalData =
nullptr;
49 meshInfo.vertexNormalStride = 0;
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 = baseResolution;
64 packOptions.blockAlign =
true;
66 xatlas::ChartOptions chartOptions;
68 xatlas::Atlas *atlas = xatlas::Create();
69 xatlas::AddMeshError err = xatlas::AddMesh(atlas, meshInfo, 1);
70 if (err != xatlas::AddMeshError::Success) {
71 qWarning(
"Failed to register mesh for UV unwrapping (error %d)",
int(err));
72 xatlas::Destroy(atlas);
75 xatlas::Generate(atlas, chartOptions, packOptions);
77 const uint32_t textureWidth = atlas->width;
78 const uint32_t textureHeight = atlas->height;
79 if (textureWidth == 0 || textureHeight == 0) {
80 qWarning(
"Texture size is empty, UV unwrapping failed");
81 xatlas::Destroy(atlas);
84 result.lightmapWidth = textureWidth;
85 result.lightmapHeight = textureHeight;
87 const xatlas::Mesh &
output = atlas->meshes[0];
88 result.lightmapUVChannel.resize(
output.vertexCount * uvStride);
91 float *uvPtr =
reinterpret_cast<float *
>(
result.lightmapUVChannel.data());
92 for (uint32_t
i = 0;
i <
output.vertexCount; ++
i) {
93 const float u =
output.vertexArray[
i].uv[0] / float(textureWidth);
94 const float v =
output.vertexArray[
i].uv[1] / float(textureHeight);
102 for (uint32_t
i = 0;
i <
output.indexCount; ++
i)
103 *indexPtr++ =
output.indexArray[
i];
105 xatlas::Destroy(atlas);
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
QSSGLightmapUVGeneratorResult run(const QByteArray &positions, const QByteArray &normals, const QByteArray &uv0, const QByteArray &index, QSSGMesh::Mesh::ComponentType indexComponentType, uint baseResolution)
Combined button and popup list for selecting options.
static const QCssKnownValue positions[NumKnownPositionModes - 1]
GLsizei const GLfloat * v
[13]
QT_BEGIN_NAMESPACE typedef uchar * output
static quint32 byteSizeForComponentType(Mesh::ComponentType componentType)