aboutsummaryrefslogtreecommitdiffstats
path: root/tools/meshdebug/main.cpp
blob: 8c45def70f06b26dc10764d1d39860fb8f527168 (plain)
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;
}