diff --git a/libraries/fbx/src/OBJReader.cpp b/libraries/fbx/src/OBJReader.cpp index 73c0f07fa6..d5eeec51d0 100644 --- a/libraries/fbx/src/OBJReader.cpp +++ b/libraries/fbx/src/OBJReader.cpp @@ -303,8 +303,10 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) { } else if (token == "Ks") { currentMaterial.specularColor = tokenizer.getVec3(); } else if ((token == "map_Kd") || (token == "map_Ke") || (token == "map_Ks") || (token == "map_bump")) { - QByteArray textureLine = QString(tokenizer.getLineAsDatum()).toUtf8(); - QByteArray filename = textureLine; // TODO: parse texture options and filename from line + const QByteArray textureLine = tokenizer.getLineAsDatum(); + QByteArray filename; + OBJMaterialTextureOptions textureOptions; + parseTextureLine(textureLine, filename, textureOptions); if (filename.endsWith(".tga")) { #ifdef WANT_DEBUG qCDebug(modelformat) << "OBJ Reader WARNING: currently ignoring tga texture " << filename << " in " << _url; @@ -315,13 +317,36 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) { currentMaterial.diffuseTextureFilename = filename; } else if (token == "map_Ke") { currentMaterial.emissiveTextureFilename = filename; - } else if( token == "map_Ks" ) { + } else if (token == "map_Ks" ) { currentMaterial.specularTextureFilename = filename; } else if (token == "map_bump") { currentMaterial.bumpTextureFilename = filename; } } } +} + +void OBJReader::parseTextureLine(const QByteArray& textureLine, QByteArray& filename, OBJMaterialTextureOptions& textureOptions) { + QString parser = textureLine; + while (parser.length() > 0) { + if (parser.startsWith("-bm")) { + parser.remove(0, 4); + int multiplierEnd = parser.indexOf(' '); + if (multiplierEnd < 0) { + multiplierEnd = parser.length(); + } + QString multiplier = parser.left(multiplierEnd); + textureOptions.bumpMultiplier = std::stof(multiplier.toStdString()); + parser.remove(0, multiplier.length() + 1); + } else { + int fileEnd = parser.indexOf(' '); + if (fileEnd < 0) { + fileEnd = parser.length(); + } + filename = parser.left(fileEnd).toUtf8(); + parser.remove(0, filename.length() + 1); + } + } } std::tuple requestData(QUrl& url) { diff --git a/libraries/fbx/src/OBJReader.h b/libraries/fbx/src/OBJReader.h index d0bbd539e9..2c1db7ccf7 100644 --- a/libraries/fbx/src/OBJReader.h +++ b/libraries/fbx/src/OBJReader.h @@ -66,6 +66,12 @@ public: OBJMaterial() : shininess(0.0f), opacity(1.0f), diffuseColor(0.9f), specularColor(0.9f), emissiveColor(0.0f) {} }; +class OBJMaterialTextureOptions { +public: + float bumpMultiplier; + OBJMaterialTextureOptions() : bumpMultiplier(1.0f) {} +}; + class OBJReader: public QObject { // QObject so we can make network requests. Q_OBJECT public: @@ -87,6 +93,7 @@ private: bool parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, FBXGeometry& geometry, float& scaleGuess, bool combineParts); void parseMaterialLibrary(QIODevice* device); + void parseTextureLine(const QByteArray& textureLine, QByteArray& filename, OBJMaterialTextureOptions& textureOptions); bool isValidTexture(const QByteArray &filename); // true if the file exists. TODO?: check content-type header and that it is a supported format. int _partCounter { 0 };