summaryrefslogtreecommitdiffstats
path: root/src/plugins/sceneformats/obj/qglobjscenehandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/sceneformats/obj/qglobjscenehandler.cpp')
-rw-r--r--src/plugins/sceneformats/obj/qglobjscenehandler.cpp468
1 files changed, 0 insertions, 468 deletions
diff --git a/src/plugins/sceneformats/obj/qglobjscenehandler.cpp b/src/plugins/sceneformats/obj/qglobjscenehandler.cpp
deleted file mode 100644
index aea28126c..000000000
--- a/src/plugins/sceneformats/obj/qglobjscenehandler.cpp
+++ /dev/null
@@ -1,468 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the Qt3D module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 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 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qglobjscenehandler.h"
-#include "qglobjscene.h"
-#include "qvector2darray.h"
-#include "qvector3darray.h"
-#include "qglbuilder.h"
-
-#include <QtCore/qiodevice.h>
-#include <QtCore/qfile.h>
-#include <QtGui/qimage.h>
-
-QT_BEGIN_NAMESPACE
-
-QGLObjSceneHandler::QGLObjSceneHandler()
- : QGLSceneFormatHandler()
- , smoothing(QGL::Faceted)
- , smoothingForced(false)
-{
-}
-
-// Documentation for OBJ and MTL files from:
-// http://www.fileformat.info/format/wavefrontobj/egff.htm
-// http://www.fileformat.info/format/material/
-
-static int objSkipWS(const QByteArray& line, int posn)
-{
- while (posn < line.size() && (line[posn] == ' ' || line[posn] == '\t'))
- ++posn;
- return posn;
-}
-
-static int objSkipNonWS(const QByteArray& line, int posn, int stopch)
-{
- while (posn < line.size() &&
- line[posn] != ' ' && line[posn] != '\t' && line[posn] != stopch)
- ++posn;
- return posn;
-}
-
-static qreal objReadFloat(const QByteArray& line, int *posn)
-{
- *posn = objSkipWS(line, *posn);
- int end = objSkipNonWS(line, *posn, 0);
- qreal value;
- if (end > *posn)
- value = qreal(line.mid(*posn, end - *posn).toDouble());
- else
- value = 0.0f;
- *posn = end;
- return value;
-}
-
-static int objReadInteger(const QByteArray& line, int *posn)
-{
- *posn = objSkipWS(line, *posn);
- int end = objSkipNonWS(line, *posn, '/');
- int value;
- if (end > *posn)
- value = line.mid(*posn, end - *posn).toInt();
- else
- value = 0;
- //*posn = objSkipNonWS(line, end, 0);
- *posn = end;
- return value;
-}
-
-static int objReadSlashInteger(const QByteArray& line, int *posn)
-{
- if (*posn >= line.size() || line[*posn] != '/')
- return 0;
- ++(*posn);
- int end = objSkipNonWS(line, *posn, '/');
- int value;
- if (end > *posn)
- value = line.mid(*posn, end - *posn).toInt();
- else
- value = 0;
- //*posn = objSkipNonWS(line, end, 0);
- *posn = end;
- return value;
-}
-
-static QColor objReadColor(const QByteArray& line, int posn)
-{
- qreal red = objReadFloat(line, &posn);
- qreal green = objReadFloat(line, &posn);
- qreal blue = objReadFloat(line, &posn);
- qreal alpha = 1.0f;
- posn = objSkipWS(line, posn);
- if (posn < line.size())
- alpha = objReadFloat(line, &posn);
- return QColor::fromRgbF(red, green, blue, alpha);
-}
-
-void QGLObjSceneHandler::decodeOptions(const QString &options)
-{
- if (options.contains(QLatin1String("ForceSmooth")))
- {
- smoothingForced = true;
- smoothing = QGL::Smooth;
- }
- else
- {
- smoothingForced = true;
- smoothing = QGL::Faceted;
- }
-}
-
-QGLAbstractScene *QGLObjSceneHandler::read()
-{
- QByteArray line;
- QByteArray keyword;
- int posn, index, count;
- int tindex, nindex;
- QVector3DArray positions;
- QVector2DArray texCoords;
- QVector3DArray normals;
- qreal x, y, z;
- quint32 fields = 0;
- QGLMaterial *material = 0;
- QGLSceneNode *defaultNode;
-
- // Create the geometry builder and start an initial Faceted section.
- QGLBuilder builder;
- builder.newSection(smoothing);
- QGLSceneNode *root = builder.sceneNode();
- palette = root->palette();
- defaultNode = root;
- defaultNode->setObjectName(QLatin1String("__main"));
- builder.pushNode();
-
- QGeometryData op;
- while (!device()->atEnd()) {
- // Read the next line, including any backslash continuations.
- line = device()->readLine().trimmed();
- while (line.endsWith('\\')) {
- line.truncate(line.size() - 1);
- if (device()->atEnd())
- break;
- line += device()->readLine().trimmed();
- }
- if (line.startsWith('#') || line.isEmpty())
- continue; // Skip comments and blank lines.
-
- // Extract the keyword at the start of the line.
- posn = 0;
- while (posn < line.size() &&
- line[posn] != ' ' && line[posn] != '\t')
- ++posn;
- keyword = line.left(posn);
-
- // Determine how to process this line from the keyword.
- if (keyword == "v") {
- x = objReadFloat(line, &posn);
- y = objReadFloat(line, &posn);
- z = objReadFloat(line, &posn);
- positions.append(x, y, z);
- } else if (keyword == "vt") {
- x = objReadFloat(line, &posn);
- y = objReadFloat(line, &posn);
- texCoords.append(x, y);
- } else if (keyword == "vn") {
- x = objReadFloat(line, &posn);
- y = objReadFloat(line, &posn);
- z = objReadFloat(line, &posn);
- normals.append(x, y, z);
- } else if (keyword == "f") {
- posn = objSkipWS(line, posn);
- count = 0;
- //QGeometryData op; //(dlist, QGL::TRIANGLE_FAN);
- op = QGeometryData(); // clear leaves field definitions
- while (posn < line.size()) {
- // Note: we currently only read the initial vertex
- // index and also use it for texture co-ordinates
- // and normals. e.g. "2/2", "3/3", etc. This will
- // need to be fixed to handle "2/1", "3/7", etc.
- index = objReadInteger(line, &posn);
- tindex = objReadSlashInteger(line, &posn);
- nindex = objReadSlashInteger(line, &posn);
- if (index < 0)
- index = positions.count() + index;
- else if (index > 0)
- --index; // Indices in obj are 1-based.
- if (index >= 0 && index < positions.count())
- op.appendVertex(positions[index]);
- if (tindex < 0)
- tindex = texCoords.count() + tindex;
- else if (tindex > 0)
- --tindex; // Indices in obj are 1-based.
- else
- tindex = -1;
- if (tindex >= 0 && tindex < texCoords.count())
- op.appendTexCoord(texCoords[tindex]);
- if (nindex < 0)
- nindex = normals.count() + nindex;
- else if (nindex > 0)
- --nindex; // Indices in obj are 1-based.
- else
- nindex = -1;
- if (nindex >= 0 && nindex < normals.count())
- op.appendNormal(normals[nindex]);
- ++count;
- posn = objSkipNonWS(line, posn, 0);
- posn = objSkipWS(line, posn);
- }
- // if geometry has already been added with a different combination
- // of fields start a new section
- // the primitive doesn't get posted to the section until op.end()
- if (op.fields() != fields)
- {
- if (fields && builder.currentNode()->count() > 0)
- builder.newSection(smoothing);
- fields = op.fields();
- }
- builder.addTriangleFan(op);
- } else if (keyword == "usemtl") {
- // Specify a material for the faces that follow.
- posn = objSkipWS(line, posn);
- QByteArray rest = line.mid(posn);
- QString materialName = QString::fromLocal8Bit(rest.constData(), rest.size());
- if (!materialName.isEmpty() &&
- materialName != QLatin1String("(null)")) {
- index = palette->indexOf(materialName);
- if (index != -1) {
- QGLSceneNode *node = builder.newNode();
- node->setMaterialIndex(index);
- QGLMaterial *material = palette->material(index);
- if (material->texture())
- node->setEffect(QGL::LitDecalTexture2D);
- else
- node->setEffect(QGL::LitMaterial);
- } else {
- qWarning() << "obj material" << materialName << "not found";
- material = 0;
- }
- }
- } else if (keyword == "mtllib") {
- // Load a material library.
- posn = objSkipWS(line, posn);
- QByteArray filename = line.mid(posn);
- loadMaterialLibrary(QString::fromLocal8Bit(filename.constData(), filename.size()));
- } else if (keyword == "s") {
- if (!smoothingForced)
- {
- // Set smoothing on or off.
- posn = objSkipWS(line, posn);
- index = objSkipNonWS(line, posn, 0);
- QByteArray arg = line.mid(posn, index - posn);
- QGL::Smoothing smooth;
- if (arg == "on" || arg == "1")
- smooth = QGL::Smooth;
- else
- smooth = QGL::Faceted;
- if (smoothing != smooth) {
- smoothing = smooth;
- builder.newSection(smooth);
- }
- }
- } else if (keyword == "g" || keyword == "o") {
- // Label the faces that follow as part of a named group or object.
- posn = objSkipWS(line, posn);
- QByteArray rest = line.mid(posn);
- QString objectName = QString::fromLocal8Bit(rest.constData(), rest.size());
- QGLSceneNode *node = builder.currentNode();
- // if content has already been added to a current group, then
- // create a new node in the scene graph for the group, otherwise
- // just label the existing group with this name
- QGLSceneNode *p = qobject_cast<QGLSceneNode*>(node->parent());
- if (node->count() > 0 && p && p->objectName().isEmpty())
- {
- node = p;
- }
- else
- {
- builder.popNode();
- node = builder.currentNode();
- builder.pushNode();
- }
- node->setObjectName(objectName);
- } else {
- qWarning() << "unsupported obj command: " << keyword.constData();
- }
- }
-
- // Create a scene from the geometry
- return new QGLObjScene(builder.finalizedSceneNode());
-}
-
-QGLAbstractScene *QGLObjSceneHandler::download()
-{
- qWarning() << "Network loading of obj files using this plugin is not implemented.";
- return NULL;
-}
-
-void QGLObjSceneHandler::loadMaterialLibrary(const QString& name)
-{
- QUrl materialUrl = url().resolved(name);
- if (materialUrl.scheme() == QLatin1String("file")) {
- QFile file(materialUrl.toLocalFile());
- if (!file.open(QIODevice::ReadOnly))
- qWarning() << "QGLObjSceneHandler::loadMaterialLibrary: could not open:" << materialUrl.toLocalFile();
- else
- loadMaterials(&file);
- } else {
- // TODO
- qWarning("QGLObjSceneHandler::loadMaterialLibrary: non-file urls not supported");
- }
-}
-
-void QGLObjSceneHandler::loadMaterials(QIODevice *device)
-{
- QByteArray line;
- QByteArray keyword;
- int posn, index;
- QGLMaterial *material = 0;
- QString materialName;
- QString textureName;
-
- while (!device->atEnd()) {
- // Read the next line, including any backslash continuations.
- line = device->readLine().trimmed();
- while (line.endsWith('\\')) {
- line.truncate(line.size() - 1);
- if (device->atEnd())
- break;
- line += device->readLine().trimmed();
- }
- if (line.startsWith('#') || line.isEmpty())
- continue; // Skip comments and blank lines.
-
- // Extract the keyword at the start of the line.
- posn = 0;
- while (posn < line.size() &&
- line[posn] != ' ' && line[posn] != '\t')
- ++posn;
- keyword = line.left(posn);
-
- // Determine how to process this line from the keyword.
- if (keyword == "newmtl") {
- // Start a new material definition.
- posn = objSkipWS(line, posn);
- QByteArray rest = line.mid(posn);
- materialName = QString::fromLocal8Bit(rest.constData(), rest.size());
- index = palette->indexOf(materialName);
- if (index != -1) {
- qWarning() << "redefining obj material:" << materialName;
- material = palette->material(index);
- } else {
- material = new QGLMaterial();
- material->setObjectName(materialName);
- palette->addMaterial(material);
- }
- } else if (keyword == "Ka") {
- // Ambient color of the material.
- if (material)
- material->setAmbientColor(objReadColor(line, posn));
- } else if (keyword == "Kd") {
- // Diffuse color of the material.
- if (material)
- material->setDiffuseColor(objReadColor(line, posn));
- } else if (keyword == "Ks") {
- // Specular color of the material.
- if (material)
- material->setSpecularColor(objReadColor(line, posn));
- } else if (keyword == "map_Kd") {
- // Texture associated with the material.
- posn = objSkipWS(line, posn);
- QByteArray rest = line.mid(posn);
- textureName = QString::fromLocal8Bit(rest.constData(), rest.size());
- QGLTexture2D *texture = loadTexture(textureName);
- if (texture) {
- index = palette->indexOf(materialName);
- if (index >= 0) {
- QGLMaterial *material = palette->material(index);
- texture->setParent(material);
- material->setTexture(texture);
- } else {
- delete texture;
- }
- }
- } else if (keyword == "d") {
- // "Dissolve factor" of the material, which is its opacity.
- if (material) {
- qreal alpha = objReadFloat(line, &posn);
- QColor ambient = material->ambientColor();
- QColor diffuse = material->diffuseColor();
- ambient.setAlphaF(alpha);
- diffuse.setAlphaF(alpha);
- material->setAmbientColor(ambient);
- material->setDiffuseColor(diffuse);
- }
- } else if (keyword == "Ns") {
- // Specular exponent of the material.
- if (material)
- material->setShininess(qRound(objReadFloat(line, &posn)));
- } else if (keyword == "illum") {
- // Illumination model - ignored at present.
- } else if (keyword == "Ni") {
- // Optical density - ignored at present.
- } else {
- qWarning() << "unsupported obj material command: " << keyword.constData();
- }
- }
-}
-
-QGLTexture2D *QGLObjSceneHandler::loadTexture(const QString& name)
-{
- QUrl textureUrl = url().resolved(name);
- if (textureUrl.scheme() == QLatin1String("file")) {
- QFile file(textureUrl.toLocalFile());
- if (!file.open(QIODevice::ReadOnly)) {
- qWarning() << "QGLObjSceneHandler::loadTexture: could not open:" << textureUrl.toLocalFile();
- return 0;
- } else {
- file.close();
- QImage image(textureUrl.toLocalFile());
- QGLTexture2D *tex = new QGLTexture2D();
- tex->setImage(image);
- return tex;
- }
- } else {
- // TODO
- qWarning("QGLObjSceneHandler::loadTexture: non-file urls not supported");
- return 0;
- }
-}
-
-QT_END_NAMESPACE