/****************************************************************************
**
** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "gltfimporter.h"

#include <QtCore/qdir.h>
#include <QtCore/qfileinfo.h>
#include <QtCore/qjsonarray.h>
#include <QtCore/qjsonobject.h>
#include <QtCore/qmath.h>

#include <QtGui/qvector2d.h>

#include <Qt3DCore/qentity.h>
#include <Qt3DCore/qtransform.h>

#include <Qt3DRender/qcameralens.h>
#include <Qt3DRender/qcamera.h>
#include <Qt3DRender/qalphacoverage.h>
#include <Qt3DRender/qalphatest.h>
#include <Qt3DRender/qblendequation.h>
#include <Qt3DRender/qblendequationarguments.h>
#include <Qt3DRender/qclipplane.h>
#include <Qt3DRender/qcolormask.h>
#include <Qt3DRender/qcullface.h>
#include <Qt3DRender/qdithering.h>
#include <Qt3DRender/qmultisampleantialiasing.h>
#include <Qt3DRender/qpointsize.h>
#include <Qt3DRender/qnodepthmask.h>
#include <Qt3DRender/qdepthrange.h>
#include <Qt3DRender/qdepthtest.h>
#include <Qt3DRender/qseamlesscubemap.h>
#include <Qt3DRender/qstencilmask.h>
#include <Qt3DRender/qstenciloperation.h>
#include <Qt3DRender/qstenciloperationarguments.h>
#include <Qt3DRender/qstenciltest.h>
#include <Qt3DRender/qstenciltestarguments.h>
#include <Qt3DRender/qeffect.h>
#include <Qt3DRender/qfrontface.h>
#include <Qt3DRender/qgeometry.h>
#include <Qt3DRender/qgeometryrenderer.h>
#include <Qt3DRender/qmaterial.h>
#include <Qt3DRender/qgraphicsapifilter.h>
#include <Qt3DRender/qparameter.h>
#include <Qt3DRender/qpolygonoffset.h>
#include <Qt3DRender/qrenderstate.h>
#include <Qt3DRender/qscissortest.h>
#include <Qt3DRender/qshaderprogram.h>
#include <Qt3DRender/qtechnique.h>
#include <Qt3DRender/qtexture.h>
#include <Qt3DRender/qtextureimagedatagenerator.h>
#include <Qt3DRender/qdirectionallight.h>
#include <Qt3DRender/qspotlight.h>
#include <Qt3DRender/qpointlight.h>

#include <Qt3DExtras/qphongmaterial.h>
#include <Qt3DExtras/qphongalphamaterial.h>
#include <Qt3DExtras/qdiffusemapmaterial.h>
#include <Qt3DExtras/qdiffusespecularmapmaterial.h>
#include <Qt3DExtras/qnormaldiffusemapmaterial.h>
#include <Qt3DExtras/qnormaldiffusemapalphamaterial.h>
#include <Qt3DExtras/qnormaldiffusespecularmapmaterial.h>
#include <Qt3DExtras/qgoochmaterial.h>
#include <Qt3DExtras/qpervertexcolormaterial.h>
#include <Qt3DExtras/qmetalroughmaterial.h>
#include <Qt3DExtras/qconemesh.h>
#include <Qt3DExtras/qcuboidmesh.h>
#include <Qt3DExtras/qcylindermesh.h>
#include <Qt3DExtras/qplanemesh.h>
#include <Qt3DExtras/qspheremesh.h>
#include <Qt3DExtras/qtorusmesh.h>

#include <private/qurlhelper_p.h>
#include <private/qloadgltf_p.h>

/**
  * glTF 2.0 conformance report
  *
  * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0
  * Samples: https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0
  *
  * Most of the reference samples are rendered correctly, with the following exceptions:
  *
  * 'extensions' and 'extras' are ignored everywhere except in nodes.
  *
  * asset
  *   generator, copyright, minVersion: not parsed
  * accessors
  *   min, max, normalized, sparse: not parsed
  * animations
  *   the whole object is not parsed
  * buffers
  *   all parsed
  * bufferViews
  *   all parsed
  * cameras
  *   all parsed
  * images
  *   mimeType, bufferView, name: not parsed
  * materials
  *   emissiveTexture, emissiveFactor: not parsed
  *   alphaMode, alphaCutoff, doubleSided: not parsed
  *   texCoord, strength: not parsed
  * meshes
  *   weights: not parsed
  * nodes
  *   skin, weights: not parsed
  * samplers
  *   all parsed
  * scenes
  *   all parsed
  * textures
  *   all parsed
  */

#ifndef qUtf16PrintableImpl // -Impl is a Qt 5.8 feature
#  define qUtf16PrintableImpl(string) \
    static_cast<const wchar_t*>(static_cast<const void*>(string.utf16()))
#endif

#define KEY_ASSET              QLatin1String("asset")
#define KEY_VERSION            QLatin1String("version")
#define KEY_CAMERA             QLatin1String("camera")
#define KEY_CAMERAS            QLatin1String("cameras")
#define KEY_SCENES             QLatin1String("scenes")
#define KEY_NODES              QLatin1String("nodes")
#define KEY_MESHES             QLatin1String("meshes")
#define KEY_CHILDREN           QLatin1String("children")
#define KEY_MESH               QLatin1String("mesh")
#define KEY_MATRIX             QLatin1String("matrix")
#define KEY_ROTATION           QLatin1String("rotation")
#define KEY_SCALE              QLatin1String("scale")
#define KEY_TRANSLATION        QLatin1String("translation")
#define KEY_TYPE               QLatin1String("type")
#define KEY_PERSPECTIVE        QLatin1String("perspective")
#define KEY_ORTHOGRAPHIC       QLatin1String("orthographic")
#define KEY_NAME               QLatin1String("name")
#define KEY_COUNT              QLatin1String("count")
#define KEY_YFOV               QLatin1String("yfov")
#define KEY_ZNEAR              QLatin1String("znear")
#define KEY_ZFAR               QLatin1String("zfar")
#define KEY_XMAG               QLatin1String("xmag")
#define KEY_YMAG               QLatin1String("ymag")
#define KEY_MATERIALS          QLatin1String("materials")
#define KEY_EXTENSIONS         QLatin1String("extensions")
#define KEY_COMMON_MAT         QLatin1String("KHR_materials_common")
#define KEY_TECHNIQUE          QLatin1String("technique")
#define KEY_VALUES             QLatin1String("values")
#define KEY_BUFFERS            QLatin1String("buffers")
#define KEY_SHADERS            QLatin1String("shaders")
#define KEY_PROGRAMS           QLatin1String("programs")
#define KEY_PROGRAM            QLatin1String("program")
#define KEY_TECHNIQUES         QLatin1String("techniques")
#define KEY_ACCESSORS          QLatin1String("accessors")
#define KEY_IMAGES             QLatin1String("images")
#define KEY_TEXTURES           QLatin1String("textures")
#define KEY_SCENE              QLatin1String("scene")
#define KEY_BUFFER             QLatin1String("buffer")
#define KEY_TARGET             QLatin1String("target")
#define KEY_BYTE_OFFSET        QLatin1String("byteOffset")
#define KEY_BYTE_LENGTH        QLatin1String("byteLength")
#define KEY_BYTE_STRIDE        QLatin1String("byteStride")
#define KEY_PRIMITIVES         QLatin1String("primitives")
#define KEY_MODE               QLatin1String("mode")
#define KEY_MATERIAL           QLatin1String("material")
#define KEY_ATTRIBUTES         QLatin1String("attributes")
#define KEY_INDICES            QLatin1String("indices")
#define KEY_URI                QLatin1String("uri")
#define KEY_FORMAT             QLatin1String("format")
#define KEY_PASSES             QLatin1String("passes")
#define KEY_SOURCE             QLatin1String("source")
#define KEY_SAMPLER            QLatin1String("sampler")
#define KEY_SAMPLERS           QLatin1String("samplers")
#define KEY_SEMANTIC           QLatin1String("semantic")
#define KEY_STATES             QLatin1String("states")
#define KEY_UNIFORMS           QLatin1String("uniforms")
#define KEY_PARAMETERS         QLatin1String("parameters")
#define KEY_WRAP_S             QLatin1String("wrapS")
#define KEY_MIN_FILTER         QLatin1String("minFilter")
#define KEY_MAG_FILTER         QLatin1String("magFilter")
#define KEY_LIGHT              QLatin1String("light")
#define KEY_LIGHTS             QLatin1String("lights")
#define KEY_POINT_LIGHT        QLatin1String("point")
#define KEY_DIRECTIONAL_LIGHT  QLatin1String("directional")
#define KEY_SPOT_LIGHT         QLatin1String("spot")
#define KEY_AMBIENT_LIGHT      QLatin1String("ambient")
#define KEY_COLOR              QLatin1String("color")
#define KEY_FALLOFF_ANGLE      QLatin1String("falloffAngle")
#define KEY_DIRECTION          QLatin1String("direction")
#define KEY_CONST_ATTENUATION  QLatin1String("constantAttenuation")
#define KEY_LINEAR_ATTENUATION QLatin1String("linearAttenuation")
#define KEY_QUAD_ATTENUATION   QLatin1String("quadraticAttenuation")
#define KEY_INTENSITY          QLatin1String("intensity")
#define KEY_PBR_METAL_ROUGH    QLatin1String("pbrMetallicRoughness")
#define KEY_BASE_COLOR         QLatin1String("baseColorFactor")
#define KEY_BASE_COLOR_TEX     QLatin1String("baseColorTexture")
#define KEY_METAL_FACTOR       QLatin1String("metallicFactor")
#define KEY_METAL_ROUGH_TEX    QLatin1String("metallicRoughnessTexture")
#define KEY_ROUGH_FACTOR       QLatin1String("roughnessFactor")
#define KEY_NORMAL_TEX         QLatin1String("normalTexture")
#define KEY_OCCLUSION_TEX      QLatin1String("occlusionTexture")
#define KEY_INDEX              QLatin1String("index")

#define KEY_INSTANCE_TECHNIQUE  QLatin1String("instanceTechnique")
#define KEY_INSTANCE_PROGRAM    QLatin1String("instanceProgram")
#define KEY_BUFFER_VIEWS        QLatin1String("bufferViews")
#define KEY_BUFFER_VIEW         QLatin1String("bufferView")
#define KEY_VERTEX_SHADER       QLatin1String("vertexShader")
#define KEY_FRAGMENT_SHADER     QLatin1String("fragmentShader")
#define KEY_TESS_CTRL_SHADER    QLatin1String("tessCtrlShader")
#define KEY_TESS_EVAL_SHADER    QLatin1String("tessEvalShader")
#define KEY_GEOMETRY_SHADER     QLatin1String("geometryShader")
#define KEY_COMPUTE_SHADER      QLatin1String("computeShader")
#define KEY_INTERNAL_FORMAT     QLatin1String("internalFormat")
#define KEY_COMPONENT_TYPE      QLatin1String("componentType")
#define KEY_ASPECT_RATIO        QLatin1String("aspect_ratio")
#define KEY_VALUE               QLatin1String("value")
#define KEY_ENABLE              QLatin1String("enable")
#define KEY_FUNCTIONS           QLatin1String("functions")
#define KEY_BLEND_EQUATION      QLatin1String("blendEquationSeparate")
#define KEY_BLEND_FUNCTION      QLatin1String("blendFuncSeparate")
#define KEY_TECHNIQUE_CORE      QLatin1String("techniqueCore")
#define KEY_TECHNIQUE_GL2       QLatin1String("techniqueGL2")
#define KEY_GABIFILTER          QLatin1String("gapifilter")
#define KEY_API                 QLatin1String("api")
#define KEY_MAJORVERSION        QLatin1String("majorVersion")
#define KEY_MINORVERSION        QLatin1String("minorVersion")
#define KEY_PROFILE             QLatin1String("profile")
#define KEY_VENDOR              QLatin1String("vendor")
#define KEY_FILTERKEYS          QLatin1String("filterkeys")
#define KEY_RENDERPASSES        QLatin1String("renderpasses")
#define KEY_EFFECT              QLatin1String("effect")
#define KEY_EFFECTS             QLatin1String("effects")
#define KEY_PROPERTIES          QLatin1String("properties")
#define KEY_POSITION            QLatin1String("position")
#define KEY_UPVECTOR            QLatin1String("upVector")
#define KEY_VIEW_CENTER         QLatin1String("viewCenter")

QT_BEGIN_NAMESPACE

using namespace Qt3DCore;
using namespace Qt3DExtras;

namespace {

inline QVector3D jsonArrToVec3(const QJsonArray &array)
{
    return QVector3D(array[0].toDouble(), array[1].toDouble(), array[2].toDouble());
}

inline QVector4D jsonArrToVec4(const QJsonArray &array)
{
    return QVector4D(array[0].toDouble(), array[1].toDouble(),
                     array[2].toDouble(), array[3].toDouble());
}

inline QVariant jsonArrToColorVariant(const QJsonArray &array)
{
    return QVariant(QColor::fromRgbF(array[0].toDouble(), array[1].toDouble(),
                                     array[2].toDouble(), array[3].toDouble()));
}

inline QColor vec4ToQColor(const QVariant &vec4Var)
{
    const QVector4D v = vec4Var.value<QVector4D>();
    return QColor::fromRgbF(v.x(), v.y(), v.z());
}

inline QVariant vec4ToColorVariant(const QVariant &vec4Var)
{
    return QVariant(vec4ToQColor(vec4Var));
}

Qt3DRender::QFilterKey *buildFilterKey(const QString &key, const QJsonValue &val)
{
    Qt3DRender::QFilterKey *fk = new Qt3DRender::QFilterKey;
    fk->setName(key);
    if (val.isString())
        fk->setValue(val.toString());
    else
        fk->setValue(val.toInt());
    return fk;
}

} // namespace

namespace Qt3DRender {

Q_LOGGING_CATEGORY(GLTFImporterLog, "Qt3D.GLTFImport", QtWarningMsg);

class GLTFRawTextureImage : public QAbstractTextureImage
{
    Q_OBJECT
public:
    explicit GLTFRawTextureImage(QNode *parent = nullptr);

    QTextureImageDataGeneratorPtr dataGenerator() const final;

    void setImage(const QImage &image);

private:
    QImage m_image;

    class GLTFRawTextureImageFunctor : public QTextureImageDataGenerator
    {
    public:
        explicit GLTFRawTextureImageFunctor(const QImage &image);

        QTextureImageDataPtr operator()() final;
        bool operator ==(const QTextureImageDataGenerator &other) const final;

        QT3D_FUNCTOR(GLTFRawTextureImageFunctor)
    private:
        QImage m_image;
    };
};

GLTFImporter::GLTFImporter()
    : QSceneImporter()
    , m_parseDone(false)
    , m_majorVersion(1)
    , m_minorVersion(0)
{
}

GLTFImporter::~GLTFImporter()
{

}

/*!
    \class Qt3DRender::GLTFImporter
    \inmodule Qt3DRender
    \internal
    \brief Handles importing of gltf files.
*/
/*!
    Set the base \a path for importing scenes.
*/
void GLTFImporter::setBasePath(const QString& path)
{
    m_basePath = path;
}

/*!
    Set a \a json document as the file used for importing a scene.
    Returns true if the operation is successful.
*/
bool GLTFImporter::setJSON(const QJsonDocument &json)
{
    if (!json.isObject()) {
        return false;
    }

    m_json = json;
    m_parseDone = false;

    return true;
}

/*!
 * Sets the path based on parameter \a source. The path is
 * used by the parser to load the scene file.
 * If the file is valid, parsing is automatically triggered.
 */
void GLTFImporter::setSource(const QUrl &source)
{
    const QString path = QUrlHelper::urlToLocalFileOrQrc(source);
    QFileInfo finfo(path);
    if (Q_UNLIKELY(!finfo.exists())) {
        qCWarning(GLTFImporterLog, "missing file: %ls", qUtf16PrintableImpl(path));
        return;
    }
    QFile f(path);
    f.open(QIODevice::ReadOnly);

    if (Q_UNLIKELY(!setJSON(qLoadGLTF(f.readAll())))) {
        qCWarning(GLTFImporterLog, "not a JSON document");
        return;
    }

    setBasePath(finfo.dir().absolutePath());
}

/*!
 * Sets the \a basePath used by the parser to load the scene file.
 * If the file derived from \a data is valid, parsing is automatically
 * triggered.
 */
void GLTFImporter::setData(const QByteArray& data, const QString &basePath)
{
    if (Q_UNLIKELY(!setJSON(qLoadGLTF(data)))) {
        qCWarning(GLTFImporterLog, "not a JSON document");
        return;
    }

    setBasePath(basePath);
}

/*!
 * Returns true if the \a extensions are supported by the
 * GLTF parser.
 */
bool GLTFImporter::areFileTypesSupported(const QStringList &extensions) const
{
    return GLTFImporter::isGLTFSupported(extensions);
}

/*!
    Imports the node specified in \a id from the GLTF file.
*/
Qt3DCore::QEntity* GLTFImporter::node(const QString &id)
{
    QJsonValue jsonVal;

    if (m_majorVersion > 1) {
        const QJsonArray nodes = m_json.object().value(KEY_NODES).toArray();
        if (Q_UNLIKELY(id.toInt() >= nodes.count())) {
            qCWarning(GLTFImporterLog, "unknown node %ls in GLTF file %ls",
                      qUtf16PrintableImpl(id), qUtf16PrintableImpl(m_basePath));
            return nullptr;
        }
        jsonVal = nodes[id.toInt()];
    } else {
        const QJsonObject nodes = m_json.object().value(KEY_NODES).toObject();
        jsonVal = nodes.value(id);
        if (Q_UNLIKELY(jsonVal.isUndefined())) {
            qCWarning(GLTFImporterLog, "unknown node %ls in GLTF file %ls",
                      qUtf16PrintableImpl(id), qUtf16PrintableImpl(m_basePath));
            return nullptr;
        }
    }

    const QJsonObject jsonObj = jsonVal.toObject();
    QEntity* result = nullptr;

    // Qt3D has a limitation that a QEntity can only have 1 mesh and 1 material component
    // So if the node has only 1 mesh, we only create 1 QEntity
    // Otherwise if there are n meshes, there is 1 QEntity, with n children for each mesh/material combo
    {
        QVector<QEntity *> entities;
        const QJsonValue meshesValue = jsonObj.value(KEY_MESHES);

        if (meshesValue.isUndefined()) {
            const QJsonValue mesh = jsonObj.value(KEY_MESH);
            if (!mesh.isUndefined()) {
                const QString meshName = QString::number(mesh.toInt());
                const auto geometryRenderers = qAsConst(m_meshDict).equal_range(meshName);
                for (auto it = geometryRenderers.first; it != geometryRenderers.second; ++it) {
                    QGeometryRenderer *geometryRenderer = it.value();
                    QEntity *entity = new QEntity;
                    entity->addComponent(geometryRenderer);
                    QMaterial *mat = material(m_meshMaterialDict[geometryRenderer]);
                    if (mat)
                        entity->addComponent(mat);
                    entities.append(entity);
                }
            }
        } else {
            const auto meshes = meshesValue.toArray();
            for (const QJsonValue &mesh : meshes) {
                const QString meshName = mesh.toString();
                const auto geometryRenderers = qAsConst(m_meshDict).equal_range(meshName);
                if (Q_UNLIKELY(geometryRenderers.first == geometryRenderers.second)) {
                    qCWarning(GLTFImporterLog, "node %ls references unknown mesh %ls",
                              qUtf16PrintableImpl(id), qUtf16PrintableImpl(meshName));
                    continue;
                }

                for (auto it = geometryRenderers.first; it != geometryRenderers.second; ++it) {
                    QGeometryRenderer *geometryRenderer = it.value();
                    QEntity *entity = new QEntity;
                    entity->addComponent(geometryRenderer);
                    QMaterial *mat = material(m_meshMaterialDict[geometryRenderer]);
                    if (mat)
                        entity->addComponent(mat);
                    entities.append(entity);
                }
            }
        }

        switch (entities.size()) {
        case 0:
            break;
        case 1:
            result = qAsConst(entities).first();
            break;
        default:
            result = new QEntity;
            for (QEntity *entity : qAsConst(entities))
                entity->setParent(result);
        }
    }

    const auto cameraVal = jsonObj.value(KEY_CAMERA);
    const auto matrix = jsonObj.value(KEY_MATRIX);
    const auto rotation = jsonObj.value(KEY_ROTATION);
    const auto translation = jsonObj.value(KEY_TRANSLATION);
    const auto scale = jsonObj.value(KEY_SCALE);
    Qt3DCore::QTransform *trans = nullptr;
    QCameraLens *cameraLens = nullptr;
    QCamera *cameraEntity = nullptr;

    // If the node contains no meshes, results will still be null here.
    // If the node has camera and transform, promote it to QCamera, as that makes it more
    // convenient to adjust the imported camera in the application.
    if (result == nullptr) {
        if (!cameraVal.isUndefined()
                && (!matrix.isUndefined() || !rotation.isUndefined() || !translation.isUndefined()
                    || !scale.isUndefined())) {
            cameraEntity = new QCamera;
            trans = cameraEntity->transform();
            cameraLens = cameraEntity->lens();
            result = cameraEntity;
        } else {
            result = new QEntity;
        }
    }

    // recursively retrieve children
    const auto children = jsonObj.value(KEY_CHILDREN).toArray();
    for (const QJsonValue &c : children) {
        QEntity* child = node((m_majorVersion > 1) ? QString::number(c.toInt()) : c.toString());
        if (!child)
            continue;
        child->setParent(result);
    }

    renameFromJson(jsonObj, result);

    // Node Transforms
    if (!matrix.isUndefined()) {
        QMatrix4x4 m(Qt::Uninitialized);

        QJsonArray matrixValues = matrix.toArray();
        for (int i = 0; i < 16; ++i) {
            double v = matrixValues.at(i).toDouble();
            m(i % 4, i >> 2) = v;
        }

        if (!trans)
            trans = new Qt3DCore::QTransform;
        trans->setMatrix(m);
    }

    // Rotation quaternion
    if (!rotation.isUndefined()) {
        if (!trans)
            trans = new Qt3DCore::QTransform;

        QQuaternion quaternion(jsonArrToVec4(rotation.toArray()));
        trans->setRotation(quaternion);
    }

    // Translation
    if (!translation.isUndefined()) {
        if (!trans)
            trans = new Qt3DCore::QTransform;
        trans->setTranslation(jsonArrToVec3(translation.toArray()));
    }

    // Scale
    if (!scale.isUndefined()) {
        if (!trans)
            trans = new Qt3DCore::QTransform;
        trans->setScale3D(jsonArrToVec3(scale.toArray()));
    }

    // Add the Transform component
    if (trans != nullptr)
        result->addComponent(trans);

    if (!cameraVal.isUndefined()) {
        const bool newLens = cameraLens == nullptr;
        if (newLens)
            cameraLens = new QCameraLens;
        const QString cameraID = (m_majorVersion > 1) ? QString::number(cameraVal.toInt()) : cameraVal.toString();
        if (!fillCamera(*cameraLens, cameraEntity, cameraID)) {
            qCWarning(GLTFImporterLog, "failed to build camera: %ls on node %ls",
                      qUtf16PrintableImpl(cameraID), qUtf16PrintableImpl(id));
        } else if (newLens) {
            result->addComponent(cameraLens);
        }
    }

    const auto extensionsVal = jsonObj.value(KEY_EXTENSIONS);
    if (!extensionsVal.isUndefined()) {
        const auto commonMat = extensionsVal.toObject().value(KEY_COMMON_MAT);
        if (!commonMat.isUndefined()) {
            const QJsonValue lightVal = commonMat.toObject().value(KEY_LIGHT);
            const QString lightId = (m_majorVersion > 1) ? QString::number(lightVal.toInt()) : lightVal.toString();
            QAbstractLight *lightComp = m_lights.value(lightId);
            if (Q_UNLIKELY(!lightComp)) {
                qCWarning(GLTFImporterLog, "failed to find light: %ls for node %ls",
                          qUtf16PrintableImpl(lightId), qUtf16PrintableImpl(id));
            } else {
                result->addComponent(lightComp);
            }
        }
    }

    return result;
}

/*!
    Imports the scene specified in parameter \a id.
*/
Qt3DCore::QEntity* GLTFImporter::scene(const QString &id)
{
    parse();

    QEntity* sceneEntity = nullptr;

    if (m_majorVersion > 1) {
        const QJsonArray scenes = m_json.object().value(KEY_SCENES).toArray();
        const auto sceneVal = scenes.first();
        if (Q_UNLIKELY(sceneVal.isUndefined())) {
            if (Q_UNLIKELY(!id.isNull()))
                qCWarning(GLTFImporterLog, "GLTF: no such scene %ls in file %ls",
                          qUtf16PrintableImpl(id), qUtf16PrintableImpl(m_basePath));
            return defaultScene();
        }
        const QJsonObject sceneObj = sceneVal.toObject();
        sceneEntity = new QEntity;
        const auto nodes = sceneObj.value(KEY_NODES).toArray();
        for (const QJsonValue &n : nodes) {
            QEntity* child = node(QString::number(n.toInt()));
            if (!child)
                continue;
            child->setParent(sceneEntity);
        }
    } else {
        const QJsonObject scenes = m_json.object().value(KEY_SCENES).toObject();
        const auto sceneVal = scenes.value(id);
        if (Q_UNLIKELY(sceneVal.isUndefined())) {
            if (Q_UNLIKELY(!id.isNull()))
                qCWarning(GLTFImporterLog, "GLTF: no such scene %ls in file %ls",
                          qUtf16PrintableImpl(id), qUtf16PrintableImpl(m_basePath));
            return defaultScene();
        }

        const QJsonObject sceneObj = sceneVal.toObject();
        sceneEntity = new QEntity;
        const auto nodes = sceneObj.value(KEY_NODES).toArray();
        for (const QJsonValue &nnv : nodes) {
            QString nodeName = nnv.toString();
            QEntity* child = node(nodeName);
            if (!child)
                continue;
            child->setParent(sceneEntity);
        }
    }

    cleanup();

    return sceneEntity;
}

GLTFImporter::BufferData::BufferData()
    : length(0)
    , data(nullptr)
{
}

GLTFImporter::BufferData::BufferData(const QJsonObject &json)
    : length(json.value(KEY_BYTE_LENGTH).toInt()),
      path(json.value(KEY_URI).toString()),
      data(nullptr)
{
}

GLTFImporter::ParameterData::ParameterData() :
    type(0)
{

}

GLTFImporter::ParameterData::ParameterData(const QJsonObject &json)
    : semantic(json.value(KEY_SEMANTIC).toString()),
      type(json.value(KEY_TYPE).toInt())
{
}

GLTFImporter::AccessorData::AccessorData()
    : type(QAttribute::Float)
    , dataSize(0)
    , count(0)
    , offset(0)
    , stride(0)
{

}

GLTFImporter::AccessorData::AccessorData(const QJsonObject &json, int major, int minor)
    : type(accessorTypeFromJSON(json.value(KEY_COMPONENT_TYPE).toInt())),
      dataSize(accessorDataSizeFromJson(json.value(KEY_TYPE).toString())),
      count(json.value(KEY_COUNT).toInt()),
      offset(0),
      stride(0)
{
    Q_UNUSED(minor)

    if (major > 1) {
        bufferViewName = QString::number(json.value(KEY_BUFFER_VIEW).toInt());
    } else {
        bufferViewName = json.value(KEY_BUFFER_VIEW).toString();
    }

    const auto byteOffset = json.value(KEY_BYTE_OFFSET);
    if (!byteOffset.isUndefined())
        offset = byteOffset.toInt();
    const auto byteStride = json.value(KEY_BYTE_STRIDE);
    if (!byteStride.isUndefined())
        stride = byteStride.toInt();
}

bool GLTFImporter::isGLTFSupported(const QStringList &extensions)
{
    for (auto suffix: qAsConst(extensions)) {
        suffix = suffix.toLower();
        if (suffix == QLatin1String("json") || suffix == QLatin1String("gltf") || suffix == QLatin1String("qgltf"))
            return true;
    }
    return false;
}

bool GLTFImporter::isEmbeddedResource(const QString &url)
{
    return url.startsWith("data:");
}

void GLTFImporter::renameFromJson(const QJsonObject &json, QObject * const object)
{
    const auto name = json.value(KEY_NAME);
    if (!name.isUndefined())
        object->setObjectName(name.toString());
}

bool GLTFImporter::hasStandardUniformNameFromSemantic(const QString &semantic)
{
    //Standard Uniforms
    if (semantic.isEmpty())
        return false;
    switch (semantic.at(0).toLatin1()) {
    case 'L':
        // return semantic == QLatin1String("LOCAL");
        return false;
    case 'M':
        return semantic == QLatin1String("MODEL")
            || semantic == QLatin1String("MODELVIEW")
            || semantic == QLatin1String("MODELVIEWPROJECTION")
            || semantic == QLatin1String("MODELINVERSE")
            || semantic == QLatin1String("MODELVIEWPROJECTIONINVERSE")
            || semantic == QLatin1String("MODELINVERSETRANSPOSE")
            || semantic == QLatin1String("MODELVIEWINVERSETRANSPOSE");
    case 'V':
        return semantic == QLatin1String("VIEW")
            || semantic == QLatin1String("VIEWINVERSE")
            || semantic == QLatin1String("VIEWPORT");
    case 'P':
        return semantic == QLatin1String("PROJECTION")
            || semantic == QLatin1String("PROJECTIONINVERSE");
    }
    return false;
}

QString GLTFImporter::standardAttributeNameFromSemantic(const QString &semantic)
{
    //Standard Attributes
    if (semantic.startsWith(QLatin1String("POSITION")))
        return QAttribute::defaultPositionAttributeName();
    if (semantic.startsWith(QLatin1String("NORMAL")))
        return QAttribute::defaultNormalAttributeName();
    if (semantic.startsWith(QLatin1String("TEXCOORD")))
        return QAttribute::defaultTextureCoordinateAttributeName();
    if (semantic.startsWith(QLatin1String("COLOR")))
        return QAttribute::defaultColorAttributeName();
    if (semantic.startsWith(QLatin1String("TANGENT")))
        return QAttribute::defaultTangentAttributeName();

//    if (semantic.startsWith(QLatin1String("JOINT")));
//    if (semantic.startsWith(QLatin1String("JOINTMATRIX")));
//    if (semantic.startsWith(QLatin1String("WEIGHT")));

    return QString();
}

QParameter *GLTFImporter::parameterFromTechnique(QTechnique *technique,
                                                 const QString &parameterName)
{
    const QList<QParameter *> parameters = m_techniqueParameters.value(technique);
    for (QParameter *parameter : parameters) {
        if (parameter->name() == parameterName)
            return parameter;
    }

    return nullptr;
}

Qt3DCore::QEntity* GLTFImporter::defaultScene()
{
    if (Q_UNLIKELY(m_defaultScene.isEmpty())) {
        qCWarning(GLTFImporterLog, "no default scene");
        return nullptr;
    }

    return scene(m_defaultScene);
}

QMaterial *GLTFImporter::materialWithCustomShader(const QString &id, const QJsonObject &jsonObj)
{
    QString effectName = jsonObj.value(KEY_EFFECT).toString();
    if (effectName.isEmpty()) {
        // GLTF custom shader material (with qgltf tool specific customizations)

        // Default ES2 Technique
        QString techniqueName = jsonObj.value(KEY_TECHNIQUE).toString();
        const auto it = qAsConst(m_techniques).find(techniqueName);
        if (Q_UNLIKELY(it == m_techniques.cend())) {
            qCWarning(GLTFImporterLog, "unknown technique %ls for material %ls in GLTF file %ls",
                      qUtf16PrintableImpl(techniqueName), qUtf16PrintableImpl(id), qUtf16PrintableImpl(m_basePath));
            return nullptr;
        }
        QTechnique *technique = *it;
        technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGLES);
        technique->graphicsApiFilter()->setMajorVersion(2);
        technique->graphicsApiFilter()->setMinorVersion(0);
        technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);

        //Optional Core technique
        QTechnique *coreTechnique = nullptr;
        QTechnique *gl2Technique = nullptr;
        QString coreTechniqueName = jsonObj.value(KEY_TECHNIQUE_CORE).toString();
        if (!coreTechniqueName.isNull()) {
            const auto it = qAsConst(m_techniques).find(coreTechniqueName);
            if (Q_UNLIKELY(it == m_techniques.cend())) {
                qCWarning(GLTFImporterLog, "unknown technique %ls for material %ls in GLTF file %ls",
                          qUtf16PrintableImpl(coreTechniqueName), qUtf16PrintableImpl(id), qUtf16PrintableImpl(m_basePath));
            } else {
                coreTechnique = it.value();
                coreTechnique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
                coreTechnique->graphicsApiFilter()->setMajorVersion(3);
                coreTechnique->graphicsApiFilter()->setMinorVersion(1);
                coreTechnique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);
            }
        }
        //Optional GL2 technique
        QString gl2TechniqueName = jsonObj.value(KEY_TECHNIQUE_GL2).toString();
        if (!gl2TechniqueName.isNull()) {
            const auto it = qAsConst(m_techniques).find(gl2TechniqueName);
            if (Q_UNLIKELY(it == m_techniques.cend())) {
                qCWarning(GLTFImporterLog, "unknown technique %ls for material %ls in GLTF file %ls",
                          qUtf16PrintableImpl(gl2TechniqueName), qUtf16PrintableImpl(id), qUtf16PrintableImpl(m_basePath));
            } else {
                gl2Technique = it.value();
                gl2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
                gl2Technique->graphicsApiFilter()->setMajorVersion(2);
                gl2Technique->graphicsApiFilter()->setMinorVersion(0);
                gl2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
            }
        }

        // glTF doesn't deal in effects, but we need a trivial one to wrap
        // up our techniques
        // However we need to create a unique effect for each material instead
        // of caching because QMaterial does not keep up with effects
        // its not the parent of.
        QEffect *effect = new QEffect;
        effect->setObjectName(techniqueName);
        effect->addTechnique(technique);
        if (coreTechnique != nullptr)
            effect->addTechnique(coreTechnique);
        if (gl2Technique != nullptr)
            effect->addTechnique(gl2Technique);

        QMaterial *mat = new QMaterial;
        mat->setEffect(effect);

        renameFromJson(jsonObj, mat);

        const QJsonObject values = jsonObj.value(KEY_VALUES).toObject();
        for (auto it = values.begin(), end = values.end(); it != end; ++it) {
            const QString vName = it.key();
            QParameter *param = parameterFromTechnique(technique, vName);

            if (param == nullptr && coreTechnique != nullptr)
                param = parameterFromTechnique(coreTechnique, vName);

            if (param == nullptr && gl2Technique != nullptr)
                param = parameterFromTechnique(gl2Technique, vName);

            if (Q_UNLIKELY(!param)) {
                qCWarning(GLTFImporterLog, "unknown parameter: %ls in technique %ls processing material %ls",
                          qUtf16PrintableImpl(vName), qUtf16PrintableImpl(techniqueName), qUtf16PrintableImpl(id));
                continue;
            }

            ParameterData paramData = m_parameterDataDict.value(param);
            QVariant var = parameterValueFromJSON(paramData.type, it.value());

            mat->addParameter(new QParameter(param->name(), var));
        } // of material technique-instance values iteration

        return mat;
    } else {
        // Qt3D exported QGLTF custom material
        QMaterial *mat = new QMaterial;
        renameFromJson(jsonObj, mat);
        QEffect *effect = m_effects.value(effectName);
        if (effect) {
            mat->setEffect(effect);
        } else {
            qCWarning(GLTFImporterLog, "Effect %ls missing for material %ls",
                      qUtf16PrintableImpl(effectName), qUtf16PrintableImpl(mat->objectName()));
        }
        const QJsonObject params = jsonObj.value(KEY_PARAMETERS).toObject();
        for (auto it = params.begin(), end = params.end(); it != end; ++it)
            mat->addParameter(buildParameter(it.key(), it.value().toObject()));

        return mat;
    }
}

QMaterial *GLTFImporter::commonMaterial(const QJsonObject &jsonObj)
{
    const auto jsonExt =
            jsonObj.value(KEY_EXTENSIONS).toObject().value(KEY_COMMON_MAT).toObject();
    if (m_majorVersion == 1 && jsonExt.isEmpty())
        return nullptr;

    QVariantHash params;
    bool hasDiffuseMap = false;
    bool hasSpecularMap = false;
    bool hasNormalMap = false;
    bool hasAlpha = false;

    if (m_majorVersion > 1) {
        QMaterial *mat = pbrMaterial(jsonObj);

        if (mat)
            return mat;
    }

    const QJsonObject values = jsonExt.value(KEY_VALUES).toObject();
    for (auto it = values.begin(), end = values.end(); it != end; ++it) {
        const QString vName = it.key();
        const QJsonValue val = it.value();
        QVariant var;
        QString propertyName = vName;
        if (vName == QLatin1String("ambient") && val.isArray()) {
            var = vec4ToColorVariant(parameterValueFromJSON(GL_FLOAT_VEC4, val));
        } else if (vName == QLatin1String("diffuse")) {
            if (val.isString()) {
                var = parameterValueFromJSON(GL_SAMPLER_2D, val);
                hasDiffuseMap = true;
            } else if (val.isArray()) {
                var = vec4ToColorVariant(parameterValueFromJSON(GL_FLOAT_VEC4, val));
            }
        } else if (vName == QLatin1String("specular")) {
            if (val.isString()) {
                var = parameterValueFromJSON(GL_SAMPLER_2D, val);
                hasSpecularMap = true;
            } else if (val.isArray()) {
                var = vec4ToColorVariant(parameterValueFromJSON(GL_FLOAT_VEC4, val));
            }
        } else if (vName == QLatin1String("cool")) { // Custom Qt3D extension for gooch
            var = vec4ToColorVariant(parameterValueFromJSON(GL_FLOAT_VEC4, val));
        } else if (vName == QLatin1String("warm")) { // Custom Qt3D extension for gooch
            var = vec4ToColorVariant(parameterValueFromJSON(GL_FLOAT_VEC4, val));
        } else if (vName == QLatin1String("shininess") && val.isDouble()) {
            var = parameterValueFromJSON(GL_FLOAT, val);
        } else if (vName == QLatin1String("normalmap") && val.isString()) {
            var = parameterValueFromJSON(GL_SAMPLER_2D, val);
            propertyName = QStringLiteral("normal");
            hasNormalMap = true;
        } else if (vName == QLatin1String("transparency")) {
            var = parameterValueFromJSON(GL_FLOAT, val);
            propertyName = QStringLiteral("alpha");
            hasAlpha = true;
        } else if (vName == QLatin1String("transparent")) {
            hasAlpha = parameterValueFromJSON(GL_BOOL, val).toBool();
        } else if (vName == QLatin1String("textureScale")) {
            var = parameterValueFromJSON(GL_FLOAT, val);
            propertyName = QStringLiteral("textureScale");
        } else if (vName == QLatin1String("alpha")) { // Custom Qt3D extension for gooch
            var = parameterValueFromJSON(GL_FLOAT, val);
        } else if (vName == QLatin1String("beta")) { // Custom Qt3D extension for gooch
            var = parameterValueFromJSON(GL_FLOAT, val);
        }
        if (var.isValid())
            params[propertyName] = var;
    }

    const QJsonObject funcValues = jsonExt.value(KEY_FUNCTIONS).toObject();
    if (!funcValues.isEmpty()) {
        const QJsonArray fArray = funcValues[KEY_BLEND_FUNCTION].toArray();
        const QJsonArray eArray = funcValues[KEY_BLEND_EQUATION].toArray();
        if (fArray.size() == 4) {
            params[QStringLiteral("sourceRgbArg")] = fArray[0].toInt();
            params[QStringLiteral("sourceAlphaArg")] = fArray[1].toInt();
            params[QStringLiteral("destinationRgbArg")] = fArray[2].toInt();
            params[QStringLiteral("destinationAlphaArg")] = fArray[3].toInt();
        }
        // We get separate values but our QPhongAlphaMaterial only supports single argument,
        // so we just use the first one.
        if (eArray.size() == 2)
            params[QStringLiteral("blendFunctionArg")] = eArray[0].toInt();
    }

    QMaterial *mat = nullptr;
    const QString technique = jsonExt.value(KEY_TECHNIQUE).toString();
    if (technique == QStringLiteral("PHONG")) {
        if (hasNormalMap) {
            if (hasSpecularMap) {
                mat = new QNormalDiffuseSpecularMapMaterial;
            } else {
                if (Q_UNLIKELY(!hasDiffuseMap)) {
                    qCWarning(GLTFImporterLog, "Common material with normal and specular maps needs a diffuse map as well");
                } else {
                    if (hasAlpha)
                        mat = new QNormalDiffuseMapAlphaMaterial;
                    else
                        mat = new QNormalDiffuseMapMaterial;
                }
            }
        } else {
            if (hasSpecularMap) {
                if (Q_UNLIKELY(!hasDiffuseMap))
                    qCWarning(GLTFImporterLog, "Common material with specular map needs a diffuse map as well");
                else
                    mat = new QDiffuseSpecularMapMaterial;
            } else if (hasDiffuseMap) {
                mat = new QDiffuseMapMaterial;
            } else {
                if (hasAlpha)
                    mat = new QPhongAlphaMaterial;
                else
                    mat = new QPhongMaterial;
            }
        }
    } else if (technique == QStringLiteral("GOOCH")) { // Qt3D specific extension
        mat = new QGoochMaterial;
    } else if (technique == QStringLiteral("PERVERTEX")) { // Qt3D specific extension
        mat = new QPerVertexColorMaterial;
    }

    if (Q_UNLIKELY(!mat)) {
        qCWarning(GLTFImporterLog, "Could not find a suitable built-in material for KHR_materials_common");
    } else {
        for (QVariantHash::const_iterator it = params.constBegin(), itEnd = params.constEnd(); it != itEnd; ++it)
            mat->setProperty(it.key().toUtf8(), it.value());
    }

    renameFromJson(jsonObj, mat);

    return mat;
}

QMaterial *GLTFImporter::pbrMaterial(const QJsonObject &jsonObj)
{
    // check for pbrMetallicRoughness material
    QMetalRoughMaterial *mrMaterial = nullptr;
    QJsonValue jsonValue = jsonObj.value(KEY_PBR_METAL_ROUGH);

    if (!jsonValue.isUndefined()) {
        const QJsonObject pbrObj = jsonValue.toObject();
        mrMaterial = new QMetalRoughMaterial;
        jsonValue = pbrObj.value(KEY_BASE_COLOR);
        if (!jsonValue.isUndefined())
            mrMaterial->setBaseColor(jsonArrToColorVariant(jsonValue.toArray()));

        jsonValue = pbrObj.value(KEY_BASE_COLOR_TEX);
        if (!jsonValue.isUndefined()) {
            const QJsonObject texObj = jsonValue.toObject();
            const QString textureId = QString::number(texObj.value(KEY_INDEX).toInt());
            const auto it = m_textures.find(textureId);
            if (Q_UNLIKELY(it == m_textures.end())) {
                qCWarning(GLTFImporterLog, "unknown texture %ls", qUtf16PrintableImpl(textureId));
            } else {
                mrMaterial->setBaseColor(QVariant::fromValue(it.value()));
            }
        }

        jsonValue = pbrObj.value(KEY_METAL_FACTOR);
        if (!jsonValue.isUndefined())
            mrMaterial->setMetalness(jsonValue.toVariant());

        jsonValue = pbrObj.value(KEY_METAL_ROUGH_TEX);
        if (!jsonValue.isUndefined()) {
            const QJsonObject texObj = jsonValue.toObject();
            const QString textureId = QString::number(texObj.value(KEY_INDEX).toInt());
            const auto it = m_textures.find(textureId);
            if (Q_UNLIKELY(it == m_textures.end())) {
                qCWarning(GLTFImporterLog, "unknown texture %ls", qUtf16PrintableImpl(textureId));
            } else {
                // find the texture again
                const QJsonArray texArray = m_json.object().value(KEY_TEXTURES).toArray();
                const QJsonObject tObj = texArray.at(texObj.value(KEY_INDEX).toInt()).toObject();
                const QString sourceId = QString::number(tObj.value(KEY_SOURCE).toInt());
                QImage image;
                if (m_imagePaths.contains(sourceId)) {
                    image.load(m_imagePaths.value(sourceId));
                } else if (m_imageData.contains(sourceId)) {
                    image = m_imageData.value(sourceId);
                } else {
                    return mrMaterial;
                }

                // at this point, in image there is data for metalness (on B) and
                // roughness (on G) bytes. 2 new textures are created
                // to make Qt3D happy, since it samples only on R.

                QTexture2D* metalTex = new QTexture2D;
                QTexture2D* roughTex = new QTexture2D;
                GLTFRawTextureImage* metalImgTex = new GLTFRawTextureImage();
                GLTFRawTextureImage* roughImgTex = new GLTFRawTextureImage();
                QImage metalness(image.size(), image.format());
                QImage roughness(image.size(), image.format());

                const uchar *imgData = image.constBits();
                const int pixelBytes = image.depth() / 8;
                Q_ASSERT_X(pixelBytes < 3, "GLTFImporter::pbrMaterial", "Unsupported texture format");

                for (int y = 0; y < image.height(); y++) {
                    for (int x = 0; x < image.width(); x++) {
                        metalness.setPixel(x, y, qRgb(imgData[0], imgData[0], imgData[0]));
                        roughness.setPixel(x, y, qRgb(imgData[1], imgData[1], imgData[1]));
                        imgData += pixelBytes;
                    }
                }

                metalImgTex->setImage(metalness);
                metalTex->addTextureImage(metalImgTex);
                roughImgTex->setImage(roughness);
                roughTex->addTextureImage(roughImgTex);

                setTextureSamplerInfo("", tObj, metalTex);
                setTextureSamplerInfo("", tObj, roughTex);

                mrMaterial->setMetalness(QVariant::fromValue(metalTex));
                mrMaterial->setRoughness(QVariant::fromValue(roughTex));
            }
        }

        jsonValue = pbrObj.value(KEY_ROUGH_FACTOR);
        if (!jsonValue.isUndefined())
            mrMaterial->setRoughness(jsonValue.toVariant());
    }

    jsonValue = jsonObj.value(KEY_NORMAL_TEX);
    if (!jsonValue.isUndefined()) {
        const QJsonObject texObj = jsonValue.toObject();
        const QString textureId = QString::number(texObj.value(KEY_INDEX).toInt());
        const auto it = m_textures.find(textureId);
        if (Q_UNLIKELY(it == m_textures.end())) {
            qCWarning(GLTFImporterLog, "unknown texture %ls", qUtf16PrintableImpl(textureId));
        } else {
            if (mrMaterial)
                mrMaterial->setNormal(QVariant::fromValue(it.value()));
        }
    }

    jsonValue = jsonObj.value(KEY_OCCLUSION_TEX);
    if (!jsonValue.isUndefined()) {
        const QJsonObject texObj = jsonValue.toObject();
        const QString textureId = QString::number(texObj.value(KEY_INDEX).toInt());
        const auto it = m_textures.find(textureId);
        if (Q_UNLIKELY(it == m_textures.end())) {
            qCWarning(GLTFImporterLog, "unknown texture %ls", qUtf16PrintableImpl(textureId));
        } else {
            if (mrMaterial)
                mrMaterial->setAmbientOcclusion(QVariant::fromValue(it.value()));
        }
    }

    return mrMaterial;
}

QMaterial* GLTFImporter::material(const QString &id)
{
    const auto it = qAsConst(m_materialCache).find(id);
    if (it != m_materialCache.cend())
        return it.value();

    QJsonValue jsonVal;

    if (m_majorVersion > 1) {
        const QJsonArray mats = m_json.object().value(KEY_MATERIALS).toArray();
        jsonVal = mats.at(id.toInt());
    } else {
        const QJsonObject mats = m_json.object().value(KEY_MATERIALS).toObject();
        jsonVal = mats.value(id);
    }

    if (Q_UNLIKELY(jsonVal.isUndefined())) {
        qCWarning(GLTFImporterLog, "unknown material %ls in GLTF file %ls",
                  qUtf16PrintableImpl(id), qUtf16PrintableImpl(m_basePath));
        return nullptr;
    }

    const QJsonObject jsonObj = jsonVal.toObject();

    QMaterial *mat = nullptr;

    // Prefer common materials over custom shaders.
    mat = commonMaterial(jsonObj);
    if (!mat)
        mat = materialWithCustomShader(id, jsonObj);

    m_materialCache[id] = mat;
    return mat;
}

bool GLTFImporter::fillCamera(QCameraLens &lens, QCamera *cameraEntity, const QString &id) const
{
    QJsonObject jsonObj;

    if (m_majorVersion > 1) {
        const QJsonArray camArray = m_json.object().value(KEY_CAMERAS).toArray();
        if (id.toInt() >= camArray.count()) {
            qCWarning(GLTFImporterLog, "unknown camera %ls in GLTF file %ls",
                      qUtf16PrintableImpl(id), qUtf16PrintableImpl(m_basePath));
            return false;
        }
        jsonObj = camArray[id.toInt()].toObject();
    } else {
        const auto jsonVal = m_json.object().value(KEY_CAMERAS).toObject().value(id);
        if (Q_UNLIKELY(jsonVal.isUndefined())) {
            qCWarning(GLTFImporterLog, "unknown camera %ls in GLTF file %ls",
                      qUtf16PrintableImpl(id), qUtf16PrintableImpl(m_basePath));
            return false;
        }
        jsonObj = jsonVal.toObject();
    }

    QString camTy = jsonObj.value(KEY_TYPE).toString();

    if (camTy == QLatin1String("perspective")) {
        const auto pVal = jsonObj.value(KEY_PERSPECTIVE);
        if (Q_UNLIKELY(pVal.isUndefined())) {
            qCWarning(GLTFImporterLog, "camera: %ls missing 'perspective' object",
                      qUtf16PrintableImpl(id));
            return false;
        }

        const QJsonObject pObj = pVal.toObject();
        double aspectRatio = pObj.value(KEY_ASPECT_RATIO).toDouble();
        double yfov = pObj.value(KEY_YFOV).toDouble();
        double frustumNear = pObj.value(KEY_ZNEAR).toDouble();
        double frustumFar = pObj.value(KEY_ZFAR).toDouble();

        lens.setPerspectiveProjection(qRadiansToDegrees(yfov), aspectRatio, frustumNear,
                                         frustumFar);
    } else if (camTy == QLatin1String("orthographic")) {
        const auto pVal = jsonObj.value(KEY_ORTHOGRAPHIC);
        if (Q_UNLIKELY(pVal.isUndefined())) {
            qCWarning(GLTFImporterLog, "camera: %ls missing 'orthographic' object",
                      qUtf16PrintableImpl(id));
            return false;
        }

        const QJsonObject pObj = pVal.toObject();
        double xmag = pObj.value(KEY_XMAG).toDouble() / 2.0f;
        double ymag = pObj.value(KEY_YMAG).toDouble() / 2.0f;
        double frustumNear = pObj.value(KEY_ZNEAR).toDouble();
        double frustumFar = pObj.value(KEY_ZFAR).toDouble();

        lens.setOrthographicProjection(-xmag, xmag, -ymag, ymag, frustumNear, frustumFar);
    } else {
        qCWarning(GLTFImporterLog, "camera: %ls has unsupported type: %ls",
                  qUtf16PrintableImpl(id), qUtf16PrintableImpl(camTy));
        return false;
    }
    if (cameraEntity) {
        if (jsonObj.contains(KEY_POSITION))
            cameraEntity->setPosition(jsonArrToVec3(jsonObj.value(KEY_POSITION).toArray()));
        if (jsonObj.contains(KEY_UPVECTOR))
            cameraEntity->setUpVector(jsonArrToVec3(jsonObj.value(KEY_UPVECTOR).toArray()));
        if (jsonObj.contains(KEY_VIEW_CENTER))
            cameraEntity->setViewCenter(jsonArrToVec3(jsonObj.value(KEY_VIEW_CENTER).toArray()));
    }
    renameFromJson(jsonObj, &lens);
    return true;
}

void GLTFImporter::parse()
{
    if (m_parseDone)
        return;

    const QJsonValue asset = m_json.object().value(KEY_ASSET);
    if (!asset.isUndefined())
        processJSONAsset(asset.toObject());

    if (m_majorVersion > 1) {
        parseV2();
    } else {
        parseV1();
    }

    m_parseDone = true;
}

void GLTFImporter::parseV1()
{
    const QJsonObject buffers = m_json.object().value(KEY_BUFFERS).toObject();
    for (auto it = buffers.begin(), end = buffers.end(); it != end; ++it)
        processJSONBuffer(it.key(), it.value().toObject());

    const QJsonObject views = m_json.object().value(KEY_BUFFER_VIEWS).toObject();
    loadBufferData();
    for (auto it = views.begin(), end = views.end(); it != end; ++it)
        processJSONBufferView(it.key(), it.value().toObject());
    unloadBufferData();

    const QJsonObject shaders = m_json.object().value(KEY_SHADERS).toObject();
    for (auto it = shaders.begin(), end = shaders.end(); it != end; ++it)
        processJSONShader(it.key(), it.value().toObject());

    const QJsonObject programs = m_json.object().value(KEY_PROGRAMS).toObject();
    for (auto it = programs.begin(), end = programs.end(); it != end; ++it)
        processJSONProgram(it.key(), it.value().toObject());

    const QJsonObject attrs = m_json.object().value(KEY_ACCESSORS).toObject();
    for (auto it = attrs.begin(), end = attrs.end(); it != end; ++it)
        processJSONAccessor(it.key(), it.value().toObject());

    const QJsonObject meshes = m_json.object().value(KEY_MESHES).toObject();
    for (auto it = meshes.begin(), end = meshes.end(); it != end; ++it)
        processJSONMesh(it.key(), it.value().toObject());

    const QJsonObject images = m_json.object().value(KEY_IMAGES).toObject();
    for (auto it = images.begin(), end = images.end(); it != end; ++it)
        processJSONImage(it.key(), it.value().toObject());

    const QJsonObject textures = m_json.object().value(KEY_TEXTURES).toObject();
    for (auto it = textures.begin(), end = textures.end(); it != end; ++it)
        processJSONTexture(it.key(), it.value().toObject());

    const QJsonObject extensions = m_json.object().value(KEY_EXTENSIONS).toObject();
    for (auto it = extensions.begin(), end = extensions.end(); it != end; ++it)
        processJSONExtensions(it.key(), it.value().toObject());

    const QJsonObject passes = m_json.object().value(KEY_RENDERPASSES).toObject();
    for (auto it = passes.begin(), end = passes.end(); it != end; ++it)
        processJSONRenderPass(it.key(), it.value().toObject());

    const QJsonObject techniques = m_json.object().value(KEY_TECHNIQUES).toObject();
    for (auto it = techniques.begin(), end = techniques.end(); it != end; ++it)
        processJSONTechnique(it.key(), it.value().toObject());

    const QJsonObject effects = m_json.object().value(KEY_EFFECTS).toObject();
    for (auto it = effects.begin(), end = effects.end(); it != end; ++it)
        processJSONEffect(it.key(), it.value().toObject());

    m_defaultScene = m_json.object().value(KEY_SCENE).toString();
}

void GLTFImporter::parseV2()
{
    int i;
    const QJsonArray buffers = m_json.object().value(KEY_BUFFERS).toArray();
    for (i = 0; i < buffers.count(); i++)
        processJSONBuffer(QString::number(i), buffers[i].toObject());

    const QJsonArray views = m_json.object().value(KEY_BUFFER_VIEWS).toArray();
    loadBufferData();
    for (i = 0; i < views.count(); i++)
        processJSONBufferView(QString::number(i), views[i].toObject());
    unloadBufferData();

    const QJsonArray accessors = m_json.object().value(KEY_ACCESSORS).toArray();
    for (i = 0; i < accessors.count(); i++)
        processJSONAccessor(QString::number(i), accessors[i].toObject());

    const QJsonArray meshes = m_json.object().value(KEY_MESHES).toArray();
    for (i = 0; i < meshes.count(); i++)
        processJSONMesh(QString::number(i), meshes[i].toObject());

    const QJsonArray images = m_json.object().value(KEY_IMAGES).toArray();
    for (i = 0; i < images.count(); i++)
        processJSONImage(QString::number(i), images[i].toObject());

    const QJsonArray textures = m_json.object().value(KEY_TEXTURES).toArray();
    for (i = 0; i < textures.count(); i++)
        processJSONTexture(QString::number(i), textures[i].toObject());

    m_defaultScene = QString::number(m_json.object().value(KEY_SCENE).toInt());
}

namespace {
template <typename C>
void delete_if_without_parent(const C &c)
{
    for (const auto *e : c) {
        if (!e->parent())
            delete e;
    }
}
} // unnamed namespace

void GLTFImporter::cleanup()
{
    m_meshDict.clear();
    m_meshMaterialDict.clear();
    m_accessorDict.clear();
    delete_if_without_parent(m_materialCache);
    m_materialCache.clear();
    m_bufferDatas.clear();
    m_buffers.clear();
    m_shaderPaths.clear();
    delete_if_without_parent(m_programs);
    m_programs.clear();
    for (const auto &params : qAsConst(m_techniqueParameters))
        delete_if_without_parent(params);
    m_techniqueParameters.clear();
    delete_if_without_parent(m_techniques);
    m_techniques.clear();
    delete_if_without_parent(m_textures);
    m_textures.clear();
    m_imagePaths.clear();
    m_imageData.clear();
    m_defaultScene.clear();
    m_parameterDataDict.clear();
    delete_if_without_parent(m_renderPasses);
    m_renderPasses.clear();
    delete_if_without_parent(m_effects);
    m_effects.clear();
}

void GLTFImporter::processJSONAsset(const QJsonObject &json)
{
    const QString version = json.value(KEY_VERSION).toString();
    if (!version.isEmpty()) {
        const QStringList verTokens = version.split('.');
        if (verTokens.length() >= 2) {
            m_majorVersion = verTokens[0].toInt();
            m_minorVersion = verTokens[1].toInt();
        }
    }
}

void GLTFImporter::processJSONBuffer(const QString &id, const QJsonObject& json)
{
    // simply cache buffers for lookup by buffer-views
    m_bufferDatas[id] = BufferData(json);
}

void GLTFImporter::processJSONBufferView(const QString &id, const QJsonObject& json)
{
    QString bufName;
    if (m_majorVersion > 1) {
        bufName = QString::number(json.value(KEY_BUFFER).toInt());
    } else {
        bufName = json.value(KEY_BUFFER).toString();
    }
    const auto it = qAsConst(m_bufferDatas).find(bufName);
    if (Q_UNLIKELY(it == m_bufferDatas.cend())) {
        qCWarning(GLTFImporterLog, "unknown buffer: %ls processing view: %ls",
                  qUtf16PrintableImpl(bufName), qUtf16PrintableImpl(id));
        return;
    }
    const auto &bufferData = *it;

    const QJsonValue targetValue = json.value(KEY_TARGET);
    int target;
    if (targetValue.isUndefined()) {
        target = GL_ARRAY_BUFFER;
    } else {
        target = targetValue.toInt();
    }

    quint64 offset = 0;
    const auto byteOffset = json.value(KEY_BYTE_OFFSET);
    if (!byteOffset.isUndefined()) {
        offset = byteOffset.toInt();
        qCDebug(GLTFImporterLog, "bv: %ls has offset: %lld", qUtf16PrintableImpl(id), offset);
    }

    quint64 len = json.value(KEY_BYTE_LENGTH).toInt();

    QByteArray bytes = bufferData.data->mid(offset, len);
    if (Q_UNLIKELY(bytes.count() != int(len))) {
        qCWarning(GLTFImporterLog, "failed to read sufficient bytes from: %ls for view %ls",
                  qUtf16PrintableImpl(bufferData.path), qUtf16PrintableImpl(id));
    }

    Qt3DRender::QBuffer *b = new Qt3DRender::QBuffer();
    b->setData(bytes);
    m_buffers[id] = b;
}

void GLTFImporter::processJSONShader(const QString &id, const QJsonObject &jsonObject)
{
    // shaders are trivial for the moment, defer the real work
    // to the program section
    QString path = jsonObject.value(KEY_URI).toString();

    if (!isEmbeddedResource(path)) {
        QFileInfo info(m_basePath, path);
        if (Q_UNLIKELY(!info.exists())) {
            qCWarning(GLTFImporterLog, "can't find shader %ls from path %ls",
                      qUtf16PrintableImpl(id), qUtf16PrintableImpl(path));
            return;
        }

        m_shaderPaths[id] = info.absoluteFilePath();
    } else {
        const QByteArray base64Data = path.toLatin1().remove(0, path.indexOf(",") + 1);
        m_shaderPaths[id] = QString(QByteArray::fromBase64(base64Data));
    }


}

void GLTFImporter::processJSONProgram(const QString &id, const QJsonObject &jsonObject)
{
    const QString fragName = jsonObject.value(KEY_FRAGMENT_SHADER).toString();
    const QString vertName = jsonObject.value(KEY_VERTEX_SHADER).toString();

    const auto fragIt = qAsConst(m_shaderPaths).find(fragName);
    const auto vertIt = qAsConst(m_shaderPaths).find(vertName);

    if (Q_UNLIKELY(fragIt == m_shaderPaths.cend() || vertIt == m_shaderPaths.cend())) {
        qCWarning(GLTFImporterLog, "program: %ls missing shader: %ls %ls",
                  qUtf16PrintableImpl(id), qUtf16PrintableImpl(fragName), qUtf16PrintableImpl(vertName));
        return;
    }

    QShaderProgram* prog = new QShaderProgram;
    prog->setObjectName(id);
    prog->setFragmentShaderCode(QShaderProgram::loadSource(QUrl::fromLocalFile(fragIt.value())));
    prog->setVertexShaderCode(QShaderProgram::loadSource(QUrl::fromLocalFile(vertIt.value())));

    const QString tessCtrlName = jsonObject.value(KEY_TESS_CTRL_SHADER).toString();
    if (!tessCtrlName.isEmpty()) {
        const auto it = qAsConst(m_shaderPaths).find(tessCtrlName);
        prog->setTessellationControlShaderCode(
                    QShaderProgram::loadSource(QUrl::fromLocalFile(it.value())));
    }

    const QString tessEvalName = jsonObject.value(KEY_TESS_EVAL_SHADER).toString();
    if (!tessEvalName.isEmpty()) {
        const auto it = qAsConst(m_shaderPaths).find(tessEvalName);
        prog->setTessellationEvaluationShaderCode(
                    QShaderProgram::loadSource(QUrl::fromLocalFile(it.value())));
    }

    const QString geomName = jsonObject.value(KEY_GEOMETRY_SHADER).toString();
    if (!geomName.isEmpty()) {
        const auto it = qAsConst(m_shaderPaths).find(geomName);
        prog->setGeometryShaderCode(QShaderProgram::loadSource(QUrl::fromLocalFile(it.value())));
    }

    const QString computeName = jsonObject.value(KEY_COMPUTE_SHADER).toString();
    if (!computeName.isEmpty()) {
        const auto it = qAsConst(m_shaderPaths).find(computeName);
        prog->setComputeShaderCode(QShaderProgram::loadSource(QUrl::fromLocalFile(it.value())));
    }

    m_programs[id] = prog;
}

void GLTFImporter::processJSONTechnique(const QString &id, const QJsonObject &jsonObject )
{
    QTechnique *t = new QTechnique;
    t->setObjectName(id);

    const QJsonObject gabifilter = jsonObject.value(KEY_GABIFILTER).toObject();
    if (gabifilter.isEmpty()) {
        // Regular GLTF technique

        // Parameters
        QHash<QString, QParameter *> paramDict;
        const QJsonObject params = jsonObject.value(KEY_PARAMETERS).toObject();
        for (auto it = params.begin(), end = params.end(); it != end; ++it) {
            const QString pname = it.key();
            const QJsonObject po = it.value().toObject();
            QParameter *p = buildParameter(pname, po);
            m_parameterDataDict.insert(p, ParameterData(po));
            // We don't want to insert invalid parameters to techniques themselves, but we
            // need to maintain link between all parameters and techniques so we can resolve
            // parameter type later when creating materials.
            if (p->value().isValid())
                t->addParameter(p);
            paramDict[pname] = p;
        }

        // Program
        QRenderPass *pass = new QRenderPass;
        addProgramToPass(pass, jsonObject.value(KEY_PROGRAM).toString());

        // Attributes
        const QJsonObject attrs = jsonObject.value(KEY_ATTRIBUTES).toObject();
        for (auto it = attrs.begin(), end = attrs.end(); it != end; ++it) {
            QString pname = it.value().toString();
            QParameter *parameter = paramDict.value(pname, nullptr);
            QString attributeName = pname;
            if (Q_UNLIKELY(!parameter)) {
                qCWarning(GLTFImporterLog, "attribute %ls defined in instanceProgram but not as parameter",
                          qUtf16PrintableImpl(pname));
                continue;
            }
            //Check if the parameter has a standard attribute semantic
            const auto paramDataIt = m_parameterDataDict.find(parameter);
            QString standardAttributeName = standardAttributeNameFromSemantic(paramDataIt->semantic);
            if (!standardAttributeName.isNull()) {
                attributeName = standardAttributeName;
                t->removeParameter(parameter);
                m_parameterDataDict.erase(paramDataIt);
                paramDict.remove(pname);
                delete parameter;
            }

        } // of program-instance attributes

        // Uniforms
        const QJsonObject uniforms = jsonObject.value(KEY_UNIFORMS).toObject();
        for (auto it = uniforms.begin(), end = uniforms.end(); it != end; ++it) {
            const QString pname = it.value().toString();
            QParameter *parameter = paramDict.value(pname, nullptr);
            if (Q_UNLIKELY(!parameter)) {
                qCWarning(GLTFImporterLog, "uniform %ls defined in instanceProgram but not as parameter",
                          qUtf16PrintableImpl(pname));
                continue;
            }
            //Check if the parameter has a standard uniform semantic
            const auto paramDataIt = m_parameterDataDict.find(parameter);
            if (hasStandardUniformNameFromSemantic(paramDataIt->semantic)) {
                t->removeParameter(parameter);
                m_parameterDataDict.erase(paramDataIt);
                paramDict.remove(pname);
                delete parameter;
            }
        } // of program-instance uniforms

        m_techniqueParameters.insert(t, paramDict.values());

        populateRenderStates(pass, jsonObject.value(KEY_STATES).toObject());

        t->addRenderPass(pass);
    } else {
        // Qt3D exported custom technique

        // Graphics API filter
        t->graphicsApiFilter()->setApi(QGraphicsApiFilter::Api(gabifilter.value(KEY_API).toInt()));
        t->graphicsApiFilter()->setMajorVersion(gabifilter.value(KEY_MAJORVERSION).toInt());
        t->graphicsApiFilter()->setMinorVersion(gabifilter.value(KEY_MINORVERSION).toInt());
        t->graphicsApiFilter()->setProfile(QGraphicsApiFilter::OpenGLProfile(
                                               gabifilter.value(KEY_PROFILE).toInt()));
        t->graphicsApiFilter()->setVendor(gabifilter.value(KEY_VENDOR).toString());
        QStringList extensionList;
        QJsonArray extArray = gabifilter.value(KEY_EXTENSIONS).toArray();
        for (const QJsonValue &extValue : extArray)
            extensionList << extValue.toString();
        t->graphicsApiFilter()->setExtensions(extensionList);

        // Filter keys (we will assume filter keys are always strings or integers)
        const QJsonObject fkObj = jsonObject.value(KEY_FILTERKEYS).toObject();
        for (auto it = fkObj.begin(), end = fkObj.end(); it != end; ++it)
            t->addFilterKey(buildFilterKey(it.key(), it.value()));

        t->setObjectName(jsonObject.value(KEY_NAME).toString());

        // Parameters
        const QJsonObject params = jsonObject.value(KEY_PARAMETERS).toObject();
        for (auto it = params.begin(), end = params.end(); it != end; ++it)
            t->addParameter(buildParameter(it.key(), it.value().toObject()));

        // Render passes
        const QJsonArray passArray = jsonObject.value(KEY_RENDERPASSES).toArray();
        for (const QJsonValue &passValue : passArray) {
            const QString passName = passValue.toString();
            QRenderPass *pass = m_renderPasses.value(passName);
            if (pass) {
                t->addRenderPass(pass);
            } else {
                qCWarning(GLTFImporterLog, "Render pass %ls missing for technique %ls",
                          qUtf16PrintableImpl(passName), qUtf16PrintableImpl(id));
            }
        }
    }

    m_techniques[id] = t;
}

void GLTFImporter::processJSONAccessor(const QString &id, const QJsonObject& json)
{
    m_accessorDict[id] = AccessorData(json, m_majorVersion, m_minorVersion);
}

void GLTFImporter::processJSONMesh(const QString &id, const QJsonObject &json)
{
    const QString meshName = json.value(KEY_NAME).toString();
    const QString meshType = json.value(KEY_TYPE).toString();
    if (meshType.isEmpty()) {
        // Custom mesh
        const QJsonArray primitivesArray = json.value(KEY_PRIMITIVES).toArray();
        for (const QJsonValue &primitiveValue : primitivesArray) {
            const QJsonObject primitiveObject = primitiveValue.toObject();
            const QJsonValue type = primitiveObject.value(KEY_MODE);
            const QJsonValue matValue = primitiveObject.value(KEY_MATERIAL);
            const QString material = (m_majorVersion > 1) ? QString::number(matValue.toInt()) : matValue.toString();

            QGeometryRenderer *geometryRenderer = new QGeometryRenderer;
            QGeometry *meshGeometry = new QGeometry(geometryRenderer);

            //Set Primitive Type
            if (type.isUndefined()) {
                geometryRenderer->setPrimitiveType(QGeometryRenderer::Triangles);
            } else {
                geometryRenderer->setPrimitiveType(static_cast<QGeometryRenderer::PrimitiveType>(type.toInt()));
            }

            //Save Material for mesh
            m_meshMaterialDict[geometryRenderer] = material;

            const QJsonObject attrs = primitiveObject.value(KEY_ATTRIBUTES).toObject();
            for (auto it = attrs.begin(), end = attrs.end(); it != end; ++it) {
                const QString k = (m_majorVersion > 1) ? QString::number(it.value().toInt()) : it.value().toString();
                const auto accessorIt = qAsConst(m_accessorDict).find(k);
                if (Q_UNLIKELY(accessorIt == m_accessorDict.cend())) {
                    qCWarning(GLTFImporterLog, "unknown attribute accessor: %ls on mesh %ls",
                              qUtf16PrintableImpl(k), qUtf16PrintableImpl(id));
                    continue;
                }

                const QString attrName = it.key();
                QString attributeName = standardAttributeNameFromSemantic(attrName);
                if (attributeName.isEmpty())
                    attributeName = attrName;

                //Get buffer handle for accessor
                Qt3DRender::QBuffer *buffer = m_buffers.value(accessorIt->bufferViewName, nullptr);
                if (Q_UNLIKELY(!buffer)) {
                    qCWarning(GLTFImporterLog, "unknown buffer-view: %ls processing accessor: %ls",
                              qUtf16PrintableImpl(accessorIt->bufferViewName),
                              qUtf16PrintableImpl(id));
                    continue;
                }

                QAttribute *attribute = new QAttribute(buffer,
                                                       attributeName,
                                                       accessorIt->type,
                                                       accessorIt->dataSize,
                                                       accessorIt->count,
                                                       accessorIt->offset,
                                                       accessorIt->stride);
                attribute->setAttributeType(QAttribute::VertexAttribute);
                meshGeometry->addAttribute(attribute);
            }

            const auto indices = primitiveObject.value(KEY_INDICES);
            if (!indices.isUndefined()) {
                const QString accIndex = (m_majorVersion > 1) ? QString::number(indices.toInt()) : indices.toString();
                const auto accessorIt = qAsConst(m_accessorDict).find(accIndex);
                if (Q_UNLIKELY(accessorIt == m_accessorDict.cend())) {
                    qCWarning(GLTFImporterLog, "unknown index accessor: %ls on mesh %ls",
                              qUtf16PrintableImpl(accIndex), qUtf16PrintableImpl(id));
                } else {
                    //Get buffer handle for accessor
                    Qt3DRender::QBuffer *buffer = m_buffers.value(accessorIt->bufferViewName, nullptr);
                    if (Q_UNLIKELY(!buffer)) {
                        qCWarning(GLTFImporterLog, "unknown buffer-view: %ls processing accessor: %ls",
                                  qUtf16PrintableImpl(accessorIt->bufferViewName),
                                  qUtf16PrintableImpl(id));
                        continue;
                    }

                    QAttribute *attribute = new QAttribute(buffer,
                                                           accessorIt->type,
                                                           accessorIt->dataSize,
                                                           accessorIt->count,
                                                           accessorIt->offset,
                                                           accessorIt->stride);
                    attribute->setAttributeType(QAttribute::IndexAttribute);
                    meshGeometry->addAttribute(attribute);
                }
            } // of has indices

            geometryRenderer->setGeometry(meshGeometry);
            geometryRenderer->setObjectName(meshName);

            m_meshDict.insert(id, geometryRenderer);
        } // of primitives iteration
    } else {
        QGeometryRenderer *mesh = nullptr;
        if (meshType == QStringLiteral("cone")) {
            mesh = new QConeMesh;
        } else if (meshType == QStringLiteral("cuboid")) {
            mesh = new QCuboidMesh;
        } else if (meshType == QStringLiteral("cylinder")) {
            mesh = new QCylinderMesh;
        } else if (meshType == QStringLiteral("plane")) {
            mesh = new QPlaneMesh;
        } else if (meshType == QStringLiteral("sphere")) {
            mesh = new QSphereMesh;
        } else if (meshType == QStringLiteral("torus")) {
            mesh = new QTorusMesh;
        } else {
            qCWarning(GLTFImporterLog,
                      "Invalid mesh type: %ls for mesh: %ls",
                      qUtf16PrintableImpl(meshType),
                      qUtf16PrintableImpl(id));
        }

        if (mesh) {
            // Read and set properties
            const QJsonObject propObj = json.value(KEY_PROPERTIES).toObject();
            for (auto it = propObj.begin(), end = propObj.end(); it != end; ++it) {
                const QByteArray propName = it.key().toLatin1();
                // Basic mesh types only have bool, int, float, and QSize type properties
                if (it.value().isBool()) {
                    mesh->setProperty(propName.constData(), QVariant(it.value().toBool()));
                } else if (it.value().isArray()) {
                    const QJsonArray valueArray = it.value().toArray();
                    if (valueArray.size() == 2) {
                        QSize size;
                        size.setWidth(valueArray.at(0).toInt());
                        size.setHeight(valueArray.at(1).toInt());
                        mesh->setProperty(propName.constData(), QVariant(size));
                    }
                } else {
                    const QVariant::Type propType = mesh->property(propName.constData()).type();
                    if (propType == QVariant::Int) {
                        mesh->setProperty(propName.constData(), QVariant(it.value().toInt()));
                    } else {
                        mesh->setProperty(propName.constData(),
                                          QVariant(float(it.value().toDouble())));
                    }
                }
            }
            mesh->setObjectName(meshName);
            m_meshMaterialDict[mesh] = (m_majorVersion > 1) ?
                        QString::number(json.value(KEY_MATERIAL).toInt()) :
                        json.value(KEY_MATERIAL).toString();
            m_meshDict.insert(id, mesh);
        }
    }
}

void GLTFImporter::processJSONImage(const QString &id, const QJsonObject &jsonObject)
{
    QString path = jsonObject.value(KEY_URI).toString();

    if (!isEmbeddedResource(path)) {
        QFileInfo info(m_basePath, path);
        if (Q_UNLIKELY(!info.exists())) {
            qCWarning(GLTFImporterLog, "can't find image %ls from path %ls",
                      qUtf16PrintableImpl(id), qUtf16PrintableImpl(path));
            return;
        }

        m_imagePaths[id] = info.absoluteFilePath();
    } else {
        const QByteArray base64Data = path.toLatin1().remove(0, path.indexOf(",") + 1);
        QImage image;
        image.loadFromData(QByteArray::fromBase64(base64Data));
        m_imageData[id] = image;
    }
}

void GLTFImporter::processJSONTexture(const QString &id, const QJsonObject &jsonObject)
{
    QJsonValue jsonVal = jsonObject.value(KEY_TARGET);
    if (!jsonVal.isUndefined()) {
        int target = jsonVal.toInt(GL_TEXTURE_2D);
        //TODO: support other targets that GL_TEXTURE_2D (though the spec doesn't support anything else)
        if (Q_UNLIKELY(target != GL_TEXTURE_2D)) {
            qCWarning(GLTFImporterLog, "unsupported texture target: %d", target);
            return;
        }
    }

    QTexture2D* tex = new QTexture2D;

    // TODO: Choose suitable internal format - may vary on OpenGL context type
    //int pixelFormat = jsonObj.value(KEY_FORMAT).toInt(GL_RGBA);
    int internalFormat = GL_RGBA;
    jsonVal = jsonObject.value(KEY_INTERNAL_FORMAT);
    if (!jsonVal.isUndefined())
        internalFormat = jsonObject.value(KEY_INTERNAL_FORMAT).toInt(GL_RGBA);

    tex->setFormat(static_cast<QAbstractTexture::TextureFormat>(internalFormat));

    QJsonValue srcValue = jsonObject.value(KEY_SOURCE);
    QString source = (m_majorVersion > 1) ? QString::number(srcValue.toInt()) : srcValue.toString();

    const auto imagIt = qAsConst(m_imagePaths).find(source);
    if (Q_UNLIKELY(imagIt == m_imagePaths.cend())) {
        // if an image is not found in paths, it probably means
        // it was an embedded resource, referenced in m_imageData
        const auto embImgIt = qAsConst(m_imageData).find(source);
        if (Q_UNLIKELY(embImgIt == m_imageData.cend())) {
            qCWarning(GLTFImporterLog, "texture %ls references missing image %ls",
                      qUtf16PrintableImpl(id), qUtf16PrintableImpl(source));
            return;
        }

        QImage img = embImgIt.value();
        GLTFRawTextureImage *imageData = new GLTFRawTextureImage();
        imageData->setImage(img);
        tex->addTextureImage(imageData);
    } else {
        QTextureImage *texImage = new QTextureImage(tex);
        texImage->setMirrored(false);
        texImage->setSource(QUrl::fromLocalFile(imagIt.value()));
        tex->addTextureImage(texImage);
    }

    setTextureSamplerInfo(id, jsonObject, tex);

    m_textures[id] = tex;
}

void GLTFImporter::processJSONExtensions(const QString &id, const QJsonObject &jsonObject)
{
    // Lights are defined in "KHR_materials_common" property of "extensions" property of the top
    // level GLTF item.
    if (id == KEY_COMMON_MAT) {
        const auto lights = jsonObject.value(KEY_LIGHTS).toObject();
        const auto keys = lights.keys();
        for (const auto &lightKey : keys) {
            const auto light = lights.value(lightKey).toObject();
            auto lightType = light.value(KEY_TYPE).toString();
            const auto lightValues = light.value(lightType).toObject();
            QAbstractLight *lightComp = nullptr;
            if (lightType == KEY_DIRECTIONAL_LIGHT) {
                auto dirLight = new QDirectionalLight;
                dirLight->setWorldDirection(
                            jsonArrToVec3(lightValues.value(KEY_DIRECTION).toArray()));
                lightComp = dirLight;
            } else if (lightType == KEY_SPOT_LIGHT) {
                auto spotLight = new QSpotLight;
                spotLight->setLocalDirection(
                            jsonArrToVec3(lightValues.value(KEY_DIRECTION).toArray()));
                spotLight->setConstantAttenuation(
                            lightValues.value(KEY_CONST_ATTENUATION).toDouble());
                spotLight->setLinearAttenuation(
                            lightValues.value(KEY_LINEAR_ATTENUATION).toDouble());
                spotLight->setQuadraticAttenuation(
                            lightValues.value(KEY_QUAD_ATTENUATION).toDouble());
                spotLight->setCutOffAngle(
                            lightValues.value(KEY_FALLOFF_ANGLE).toDouble());
                lightComp = spotLight;
            } else if (lightType == KEY_POINT_LIGHT) {
                auto pointLight = new QPointLight;
                pointLight->setConstantAttenuation(
                            lightValues.value(KEY_CONST_ATTENUATION).toDouble());
                pointLight->setLinearAttenuation(
                            lightValues.value(KEY_LINEAR_ATTENUATION).toDouble());
                pointLight->setQuadraticAttenuation(
                            lightValues.value(KEY_QUAD_ATTENUATION).toDouble());
                lightComp = pointLight;
            } else if (lightType == KEY_AMBIENT_LIGHT) {
                qCWarning(GLTFImporterLog, "Ambient lights are not supported.");
            } else {
                qCWarning(GLTFImporterLog, "Unknown light type: %ls",
                          qUtf16PrintableImpl(lightType));
            }

            if (lightComp) {
                auto colorVal = lightValues.value(KEY_COLOR);
                lightComp->setColor(vec4ToQColor(parameterValueFromJSON(GL_FLOAT_VEC4, colorVal)));
                lightComp->setIntensity(lightValues.value(KEY_INTENSITY).toDouble());
                lightComp->setObjectName(light.value(KEY_NAME).toString());

                m_lights.insert(lightKey, lightComp);
            }
        }
    }

}

void GLTFImporter::processJSONEffect(const QString &id, const QJsonObject &jsonObject)
{
    QEffect *effect = new QEffect;
    renameFromJson(jsonObject, effect);

    const QJsonObject params = jsonObject.value(KEY_PARAMETERS).toObject();
    for (auto it = params.begin(), end = params.end(); it != end; ++it)
        effect->addParameter(buildParameter(it.key(), it.value().toObject()));

    const QJsonArray techArray = jsonObject.value(KEY_TECHNIQUES).toArray();
    for (const QJsonValue &techValue : techArray) {
        const QString techName = techValue.toString();
        QTechnique *tech = m_techniques.value(techName);
        if (tech) {
            effect->addTechnique(tech);
        } else {
            qCWarning(GLTFImporterLog, "Technique pass %ls missing for effect %ls",
                      qUtf16PrintableImpl(techName), qUtf16PrintableImpl(id));
        }
    }

    m_effects[id] = effect;
}

void GLTFImporter::processJSONRenderPass(const QString &id, const QJsonObject &jsonObject)
{
    QRenderPass *pass = new QRenderPass;
    const QJsonObject passFkObj = jsonObject.value(KEY_FILTERKEYS).toObject();
    for (auto it = passFkObj.begin(), end = passFkObj.end(); it != end; ++it)
        pass->addFilterKey(buildFilterKey(it.key(), it.value()));

    const QJsonObject params = jsonObject.value(KEY_PARAMETERS).toObject();
    for (auto it = params.begin(), end = params.end(); it != end; ++it)
        pass->addParameter(buildParameter(it.key(), it.value().toObject()));

    populateRenderStates(pass, jsonObject.value(KEY_STATES).toObject());
    addProgramToPass(pass, jsonObject.value(KEY_PROGRAM).toString());

    renameFromJson(jsonObject, pass);

    m_renderPasses[id] = pass;
}

/*!
    Loads raw data from the GLTF file into the buffer.
*/
void GLTFImporter::loadBufferData()
{
    for (auto &bufferData : m_bufferDatas) {
        if (!bufferData.data) {
            bufferData.data = new QByteArray(resolveLocalData(bufferData.path));
        }
    }
}

/*!
    Removes all data from the buffer.
*/
void GLTFImporter::unloadBufferData()
{
    for (const auto &bufferData : qAsConst(m_bufferDatas)) {
        QByteArray *data = bufferData.data;
        delete data;
    }
}

QByteArray GLTFImporter::resolveLocalData(const QString &path) const
{
    QDir d(m_basePath);
    Q_ASSERT(d.exists());

    // check for embedded data
    if (isEmbeddedResource(path)) {
        const QByteArray base64Data = path.toLatin1().remove(0, path.indexOf(",") + 1);
        return QByteArray::fromBase64(base64Data);
    } else {
        const QString absPath = d.absoluteFilePath(path);
        QFile f(absPath);
        f.open(QIODevice::ReadOnly);
        return f.readAll();
    }
}

QVariant GLTFImporter::parameterValueFromJSON(int type, const QJsonValue &value) const
{
    if (value.isBool()) {
        if (type == GL_BOOL)
            return QVariant(static_cast<GLboolean>(value.toBool()));
    } else if (value.isString()) {
        if (type == GL_SAMPLER_2D) {
            //Textures are special because we need to do a lookup to return the
            //QAbstractTexture
            QString textureId = value.toString();
            const auto it = m_textures.find(textureId);
            if (Q_UNLIKELY(it == m_textures.end())) {
                qCWarning(GLTFImporterLog, "unknown texture %ls", qUtf16PrintableImpl(textureId));
                return QVariant();
            } else {
                return QVariant::fromValue(it.value());
            }
        }
    } else if (value.isDouble()) {
        switch (type) {
        case GL_BYTE:
            return QVariant(static_cast<GLbyte>(value.toInt()));
        case GL_UNSIGNED_BYTE:
            return QVariant(static_cast<GLubyte>(value.toInt()));
        case GL_SHORT:
            return QVariant(static_cast<GLshort>(value.toInt()));
        case GL_UNSIGNED_SHORT:
            return QVariant(static_cast<GLushort>(value.toInt()));
        case GL_INT:
            return QVariant(static_cast<GLint>(value.toInt()));
        case GL_UNSIGNED_INT:
            return QVariant(static_cast<GLuint>(value.toInt()));
        case GL_FLOAT:
            return QVariant(static_cast<GLfloat>(value.toDouble()));
        default:
            break;
        }
    } else if (value.isArray()) {

        const QJsonArray valueArray = value.toArray();

        QVector2D vector2D;
        QVector3D vector3D;
        QVector4D vector4D;
        QVector<float> dataMat2(4, 0.0f);
        QVector<float> dataMat3(9, 0.0f);

        switch (type) {
        case GL_BYTE:
            return QVariant(static_cast<GLbyte>(valueArray.first().toInt()));
        case GL_UNSIGNED_BYTE:
            return QVariant(static_cast<GLubyte>(valueArray.first().toInt()));
        case GL_SHORT:
            return QVariant(static_cast<GLshort>(valueArray.first().toInt()));
        case GL_UNSIGNED_SHORT:
            return QVariant(static_cast<GLushort>(valueArray.first().toInt()));
        case GL_INT:
            return QVariant(static_cast<GLint>(valueArray.first().toInt()));
        case GL_UNSIGNED_INT:
            return QVariant(static_cast<GLuint>(valueArray.first().toInt()));
        case GL_FLOAT:
            return QVariant(static_cast<GLfloat>(valueArray.first().toDouble()));
        case GL_FLOAT_VEC2:
            vector2D.setX(static_cast<GLfloat>(valueArray.at(0).toDouble()));
            vector2D.setY(static_cast<GLfloat>(valueArray.at(1).toDouble()));
            return QVariant(vector2D);
        case GL_FLOAT_VEC3:
            vector3D.setX(static_cast<GLfloat>(valueArray.at(0).toDouble()));
            vector3D.setY(static_cast<GLfloat>(valueArray.at(1).toDouble()));
            vector3D.setZ(static_cast<GLfloat>(valueArray.at(2).toDouble()));
            return QVariant(vector3D);
        case GL_FLOAT_VEC4:
            vector4D.setX(static_cast<GLfloat>(valueArray.at(0).toDouble()));
            vector4D.setY(static_cast<GLfloat>(valueArray.at(1).toDouble()));
            vector4D.setZ(static_cast<GLfloat>(valueArray.at(2).toDouble()));
            vector4D.setW(static_cast<GLfloat>(valueArray.at(3).toDouble()));
            return QVariant(vector4D);
        case GL_INT_VEC2:
            vector2D.setX(static_cast<GLint>(valueArray.at(0).toInt()));
            vector2D.setY(static_cast<GLint>(valueArray.at(1).toInt()));
            return QVariant(vector2D);
        case GL_INT_VEC3:
            vector3D.setX(static_cast<GLint>(valueArray.at(0).toInt()));
            vector3D.setY(static_cast<GLint>(valueArray.at(1).toInt()));
            vector3D.setZ(static_cast<GLint>(valueArray.at(2).toInt()));
            return QVariant(vector3D);
        case GL_INT_VEC4:
            vector4D.setX(static_cast<GLint>(valueArray.at(0).toInt()));
            vector4D.setY(static_cast<GLint>(valueArray.at(1).toInt()));
            vector4D.setZ(static_cast<GLint>(valueArray.at(2).toInt()));
            vector4D.setW(static_cast<GLint>(valueArray.at(3).toInt()));
            return QVariant(vector4D);
        case GL_BOOL:
            return QVariant(static_cast<GLboolean>(valueArray.first().toBool()));
        case GL_BOOL_VEC2:
            vector2D.setX(static_cast<GLboolean>(valueArray.at(0).toBool()));
            vector2D.setY(static_cast<GLboolean>(valueArray.at(1).toBool()));
            return QVariant(vector2D);
        case GL_BOOL_VEC3:
            vector3D.setX(static_cast<GLboolean>(valueArray.at(0).toBool()));
            vector3D.setY(static_cast<GLboolean>(valueArray.at(1).toBool()));
            vector3D.setZ(static_cast<GLboolean>(valueArray.at(2).toBool()));
            return QVariant(vector3D);
        case GL_BOOL_VEC4:
            vector4D.setX(static_cast<GLboolean>(valueArray.at(0).toBool()));
            vector4D.setY(static_cast<GLboolean>(valueArray.at(1).toBool()));
            vector4D.setZ(static_cast<GLboolean>(valueArray.at(2).toBool()));
            vector4D.setW(static_cast<GLboolean>(valueArray.at(3).toBool()));
            return QVariant(vector4D);
        case GL_FLOAT_MAT2:
            //Matrix2x2 is in Row Major ordering (so we need to convert)
            dataMat2[0] = static_cast<GLfloat>(valueArray.at(0).toDouble());
            dataMat2[1] = static_cast<GLfloat>(valueArray.at(2).toDouble());
            dataMat2[2] = static_cast<GLfloat>(valueArray.at(1).toDouble());
            dataMat2[3] = static_cast<GLfloat>(valueArray.at(3).toDouble());
            return QVariant::fromValue(QMatrix2x2(dataMat2.constData()));
        case GL_FLOAT_MAT3:
            //Matrix3x3 is in Row Major ordering (so we need to convert)
            dataMat3[0] = static_cast<GLfloat>(valueArray.at(0).toDouble());
            dataMat3[1] = static_cast<GLfloat>(valueArray.at(3).toDouble());
            dataMat3[2] = static_cast<GLfloat>(valueArray.at(6).toDouble());
            dataMat3[3] = static_cast<GLfloat>(valueArray.at(1).toDouble());
            dataMat3[4] = static_cast<GLfloat>(valueArray.at(4).toDouble());
            dataMat3[5] = static_cast<GLfloat>(valueArray.at(7).toDouble());
            dataMat3[6] = static_cast<GLfloat>(valueArray.at(2).toDouble());
            dataMat3[7] = static_cast<GLfloat>(valueArray.at(5).toDouble());
            dataMat3[8] = static_cast<GLfloat>(valueArray.at(8).toDouble());
            return QVariant::fromValue(QMatrix3x3(dataMat3.constData()));
        case GL_FLOAT_MAT4:
            //Matrix4x4 is Column Major ordering
            return QVariant(QMatrix4x4(static_cast<GLfloat>(valueArray.at(0).toDouble()),
                                       static_cast<GLfloat>(valueArray.at(1).toDouble()),
                                       static_cast<GLfloat>(valueArray.at(2).toDouble()),
                                       static_cast<GLfloat>(valueArray.at(3).toDouble()),
                                       static_cast<GLfloat>(valueArray.at(4).toDouble()),
                                       static_cast<GLfloat>(valueArray.at(5).toDouble()),
                                       static_cast<GLfloat>(valueArray.at(6).toDouble()),
                                       static_cast<GLfloat>(valueArray.at(7).toDouble()),
                                       static_cast<GLfloat>(valueArray.at(8).toDouble()),
                                       static_cast<GLfloat>(valueArray.at(9).toDouble()),
                                       static_cast<GLfloat>(valueArray.at(10).toDouble()),
                                       static_cast<GLfloat>(valueArray.at(11).toDouble()),
                                       static_cast<GLfloat>(valueArray.at(12).toDouble()),
                                       static_cast<GLfloat>(valueArray.at(13).toDouble()),
                                       static_cast<GLfloat>(valueArray.at(14).toDouble()),
                                       static_cast<GLfloat>(valueArray.at(15).toDouble())));
        case GL_SAMPLER_2D:
            return QVariant(valueArray.at(0).toString());
        }
    }
    return QVariant();
}

QAttribute::VertexBaseType GLTFImporter::accessorTypeFromJSON(int componentType)
{
    if (componentType == GL_BYTE) {
        return QAttribute::Byte;
    } else if (componentType == GL_UNSIGNED_BYTE) {
        return QAttribute::UnsignedByte;
    } else if (componentType == GL_SHORT) {
        return QAttribute::Short;
    } else if (componentType == GL_UNSIGNED_SHORT) {
        return QAttribute::UnsignedShort;
    } else if (componentType == GL_UNSIGNED_INT) {
        return QAttribute::UnsignedInt;
    } else if (componentType == GL_FLOAT) {
        return QAttribute::Float;
    }

    //There shouldn't be an invalid case here
    qCWarning(GLTFImporterLog, "unsupported accessor type %d", componentType);
    return QAttribute::Float;
}

uint GLTFImporter::accessorDataSizeFromJson(const QString &type)
{
    QString typeName = type.toUpper();
    if (typeName == QLatin1String("SCALAR"))
        return 1;
    if (typeName == QLatin1String("VEC2"))
        return 2;
    if (typeName == QLatin1String("VEC3"))
        return 3;
    if (typeName == QLatin1String("VEC4"))
        return 4;
    if (typeName == QLatin1String("MAT2"))
        return 4;
    if (typeName == QLatin1String("MAT3"))
        return 9;
    if (typeName == QLatin1String("MAT4"))
        return 16;

    return 0;
}

QRenderState *GLTFImporter::buildStateEnable(int state)
{
    int type = 0;
    //By calling buildState with QJsonValue(), a Render State with
    //default values is created.

    switch (state) {
    case GL_BLEND:
        //It doesn't make sense to handle this state alone
        return nullptr;
    case GL_CULL_FACE:
        return buildState(QStringLiteral("cullFace"), QJsonValue(), type);
    case GL_DEPTH_TEST:
        return buildState(QStringLiteral("depthFunc"), QJsonValue(), type);
    case GL_POLYGON_OFFSET_FILL:
        return buildState(QStringLiteral("polygonOffset"), QJsonValue(), type);
    case GL_SAMPLE_ALPHA_TO_COVERAGE:
        return new QAlphaCoverage();
    case GL_SCISSOR_TEST:
        return buildState(QStringLiteral("scissor"), QJsonValue(), type);
    case GL_DITHER: // Qt3D Custom
        return new QDithering();
    case 0x809D: // GL_MULTISAMPLE - Qt3D Custom
        return new QMultiSampleAntiAliasing();
    case 0x884F: // GL_TEXTURE_CUBE_MAP_SEAMLESS - Qt3D Custom
        return new QSeamlessCubemap();
    default:
        break;
    }

    qCWarning(GLTFImporterLog, "unsupported render state: %d", state);

    return nullptr;
}

QRenderState* GLTFImporter::buildState(const QString& functionName, const QJsonValue &value, int &type)
{
    type = -1;
    QJsonArray values = value.toArray();

    if (functionName == QLatin1String("blendColor")) {
        type = GL_BLEND;
        //TODO: support render state blendColor
        qCWarning(GLTFImporterLog, "unsupported render state: %ls", qUtf16PrintableImpl(functionName));
        return nullptr;
    }

    if (functionName == QLatin1String("blendEquationSeparate")) {
        type = GL_BLEND;
        //TODO: support settings blendEquation alpha
        QBlendEquation *blendEquation = new QBlendEquation;
        blendEquation->setBlendFunction((QBlendEquation::BlendFunction)values.at(0).toInt(GL_FUNC_ADD));
        return blendEquation;
    }

    if (functionName == QLatin1String("blendFuncSeparate")) {
        type = GL_BLEND;
        QBlendEquationArguments *blendArgs = new QBlendEquationArguments;
        blendArgs->setSourceRgb((QBlendEquationArguments::Blending)values.at(0).toInt(GL_ONE));
        blendArgs->setSourceAlpha((QBlendEquationArguments::Blending)values.at(1).toInt(GL_ONE));
        blendArgs->setDestinationRgb((QBlendEquationArguments::Blending)values.at(2).toInt(GL_ZERO));
        blendArgs->setDestinationAlpha((QBlendEquationArguments::Blending)values.at(3).toInt(GL_ZERO));
        blendArgs->setBufferIndex(values.at(4).toInt(-1));
        return blendArgs;
    }

    if (functionName == QLatin1String("colorMask")) {
        QColorMask *colorMask = new QColorMask;
        colorMask->setRedMasked(values.at(0).toBool(true));
        colorMask->setGreenMasked(values.at(1).toBool(true));
        colorMask->setBlueMasked(values.at(2).toBool(true));
        colorMask->setAlphaMasked(values.at(3).toBool(true));
        return colorMask;
    }

    if (functionName == QLatin1String("cullFace")) {
        type = GL_CULL_FACE;
        QCullFace *cullFace = new QCullFace;
        cullFace->setMode((QCullFace::CullingMode)values.at(0).toInt(GL_BACK));
        return cullFace;
    }

    if (functionName == QLatin1String("depthFunc")) {
        type = GL_DEPTH_TEST;
        QDepthTest *depthTest = new QDepthTest;
        depthTest->setDepthFunction((QDepthTest::DepthFunction)values.at(0).toInt(GL_LESS));
        return depthTest;
    }

    if (functionName == QLatin1String("depthMask")) {
        if (!values.at(0).toBool(true)) {
            QNoDepthMask *depthMask = new QNoDepthMask;
            return depthMask;
        }
        return nullptr;
    }

    if (functionName == QLatin1String("depthRange")) {
        type = GL_DEPTH_RANGE;
        QDepthRange *depthRange = new QDepthRange;
        depthRange->setNearValue(values.at(0).toDouble(0.0));
        depthRange->setFarValue(values.at(1).toDouble(1.0));
        return depthRange;
    }

    if (functionName == QLatin1String("frontFace")) {
        QFrontFace *frontFace = new QFrontFace;
        frontFace->setDirection((QFrontFace::WindingDirection)values.at(0).toInt(GL_CCW));
        return frontFace;
    }

    if (functionName == QLatin1String("lineWidth")) {
        //TODO: support render state lineWidth
        qCWarning(GLTFImporterLog, "unsupported render state: %ls", qUtf16PrintableImpl(functionName));
        return nullptr;
    }

    if (functionName == QLatin1String("polygonOffset")) {
        type = GL_POLYGON_OFFSET_FILL;
        QPolygonOffset *polygonOffset = new QPolygonOffset;
        polygonOffset->setScaleFactor((float)values.at(0).toDouble(0.0f));
        polygonOffset->setDepthSteps((float)values.at(1).toDouble(0.0f));
        return polygonOffset;
    }

    if (functionName == QLatin1String("scissor")) {
        type = GL_SCISSOR_TEST;
        QScissorTest *scissorTest = new QScissorTest;
        scissorTest->setLeft(values.at(0).toDouble(0.0f));
        scissorTest->setBottom(values.at(1).toDouble(0.0f));
        scissorTest->setWidth(values.at(2).toDouble(0.0f));
        scissorTest->setHeight(values.at(3).toDouble(0.0f));
        return scissorTest;
    }

    // Qt3D custom functions
    if (functionName == QLatin1String("alphaTest")) {
        QAlphaTest *args = new QAlphaTest;
        args->setAlphaFunction(QAlphaTest::AlphaFunction(values.at(0).toInt()));
        args->setReferenceValue(float(values.at(1).toDouble()));
        return args;
    }

    if (functionName == QLatin1String("clipPlane")) {
        QClipPlane *args = new QClipPlane;
        args->setPlaneIndex(values.at(0).toInt());
        args->setNormal(QVector3D(float(values.at(1).toDouble()),
                                  float(values.at(2).toDouble()),
                                  float(values.at(3).toDouble())));
        args->setDistance(float(values.at(4).toDouble()));
        return args;
    }

    if (functionName == QLatin1String("pointSize")) {
        QPointSize *pointSize = new QPointSize;
        pointSize->setSizeMode(QPointSize::SizeMode(values.at(0).toInt(QPointSize::Programmable)));
        pointSize->setValue(float(values.at(1).toDouble()));
        return pointSize;
    }

    if (functionName == QLatin1String("stencilMask")) {
        QStencilMask *stencilMask = new QStencilMask;
        stencilMask->setFrontOutputMask(uint(values.at(0).toInt()));
        stencilMask->setBackOutputMask(uint(values.at(1).toInt()));
        return stencilMask;
    }

    if (functionName == QLatin1String("stencilOperation")) {
        QStencilOperation *stencilOperation = new QStencilOperation;
        stencilOperation->front()->setStencilTestFailureOperation(
                    QStencilOperationArguments::Operation(values.at(0).toInt(
                                                              QStencilOperationArguments::Keep)));
        stencilOperation->front()->setDepthTestFailureOperation(
                    QStencilOperationArguments::Operation(values.at(1).toInt(
                                                              QStencilOperationArguments::Keep)));
        stencilOperation->front()->setAllTestsPassOperation(
                    QStencilOperationArguments::Operation(values.at(2).toInt(
                                                              QStencilOperationArguments::Keep)));
        stencilOperation->back()->setStencilTestFailureOperation(
                    QStencilOperationArguments::Operation(values.at(3).toInt(
                                                              QStencilOperationArguments::Keep)));
        stencilOperation->back()->setDepthTestFailureOperation(
                    QStencilOperationArguments::Operation(values.at(4).toInt(
                                                              QStencilOperationArguments::Keep)));
        stencilOperation->back()->setAllTestsPassOperation(
                    QStencilOperationArguments::Operation(values.at(5).toInt(
                                                              QStencilOperationArguments::Keep)));
        return stencilOperation;
    }

    if (functionName == QLatin1String("stencilTest")) {
        QStencilTest *stencilTest = new QStencilTest;
        stencilTest->front()->setComparisonMask(uint(values.at(0).toInt()));
        stencilTest->front()->setReferenceValue(values.at(1).toInt());
        stencilTest->front()->setStencilFunction(
                    QStencilTestArguments::StencilFunction(values.at(2).toInt(
                                                               QStencilTestArguments::Never)));
        stencilTest->back()->setComparisonMask(uint(values.at(3).toInt()));
        stencilTest->back()->setReferenceValue(values.at(4).toInt());
        stencilTest->back()->setStencilFunction(
                    QStencilTestArguments::StencilFunction(values.at(5).toInt(
                                                               QStencilTestArguments::Never)));
        return stencilTest;
    }

    qCWarning(GLTFImporterLog, "unsupported render state: %ls", qUtf16PrintableImpl(functionName));
    return nullptr;
}

QParameter *GLTFImporter::buildParameter(const QString &key, const QJsonObject &paramObj)
{
    QParameter *p = new QParameter;
    p->setName(key);
    QJsonValue value = paramObj.value(KEY_VALUE);

    if (!value.isUndefined()) {
        int dataType = paramObj.value(KEY_TYPE).toInt();
        p->setValue(parameterValueFromJSON(dataType, value));
    }

    return p;
}

void GLTFImporter::populateRenderStates(QRenderPass *pass, const QJsonObject &states)
{
    // Process states to enable
    const QJsonArray enableStatesArray = states.value(KEY_ENABLE).toArray();
    QVector<int> enableStates;
    for (const QJsonValue &enableValue : enableStatesArray)
        enableStates.append(enableValue.toInt());

    // Process the list of state functions
    const QJsonObject functions = states.value(KEY_FUNCTIONS).toObject();
    for (auto it = functions.begin(), end = functions.end(); it != end; ++it) {
        int enableStateType = 0;
        QRenderState *renderState = buildState(it.key(), it.value(), enableStateType);
        if (renderState != nullptr) {
            //Remove the need to set a default state values for enableStateType
            enableStates.removeOne(enableStateType);
            pass->addRenderState(renderState);
        }
    }

    // Create render states with default values for any remaining enable states
    for (int enableState : qAsConst(enableStates)) {
        QRenderState *renderState = buildStateEnable(enableState);
        if (renderState != nullptr)
            pass->addRenderState(renderState);
    }
}

void GLTFImporter::addProgramToPass(QRenderPass *pass, const QString &progName)
{
    const auto progIt = qAsConst(m_programs).find(progName);
    if (Q_UNLIKELY(progIt == m_programs.cend()))
        qCWarning(GLTFImporterLog, "missing program %ls", qUtf16PrintableImpl(progName));
    else
        pass->setShaderProgram(progIt.value());
}

void GLTFImporter::setTextureSamplerInfo(const QString &id, const QJsonObject &jsonObj, QTexture2D *tex)
{
    QJsonObject sampler;
    const QJsonValue jsonValue = jsonObj.value(KEY_SAMPLER);
    if (jsonValue.isUndefined())
        return;

    if (m_majorVersion > 1) {
        const int samplerId = jsonValue.toInt();
        const QJsonArray sArray = m_json.object().value(KEY_SAMPLERS).toArray();
        if (Q_UNLIKELY(samplerId >= sArray.count())) {
            qCWarning(GLTFImporterLog, "texture %ls references unknown sampler %d",
                      qUtf16PrintableImpl(id), samplerId);
            return;
        }
        sampler = sArray[samplerId].toObject();
    } else {
        const QString samplerId = jsonValue.toString();
        const QJsonValue samplersDictValue = m_json.object().value(KEY_SAMPLERS).toObject().value(samplerId);
        if (Q_UNLIKELY(samplersDictValue.isUndefined())) {
            qCWarning(GLTFImporterLog, "texture %ls references unknown sampler %ls",
                      qUtf16PrintableImpl(id), qUtf16PrintableImpl(samplerId));
            return;
        }
        sampler = samplersDictValue.toObject();
    }

    tex->setWrapMode(QTextureWrapMode(static_cast<QTextureWrapMode::WrapMode>(sampler.value(KEY_WRAP_S).toInt())));
    tex->setMinificationFilter(static_cast<QAbstractTexture::Filter>(sampler.value(KEY_MIN_FILTER).toInt()));
    if (tex->minificationFilter() == QAbstractTexture::NearestMipMapLinear ||
        tex->minificationFilter() == QAbstractTexture::LinearMipMapNearest ||
        tex->minificationFilter() == QAbstractTexture::NearestMipMapNearest ||
        tex->minificationFilter() == QAbstractTexture::LinearMipMapLinear) {

        tex->setGenerateMipMaps(true);
    }
    tex->setMagnificationFilter(static_cast<QAbstractTexture::Filter>(sampler.value(KEY_MAG_FILTER).toInt()));
}

GLTFRawTextureImage::GLTFRawTextureImage(QNode *parent)
    : QAbstractTextureImage(parent)
{
}

QTextureImageDataGeneratorPtr GLTFRawTextureImage::dataGenerator() const
{
    return QTextureImageDataGeneratorPtr(new GLTFRawTextureImageFunctor(m_image));
}

void GLTFRawTextureImage::setImage(const QImage &image)
{
    if (image != m_image) {
        m_image = image;
        notifyDataGeneratorChanged();
    }
}

GLTFRawTextureImage::GLTFRawTextureImageFunctor::GLTFRawTextureImageFunctor(const QImage &image)
    : QTextureImageDataGenerator()
    , m_image(image)
{
}

QTextureImageDataPtr GLTFRawTextureImage::GLTFRawTextureImageFunctor::operator()()
{
    QTextureImageDataPtr dataPtr = QTextureImageDataPtr::create();
    // Note: we assume 4 components per pixel and not compressed for now
    dataPtr->setImage(m_image);
    return dataPtr;
}

bool GLTFRawTextureImage::GLTFRawTextureImageFunctor::operator ==(const QTextureImageDataGenerator &other) const
{
    const GLTFRawTextureImageFunctor *otherFunctor = functor_cast<GLTFRawTextureImageFunctor>(&other);
    return (otherFunctor != nullptr && otherFunctor->m_image == m_image);
}

} // namespace Qt3DRender

QT_END_NAMESPACE

#include "gltfimporter.moc"
