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