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
11using Qt::hex;
12
13using namespace QSSGMesh;
14
15int 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 multiHeader = 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 header;
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

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtquick3d/tools/meshdebug/main.cpp