diff options
author | Mike Krus <mike.krus@kdab.com> | 2015-11-18 09:34:27 +0000 |
---|---|---|
committer | Sean Harmer <sean.harmer@kdab.com> | 2015-11-21 10:41:03 +0000 |
commit | 8970b041ecb17767c9277c8ff9df4a03cc3ae589 (patch) | |
tree | 8cb1f6c54f8d85f74edd0111bcee9e62b572ed9e /src/render/io | |
parent | 7415a4b5161bbd3956d8ba94c1b719f5b87abfd4 (diff) |
Added support for partial OBJ mesh loading
Added a subMesh string property to the QMesh class.
This is passed to the ObjLoader and, if not empty,
it will only load the sub meshes at match.
The string is assumed to be a regular expression against
which sub mesh names are matched.
If the string is not a valid regex then a valid one
is constructed.
Change-Id: Iecc39af8a41429bb924fb1e3e47d8cbdb9ff1086
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src/render/io')
-rw-r--r-- | src/render/io/objloader.cpp | 71 | ||||
-rw-r--r-- | src/render/io/objloader_p.h | 4 |
2 files changed, 53 insertions, 22 deletions
diff --git a/src/render/io/objloader.cpp b/src/render/io/objloader.cpp index 54eb45ff0..7e58ae738 100644 --- a/src/render/io/objloader.cpp +++ b/src/render/io/objloader.cpp @@ -45,6 +45,7 @@ #include <QFile> #include <QTextStream> #include <QVector> +#include <QRegExp> #include <Qt3DRender/qgeometry.h> #include <Qt3DRender/qattribute.h> @@ -68,7 +69,7 @@ ObjLoader::ObjLoader() { } -bool ObjLoader::load( const QString& fileName ) +bool ObjLoader::load(const QString& fileName , const QString &subMesh) { QFile file(fileName); if (!file.open(::QIODevice::ReadOnly|::QIODevice::Text)) { @@ -76,7 +77,7 @@ bool ObjLoader::load( const QString& fileName ) return false; } - return load(&file); + return load(&file, subMesh); } static void addFaceVertex(const FaceIndices &faceIndices, @@ -92,7 +93,7 @@ static void addFaceVertex(const FaceIndices &faceIndices, } } -bool ObjLoader::load(::QIODevice *ioDev) +bool ObjLoader::load(::QIODevice *ioDev, const QString &subMesh) { Q_CHECK_PTR(ioDev); if (!ioDev->isOpen()) { @@ -112,6 +113,16 @@ bool ObjLoader::load(::QIODevice *ioDev) QHash<FaceIndices, unsigned int> faceIndexMap; QVector<FaceIndices> faceIndexVector; + bool skipping = false; + int positionsOffset = 0; + int normalsOffset = 0; + int texCoordsOffset = 0; + + QRegExp subMeshMatch(subMesh); + if (!subMeshMatch.isValid()) + subMeshMatch.setPattern(QString(QStringLiteral("^(%1)$")).arg(subMesh)); + Q_ASSERT(subMeshMatch.isValid()); + QTextStream stream(ioDev); while (!stream.atEnd()) { QString line = stream.readLine(); @@ -123,21 +134,33 @@ bool ObjLoader::load(::QIODevice *ioDev) lineStream >> token; if (token == QStringLiteral("v")) { - float x, y, z; - lineStream >> x >> y >> z; - positions.append(QVector3D( x, y, z )); + if (!skipping) { + float x, y, z; + lineStream >> x >> y >> z; + positions.append(QVector3D( x, y, z )); + } else { + positionsOffset++; + } } else if (token == QStringLiteral("vt") && m_loadTextureCoords) { - // Process texture coordinate - float s,t; - lineStream >> s >> t; - //FlipUVs - t = 1.0f - t; - texCoords.append(QVector2D(s, t)); + if (!skipping) { + // Process texture coordinate + float s,t; + lineStream >> s >> t; + //FlipUVs + t = 1.0f - t; + texCoords.append(QVector2D(s, t)); + } else { + texCoordsOffset++; + } } else if (token == QStringLiteral("vn")) { - float x, y, z; - lineStream >> x >> y >> z; - normals.append(QVector3D( x, y, z )); - } else if (token == QStringLiteral("f")) { + if (!skipping) { + float x, y, z; + lineStream >> x >> y >> z; + normals.append(QVector3D( x, y, z )); + } else { + normalsOffset++; + } + } else if (!skipping && token == QStringLiteral("f")) { // Process face ++faceCount; QVector<FaceIndices> face; @@ -150,11 +173,11 @@ bool ObjLoader::load(::QIODevice *ioDev) QStringList indices = faceString.split(QChar::fromLatin1('/')); switch (indices.size()) { case 3: - faceIndices.normalIndex = indices.at(2).toInt() - 1; // fall through + faceIndices.normalIndex = indices.at(2).toInt() - 1 - normalsOffset; // fall through case 2: - faceIndices.texCoordIndex = indices.at(1).toInt() - 1; // fall through + faceIndices.texCoordIndex = indices.at(1).toInt() - 1 - texCoordsOffset; // fall through case 1: - faceIndices.positionIndex = indices.at(0).toInt() - 1; + faceIndices.positionIndex = indices.at(0).toInt() - 1 - positionsOffset; break; default: qCWarning(Render::Io) << "Unsupported number of indices in face element"; @@ -182,7 +205,15 @@ bool ObjLoader::load(::QIODevice *ioDev) addFaceVertex(v1, faceIndexVector, faceIndexMap); addFaceVertex(v2, faceIndexVector, faceIndexMap); } - } // end of face + + // end of face + } else if ( token == QStringLiteral("o") ) { + if (!subMesh.isEmpty() ) { + QString objName; + lineStream >> objName; + skipping = subMeshMatch.indexIn(objName) < 0; + } + } } // end of input line } // while (!stream.atEnd()) diff --git a/src/render/io/objloader_p.h b/src/render/io/objloader_p.h index 68cadfad3..a4b46a1cc 100644 --- a/src/render/io/objloader_p.h +++ b/src/render/io/objloader_p.h @@ -108,8 +108,8 @@ public: bool hasTextureCoordinates() const { return !m_texCoords.isEmpty(); } bool hasTangents() const { return !m_tangents.isEmpty(); } - bool load( const QString& fileName ); - bool load( ::QIODevice* ioDev ); + bool load( const QString& fileName, const QString& subMesh = QString() ); + bool load( ::QIODevice* ioDev, const QString& subMesh = QString() ); QVector<QVector3D> vertices() const { return m_points; } QVector<QVector3D> normals() const { return m_normals; } |