// Copyright (C) 2021 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef QSSGLIGHTMAPUVGENERATOR_P_H #define QSSGLIGHTMAPUVGENERATOR_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include QT_BEGIN_NAMESPACE struct QSSGLightmapUVGeneratorResult { QByteArray lightmapUVChannel; QVector vertexMap; QByteArray indexData; quint32 lightmapWidth = 0; quint32 lightmapHeight = 0; bool isValid() const { return !lightmapUVChannel.isEmpty() && !vertexMap.isEmpty(); } }; class Q_QUICK3DUTILS_EXPORT QSSGLightmapUVGenerator { public: // Takes in position, normals, UV0, indices and returns a new lightmap UV // channel, new index data, and a mapping to original vertices. // // The topology must be triangles. The position data is expected to contain // 3 component float positions. normals is expected to contain 3 component // float normal vectors. uv0 is expected to contain 2 component float UV // coordinates. When not available, normals and uv0 can be left empty. // // The resulting index data has always the same number of indices as the // original, but regardless of the original component type, the new data // always has a component type of uint32. // // The resulting lightmapUVChannel contains 2 component floats. There can // be more lightmap UVs than input positions, because the unwrapping // process may add extra vertices to avoid seams. The new vertices always // correspond to an original vertex. That is why the result also has a list // that has one element for each UV in the lightmap UV data, the value // being an index of a vertex in the original position channel. This // mapping must be used by the caller to grow and rewrite all vertex input // data (position, normals, UVs, etc.) so that the count of their elements // matches the lightmap UV channel. // // texelsPerUnit // Unit to texel scale. e.g. a 1x1 quad with texelsPerUnit of 32 will take // up approximately 32x32 texels in the atlas. // QSSGLightmapUVGeneratorResult run(const QByteArray &positions, const QByteArray &normals, const QByteArray &uv0, const QByteArray &index, QSSGMesh::Mesh::ComponentType indexComponentType, float texelsPerUnit); // source is of N elements of componentCount * sizeof(T) bytes each. The // returned data is M elements of componentCount * sizeof(T) bytes each, where // M >= N. vertexMap is the mapping table with M elements where each element // is an index in range [0, N-1]. template static QByteArray remap(const QByteArray &source, const QVector &vertexMap, int componentCount) { if (source.isEmpty()) return QByteArray(); const T *src = reinterpret_cast(source.constData()); const int byteStride = sizeof(T) * componentCount; QByteArray result(vertexMap.size() * byteStride, Qt::Uninitialized); T *dst = reinterpret_cast(result.data()); for (int i = 0, count = vertexMap.size(); i != count; ++i) { const quint32 originalVertexIndex = vertexMap[i]; for (int j = 0; j < componentCount; ++j) *dst++ = src[originalVertexIndex * componentCount + j]; } return result; } }; QT_END_NAMESPACE #endif // QSSGLIGHTMAPUVGENERATOR_P_H