From cbaba8688171d3530859f659038a4131afd604d1 Mon Sep 17 00:00:00 2001
From: David Back <davidback@highfidelity.io>
Date: Wed, 3 Jan 2018 15:50:24 -0800
Subject: [PATCH] more texture options

---
 interface/resources/qml/js/Utils.jsc | Bin 6548 -> 6516 bytes
 libraries/fbx/src/OBJReader.cpp      | 131 +++++++++++++++++++++++----
 libraries/fbx/src/OBJReader.h        |  18 ++--
 3 files changed, 121 insertions(+), 28 deletions(-)

diff --git a/interface/resources/qml/js/Utils.jsc b/interface/resources/qml/js/Utils.jsc
index 0e4b04d46e53fb0fdea77cfc8b85627fa9276aad..8da68e4e192018ee2b4f3d835ec91f36f0161eca 100644
GIT binary patch
delta 155
zcmbPY{KZJ8u*@VmC9xz?kb!}Lk&~5STcM<00wV*14l4u0rhn_zD^;ej?k>4g!mi%G
zd7@4Wqrt?D;Y<(MCv!1|F&>zl$QaJ3FnK4VKhp!@$y`j^1h=p-FdSiFV7S7<!0?2H
zfk9^TMW$><WlIJIhBSsuh8%`e1}g@AFmwU4QW%mL5*d;ivL_d_gib!gQnNXL)kOpV
DdBiDO

delta 180
zcmW;8JqrPG9KiAK@A_XIoALs@0CnO@Nl`9F7A%U(LtQK$x|L+t^_Lf5mJ%uN!D2Uf
z0Y)2x(r5X+)0<3k95~&cH}hhEL`*t~b<h!TO=x|W-9@c@*q-;F!fta9lPjr($EJa$
zqtcM4_M|CAeU+*~Tt|&d?55zM;HBWJz&YKGp=3+I0G|<ka@c>R|LRQXGhvF2i${P@
W51R@;Gu>8oK_AsT%v-0F>BfHt$1Yz0

diff --git a/libraries/fbx/src/OBJReader.cpp b/libraries/fbx/src/OBJReader.cpp
index 1e31371178..2e4fff700c 100644
--- a/libraries/fbx/src/OBJReader.cpp
+++ b/libraries/fbx/src/OBJReader.cpp
@@ -323,33 +323,124 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) {
                 currentMaterial.specularTextureFilename = filename;
             } else if ((token == "map_bump") || (token == "bump")) {
                 currentMaterial.bumpTextureFilename = filename;
-                currentMaterial.bumpMultiplier = textureOptions.bumpMultiplier;
+                currentMaterial.bumpTextureOptions = textureOptions;
             }
         }
     }
 } 
 
+bool OBJReader::parseTextureLineFloat(QString& parser, float& result) {
+    if (parser.length() == 0) {
+        return false;
+    }
+    auto firstChar = parser[0];
+    if ((firstChar < '0' || firstChar > '9') && firstChar != '-') {
+        return false;
+    }
+    int floatEnd = parser.indexOf(' ');
+    if (floatEnd < 0) {
+        floatEnd = parser.length();
+    }
+    QString floatStr = parser.left(floatEnd);
+    try
+    {
+        result = std::stof(floatStr.toStdString());
+        parser.remove(0, floatStr.length() + 1);
+        return true;
+    }
+    catch (const std::exception& /*e*/)
+    {
+        return false;
+    }
+}
+
+bool OBJReader::parseTextureLineString(QString& parser, QByteArray& result) {
+    if (parser.length() == 0) {
+        return false;
+    }
+    int stringEnd = parser.indexOf(' ');
+    if (stringEnd < 0) {
+        stringEnd = parser.length();
+    }
+    result = parser.left(stringEnd).toUtf8();
+    parser.remove(0, result.length() + 1);
+    return true;
+}
+
 void OBJReader::parseTextureLine(const QByteArray& textureLine, QByteArray& filename, OBJMaterialTextureOptions& textureOptions) {
+    // Texture options reference http://paulbourke.net/dataformats/mtl/
+    // and https://wikivisually.com/wiki/Material_Template_Library
     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 if (parser[0] == '-') {
-            // TO DO
-        } else {
-            int fileEnd = parser.indexOf(' ');
-            if (fileEnd < 0) {
-                fileEnd = parser.length();
-            }
-            filename = parser.left(fileEnd).toUtf8();
-            parser.remove(0, filename.length() + 1);
+        if (parser.startsWith("-blendu") || parser.startsWith("-blendv")) {
+            parser.remove(0, 11); // remove through "-blendu on " or "-blendu off"
+            if (parser[0] == ' ') // extra character for space after off
+                parser.remove(0, 1);
+            #ifdef WANT_DEBUG
+            qCDebug(modelformat) << "OBJ Reader WARNING: Ignoring texture option -blendu/-blendv";
+            #endif
+        } else if (parser.startsWith("-bm")) {
+            parser.remove(0, 4); // remove through "-bm "
+            parseTextureLineFloat(parser, textureOptions.bumpMultiplier);
+        } else if (parser.startsWith("-boost")) {
+            parser.remove(0, 7); // remove through "-boost "
+            float ignore;
+            parseTextureLineFloat(parser, ignore);
+            #ifdef WANT_DEBUG
+            qCDebug(modelformat) << "OBJ Reader WARNING: Ignoring texture option -boost";
+            #endif
+        } else if (parser.startsWith("-cc")) {
+            parser.remove(0, 7); // remove through "-cc on " or "-cc off"
+            if (parser[0] == ' ') // extra character for space after off
+                parser.remove(0, 1);
+            #ifdef WANT_DEBUG
+            qCDebug(modelformat) << "OBJ Reader WARNING: Ignoring texture option -cc";
+            #endif
+        } else if (parser.startsWith("-clamp")) {
+            parser.remove(0, 10); // remove through "-clamp on " or "-clamp off"
+            if (parser[0] == ' ') // extra character for space after off
+                parser.remove(0, 1);
+            #ifdef WANT_DEBUG
+            qCDebug(modelformat) << "OBJ Reader WARNING: Ignoring texture option -clamp";
+            #endif
+        } else if (parser.startsWith("-imfchan")) {
+            parser.remove(0, 11); // remove through "-imfchan X "
+            #ifdef WANT_DEBUG
+            qCDebug(modelformat) << "OBJ Reader WARNING: Ignoring texture option -imfchan";
+            #endif
+        } else if (parser.startsWith("-mm")) {
+            parser.remove(0, 4); // remove through "-mm "
+            float ignore;
+            parseTextureLineFloat(parser, ignore);
+            parseTextureLineFloat(parser, ignore);
+            #ifdef WANT_DEBUG
+            qCDebug(modelformat) << "OBJ Reader WARNING: Ignoring texture option -mm";
+            #endif
+        } else if (parser.startsWith("-o") || parser.startsWith("-s") || parser.startsWith("-t")) {
+            parser.remove(0, 3); // remove through "-o "
+            float ignore;
+            parseTextureLineFloat(parser, ignore);
+            parseTextureLineFloat(parser, ignore);
+            parseTextureLineFloat(parser, ignore);
+            #ifdef WANT_DEBUG
+            qCDebug(modelformat) << "OBJ Reader WARNING: Ignoring texture option -o/-s/-t";
+            #endif
+        } else if (parser.startsWith("-texres")) {
+            parser.remove(0, 8); // remove through "-texres "
+            float ignore;
+            parseTextureLineFloat(parser, ignore);
+            #ifdef WANT_DEBUG
+            qCDebug(modelformat) << "OBJ Reader WARNING: Ignoring texture option -texres";
+            #endif
+        } else if (parser.startsWith("-type")) {
+            parser.remove(0, 6); // remove through "-type "
+            QByteArray ignore;
+            parseTextureLineString(parser, ignore);
+            #ifdef WANT_DEBUG
+            qCDebug(modelformat) << "OBJ Reader WARNING: Ignoring texture option -type";
+            #endif
+        } else { // assume filename
+            parseTextureLineString(parser, filename);
         }
     }
 }
@@ -818,7 +909,7 @@ FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping,
         if (!objMaterial.bumpTextureFilename.isEmpty()) {
             fbxMaterial.normalTexture.filename = objMaterial.bumpTextureFilename;
             fbxMaterial.normalTexture.isBumpmap = true;
-            fbxMaterial.bumpMultiplier = objMaterial.bumpMultiplier;
+            fbxMaterial.bumpMultiplier = objMaterial.bumpTextureOptions.bumpMultiplier;
         }
 
         modelMaterial->setEmissive(fbxMaterial.emissiveColor);
diff --git a/libraries/fbx/src/OBJReader.h b/libraries/fbx/src/OBJReader.h
index eb7376c64f..a4582d6ef4 100644
--- a/libraries/fbx/src/OBJReader.h
+++ b/libraries/fbx/src/OBJReader.h
@@ -48,6 +48,12 @@ private:
     void addFrom(const OBJFace* face, int index);
 };
 
+class OBJMaterialTextureOptions {
+public:
+    float bumpMultiplier;
+    OBJMaterialTextureOptions() : bumpMultiplier(1.0f) {}
+}
+;
 // Materials and references to material names can come in any order, and different mesh parts can refer to the same material.
 // Therefore it would get pretty hacky to try to use FBXMeshPart to store these as we traverse the files.
 class OBJMaterial {
@@ -61,17 +67,11 @@ public:
     QByteArray specularTextureFilename;
     QByteArray emissiveTextureFilename;
     QByteArray bumpTextureFilename;
-    float bumpMultiplier;
+    OBJMaterialTextureOptions bumpTextureOptions;
     int illuminationModel;
     bool used { false };
     bool userSpecifiesUV { false };
-    OBJMaterial() : shininess(0.0f), opacity(1.0f), diffuseColor(0.9f), specularColor(0.9f), emissiveColor(0.0f), bumpMultiplier(1.0f) {}
-};
-
-class OBJMaterialTextureOptions {
-public:
-    float bumpMultiplier;
-    OBJMaterialTextureOptions() : bumpMultiplier(1.0f) {}
+    OBJMaterial() : shininess(0.0f), opacity(1.0f), diffuseColor(0.9f), specularColor(0.9f), emissiveColor(0.0f), illuminationModel(0) {}
 };
 
 class OBJReader: public QObject { // QObject so we can make network requests.
@@ -95,6 +95,8 @@ private:
     bool parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, FBXGeometry& geometry,
                        float& scaleGuess, bool combineParts);
     void parseMaterialLibrary(QIODevice* device);
+    bool parseTextureLineFloat(QString& parser, float& result);
+    bool parseTextureLineString(QString& parser, QByteArray& result);
     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.