1 | // Copyright (C) 2014-2016 Klarälvdalens Datakonsult AB (KDAB). |
2 | // Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies). |
3 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
4 | |
5 | #ifndef GLTFIMPORTER_H |
6 | #define GLTFIMPORTER_H |
7 | |
8 | // |
9 | // W A R N I N G |
10 | // ------------- |
11 | // |
12 | // This file is not part of the Qt API. It exists for the convenience |
13 | // of other Qt classes. This header file may change from version to |
14 | // version without notice, or even be removed. |
15 | // |
16 | // We mean it. |
17 | // |
18 | |
19 | #include <Qt3DCore/qattribute.h> |
20 | #include <Qt3DCore/qbuffer.h> |
21 | #include <QtCore/qjsondocument.h> |
22 | #include <QtCore/qjsonobject.h> |
23 | #include <QtCore/qhash.h> |
24 | #include <QtCore/qloggingcategory.h> |
25 | |
26 | #include <Qt3DRender/private/qsceneimporter_p.h> |
27 | |
28 | QT_BEGIN_NAMESPACE |
29 | |
30 | class QByteArray; |
31 | |
32 | namespace Qt3DCore { |
33 | class QEntity; |
34 | } |
35 | |
36 | namespace Qt3DRender { |
37 | |
38 | class QCamera; |
39 | class QCameraLens; |
40 | class QMaterial; |
41 | class QShaderProgram; |
42 | class QEffect; |
43 | class QAbstractTexture; |
44 | class QRenderState; |
45 | class QTechnique; |
46 | class QParameter; |
47 | class QGeometryRenderer; |
48 | class QAbstractLight; |
49 | class QRenderPass; |
50 | class QTexture2D; |
51 | |
52 | Q_DECLARE_LOGGING_CATEGORY(GLTFImporterLog) |
53 | |
54 | class GLTFImporter : public QSceneImporter |
55 | { |
56 | Q_OBJECT |
57 | |
58 | public: |
59 | GLTFImporter(); |
60 | ~GLTFImporter(); |
61 | |
62 | void setBasePath(const QString& path); |
63 | bool setJSON(const QJsonDocument &json); |
64 | |
65 | // SceneParserInterface interface |
66 | void setSource(const QUrl &source) final; |
67 | void setData(const QByteArray& data, const QString &basePath) final; |
68 | bool areFileTypesSupported(const QStringList &extensions) const final; |
69 | Qt3DCore::QEntity *node(const QString &id) final; |
70 | Qt3DCore::QEntity *scene(const QString &id = QString()) final; |
71 | |
72 | private: |
73 | class BufferData |
74 | { |
75 | public: |
76 | BufferData(); |
77 | explicit BufferData(const QJsonObject &json); |
78 | |
79 | quint64 length; |
80 | QString path; |
81 | QByteArray *data; |
82 | // type if ever useful |
83 | }; |
84 | |
85 | class ParameterData |
86 | { |
87 | public: |
88 | ParameterData(); |
89 | explicit ParameterData(const QJsonObject &json); |
90 | |
91 | QString semantic; |
92 | int type; |
93 | }; |
94 | |
95 | class AccessorData |
96 | { |
97 | public: |
98 | AccessorData(); |
99 | explicit AccessorData(const QJsonObject& json, int major, int minor); |
100 | |
101 | QString bufferViewName; |
102 | Qt3DCore::QAttribute::VertexBaseType type; |
103 | uint dataSize; |
104 | int count; |
105 | int offset; |
106 | int stride; |
107 | }; |
108 | |
109 | static bool isGLTFSupported(const QStringList &extensions); |
110 | static bool isEmbeddedResource(const QString &url); |
111 | static void renameFromJson(const QJsonObject& json, QObject * const object ); |
112 | static bool hasStandardUniformNameFromSemantic(const QString &semantic); |
113 | static QString standardAttributeNameFromSemantic(const QString &semantic); |
114 | QParameter *parameterFromTechnique(QTechnique *technique, const QString ¶meterName); |
115 | |
116 | Qt3DCore::QEntity *defaultScene(); |
117 | QMaterial *material(const QString &id); |
118 | bool fillCamera(QCameraLens &lens, QCamera *cameraEntity, const QString &id) const; |
119 | |
120 | void parse(); |
121 | void parseV1(); |
122 | void parseV2(); |
123 | void cleanup(); |
124 | |
125 | void processJSONAsset(const QJsonObject &json); |
126 | void processJSONBuffer(const QString &id, const QJsonObject &json); |
127 | void processJSONBufferView(const QString &id, const QJsonObject &json); |
128 | void processJSONShader(const QString &id, const QJsonObject &jsonObject); |
129 | void processJSONProgram(const QString &id, const QJsonObject &jsonObject); |
130 | void processJSONTechnique(const QString &id, const QJsonObject &jsonObject); |
131 | void processJSONAccessor(const QString &id, const QJsonObject &json); |
132 | void processJSONMesh(const QString &id, const QJsonObject &json); |
133 | void processJSONImage(const QString &id, const QJsonObject &jsonObject); |
134 | void processJSONTexture(const QString &id, const QJsonObject &jsonObject); |
135 | void processJSONExtensions(const QString &id, const QJsonObject &jsonObject); |
136 | void processJSONEffect(const QString &id, const QJsonObject &jsonObject); |
137 | void processJSONRenderPass(const QString &id, const QJsonObject &jsonObject); |
138 | |
139 | void loadBufferData(); |
140 | void unloadBufferData(); |
141 | |
142 | QByteArray resolveLocalData(const QString &path) const; |
143 | |
144 | QVariant parameterValueFromJSON(int type, const QJsonValue &value) const; |
145 | static Qt3DCore::QAttribute::VertexBaseType accessorTypeFromJSON(int componentType); |
146 | static uint accessorDataSizeFromJson(const QString &type); |
147 | |
148 | static QRenderState *buildStateEnable(int state); |
149 | static QRenderState *buildState(const QString& functionName, const QJsonValue &value, int &type); |
150 | QParameter *buildParameter(const QString &key, const QJsonObject ¶mObj); |
151 | void populateRenderStates(QRenderPass *pass, const QJsonObject &states); |
152 | void addProgramToPass(QRenderPass *pass, const QString &progName); |
153 | |
154 | void setTextureSamplerInfo(const QString &id, const QJsonObject &jsonObj, QTexture2D *tex); |
155 | QMaterial *materialWithCustomShader(const QString &id, const QJsonObject &jsonObj); |
156 | QMaterial *commonMaterial(const QJsonObject &jsonObj); |
157 | QMaterial *pbrMaterial(const QJsonObject &jsonObj); |
158 | |
159 | QJsonDocument m_json; |
160 | QString m_basePath; |
161 | bool m_parseDone; |
162 | int m_majorVersion; |
163 | int m_minorVersion; |
164 | QString m_defaultScene; |
165 | |
166 | // multi-hash because our QMeshData corresponds to a single primitive |
167 | // in glTf. |
168 | QMultiHash<QString, QGeometryRenderer*> m_meshDict; |
169 | |
170 | // GLTF assigns materials at the mesh level, but we do them as siblings, |
171 | // so record the association here for when we instantiate meshes |
172 | QHash<QGeometryRenderer*, QString> m_meshMaterialDict; |
173 | |
174 | QHash<QString, AccessorData> m_accessorDict; |
175 | |
176 | QHash<QString, QMaterial*> m_materialCache; |
177 | |
178 | QHash<QString, BufferData> m_bufferDatas; |
179 | QHash<QString, Qt3DCore::QBuffer*> m_buffers; |
180 | |
181 | QHash<QString, QString> m_shaderPaths; |
182 | QHash<QString, QShaderProgram*> m_programs; |
183 | |
184 | QHash<QString, QTechnique *> m_techniques; |
185 | QHash<QString, QRenderPass *> m_renderPasses; |
186 | QHash<QString, QEffect *> m_effects; |
187 | QHash<QTechnique *, QList<QParameter *> > m_techniqueParameters; |
188 | QHash<QParameter*, ParameterData> m_parameterDataDict; |
189 | |
190 | QHash<QString, QAbstractTexture*> m_textures; |
191 | QHash<QString, QString> m_imagePaths; |
192 | QHash<QString, QImage> m_imageData; |
193 | QHash<QString, QAbstractLight *> m_lights; |
194 | }; |
195 | |
196 | } // namespace Qt3DRender |
197 | |
198 | QT_END_NAMESPACE |
199 | |
200 | #endif // GLTFIMPORTER_H |
201 | |