summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2019-07-10 20:45:04 +0200
committerMarc Mutz <marc.mutz@kdab.com>2019-07-18 12:06:00 +0200
commit509e5730b02284fa2998032b97524e367abcf262 (patch)
treee4674c922206d1c517c5b06f91259f7358fcc219
parentcc834ee647dee624805215d8270cb6f23083aa2a (diff)
Remove unused file gltfparser.cpp
Found because it's full of Q_FOREACH when the module compiles fine with QT_NO_FOREACH... Change-Id: I8e34a3f54c1070d4dcc9b5c7b578760860eab72c Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
-rw-r--r--src/plugins/sceneparsers/gltf/gltfparser.cpp1560
1 files changed, 0 insertions, 1560 deletions
diff --git a/src/plugins/sceneparsers/gltf/gltfparser.cpp b/src/plugins/sceneparsers/gltf/gltfparser.cpp
deleted file mode 100644
index 881e7f1b2..000000000
--- a/src/plugins/sceneparsers/gltf/gltfparser.cpp
+++ /dev/null
@@ -1,1560 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
-** Copyright (C) 2015 The Qt Company Ltd and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the Qt3D module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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 http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "gltfparser.h"
-
-#include <QtCore/QDir>
-#include <QtCore/QFileInfo>
-#include <QtCore/QJsonArray>
-#include <QtCore/QJsonObject>
-
-#include <QtGui/QVector2D>
-
-#include <Qt3DCore/QCameraLens>
-#include <Qt3DCore/QEntity>
-#include <Qt3DCore/QTransform>
-
-#include <Qt3DRender/private/qurlhelper_p.h>
-
-#include <Qt3DRender/QAlphaCoverage>
-#include <Qt3DRender/QBlendEquation>
-#include <Qt3DRender/QBlendStateSeparate>
-#include <Qt3DRender/QColorMask>
-#include <Qt3DRender/QCullFace>
-#include <Qt3DRender/QDepthMask>
-#include <Qt3DRender/QDepthTest>
-#include <Qt3DRender/QEffect>
-#include <Qt3DRender/QFrontFace>
-#include <Qt3DRender/QGeometry>
-#include <Qt3DRender/QGeometryRenderer>
-#include <Qt3DRender/QMaterial>
-#include <Qt3DRender/QGraphicsApiFilter>
-#include <Qt3DRender/QParameter>
-#include <Qt3DRender/QParameterMapping>
-#include <Qt3DRender/QPolygonOffset>
-#include <Qt3DRender/QRenderState>
-#include <Qt3DRender/QScissorTest>
-#include <Qt3DRender/QShaderProgram>
-#include <Qt3DRender/QTechnique>
-#include <Qt3DRender/QTexture>
-
-#include <Qt3DRender/QPhongMaterial>
-#include <Qt3DRender/QDiffuseMapMaterial>
-#include <Qt3DRender/QDiffuseSpecularMapMaterial>
-#include <Qt3DRender/QNormalDiffuseMapMaterial>
-#include <Qt3DRender/QNormalDiffuseSpecularMapMaterial>
-
-QT_BEGIN_NAMESPACE
-
-using namespace Qt3DCore;
-
-namespace Qt3DRender {
-
-Q_LOGGING_CATEGORY(GLTFParserLog, "Qt3D.GLTFParser")
-
-namespace {
-
-const QString KEY_CAMERA = QStringLiteral("camera");
-const QString KEY_CAMERAS = QStringLiteral("cameras");
-const QString KEY_SCENES = QStringLiteral("scenes");
-const QString KEY_NODES = QStringLiteral("nodes");
-const QString KEY_MESHES = QStringLiteral("meshes");
-const QString KEY_CHILDREN = QStringLiteral("children");
-const QString KEY_MATRIX = QStringLiteral("matrix");
-const QString KEY_ROTATION = QStringLiteral("rotation");
-const QString KEY_SCALE = QStringLiteral("scale");
-const QString KEY_TRANSLATION = QStringLiteral("translation");
-const QString KEY_TYPE = QStringLiteral("type");
-const QString KEY_PERSPECTIVE =QStringLiteral("perspective");
-const QString KEY_NAME = QStringLiteral("name");
-const QString KEY_COUNT = QStringLiteral("count");
-const QString KEY_YFOV = QStringLiteral("yfov");
-const QString KEY_ZNEAR = QStringLiteral("znear");
-const QString KEY_ZFAR = QStringLiteral("zfar");
-const QString KEY_MATERIALS = QStringLiteral("materials");
-const QString KEY_EXTENSIONS = QStringLiteral("extensions");
-const QString KEY_COMMON_MAT = QStringLiteral("KHR_materials_common");
-const QString KEY_TECHNIQUE = QStringLiteral("technique");
-const QString KEY_VALUES = QStringLiteral("values");
-const QString KEY_BUFFERS = QStringLiteral("buffers");
-const QString KEY_SHADERS = QStringLiteral("shaders");
-const QString KEY_PROGRAMS = QStringLiteral("programs");
-const QString KEY_PROGRAM = QStringLiteral("program");
-const QString KEY_TECHNIQUES = QStringLiteral("techniques");
-const QString KEY_ACCESSORS = QStringLiteral("accessors");
-const QString KEY_IMAGES = QStringLiteral("images");
-const QString KEY_TEXTURES = QStringLiteral("textures");
-const QString KEY_SCENE = QStringLiteral("scene");
-const QString KEY_BUFFER = QStringLiteral("buffer");
-const QString KEY_TARGET = QStringLiteral("target");
-const QString KEY_BYTE_OFFSET = QStringLiteral("byteOffset");
-const QString KEY_BYTE_LENGTH = QStringLiteral("byteLength");
-const QString KEY_BYTE_STRIDE = QStringLiteral("byteStride");
-const QString KEY_PRIMITIVES = QStringLiteral("primitives");
-const QString KEY_MODE = QStringLiteral("mode");
-const QString KEY_MATERIAL = QStringLiteral("material");
-const QString KEY_ATTRIBUTES = QStringLiteral("attributes");
-const QString KEY_INDICES = QStringLiteral("indices");
-const QString KEY_URI = QStringLiteral("uri");
-const QString KEY_FORMAT = QStringLiteral("format");
-const QString KEY_PASSES = QStringLiteral("passes");
-const QString KEY_SOURCE = QStringLiteral("source");
-const QString KEY_SAMPLER = QStringLiteral("sampler");
-const QString KEY_SAMPLERS = QStringLiteral("samplers");
-const QString KEY_SEMANTIC = QStringLiteral("semantic");
-const QString KEY_STATES = QStringLiteral("states");
-const QString KEY_UNIFORMS = QStringLiteral("uniforms");
-const QString KEY_PARAMETERS = QStringLiteral("parameters");
-const QString KEY_WRAP_S = QStringLiteral("wrapS");
-const QString KEY_MIN_FILTER = QStringLiteral("minFilter");
-const QString KEY_MAG_FILTER = QStringLiteral("magFilter");
-
-const QString KEY_INSTANCE_TECHNIQUE = QStringLiteral("instanceTechnique");
-const QString KEY_INSTANCE_PROGRAM = QStringLiteral("instanceProgram");
-const QString KEY_BUFFER_VIEWS = QStringLiteral("bufferViews");
-const QString KEY_BUFFER_VIEW = QStringLiteral("bufferView");
-const QString KEY_VERTEX_SHADER = QStringLiteral("vertexShader");
-const QString KEY_FRAGMENT_SHADER = QStringLiteral("fragmentShader");
-const QString KEY_INTERNAL_FORMAT = QStringLiteral("internalFormat");
-const QString KEY_COMPONENT_TYPE = QStringLiteral("componentType");
-const QString KEY_ASPECT_RATIO = QStringLiteral("aspect_ratio");
-const QString KEY_VALUE = QStringLiteral("value");
-const QString KEY_ENABLE = QStringLiteral("enable");
-const QString KEY_FUNCTIONS = QStringLiteral("functions");
-const QString KEY_TECHNIQUE_CORE = QStringLiteral("techniqueCore");
-const QString KEY_TECHNIQUE_GL2 = QStringLiteral("techniqueGL2");
-
-} // of anonymous namespace
-
-GLTFParser::GLTFParser() : QAbstractSceneParser(),
- m_parseDone(false)
-{
-}
-
-GLTFParser::~GLTFParser()
-{
-
-}
-
-void GLTFParser::setBasePath(const QString& path)
-{
- m_basePath = path;
-}
-
-bool GLTFParser::setJSON(const QJsonDocument &json )
-{
- if ( !json.isObject() ) {
- return false;
- }
-
- m_json = json;
- m_parseDone = false;
-
- cleanup();
-
- return true;
-}
-
-/*
- * Sets the \a path used by the parser to load the scene file.
- * If the file is valid, parsing is automatically triggered.
- */
-void GLTFParser::setSource(const QUrl &source)
-{
- const QString path = QUrlHelper::urlToLocalFileOrQrc(source);
- QFile f(path);
- if (Q_UNLIKELY(!f.open(QIODevice::ReadOnly))) {
- qCWarning(GLTFParserLog) << "cannot open " << path << ": " << f.errorString();
- return;
- }
-
- QByteArray jsonData = f.readAll();
- QJsonDocument sceneDocument = QJsonDocument::fromBinaryData(jsonData);
- if (sceneDocument.isNull())
- sceneDocument = QJsonDocument::fromJson(jsonData);
-
- if (!setJSON(sceneDocument)) {
- qCWarning(GLTFParserLog) << "not a JSON document";
- return;
- }
-
- setBasePath(QFileInfo(path).dir().absolutePath());
-}
-
-/*
- * Returns true if the extension of \a path is supported by the
- * GLTF parser.
- */
-bool GLTFParser::isExtensionSupported(const QUrl &source) const
-{
- const QString path = QUrlHelper::urlToLocalFileOrQrc(source);
- return GLTFParser::isGLTFPath(path);
-}
-
-Qt3DCore::QEntity* GLTFParser::node(const QString &id)
-{
- QJsonObject nodes = m_json.object().value(KEY_NODES).toObject();
- if (!nodes.contains(id)) {
- qCWarning(GLTFParserLog) << "unknown node" << id << "in GLTF file" << m_basePath;
- return NULL;
- }
-
- QJsonObject jsonObj = nodes.value(id).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
- if (jsonObj.contains(KEY_MESHES)) {
- QVector<QEntity *> entities;
-
- Q_FOREACH (QJsonValue mesh, jsonObj.value(KEY_MESHES).toArray()) {
- if (!m_meshDict.contains(mesh.toString())) {
- qCWarning(GLTFParserLog) << "node" << id << "references unknown mesh" << mesh.toString();
- continue;
- }
-
- Q_FOREACH (QGeometryRenderer *geometryRenderer, m_meshDict.values(mesh.toString())) {
- QEntity *entity = new QEntity;
- entity->addComponent(geometryRenderer);
- QMaterial *mat = material(m_meshMaterialDict[geometryRenderer]);
- if (mat)
- entity->addComponent(mat);
- entities.append(entity);
- }
-
- }
-
- if (entities.count() == 1) {
- result = entities.first();
- } else {
- result = new QEntity;
- Q_FOREACH (QEntity *entity, entities) {
- entity->setParent(result);
- }
- }
- }
-
- //If the entity contains no meshes, results will still be null here
- if (result == nullptr)
- result = new QEntity;
-
- if ( jsonObj.contains(KEY_CHILDREN) ) {
- Q_FOREACH (QJsonValue c, jsonObj.value(KEY_CHILDREN).toArray()) {
- QEntity* child = node(c.toString());
- if (!child)
- continue;
- child->setParent(result);
- }
- }
-
- renameFromJson(jsonObj, result);
-
-
- // Node Transforms
- Qt3DCore::QTransform *trans = nullptr;
- if ( jsonObj.contains(KEY_MATRIX) ) {
- QMatrix4x4 m(Qt::Uninitialized);
-
- QJsonArray matrixValues = jsonObj.value(KEY_MATRIX).toArray();
- for (int i=0; i<16; ++i) {
- double v = matrixValues.at( i ).toDouble();
- m(i % 4, i >> 2) = v;
- }
-
- // ADD MATRIX TRANSFORM COMPONENT TO ENTITY
- if (trans == nullptr)
- trans = new Qt3DCore::QTransform;
- trans->setMatrix(m);
- }
-
- // Rotation quaternion
- if (jsonObj.contains(KEY_ROTATION)) {
- if (trans == nullptr)
- trans = new Qt3DCore::QTransform;
-
- QJsonArray quaternionValues = jsonObj.value(KEY_ROTATION).toArray();
- QQuaternion quaternion(quaternionValues[0].toDouble(),
- quaternionValues[1].toDouble(),
- quaternionValues[2].toDouble(),
- quaternionValues[3].toDouble());
- trans->setRotation(quaternion);
- }
-
- // Translation
- if (jsonObj.contains(KEY_TRANSLATION)) {
- if (trans == nullptr)
- trans = new Qt3DCore::QTransform;
-
- QJsonArray translationValues = jsonObj.value(KEY_TRANSLATION).toArray();
- trans->setTranslation(QVector3D(translationValues[0].toDouble(),
- translationValues[1].toDouble(),
- translationValues[2].toDouble()));
- }
-
- // Scale
- if (jsonObj.contains(KEY_SCALE)) {
- if (trans == nullptr)
- trans = new Qt3DCore::QTransform;
-
- QJsonArray scaleValues = jsonObj.value(KEY_SCALE).toArray();
- trans->setScale3D(QVector3D(scaleValues[0].toDouble(),
- scaleValues[1].toDouble(),
- scaleValues[2].toDouble()));
- }
-
- // Add the Transform component
- if (trans != nullptr)
- result->addComponent(trans);
-
- if ( jsonObj.contains(KEY_CAMERA) ) {
- QCameraLens* cam = camera( jsonObj.value(KEY_CAMERA).toString() );
- if (!cam) {
- qCWarning(GLTFParserLog) << "failed to build camera:" << jsonObj.value(KEY_CAMERA)
- << "on node" << id;
- } else {
- result->addComponent(cam);
- }
- } // of have camera attribute
-
- return result;
-}
-
-Qt3DCore::QEntity* GLTFParser::scene(const QString &id)
-{
- parse();
-
- QJsonObject scenes = m_json.object().value(KEY_SCENES).toObject();
- if (!scenes.contains(id)) {
- if (!id.isNull())
- qCWarning(GLTFParserLog) << "GLTF: no such scene" << id << "in file" << m_basePath;
- return defaultScene();
- }
-
- QJsonObject sceneObj = scenes.value(id).toObject();
- QEntity* sceneEntity = new QEntity;
- Q_FOREACH (QJsonValue nnv, sceneObj.value(KEY_NODES).toArray()) {
- QString nodeName = nnv.toString();
- QEntity* child = node(nodeName);
- if (!child)
- continue;
- child->setParent(sceneEntity);
- }
-
- return sceneEntity;
-}
-
-GLTFParser::BufferData::BufferData()
- : length(0)
- , data(nullptr)
-{
-}
-
-GLTFParser::BufferData::BufferData(QJsonObject json)
-{
- path = json.value(KEY_URI).toString();
- length = json.value(KEY_BYTE_LENGTH).toInt();
- data = nullptr;
-}
-
-GLTFParser::ParameterData::ParameterData() :
- type(0)
-{
-
-}
-
-GLTFParser::ParameterData::ParameterData(QJsonObject json)
-{
- type = json.value(KEY_TYPE).toInt();
- semantic = json.value(KEY_SEMANTIC).toString();
-}
-
-GLTFParser::AccessorData::AccessorData()
- : type(QAttribute::Float)
- , dataSize(0)
- , count(0)
- , offset(0)
- , stride(0)
-{
-
-}
-
-GLTFParser::AccessorData::AccessorData(const QJsonObject &json)
-{
- bufferViewName = json.value(KEY_BUFFER_VIEW).toString();
- offset = 0;
- stride = 0;
- int componentType = json.value(KEY_COMPONENT_TYPE).toInt();
- type = accessorTypeFromJSON(componentType);
- count = json.value(KEY_COUNT).toInt();
- dataSize = accessorDataSizeFromJson(json.value(KEY_TYPE).toString());
-
- if ( json.contains(KEY_BYTE_OFFSET))
- offset = json.value(KEY_BYTE_OFFSET).toInt();
- if ( json.contains(KEY_BYTE_STRIDE))
- stride = json.value(KEY_BYTE_STRIDE).toInt();
-}
-
-bool GLTFParser::isGLTFPath(const QString& path)
-{
- QFileInfo finfo(path);
- if (!finfo.exists())
- return false;
-
- // might need to detect other things in the future, but would
- // prefer to avoid doing a full parse.
- QString suffix = finfo.suffix().toLower();
- return (suffix == QStringLiteral("json") || suffix == QStringLiteral("gltf") || suffix == QStringLiteral("qgltf"));
-}
-
-void GLTFParser::renameFromJson(const QJsonObject &json, QObject * const object)
-{
- if ( json.contains(KEY_NAME) )
- object->setObjectName( json.value(KEY_NAME).toString() );
-}
-
-QString GLTFParser::standardUniformNamefromSemantic(const QString &semantic)
-{
- //Standard Uniforms
- //if (semantic == QStringLiteral("LOCAL"));
- if (semantic == QStringLiteral("MODEL"))
- return QStringLiteral("modelMatrix");
- if (semantic == QStringLiteral("VIEW"))
- return QStringLiteral("viewMatrix");
- if (semantic == QStringLiteral("PROJECTION"))
- return QStringLiteral("projectionMatrix");
- if (semantic == QStringLiteral("MODELVIEW"))
- return QStringLiteral("modelView");
- if (semantic == QStringLiteral("MODELVIEWPROJECTION"))
- return QStringLiteral("modelViewProjection");
- if (semantic == QStringLiteral("MODELINVERSE"))
- return QStringLiteral("inverseModelMatrix");
- if (semantic == QStringLiteral("VIEWINVERSE"))
- return QStringLiteral("inverViewMatrix");
- if (semantic == QStringLiteral("PROJECTIONINVERSE"))
- return QStringLiteral("inverseProjectionMatrix");
- if (semantic == QStringLiteral("MODELVIEWPROJECTIONINVERSE"))
- return QStringLiteral("inverseModelViewProjection");
- if (semantic == QStringLiteral("MODELINVERSETRANSPOSE"))
- return QStringLiteral("modelNormalMatrix");
- if (semantic == QStringLiteral("MODELVIEWINVERSETRANSPOSE"))
- return QStringLiteral("modelViewNormal");
- if (semantic == QStringLiteral("VIEWPORT"))
- return QStringLiteral("viewportMatrix");
-
- return QString();
-}
-
-QString GLTFParser::standardAttributeNameFromSemantic(const QString &semantic)
-{
- //Standard Attributes
- if (semantic.startsWith(QStringLiteral("POSITION")))
- return QAttribute::defaultPositionAttributeName();
- if (semantic.startsWith(QStringLiteral("NORMAL")))
- return QAttribute::defaultNormalAttributeName();
- if (semantic.startsWith(QStringLiteral("TEXCOORD")))
- return QAttribute::defaultTextureCoordinateAttributeName();
- if (semantic.startsWith(QStringLiteral("COLOR")))
- return QAttribute::defaultColorAttributeName();
- if (semantic.startsWith(QStringLiteral("TANGENT")))
- return QAttribute::defaultTangentAttributeName();
-
-// if (semantic.startsWith(QStringLiteral("JOINT")));
-// if (semantic.startsWith(QStringLiteral("JOINTMATRIX")));
-// if (semantic.startsWith(QStringLiteral("WEIGHT")));
-
- return QString();
-}
-
-QParameter *GLTFParser::parameterFromTechnique(QTechnique *technique, const QString &parameterName)
-{
- Q_FOREACH (QParameter *parameter, technique->parameters()) {
- if (parameter->name() == parameterName) {
- return parameter;
- }
- }
-
- return nullptr;
-}
-
-Qt3DCore::QEntity* GLTFParser::defaultScene()
-{
- if (m_defaultScene.isEmpty()) {
- qCWarning(GLTFParserLog) << Q_FUNC_INFO << "no default scene";
- return NULL;
- }
-
- return scene(m_defaultScene);
-}
-
-QMaterial *GLTFParser::materialWithCustomShader(const QString &id, const QJsonObject &jsonObj)
-{
- //Default ES2 Technique
- QString techniqueName = jsonObj.value(KEY_TECHNIQUE).toString();
- if (!m_techniques.contains(techniqueName)) {
- qCWarning(GLTFParserLog) << "unknown technique" << techniqueName
- << "for material" << id << "in GLTF file" << m_basePath;
- return NULL;
- }
- QTechnique *technique = m_techniques.value(techniqueName);
- 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()) {
- if (!m_techniques.contains(coreTechniqueName)) {
- qCWarning(GLTFParserLog) << "unknown technique" << coreTechniqueName
- << "for material" << id << "in GLTF file" << m_basePath;
- } else {
- coreTechnique = m_techniques.value(coreTechniqueName);
- 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()) {
- if (!m_techniques.contains(gl2TechniqueName)) {
- qCWarning(GLTFParserLog) << "unknown technique" << gl2TechniqueName
- << "for material" << id << "in GLTF file" << m_basePath;
- } else {
- gl2Technique = m_techniques.value(gl2TechniqueName);
- 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);
-
- QJsonObject values = jsonObj.value(KEY_VALUES).toObject();
- Q_FOREACH (QString vName, values.keys()) {
- QParameter *param = parameterFromTechnique(technique, vName);
-
- if (param == nullptr && coreTechnique != nullptr) {
- param = parameterFromTechnique(coreTechnique, vName);
- }
-
- if (param == nullptr && gl2Technique != nullptr) {
- param = parameterFromTechnique(gl2Technique, vName);
- }
-
- if (param == nullptr) {
- qCWarning(GLTFParserLog) << "unknown parameter:" << vName << "in technique" << techniqueName
- << "processing material" << id;
- continue;
- }
-
- ParameterData paramData = m_parameterDataDict.value(param);
- QVariant var = parameterValueFromJSON(paramData.type, values.value(vName));
-
- mat->addParameter(new QParameter(param->name(), var));
- } // of material technique-instance values iteration
-
- return mat;
-}
-
-static inline QVariant vec4ToRgb(const QVariant &vec4Var)
-{
- const QVector4D v = vec4Var.value<QVector4D>();
- return QVariant(QColor::fromRgbF(v.x(), v.y(), v.z()));
-}
-
-QMaterial *GLTFParser::commonMaterial(const QJsonObject &jsonObj)
-{
- QVariantHash params;
- bool hasDiffuseMap = false;
- bool hasSpecularMap = false;
- bool hasNormalMap = false;
-
- QJsonObject values = jsonObj.value(KEY_VALUES).toObject();
- Q_FOREACH (const QString &vName, values.keys()) {
- const QJsonValue val = values.value(vName);
- QVariant var;
- QString propertyName = vName;
- if (vName == QStringLiteral("ambient") && val.isArray()) {
- var = vec4ToRgb(parameterValueFromJSON(GL_FLOAT_VEC4, val));
- } else if (vName == QStringLiteral("diffuse")) {
- if (val.isString()) {
- var = parameterValueFromJSON(GL_SAMPLER_2D, val);
- hasDiffuseMap = true;
- } else if (val.isArray()) {
- var = vec4ToRgb(parameterValueFromJSON(GL_FLOAT_VEC4, val));
- }
- } else if (vName == QStringLiteral("specular")) {
- if (val.isString()) {
- var = parameterValueFromJSON(GL_SAMPLER_2D, val);
- hasSpecularMap = true;
- } else if (val.isArray()) {
- var = vec4ToRgb(parameterValueFromJSON(GL_FLOAT_VEC4, val));
- }
- } else if (vName == QStringLiteral("shininess") && val.isDouble()) {
- var = parameterValueFromJSON(GL_FLOAT, val);
- } else if (vName == QStringLiteral("normalmap") && val.isString()) {
- var = parameterValueFromJSON(GL_SAMPLER_2D, val);
- propertyName = QStringLiteral("normal");
- hasNormalMap = true;
- } else if (vName == QStringLiteral("transparency")) {
- qCWarning(GLTFParserLog) << "Semi-transparent common materials are not currently supported, ignoring alpha";
- }
- if (var.isValid())
- params[propertyName] = var;
- }
-
- QMaterial *mat = nullptr;
- if (hasNormalMap) {
- if (hasSpecularMap) {
- mat = new QNormalDiffuseSpecularMapMaterial;
- } else {
- if (hasDiffuseMap)
- mat = new QNormalDiffuseMapMaterial;
- else
- qCWarning(GLTFParserLog) << "Common material with normal and specular maps needs a diffuse map as well";
- }
- } else {
- if (hasSpecularMap) {
- if (hasDiffuseMap)
- mat = new QDiffuseSpecularMapMaterial;
- else
- qCWarning(GLTFParserLog) << "Common material with specular map needs a diffuse map as well";
- } else if (hasDiffuseMap) {
- mat = new QDiffuseMapMaterial;
- } else {
- mat = new QPhongMaterial;
- }
- }
-
- if (mat) {
- for (QVariantHash::const_iterator it = params.constBegin(), itEnd = params.constEnd(); it != itEnd; ++it)
- mat->setProperty(it.key().toUtf8(), it.value());
- } else {
- qCWarning(GLTFParserLog) << "Could not find a suitable built-in material for KHR_materials_common";
- }
-
- return mat;
-}
-
-QMaterial* GLTFParser::material(const QString &id)
-{
- if (m_materialCache.contains(id))
- return m_materialCache.value(id);
-
- QJsonObject mats = m_json.object().value(KEY_MATERIALS).toObject();
- if (!mats.contains(id)) {
- qCWarning(GLTFParserLog) << "unknown material" << id << "in GLTF file" << m_basePath;
- return NULL;
- }
-
- QJsonObject jsonObj = mats.value(id).toObject();
-
- QMaterial *mat = nullptr;
-
- // Prefer common materials over custom shaders.
- if (jsonObj.contains(KEY_EXTENSIONS)) {
- QJsonObject extensions = jsonObj.value(KEY_EXTENSIONS).toObject();
- if (extensions.contains(KEY_COMMON_MAT))
- mat = commonMaterial(extensions.value(KEY_COMMON_MAT).toObject());
- }
-
- if (!mat)
- mat = materialWithCustomShader(id, jsonObj);
-
- m_materialCache[id] = mat;
- return mat;
-}
-
-QCameraLens* GLTFParser::camera(const QString &id) const
-{
- QJsonObject cams = m_json.object().value(KEY_CAMERAS).toObject();
- if (!cams.contains(id)) {
- qCWarning(GLTFParserLog) << "unknown camera" << id << "in GLTF file" << m_basePath;
- return nullptr;
- }
-
- QJsonObject jsonObj = cams.value(id).toObject();
- QString camTy = jsonObj.value(KEY_TYPE).toString();
-
- if (camTy == QStringLiteral("perspective")) {
- if (!jsonObj.contains(KEY_PERSPECTIVE)) {
- qCWarning(GLTFParserLog) << "camera:" << id << "missing 'perspective' object";
- return nullptr;
- }
-
- QJsonObject pObj = jsonObj.value(KEY_PERSPECTIVE).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();
-
- QCameraLens* result = new QCameraLens;
- result->setPerspectiveProjection(yfov, aspectRatio, frustumNear, frustumFar);
- return result;
- } else if (camTy == QStringLiteral("orthographic")) {
- qCWarning(GLTFParserLog) << Q_FUNC_INFO << "implement me";
-
- return nullptr;
- } else {
- qCWarning(GLTFParserLog) << "camera:" << id << "has unsupported type:" << camTy;
- return nullptr;
- }
-}
-
-
-void GLTFParser::parse()
-{
- if (m_parseDone)
- return;
-
- QJsonObject buffers = m_json.object().value(KEY_BUFFERS).toObject();
- Q_FOREACH (QString nm, buffers.keys()) {
- processJSONBuffer( nm, buffers.value(nm).toObject() );
- }
-
- QJsonObject views = m_json.object().value(KEY_BUFFER_VIEWS).toObject();
- loadBufferData();
- Q_FOREACH (QString nm, views.keys()) {
- processJSONBufferView( nm, views.value(nm).toObject() );
- }
- unloadBufferData();
-
- QJsonObject shaders = m_json.object().value(KEY_SHADERS).toObject();
- Q_FOREACH (QString nm, shaders.keys()) {
- processJSONShader( nm, shaders.value(nm).toObject() );
- }
-
- QJsonObject programs = m_json.object().value(KEY_PROGRAMS).toObject();
- Q_FOREACH (QString nm, programs.keys()) {
- processJSONProgram( nm, programs.value(nm).toObject() );
- }
-
- QJsonObject techniques = m_json.object().value(KEY_TECHNIQUES).toObject();
- Q_FOREACH (QString nm, techniques.keys()) {
- processJSONTechnique( nm, techniques.value(nm).toObject() );
- }
-
- QJsonObject attrs = m_json.object().value(KEY_ACCESSORS).toObject();
- Q_FOREACH (QString nm, attrs.keys()) {
- processJSONAccessor( nm, attrs.value(nm).toObject() );
- }
-
- QJsonObject meshes = m_json.object().value(KEY_MESHES).toObject();
- Q_FOREACH (QString nm, meshes.keys()) {
- processJSONMesh( nm, meshes.value(nm).toObject() );
- }
-
- QJsonObject images = m_json.object().value(KEY_IMAGES).toObject();
- Q_FOREACH (QString nm, images.keys()) {
- processJSONImage( nm, images.value(nm).toObject() );
- }
-
- QJsonObject textures = m_json.object().value(KEY_TEXTURES).toObject();
- Q_FOREACH (QString nm, textures.keys()) {
- processJSONTexture(nm, textures.value(nm).toObject() );
- }
-
- m_defaultScene = m_json.object().value(KEY_SCENE).toString();
- m_parseDone = true;
-}
-
-void GLTFParser::cleanup()
-{
- m_meshDict.clear();
- m_meshMaterialDict.clear();
- m_accessorDict.clear();
- //Check for Materials with no parent
- Q_FOREACH (QMaterial *material, m_materialCache.values()) {
- if (material->parent() == nullptr)
- delete material;
- }
- m_materialCache.clear();
- m_bufferDatas.clear();
- m_buffers.clear();
- m_shaderPaths.clear();
- //Check for ShaderPrograms with no parent
- Q_FOREACH (QShaderProgram *program, m_programs.values()) {
- if (program->parent() == nullptr)
- delete program;
- }
- m_programs.clear();
- //Check for Techniques with no parent
- Q_FOREACH (QTechnique *technique, m_techniques.values()) {
- if (technique->parent() == nullptr)
- delete technique;
- }
- m_techniques.clear();
- //Check for Textures with no parent
- Q_FOREACH (QAbstractTextureProvider *texture, m_textures.values()) {
- if (texture->parent() == nullptr)
- delete texture;
- }
- m_textures.clear();
- m_imagePaths.clear();
- m_defaultScene.clear();
- m_parameterDataDict.clear();
-}
-
-void GLTFParser::processJSONBuffer(const QString &id, const QJsonObject& json)
-{
- // simply cache buffers for lookup by buffer-views
- m_bufferDatas[id] = BufferData(json);
-}
-
-void GLTFParser::processJSONBufferView(const QString &id, const QJsonObject& json)
-{
- QString bufName = json.value(KEY_BUFFER).toString();
- if (!m_bufferDatas.contains(bufName)) {
- qCWarning(GLTFParserLog) << "unknown buffer:" << bufName << "processing view:" << id;
- return;
- }
-
- int target = json.value(KEY_TARGET).toInt();
- QBuffer::BufferType ty(QBuffer::VertexBuffer);
-
- switch (target) {
- case GL_ARRAY_BUFFER: ty = QBuffer::VertexBuffer; break;
- case GL_ELEMENT_ARRAY_BUFFER: ty = QBuffer::IndexBuffer; break;
- default:
- qCWarning(GLTFParserLog) << Q_FUNC_INFO << "buffer" << id << "unsupported target:" << target;
- return;
- }
-
- quint64 offset = 0;
- if (json.contains(KEY_BYTE_OFFSET)) {
- offset = json.value(KEY_BYTE_OFFSET).toInt();
- qCDebug(GLTFParserLog) << "bv:" << id << "has offset:" << offset;
- }
-
- quint64 len = json.value(KEY_BYTE_LENGTH).toInt();
-
- QByteArray bytes(m_bufferDatas[bufName].data->mid(offset, len));
- if (bytes.count() != (int) len) {
- qCWarning(GLTFParserLog) << "failed to read sufficient bytes from:" << m_bufferDatas[bufName].path
- << "for view" << id;
- }
-
- QBuffer *b(new QBuffer(ty));
- b->setData(bytes);
- m_buffers[id] = b;
-}
-
-void GLTFParser::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();
-
- QFileInfo info(m_basePath, path);
- if (!info.exists()) {
- qCWarning(GLTFParserLog) << "can't find shader" << id << "from path" << path;
- return;
- }
-
- m_shaderPaths[id] = info.absoluteFilePath();
-}
-
-void GLTFParser::processJSONProgram(const QString &id, const QJsonObject &jsonObject)
-{
- QShaderProgram* prog = new QShaderProgram;
- prog->setObjectName(id);
-
- QString fragName = jsonObject.value(KEY_FRAGMENT_SHADER).toString(),
- vertName = jsonObject.value(KEY_VERTEX_SHADER).toString();
- if (!m_shaderPaths.contains(fragName) || !m_shaderPaths.contains(vertName)) {
- qCWarning(GLTFParserLog) << Q_FUNC_INFO << "program:" << id << "missing shader:"
- << fragName << vertName;
- return;
- }
-
- prog->setFragmentShaderCode(QShaderProgram::loadSource(QUrl::fromLocalFile(m_shaderPaths[fragName])));
- prog->setVertexShaderCode(QShaderProgram::loadSource(QUrl::fromLocalFile(m_shaderPaths[vertName])));
- m_programs[id] = prog;
-}
-
-void GLTFParser::processJSONTechnique(const QString &id, const QJsonObject &jsonObject )
-{
- QTechnique *t = new QTechnique;
- t->setObjectName(id);
-
- // Parameters
- QHash<QString, QParameter*> paramDict;
- QJsonObject params = jsonObject.value(KEY_PARAMETERS).toObject();
- Q_FOREACH (QString pname, params.keys()) {
- QJsonObject po = params.value(pname).toObject();
-
- //QString semantic = po.value(KEY_SEMANTIC).toString();
- QParameter *p = new QParameter(t);
- p->setName(pname);
- m_parameterDataDict.insert(p, ParameterData(po));
-
- //If the parameter has default value, set it
- QJsonValue value = po.value(KEY_VALUE);
- if (!value.isUndefined()) {
- int dataType = po.value(KEY_TYPE).toInt();
- p->setValue(parameterValueFromJSON(dataType, value));
- }
-
- t->addParameter(p);
-
- paramDict[pname] = p;
- } // of parameters iteration
-
- // Program
- QString programName = jsonObject.value(KEY_PROGRAM).toString();
- if (!m_programs.contains(programName)) {
- qCWarning(GLTFParserLog) << Q_FUNC_INFO << "technique" << id
- << ": missing program" << programName;
- }
-
- QRenderPass* pass = new QRenderPass;
- pass->setShaderProgram(m_programs[programName]);
-
- // Attributes
- QJsonObject attrs = jsonObject.value(KEY_ATTRIBUTES).toObject();
- Q_FOREACH ( QString shaderAttributeName, attrs.keys() ) {
- QString pname = attrs.value(shaderAttributeName).toString();
- QParameter *parameter = paramDict.value(pname, nullptr);
- QString attributeName = pname;
- if (parameter == nullptr) {
- qCWarning(GLTFParserLog) << Q_FUNC_INFO << "attribute " << pname
- << "defined in instanceProgram but not as parameter";
- continue;
- }
- //Check if the parameter has a standard attribute semantic
- QString standardAttributeName = standardAttributeNameFromSemantic(m_parameterDataDict[parameter].semantic);
- if (!standardAttributeName.isNull()) {
- attributeName = standardAttributeName;
- t->removeParameter(parameter);
- m_parameterDataDict.remove(parameter);
- delete parameter;
- }
-
- pass->addBinding(new QParameterMapping(attributeName, shaderAttributeName, QParameterMapping::Attribute));
- } // of program-instance attributes
-
- // Uniforms
- QJsonObject uniforms = jsonObject.value(KEY_UNIFORMS).toObject();
- Q_FOREACH (QString shaderUniformName, uniforms.keys()) {
- QString pname = uniforms.value(shaderUniformName).toString();
- QParameter *parameter = paramDict.value(pname, nullptr);
- if (parameter == nullptr) {
- qCWarning(GLTFParserLog) << Q_FUNC_INFO << "uniform " << pname
- << "defined in instanceProgram but not as parameter";
- continue;
- }
- //Check if the parameter has a standard uniform semantic
- QString standardUniformName = standardUniformNamefromSemantic(m_parameterDataDict[parameter].semantic);
- if (standardUniformName.isNull()) {
- pass->addBinding(new QParameterMapping(pname, shaderUniformName, QParameterMapping::Uniform));
- } else {
- pass->addBinding(new QParameterMapping(standardUniformName, shaderUniformName, QParameterMapping::StandardUniform));
- t->removeParameter(parameter);
- m_parameterDataDict.remove(parameter);
- delete parameter;
- }
- } // of program-instance uniforms
-
-
- // States
- QJsonObject states = jsonObject.value(KEY_STATES).toObject();
-
- //Process states to enable
- QJsonArray enableStatesArray = states.value(KEY_ENABLE).toArray();
- QVector<int> enableStates;
- Q_FOREACH (QJsonValue enableValue, enableStatesArray) {
- enableStates.append(enableValue.toInt());
- }
-
- //Process the list of state functions
- QJsonObject functions = states.value(KEY_FUNCTIONS).toObject();
- Q_FOREACH (QString functionName, functions.keys()) {
- int enableStateType = 0;
- QRenderState *renderState = buildState(functionName, functions.value(functionName), 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
- Q_FOREACH (int enableState, enableStates) {
- QRenderState *renderState = buildStateEnable(enableState);
- if (renderState != nullptr)
- pass->addRenderState(renderState);
- }
-
-
- t->addPass(pass);
-
- m_techniques[id] = t;
-}
-
-void GLTFParser::processJSONAccessor( const QString &id, const QJsonObject& json )
-{
- m_accessorDict[id] = AccessorData(json);
-}
-
-void GLTFParser::processJSONMesh(const QString &id, const QJsonObject &json)
-{
- QJsonArray primitivesArray = json.value(KEY_PRIMITIVES).toArray();
- Q_FOREACH (QJsonValue primitiveValue, primitivesArray) {
- QJsonObject primitiveObject = primitiveValue.toObject();
- int type = primitiveObject.value(KEY_MODE).toInt();
- QString material = primitiveObject.value(KEY_MATERIAL).toString();
-
- if ( material.isEmpty()) {
- qCWarning(GLTFParserLog) << "malformed primitive on " << id << ", missing material value"
- << material;
- continue;
- }
-
- QGeometryRenderer *geometryRenderer = new QGeometryRenderer;
- QGeometry *meshGeometry = new QGeometry(geometryRenderer);
-
- //Set Primitive Type
- geometryRenderer->setPrimitiveType(static_cast<QGeometryRenderer::PrimitiveType>(type));
-
- //Save Material for mesh
- m_meshMaterialDict[geometryRenderer] = material;
-
- QJsonObject attrs = primitiveObject.value(KEY_ATTRIBUTES).toObject();
- Q_FOREACH (QString attrName, attrs.keys()) {
- QString k = attrs.value(attrName).toString();
- if (!m_accessorDict.contains(k)) {
- qCWarning(GLTFParserLog) << "unknown attribute accessor:" << k << "on mesh" << id;
- continue;
- }
-
- QString attributeName = standardAttributeNameFromSemantic(attrName);
- if (attributeName.isEmpty())
- attributeName = attrName;
-
- //Get buffer handle for accessor
- QBuffer *buffer = m_buffers.value(m_accessorDict[k].bufferViewName, nullptr);
- if (buffer == nullptr) {
- qCWarning(GLTFParserLog) << "unknown buffer-view:" << m_accessorDict[k].bufferViewName << "processing accessor:" << id;
- continue;
- }
-
- QAttribute *attribute = new QAttribute(buffer,
- attributeName,
- m_accessorDict[k].type,
- m_accessorDict[k].dataSize,
- m_accessorDict[k].count,
- m_accessorDict[k].offset,
- m_accessorDict[k].stride);
- attribute->setAttributeType(QAttribute::VertexAttribute);
- meshGeometry->addAttribute(attribute);
- }
-
- if ( primitiveObject.contains(KEY_INDICES)) {
- QString k = primitiveObject.value(KEY_INDICES).toString();
- if (!m_accessorDict.contains(k)) {
- qCWarning(GLTFParserLog) << "unknown index accessor:" << k << "on mesh" << id;
- } else {
- //Get buffer handle for accessor
- QBuffer *buffer = m_buffers.value(m_accessorDict[k].bufferViewName, nullptr);
- if (buffer == nullptr) {
- qCWarning(GLTFParserLog) << "unknown buffer-view:" << m_accessorDict[k].bufferViewName << "processing accessor:" << id;
- continue;
- }
-
- QAttribute *attribute = new QAttribute(buffer,
- m_accessorDict[k].type,
- m_accessorDict[k].dataSize,
- m_accessorDict[k].count,
- m_accessorDict[k].offset,
- m_accessorDict[k].stride);
- attribute->setAttributeType(QAttribute::IndexAttribute);
- meshGeometry->addAttribute(attribute);
- }
- } // of has indices
-
- geometryRenderer->setGeometry(meshGeometry);
-
- m_meshDict.insert( id, geometryRenderer);
- } // of primitives iteration
-}
-
-void GLTFParser::processJSONImage(const QString &id, const QJsonObject &jsonObject)
-{
- QString path = jsonObject.value(KEY_URI).toString();
- QFileInfo info(m_basePath, path);
- if (!info.exists()) {
- qCWarning(GLTFParserLog) << "can't find image" << id << "from path" << path;
- return;
- }
-
- m_imagePaths[id] = info.absoluteFilePath();
-}
-
-void GLTFParser::processJSONTexture(const QString &id, const QJsonObject &jsonObject)
-{
- int target = jsonObject.value(KEY_TARGET).toInt(GL_TEXTURE_2D);
- //TODO: support other targets that GL_TEXTURE_2D (though the spec doesn't support anything else)
- if (target != GL_TEXTURE_2D) {
- qCWarning(GLTFParserLog) << "unsupported texture target: " << 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 = jsonObject.value(KEY_INTERNAL_FORMAT).toInt(GL_RGBA);
-
- tex->setFormat(static_cast<QAbstractTextureProvider::TextureFormat>(internalFormat));
-
- QString samplerId = jsonObject.value(KEY_SAMPLER).toString();
- QString source = jsonObject.value(KEY_SOURCE).toString();
- if (!m_imagePaths.contains(source)) {
- qCWarning(GLTFParserLog) << "texture" << id << "references missing image" << source;
- return;
- }
-
- QTextureImage *texImage = new QTextureImage(tex);
- texImage->setSource(QUrl::fromLocalFile(m_imagePaths[source]));
- tex->addTextureImage(texImage);
-
- QJsonObject samplersDict(m_json.object().value(KEY_SAMPLERS).toObject());
- if (!samplersDict.contains(samplerId)) {
- qCWarning(GLTFParserLog) << "texture" << id << "references unknown sampler" << samplerId;
- return;
- }
-
- QJsonObject sampler = samplersDict.value(samplerId).toObject();
-
- tex->setWrapMode(QTextureWrapMode(static_cast<QTextureWrapMode::WrapMode>(sampler.value(KEY_WRAP_S).toInt())));
- tex->setMinificationFilter(static_cast<QAbstractTextureProvider::Filter>(sampler.value(KEY_MIN_FILTER).toInt()));
- if (tex->minificationFilter() == QAbstractTextureProvider::NearestMipMapLinear ||
- tex->minificationFilter() == QAbstractTextureProvider::LinearMipMapNearest ||
- tex->minificationFilter() == QAbstractTextureProvider::NearestMipMapNearest ||
- tex->minificationFilter() == QAbstractTextureProvider::LinearMipMapLinear) {
-
- tex->setGenerateMipMaps(true);
- }
- tex->setMagnificationFilter(static_cast<QAbstractTextureProvider::Filter>(sampler.value(KEY_MAG_FILTER).toInt()));
-
- m_textures[id] = tex;
-}
-
-void GLTFParser::loadBufferData()
-{
- Q_FOREACH (QString bufferName, m_bufferDatas.keys()) {
- if (m_bufferDatas[bufferName].data == nullptr) {
- QFile* bufferFile = resolveLocalData(m_bufferDatas[bufferName].path);
- QByteArray *data = new QByteArray(bufferFile->readAll());
- m_bufferDatas[bufferName].data = data;
- delete bufferFile;
- }
- }
-}
-
-void GLTFParser::unloadBufferData()
-{
- Q_FOREACH (QString bufferName, m_bufferDatas.keys()) {
- QByteArray *data = m_bufferDatas[bufferName].data;
- delete data;
- }
-}
-
-QFile *GLTFParser::resolveLocalData(QString path) const
-{
- QDir d(m_basePath);
- Q_ASSERT(d.exists());
-
- QString absPath = d.absoluteFilePath(path);
- QFile* f = new QFile(absPath);
- f->open(QIODevice::ReadOnly);
- return f;
-}
-
-QVariant GLTFParser::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
- //QAbstractTextureProvider
- QString textureId = value.toString();
- if (!m_textures.contains(textureId)) {
- qCWarning(GLTFParserLog) << "unknown texture" << textureId;
- return QVariant();
- } else {
- return QVariant::fromValue(m_textures.value(textureId));
- }
- }
- } 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()));
- }
- } else if (value.isArray()) {
-
- 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::DataType GLTFParser::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(GLTFParserLog) << "unsupported accessor type" << componentType;
- return QAttribute::Float;
-}
-
-uint GLTFParser::accessorDataSizeFromJson(const QString &type)
-{
- QString typeName = type.toUpper();
- if (typeName == "SCALAR")
- return 1;
- if (typeName == "VEC2")
- return 2;
- if (typeName == "VEC3")
- return 3;
- if (typeName == "VEC4")
- return 4;
- if (typeName == "MAT2")
- return 4;
- if (typeName == "MAT3")
- return 9;
- if (typeName == "MAT4")
- return 16;
-
- return 0;
-}
-
-QRenderState *GLTFParser::buildStateEnable(int state)
-{
- int type = 0;
- //By calling buildState with QJsonValue(), a Render State with
- //default values is created.
-
- if (state == GL_BLEND) {
- //It doesn't make sense to handle this state alone
- return nullptr;
- }
-
- if (state == GL_CULL_FACE) {
- return buildState(QStringLiteral("cullFace"), QJsonValue(), type);
- }
-
- if (state == GL_DEPTH_TEST) {
- return buildState(QStringLiteral("depthFunc"), QJsonValue(), type);
- }
-
- if (state == GL_POLYGON_OFFSET_FILL) {
- return buildState(QStringLiteral("polygonOffset"), QJsonValue(), type);
- }
-
- if (state == GL_SAMPLE_ALPHA_TO_COVERAGE) {
- return new QAlphaCoverage();
- }
-
- if (state == GL_SCISSOR_TEST) {
- return buildState(QStringLiteral("scissor"), QJsonValue(), type);
- }
-
- qCWarning(GLTFParserLog) << Q_FUNC_INFO << "unsupported render state:" << state;
-
- return nullptr;
-}
-
-QRenderState* GLTFParser::buildState(const QString& functionName, const QJsonValue &value, int &type)
-{
- type = -1;
- QJsonArray values = value.toArray();
-
- if (functionName == QStringLiteral("blendColor")) {
- type = GL_BLEND;
- //TODO: support render state blendColor
- qCWarning(GLTFParserLog) << Q_FUNC_INFO << "unsupported render state:" << functionName;
- return nullptr;
- }
-
- if (functionName == QStringLiteral("blendEquationSeparate")) {
- type = GL_BLEND;
- //TODO: support settings blendEquation alpha
- QBlendEquation *blendEquation = new QBlendEquation;
- blendEquation->setMode((QBlendEquation::BlendMode)values.at(0).toInt(GL_FUNC_ADD));
- return blendEquation;
- }
-
- if (functionName == QStringLiteral("blendFuncSeparate")) {
- type = GL_BLEND;
- QBlendStateSeparate *blendState = new QBlendStateSeparate;
- blendState->setSrcRGB((QBlendState::Blending)values.at(0).toInt(GL_ONE));
- blendState->setSrcAlpha((QBlendState::Blending)values.at(1).toInt(GL_ONE));
- blendState->setDstRGB((QBlendState::Blending)values.at(2).toInt(GL_ZERO));
- blendState->setDstAlpha((QBlendState::Blending)values.at(3).toInt(GL_ZERO));
- return blendState;
- }
-
- if (functionName == QStringLiteral("colorMask")) {
- QColorMask *colorMask = new QColorMask;
- colorMask->setRed(values.at(0).toBool(true));
- colorMask->setGreen(values.at(1).toBool(true));
- colorMask->setBlue(values.at(2).toBool(true));
- colorMask->setAlpha(values.at(3).toBool(true));
- return colorMask;
- }
-
- if (functionName == QStringLiteral("cullFace")) {
- type = GL_CULL_FACE;
- QCullFace *cullFace = new QCullFace;
- cullFace->setMode((QCullFace::CullingMode)values.at(0).toInt(GL_BACK));
- return cullFace;
- }
-
- if (functionName == QStringLiteral("depthFunc")) {
- type = GL_DEPTH_TEST;
- QDepthTest *depthTest = new QDepthTest;
- depthTest->setFunc((QDepthTest::DepthFunc)values.at(0).toInt(GL_LESS));
- return depthTest;
- }
-
- if (functionName == QStringLiteral("depthMask")) {
- QDepthMask *depthMask = new QDepthMask;
- depthMask->setMask(values.at(0).toBool(true));
- }
-
- if (functionName == QStringLiteral("depthRange")) {
- //TODO: support render state depthRange
- qCWarning(GLTFParserLog) << Q_FUNC_INFO << "unsupported render state:" << functionName;
- return nullptr;
- }
-
- if (functionName == QStringLiteral("frontFace")) {
- QFrontFace *frontFace = new QFrontFace;
- frontFace->setDirection((QFrontFace::FaceDir)values.at(0).toInt(GL_CCW));
- return frontFace;
- }
-
- if (functionName == QStringLiteral("lineWidth")) {
- //TODO: support render state lineWidth
- qCWarning(GLTFParserLog) << Q_FUNC_INFO << "unsupported render state:" << functionName;
- return nullptr;
- }
-
- if (functionName == QStringLiteral("polygonOffset")) {
- type = GL_POLYGON_OFFSET_FILL;
- QPolygonOffset *polygonOffset = new QPolygonOffset;
- polygonOffset->setFactor((float)values.at(0).toDouble(0.0f));
- polygonOffset->setUnits((float)values.at(1).toDouble(0.0f));
- return polygonOffset;
- }
-
- if (functionName == QStringLiteral("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;
- }
-
- qCWarning(GLTFParserLog) << Q_FUNC_INFO << "unsupported render state:" << functionName;
- return nullptr;
-}
-
-} // namespace Qt3DRender
-
-QT_END_NAMESPACE