1 | // Copyright (C) 2019 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 |
3 | |
4 | #include <QtCore/QCoreApplication> |
5 | #include <QtCore/QCommandLineParser> |
6 | #include <QtCore/QFile> |
7 | #include <QtCore/QDebug> |
8 | |
9 | #include <QtQuick3DUtils/private/qssgmesh_p.h> |
10 | |
11 | using Qt::hex; |
12 | |
13 | using namespace QSSGMesh; |
14 | |
15 | int main(int argc, char *argv[]) |
16 | { |
17 | QCoreApplication app(argc, argv); |
18 | |
19 | // Setup command line arguments |
20 | QCommandLineParser cmdLineParser; |
21 | cmdLineParser.setApplicationDescription( |
22 | "Allows to debug the high level structure of .mesh files for use with Qt Quick 3D" ); |
23 | cmdLineParser.addHelpOption(); |
24 | cmdLineParser.process(app); |
25 | QStringList meshFileNames = cmdLineParser.positionalArguments(); |
26 | |
27 | // if there is nothing to do return early |
28 | if (meshFileNames.isEmpty()) |
29 | return -1; |
30 | |
31 | // Process Mesh files |
32 | for (const auto &meshFileName : meshFileNames) { |
33 | QFile meshFile(meshFileName); |
34 | if (!meshFile.open(flags: QIODevice::ReadOnly)) { |
35 | qWarning() << "could not open" << meshFileName; |
36 | continue; |
37 | } |
38 | |
39 | MeshInternal::MultiMeshInfo = MeshInternal::readFileHeader(device: &meshFile); |
40 | if (multiHeader.isValid()) { |
41 | // Print Multiheader information |
42 | qDebug() << " -- Multiheader --" ; |
43 | qDebug() << "fileId:" << multiHeader.fileId; |
44 | qDebug() << "version:" << multiHeader.fileVersion; |
45 | qDebug() << "mesh entries:" << multiHeader.meshEntries.size(); |
46 | |
47 | for (auto it = multiHeader.meshEntries.cbegin(), end = multiHeader.meshEntries.cend(); it != end; ++it) { |
48 | const quint32 meshId = it.key(); |
49 | const quint64 meshOffset = it.value(); |
50 | qDebug() << "\t -- mesh entry --" ; |
51 | qDebug() << "\tid:" << meshId; |
52 | qDebug() << "\toffset:" << Qt::hex << meshOffset; |
53 | |
54 | MeshInternal::MeshDataHeader ; |
55 | Mesh mesh; |
56 | if (!MeshInternal::readMeshData(device: &meshFile, offset: meshOffset, mesh: &mesh, header: &header)) { |
57 | qWarning(msg: "Failed to load mesh body" ); |
58 | continue; |
59 | } |
60 | |
61 | // Header |
62 | qDebug() << "\t -- MeshDataHeader --" ; |
63 | qDebug() << "\tfileId:" << header.fileId; |
64 | qDebug() << "\tfileVersion:" << header.fileVersion; |
65 | qDebug() << "\tflags:" << header.flags; |
66 | qDebug() << "\tsize in bytes:" << header.sizeInBytes; |
67 | |
68 | // Draw Mode |
69 | qDebug() << "\t\tdraw mode:" << static_cast<int>(mesh.drawMode()); |
70 | |
71 | // Winding |
72 | qDebug() << "\t\twinding:" << QSSGBaseTypeHelpers::toString(value: QSSGRenderWinding(mesh.winding())); |
73 | |
74 | // Vertex Buffer |
75 | const Mesh::VertexBuffer vb = mesh.vertexBuffer(); |
76 | qDebug() << "\t\t -- Vertex Buffer --" ; |
77 | qDebug() << "\t\tentry count:" << vb.entries.size(); |
78 | for (quint32 idx = 0, end = vb.entries.size(); idx < end; ++idx) { |
79 | qDebug() << "\t\t\t -- Vertex Buffer Entry" << idx << "--" ; |
80 | const Mesh::VertexBufferEntry &entry(vb.entries[idx]); |
81 | qDebug() << "\t\t\tname:" << entry.name; |
82 | qDebug() << "\t\t\ttype:" << QSSGBaseTypeHelpers::toString(value: QSSGRenderComponentType(entry.componentType)); |
83 | qDebug() << "\t\t\tcomponentCount:" << entry.componentCount; |
84 | qDebug() << "\t\t\tstart offset:" << entry.offset; |
85 | } |
86 | qDebug() << "\t\tstride:" << vb.stride; |
87 | qDebug() << "\t\tdata size in bytes:" << vb.data.size(); |
88 | |
89 | // Target Buffer |
90 | if (header.hasSeparateTargetBuffer()) { |
91 | const Mesh::TargetBuffer tb = mesh.targetBuffer(); |
92 | qDebug() << "\t\t -- Morph Target Buffers --" ; |
93 | qDebug() << "\t\tentry count:" << tb.entries.count(); |
94 | for (quint32 idx = 0, end = tb.entries.count(); idx < end; ++idx) { |
95 | qDebug() << "\t\t\t -- Target Buffer Entry" << idx << "--" ; |
96 | const Mesh::VertexBufferEntry &entry(vb.entries[idx]); |
97 | qDebug() << "\t\t\tname:" << entry.name; |
98 | qDebug() << "\t\t\ttype:" << QSSGBaseTypeHelpers::toString(value: QSSGRenderComponentType(entry.componentType)); |
99 | qDebug() << "\t\t\tcomponentCount:" << entry.componentCount; |
100 | qDebug() << "\t\t\tstart offset:" << entry.offset; |
101 | } |
102 | qDebug() << "\t\tnumber of targets:" << tb.numTargets; |
103 | qDebug() << "\t\tdata size in bytes:" << tb.data.size(); |
104 | } |
105 | |
106 | // Index Buffer |
107 | const Mesh::IndexBuffer ib = mesh.indexBuffer(); |
108 | qDebug() << "\t\t -- Index Buffer --" ; |
109 | qDebug() << "\t\tcomponentType:" << QSSGBaseTypeHelpers::toString(value: QSSGRenderComponentType(ib.componentType)); |
110 | qDebug() << "\t\tdata size in bytes:" << ib.data.size(); |
111 | |
112 | // Subsets |
113 | const QVector<Mesh::Subset> subsets = mesh.subsets(); |
114 | qDebug() << "\t\t -- Subsets --" ; |
115 | qDebug() << "\t\tsubset count:" << subsets.size(); |
116 | for (quint32 idx = 0, end = subsets.size(); idx < end; ++idx) { |
117 | qDebug() << "\t\t -- Subset" << idx << "--" ; |
118 | const Mesh::Subset &subset(subsets[idx]); |
119 | qDebug() << "\t\tindex count:" << subset.count; |
120 | qDebug() << "\t\tstart offset in indices:" << subset.offset; |
121 | qDebug() << "\t\tbounds: (" << |
122 | subset.bounds.min.x() << "," << |
123 | subset.bounds.min.y() << "," << |
124 | subset.bounds.min.z() << ") (" << |
125 | subset.bounds.max.x() << "," << |
126 | subset.bounds.max.y() << "," << |
127 | subset.bounds.max.z() << ")" ; |
128 | qDebug() << "\t\tname:" << subset.name; |
129 | if (header.hasLightmapSizeHint()) |
130 | qDebug() << "\t\tlightmap size hint:" << subset.lightmapSizeHint; |
131 | if (header.hasLodDataHint()) { |
132 | qDebug() << "\t\tlods: " ; |
133 | for (auto lod : subset.lods) { |
134 | qDebug() << "\t\t\tcount: " << lod.count << "offset: " << lod.offset << "distance: " << lod.distance; |
135 | } |
136 | } |
137 | } |
138 | } |
139 | |
140 | } |
141 | |
142 | meshFile.close(); |
143 | qDebug() << "closed meshFile" ; |
144 | } |
145 | |
146 | return 0; |
147 | } |
148 | |