From c5cb3543ebb6df8088edfd16c57deb6e43f0e1c4 Mon Sep 17 00:00:00 2001
From: Zach Pomerantz <zach@highfidelity.io>
Date: Tue, 1 Mar 2016 12:29:32 -0800
Subject: [PATCH 1/3] Cache inline textures under fbx

---
 .../src/model-networking/ModelCache.cpp           | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp
index 2f8e04890c..107d91ec3b 100644
--- a/libraries/model-networking/src/model-networking/ModelCache.cpp
+++ b/libraries/model-networking/src/model-networking/ModelCache.cpp
@@ -305,13 +305,17 @@ static NetworkMesh* buildNetworkMesh(const FBXMesh& mesh, const QUrl& textureBas
 }
 
 static NetworkMaterial* buildNetworkMaterial(const FBXMaterial& material, const QUrl& textureBaseUrl) {
+    // Create a local url to cache inline textures
+    auto localBaseUrl = QUrl(textureBaseUrl.url() + "/");
+
     auto textureCache = DependencyManager::get<TextureCache>();
     NetworkMaterial* networkMaterial = new NetworkMaterial();
 
     networkMaterial->_material = material._material;
 
     if (!material.diffuseTexture.filename.isEmpty()) {
-        networkMaterial->diffuseTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.diffuseTexture.filename)), DEFAULT_TEXTURE, material.diffuseTexture.content);
+        const auto& baseUrl = material.diffuseTexture.content.isEmpty() ? textureBaseUrl : localBaseUrl;
+        networkMaterial->diffuseTexture = textureCache->getTexture(baseUrl.resolved(QUrl(material.diffuseTexture.filename)), DEFAULT_TEXTURE, material.diffuseTexture.content);
         networkMaterial->diffuseTextureName = material.diffuseTexture.name;
 
         auto diffuseMap = model::TextureMapPointer(new model::TextureMap());
@@ -321,7 +325,8 @@ static NetworkMaterial* buildNetworkMaterial(const FBXMaterial& material, const
         material._material->setTextureMap(model::MaterialKey::DIFFUSE_MAP, diffuseMap);
     }
     if (!material.normalTexture.filename.isEmpty()) {
-        networkMaterial->normalTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.normalTexture.filename)), (material.normalTexture.isBumpmap ? BUMP_TEXTURE : NORMAL_TEXTURE), material.normalTexture.content);
+        const auto& baseUrl = material.normalTexture.content.isEmpty() ? textureBaseUrl : localBaseUrl;
+        networkMaterial->normalTexture = textureCache->getTexture(baseUrl.resolved(QUrl(material.normalTexture.filename)), (material.normalTexture.isBumpmap ? BUMP_TEXTURE : NORMAL_TEXTURE), material.normalTexture.content);
         networkMaterial->normalTextureName = material.normalTexture.name;
 
         auto normalMap = model::TextureMapPointer(new model::TextureMap());
@@ -330,7 +335,8 @@ static NetworkMaterial* buildNetworkMaterial(const FBXMaterial& material, const
         material._material->setTextureMap(model::MaterialKey::NORMAL_MAP, normalMap);
     }
     if (!material.specularTexture.filename.isEmpty()) {
-        networkMaterial->specularTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.specularTexture.filename)), SPECULAR_TEXTURE, material.specularTexture.content);
+        const auto& baseUrl = material.specularTexture.content.isEmpty() ? textureBaseUrl : localBaseUrl;
+        networkMaterial->specularTexture = textureCache->getTexture(baseUrl.resolved(QUrl(material.specularTexture.filename)), SPECULAR_TEXTURE, material.specularTexture.content);
         networkMaterial->specularTextureName = material.specularTexture.name;
 
         auto glossMap = model::TextureMapPointer(new model::TextureMap());
@@ -339,7 +345,8 @@ static NetworkMaterial* buildNetworkMaterial(const FBXMaterial& material, const
         material._material->setTextureMap(model::MaterialKey::GLOSS_MAP, glossMap);
     }
     if (!material.emissiveTexture.filename.isEmpty()) {
-        networkMaterial->emissiveTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.emissiveTexture.filename)), LIGHTMAP_TEXTURE, material.emissiveTexture.content);
+        const auto& baseUrl = material.emissiveTexture.content.isEmpty() ? textureBaseUrl : localBaseUrl;
+        networkMaterial->emissiveTexture = textureCache->getTexture(baseUrl.resolved(QUrl(material.emissiveTexture.filename)), LIGHTMAP_TEXTURE, material.emissiveTexture.content);
         networkMaterial->emissiveTextureName = material.emissiveTexture.name;
 
 

From 19c83e869f41d3d62efc3652e6c4aba94da79546 Mon Sep 17 00:00:00 2001
From: Zach Pomerantz <zach@highfidelity.io>
Date: Tue, 1 Mar 2016 12:31:26 -0800
Subject: [PATCH 2/3] Add helper to buildNetworkMaterial

---
 .../src/model-networking/ModelCache.cpp       | 60 ++++++++-----------
 1 file changed, 26 insertions(+), 34 deletions(-)

diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp
index 107d91ec3b..a2e3516690 100644
--- a/libraries/model-networking/src/model-networking/ModelCache.cpp
+++ b/libraries/model-networking/src/model-networking/ModelCache.cpp
@@ -309,53 +309,45 @@ static NetworkMaterial* buildNetworkMaterial(const FBXMaterial& material, const
     auto localBaseUrl = QUrl(textureBaseUrl.url() + "/");
 
     auto textureCache = DependencyManager::get<TextureCache>();
-    NetworkMaterial* networkMaterial = new NetworkMaterial();
 
+    NetworkMaterial* networkMaterial = new NetworkMaterial();
     networkMaterial->_material = material._material;
 
+    auto setupMaterialTexture = [&](const FBXTexture& texture,
+            TextureType type, model::MaterialKey::MapChannel channel,
+            NetworkTexturePointer& networkTexture, QString& networkTextureName){
+        const auto& baseUrl = texture.content.isEmpty() ? textureBaseUrl : localBaseUrl;
+        networkTexture = textureCache->getTexture(baseUrl.resolved(QUrl(texture.filename)), type, texture.content);
+        networkTextureName = texture.name;
+
+        auto map = std::make_shared<model::TextureMap>();
+        map->setTextureSource(networkTexture->_textureSource);
+        material._material->setTextureMap(channel, map);
+        return map;
+    };
+
     if (!material.diffuseTexture.filename.isEmpty()) {
-        const auto& baseUrl = material.diffuseTexture.content.isEmpty() ? textureBaseUrl : localBaseUrl;
-        networkMaterial->diffuseTexture = textureCache->getTexture(baseUrl.resolved(QUrl(material.diffuseTexture.filename)), DEFAULT_TEXTURE, material.diffuseTexture.content);
-        networkMaterial->diffuseTextureName = material.diffuseTexture.name;
-
-        auto diffuseMap = model::TextureMapPointer(new model::TextureMap());
-        diffuseMap->setTextureSource(networkMaterial->diffuseTexture->_textureSource);
+        auto diffuseMap = setupMaterialTexture(material.diffuseTexture,
+            DEFAULT_TEXTURE, model::MaterialKey::DIFFUSE_MAP,
+            networkMaterial->diffuseTexture, networkMaterial->diffuseTextureName);
         diffuseMap->setTextureTransform(material.diffuseTexture.transform);
-
-        material._material->setTextureMap(model::MaterialKey::DIFFUSE_MAP, diffuseMap);
     }
     if (!material.normalTexture.filename.isEmpty()) {
-        const auto& baseUrl = material.normalTexture.content.isEmpty() ? textureBaseUrl : localBaseUrl;
-        networkMaterial->normalTexture = textureCache->getTexture(baseUrl.resolved(QUrl(material.normalTexture.filename)), (material.normalTexture.isBumpmap ? BUMP_TEXTURE : NORMAL_TEXTURE), material.normalTexture.content);
-        networkMaterial->normalTextureName = material.normalTexture.name;
-
-        auto normalMap = model::TextureMapPointer(new model::TextureMap());
-        normalMap->setTextureSource(networkMaterial->normalTexture->_textureSource);
-
-        material._material->setTextureMap(model::MaterialKey::NORMAL_MAP, normalMap);
+        setupMaterialTexture(material.normalTexture,
+            (material.normalTexture.isBumpmap ? BUMP_TEXTURE : NORMAL_TEXTURE), model::MaterialKey::NORMAL_MAP,
+            networkMaterial->normalTexture, networkMaterial->normalTextureName);
     }
     if (!material.specularTexture.filename.isEmpty()) {
-        const auto& baseUrl = material.specularTexture.content.isEmpty() ? textureBaseUrl : localBaseUrl;
-        networkMaterial->specularTexture = textureCache->getTexture(baseUrl.resolved(QUrl(material.specularTexture.filename)), SPECULAR_TEXTURE, material.specularTexture.content);
-        networkMaterial->specularTextureName = material.specularTexture.name;
-
-        auto glossMap = model::TextureMapPointer(new model::TextureMap());
-        glossMap->setTextureSource(networkMaterial->specularTexture->_textureSource);
-
-        material._material->setTextureMap(model::MaterialKey::GLOSS_MAP, glossMap);
+        setupMaterialTexture(material.specularTexture,
+            SPECULAR_TEXTURE, model::MaterialKey::GLOSS_MAP,
+            networkMaterial->specularTexture, networkMaterial->specularTextureName);
     }
     if (!material.emissiveTexture.filename.isEmpty()) {
-        const auto& baseUrl = material.emissiveTexture.content.isEmpty() ? textureBaseUrl : localBaseUrl;
-        networkMaterial->emissiveTexture = textureCache->getTexture(baseUrl.resolved(QUrl(material.emissiveTexture.filename)), LIGHTMAP_TEXTURE, material.emissiveTexture.content);
-        networkMaterial->emissiveTextureName = material.emissiveTexture.name;
-
-
-        auto lightmapMap = model::TextureMapPointer(new model::TextureMap());
-        lightmapMap->setTextureSource(networkMaterial->emissiveTexture->_textureSource);
+        auto lightmapMap = setupMaterialTexture(material.emissiveTexture,
+            LIGHTMAP_TEXTURE, model::MaterialKey::LIGHTMAP_MAP,
+            networkMaterial->emissiveTexture, networkMaterial->emissiveTextureName);
         lightmapMap->setTextureTransform(material.emissiveTexture.transform);
         lightmapMap->setLightmapOffsetScale(material.emissiveParams.x, material.emissiveParams.y);
-
-        material._material->setTextureMap(model::MaterialKey::LIGHTMAP_MAP, lightmapMap);
     }
 
     return networkMaterial;

From d5a5ce8c70e74e51f9e047744bd7475f04c583b5 Mon Sep 17 00:00:00 2001
From: Zach Pomerantz <zach@highfidelity.io>
Date: Tue, 1 Mar 2016 13:25:10 -0800
Subject: [PATCH 3/3] Refactor helper from lambda to static fn

---
 .../src/model-networking/ModelCache.cpp       | 50 +++++++++----------
 1 file changed, 25 insertions(+), 25 deletions(-)

diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp
index a2e3516690..a3cc920a40 100644
--- a/libraries/model-networking/src/model-networking/ModelCache.cpp
+++ b/libraries/model-networking/src/model-networking/ModelCache.cpp
@@ -304,50 +304,50 @@ static NetworkMesh* buildNetworkMesh(const FBXMesh& mesh, const QUrl& textureBas
     return networkMesh;
 }
 
-static NetworkMaterial* buildNetworkMaterial(const FBXMaterial& material, const QUrl& textureBaseUrl) {
-    // Create a local url to cache inline textures
-    auto localBaseUrl = QUrl(textureBaseUrl.url() + "/");
-
+static model::TextureMapPointer setupNetworkTextureMap(const QUrl& textureBaseUrl,
+        const FBXTexture& texture, TextureType type,
+        NetworkTexturePointer& networkTexture, QString& networkTextureName) {
     auto textureCache = DependencyManager::get<TextureCache>();
 
+    // If content is inline, cache it under the fbx file, not its base url
+    const auto baseUrl = texture.content.isEmpty() ? textureBaseUrl : QUrl(textureBaseUrl.url() + "/");
+    const auto filename = baseUrl.resolved(QUrl(texture.filename));
+
+    networkTexture = textureCache->getTexture(filename, type, texture.content);
+    networkTextureName = texture.name;
+
+    auto map = std::make_shared<model::TextureMap>();
+    map->setTextureSource(networkTexture->_textureSource);
+    return map;
+}
+
+static NetworkMaterial* buildNetworkMaterial(const FBXMaterial& material, const QUrl& textureBaseUrl) {
     NetworkMaterial* networkMaterial = new NetworkMaterial();
     networkMaterial->_material = material._material;
 
-    auto setupMaterialTexture = [&](const FBXTexture& texture,
-            TextureType type, model::MaterialKey::MapChannel channel,
-            NetworkTexturePointer& networkTexture, QString& networkTextureName){
-        const auto& baseUrl = texture.content.isEmpty() ? textureBaseUrl : localBaseUrl;
-        networkTexture = textureCache->getTexture(baseUrl.resolved(QUrl(texture.filename)), type, texture.content);
-        networkTextureName = texture.name;
-
-        auto map = std::make_shared<model::TextureMap>();
-        map->setTextureSource(networkTexture->_textureSource);
-        material._material->setTextureMap(channel, map);
-        return map;
-    };
-
     if (!material.diffuseTexture.filename.isEmpty()) {
-        auto diffuseMap = setupMaterialTexture(material.diffuseTexture,
-            DEFAULT_TEXTURE, model::MaterialKey::DIFFUSE_MAP,
+        auto diffuseMap = setupNetworkTextureMap(textureBaseUrl, material.diffuseTexture, DEFAULT_TEXTURE,
             networkMaterial->diffuseTexture, networkMaterial->diffuseTextureName);
         diffuseMap->setTextureTransform(material.diffuseTexture.transform);
+        networkMaterial->_material->setTextureMap(model::MaterialKey::DIFFUSE_MAP, diffuseMap);
     }
     if (!material.normalTexture.filename.isEmpty()) {
-        setupMaterialTexture(material.normalTexture,
-            (material.normalTexture.isBumpmap ? BUMP_TEXTURE : NORMAL_TEXTURE), model::MaterialKey::NORMAL_MAP,
+        auto normalMap = setupNetworkTextureMap(textureBaseUrl, material.normalTexture,
+            (material.normalTexture.isBumpmap ? BUMP_TEXTURE : NORMAL_TEXTURE),
             networkMaterial->normalTexture, networkMaterial->normalTextureName);
+        networkMaterial->_material->setTextureMap(model::MaterialKey::NORMAL_MAP, normalMap);
     }
     if (!material.specularTexture.filename.isEmpty()) {
-        setupMaterialTexture(material.specularTexture,
-            SPECULAR_TEXTURE, model::MaterialKey::GLOSS_MAP,
+        auto glossMap = setupNetworkTextureMap(textureBaseUrl, material.specularTexture, SPECULAR_TEXTURE,
             networkMaterial->specularTexture, networkMaterial->specularTextureName);
+        networkMaterial->_material->setTextureMap(model::MaterialKey::GLOSS_MAP, glossMap);
     }
     if (!material.emissiveTexture.filename.isEmpty()) {
-        auto lightmapMap = setupMaterialTexture(material.emissiveTexture,
-            LIGHTMAP_TEXTURE, model::MaterialKey::LIGHTMAP_MAP,
+        auto lightmapMap = setupNetworkTextureMap(textureBaseUrl, material.emissiveTexture, LIGHTMAP_TEXTURE,
             networkMaterial->emissiveTexture, networkMaterial->emissiveTextureName);
         lightmapMap->setTextureTransform(material.emissiveTexture.transform);
         lightmapMap->setLightmapOffsetScale(material.emissiveParams.x, material.emissiveParams.y);
+        networkMaterial->_material->setTextureMap(model::MaterialKey::LIGHTMAP_MAP, lightmapMap);
     }
 
     return networkMaterial;