1 | // Copyright (C) 2021 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
3 | |
4 | #ifndef QSSGLIGHTMAPUVGENERATOR_P_H |
5 | #define QSSGLIGHTMAPUVGENERATOR_P_H |
6 | |
7 | // |
8 | // W A R N I N G |
9 | // ------------- |
10 | // |
11 | // This file is not part of the Qt API. It exists purely as an |
12 | // implementation detail. This header file may change from version to |
13 | // version without notice, or even be removed. |
14 | // |
15 | // We mean it. |
16 | // |
17 | |
18 | #include <QtQuick3DUtils/private/qssgmesh_p.h> |
19 | |
20 | QT_BEGIN_NAMESPACE |
21 | |
22 | struct QSSGLightmapUVGeneratorResult |
23 | { |
24 | QByteArray lightmapUVChannel; |
25 | QVector<quint32> vertexMap; |
26 | QByteArray indexData; |
27 | quint32 lightmapWidth = 0; |
28 | quint32 lightmapHeight = 0; |
29 | |
30 | bool isValid() const { |
31 | return !lightmapUVChannel.isEmpty() && !vertexMap.isEmpty(); |
32 | } |
33 | }; |
34 | |
35 | class Q_QUICK3DUTILS_EXPORT QSSGLightmapUVGenerator |
36 | { |
37 | public: |
38 | // Takes in position, normals, UV0, indices and returns a new lightmap UV |
39 | // channel, new index data, and a mapping to original vertices. |
40 | // |
41 | // The topology must be triangles. The position data is expected to contain |
42 | // 3 component float positions. normals is expected to contain 3 component |
43 | // float normal vectors. uv0 is expected to contain 2 component float UV |
44 | // coordinates. When not available, normals and uv0 can be left empty. |
45 | // |
46 | // The resulting index data has always the same number of indices as the |
47 | // original, but regardless of the original component type, the new data |
48 | // always has a component type of uint32. |
49 | // |
50 | // The resulting lightmapUVChannel contains 2 component floats. There can |
51 | // be more lightmap UVs than input positions, because the unwrapping |
52 | // process may add extra vertices to avoid seams. The new vertices always |
53 | // correspond to an original vertex. That is why the result also has a list |
54 | // that has one element for each UV in the lightmap UV data, the value |
55 | // being an index of a vertex in the original position channel. This |
56 | // mapping must be used by the caller to grow and rewrite all vertex input |
57 | // data (position, normals, UVs, etc.) so that the count of their elements |
58 | // matches the lightmap UV channel. |
59 | // |
60 | // baseResolution sepecifies the approx. size on which the lightmap size |
61 | // calculation is based; the returned width and height are in the same |
62 | // ballpark as much as possible (but may be bigger, depending on the mesh). |
63 | // |
64 | QSSGLightmapUVGeneratorResult run(const QByteArray &positions, |
65 | const QByteArray &normals, |
66 | const QByteArray &uv0, |
67 | const QByteArray &index, |
68 | QSSGMesh::Mesh::ComponentType indexComponentType, |
69 | uint baseResolution); |
70 | |
71 | // source is of N elements of componentCount * sizeof(T) bytes each. The |
72 | // returned data is M elements of componentCount * sizeof(T) bytes each, where |
73 | // M >= N. vertexMap is the mapping table with M elements where each element |
74 | // is an index in range [0, N-1]. |
75 | template<typename T> |
76 | static QByteArray remap(const QByteArray &source, const QVector<quint32> &vertexMap, int componentCount) |
77 | { |
78 | if (source.isEmpty()) |
79 | return QByteArray(); |
80 | const T *src = reinterpret_cast<const T *>(source.constData()); |
81 | const int byteStride = sizeof(T) * componentCount; |
82 | QByteArray result(vertexMap.size() * byteStride, Qt::Uninitialized); |
83 | T *dst = reinterpret_cast<T *>(result.data()); |
84 | for (int i = 0, count = vertexMap.size(); i != count; ++i) { |
85 | const quint32 originalVertexIndex = vertexMap[i]; |
86 | for (int j = 0; j < componentCount; ++j) |
87 | *dst++ = src[originalVertexIndex * componentCount + j]; |
88 | } |
89 | return result; |
90 | } |
91 | }; |
92 | |
93 | QT_END_NAMESPACE |
94 | |
95 | #endif // QSSGLIGHTMAPUVGENERATOR_P_H |
96 | |