summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Nichols <andy.nichols@theqtcompany.com>2015-11-11 15:21:11 +0100
committerLaszlo Agocs <laszlo.agocs@theqtcompany.com>2015-11-13 09:59:45 +0000
commit70581c93743ea60188192107d5f78ede274f247e (patch)
treeb398d4f724e9c8aafb6b06bbfe3a51177e869e75
parentc40cdff485f24fba57a7e5f671699ab386f0351b (diff)
gltfparser: Update to support glTF 1.0draft spec
Change-Id: I00e830e05c393e2e137db26b5443de5ec26870c5 Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
-rw-r--r--src/plugins/sceneparsers/gltf/gltfparser.cpp232
1 files changed, 145 insertions, 87 deletions
diff --git a/src/plugins/sceneparsers/gltf/gltfparser.cpp b/src/plugins/sceneparsers/gltf/gltfparser.cpp
index 5c21604bc..c35a08fb6 100644
--- a/src/plugins/sceneparsers/gltf/gltfparser.cpp
+++ b/src/plugins/sceneparsers/gltf/gltfparser.cpp
@@ -47,7 +47,10 @@
#include <Qt3DCore/QCameraLens>
#include <Qt3DCore/QEntity>
#include <Qt3DCore/QMatrixTransform>
+#include <Qt3DCore/QRotateTransform>
+#include <Qt3DCore/QScaleTransform>
#include <Qt3DCore/QTransform>
+#include <Qt3DCore/QTranslateTransform>
#include <Qt3DCore/private/qurlhelper_p.h>
@@ -90,6 +93,9 @@ 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");
@@ -115,7 +121,7 @@ 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_PRIMITIVE = QStringLiteral("primitive");
+const QString KEY_MODE = QStringLiteral("mode");
const QString KEY_MATERIAL = QStringLiteral("material");
const QString KEY_ATTRIBUTES = QStringLiteral("attributes");
const QString KEY_INDICES = QStringLiteral("indices");
@@ -274,6 +280,9 @@ Qt3DCore::QEntity* GLTFParser::node(const QString &id)
renameFromJson(jsonObj, result);
+
+ // Node Transforms
+ Qt3DCore::QTransform *trans = Q_NULLPTR;
if ( jsonObj.contains(KEY_MATRIX) ) {
QMatrix4x4 m(Qt::Uninitialized);
@@ -284,11 +293,63 @@ Qt3DCore::QEntity* GLTFParser::node(const QString &id)
}
// ADD MATRIX TRANSFORM COMPONENT TO ENTITY
- Qt3DCore::QTransform *trans = new Qt3DCore::QTransform();
+ if ( trans == Q_NULLPTR)
+ trans = new Qt3DCore::QTransform;
trans->addTransform(new QMatrixTransform(m));
- result->addComponent(trans);
+
+ }
+
+ // Rotation quaternion
+ if (jsonObj.contains(KEY_ROTATION)) {
+ if ( trans == Q_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());
+
+ QVector3D axis;
+ float angle;
+ quaternion.getAxisAndAngle(&axis, &angle);
+
+ Qt3DCore::QRotateTransform *rotateTransform = new Qt3DCore::QRotateTransform;
+ rotateTransform->setAxis(axis);
+ rotateTransform->setAngleDeg(angle);
+ trans->addTransform(rotateTransform);
+ }
+
+ // Translation
+ if (jsonObj.contains(KEY_TRANSLATION)) {
+ if ( trans == Q_NULLPTR)
+ trans = new Qt3DCore::QTransform;
+
+ QJsonArray translationValues = jsonObj.value(KEY_TRANSLATION).toArray();
+ Qt3DCore::QTranslateTransform *translateTransform = new Qt3DCore::QTranslateTransform;
+ translateTransform->setDx(translationValues[0].toDouble());
+ translateTransform->setDy(translationValues[1].toDouble());
+ translateTransform->setDz(translationValues[2].toDouble());
+ trans->addTransform(translateTransform);
+ }
+
+ // Scale
+ if (jsonObj.contains(KEY_SCALE)) {
+ if ( trans == Q_NULLPTR)
+ trans = new Qt3DCore::QTransform;
+
+ QJsonArray scaleValues = jsonObj.value(KEY_SCALE).toArray();
+ Qt3DCore::QScaleTransform *scaleTransform = new Qt3DCore::QScaleTransform;
+ scaleTransform->setScale3D(QVector3D(scaleValues[0].toDouble(),
+ scaleValues[1].toDouble(),
+ scaleValues[2].toDouble()));
+ trans->addTransform(scaleTransform);
}
+ // Add the Transform component
+ if (trans != Q_NULLPTR)
+ result->addComponent(trans);
+
if ( jsonObj.contains(KEY_CAMERA) ) {
QCameraLens* cam = camera( jsonObj.value(KEY_CAMERA).toString() );
if (!cam) {
@@ -482,10 +543,8 @@ QMaterial* GLTFParser::material(const QString &id)
QJsonObject jsonObj = mats.value(id).toObject();
- QJsonObject tech = jsonObj.value(KEY_INSTANCE_TECHNIQUE).toObject();
-
//Default ES2 Technique
- QString techniqueName = tech.value(KEY_TECHNIQUE).toString();
+ 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;
@@ -501,7 +560,7 @@ QMaterial* GLTFParser::material(const QString &id)
//Optional Core technique
QTechnique *coreTechnique = Q_NULLPTR;
QTechnique *gl2Technique = Q_NULLPTR;
- QString coreTechniqueName = tech.value(KEY_TECHNIQUE_CORE).toString();
+ QString coreTechniqueName = jsonObj.value(KEY_TECHNIQUE_CORE).toString();
if (!coreTechniqueName.isNull()) {
if (!m_techniques.contains(coreTechniqueName)) {
qCWarning(GLTFParserLog) << "unknown technique" << coreTechniqueName
@@ -515,7 +574,7 @@ QMaterial* GLTFParser::material(const QString &id)
}
}
//Optional GL2 technique
- QString gl2TechniqueName = tech.value(KEY_TECHNIQUE_GL2).toString();
+ QString gl2TechniqueName = jsonObj.value(KEY_TECHNIQUE_GL2).toString();
if (!gl2TechniqueName.isNull()) {
if (!m_techniques.contains(gl2TechniqueName)) {
qCWarning(GLTFParserLog) << "unknown technique" << gl2TechniqueName
@@ -548,7 +607,7 @@ QMaterial* GLTFParser::material(const QString &id)
renameFromJson(jsonObj, mat);
- QJsonObject values = tech.value(KEY_VALUES).toObject();
+ QJsonObject values = jsonObj.value(KEY_VALUES).toObject();
Q_FOREACH (QString vName, values.keys()) {
QParameter *param = parameterFromTechnique(technique, vName);
@@ -788,6 +847,7 @@ void GLTFParser::processJSONTechnique(const QString &id, const QJsonObject &json
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()) {
@@ -810,95 +870,93 @@ void GLTFParser::processJSONTechnique(const QString &id, const QJsonObject &json
paramDict[pname] = p;
} // of parameters iteration
- QJsonObject passes = jsonObject.value(KEY_PASSES).toObject();
- Q_FOREACH (QString pname, passes.keys()) {
- QJsonObject po = passes.value(pname).toObject();
- QJsonObject ip = po.value(KEY_INSTANCE_PROGRAM).toObject();
+ // Program
+ QString programName = jsonObject.value(KEY_PROGRAM).toString();
+ if (!m_programs.contains(programName)) {
+ qCWarning(GLTFParserLog) << Q_FUNC_INFO << "technique" << id
+ << ": missing program" << programName;
+ }
- QString programName = ip.value(KEY_PROGRAM).toString();
- if (!m_programs.contains(programName)) {
- qCWarning(GLTFParserLog) << Q_FUNC_INFO << "technique" << id << "pass" << pname
- << ": 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, Q_NULLPTR);
+ QString attributeName = pname;
+ if (parameter == Q_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;
+ }
- QRenderPass* pass = new QRenderPass;
- pass->setShaderProgram(m_programs[programName]);
-
- QJsonObject attrs = ip.value(KEY_ATTRIBUTES).toObject();
- Q_FOREACH ( QString shaderAttributeName, attrs.keys() ) {
- QString pname = attrs.value(shaderAttributeName).toString();
- QParameter *parameter = paramDict.value(pname, Q_NULLPTR);
- QString attributeName = pname;
- if (parameter == Q_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
+ 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, Q_NULLPTR);
+ if (parameter == Q_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
- QJsonObject uniforms = ip.value(KEY_UNIFORMS).toObject();
- Q_FOREACH (QString shaderUniformName, uniforms.keys()) {
- QString pname = uniforms.value(shaderUniformName).toString();
- QParameter *parameter = paramDict.value(pname, Q_NULLPTR);
- if (parameter == Q_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
- QJsonObject states = po.value(KEY_STATES).toObject();
+ // 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 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 != Q_NULLPTR) {
- //Remove the need to set a default state values for enableStateType
- enableStates.removeOne(enableStateType);
- pass->addRenderState(renderState);
- }
+ //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 != Q_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 != Q_NULLPTR)
- 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 != Q_NULLPTR)
+ pass->addRenderState(renderState);
+ }
- t->addPass(pass);
- } // of passes iteration
+ t->addPass(pass);
m_techniques[id] = t;
}
@@ -913,7 +971,7 @@ 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_PRIMITIVE).toInt();
+ int type = primitiveObject.value(KEY_MODE).toInt();
QString material = primitiveObject.value(KEY_MATERIAL).toString();
if ( material.isEmpty()) {