support relative paths for material images

This commit is contained in:
SamGondelman 2018-03-19 09:59:11 -07:00
parent b96f398274
commit 8ddf360c79
5 changed files with 44 additions and 43 deletions

View file

@ -157,7 +157,7 @@ void MaterialEntityItem::setMaterialURL(const QString& materialURLString, bool u
} }
if (usingUserData) { if (usingUserData) {
_parsedMaterials = NetworkMaterialResource::parseJSONMaterials(QJsonDocument::fromJson(getUserData().toUtf8())); _parsedMaterials = NetworkMaterialResource::parseJSONMaterials(QJsonDocument::fromJson(getUserData().toUtf8()), materialURLString);
// Since our material changed, the current name might not be valid anymore, so we need to update // Since our material changed, the current name might not be valid anymore, so we need to update
setCurrentMaterialName(_currentMaterialName); setCurrentMaterialName(_currentMaterialName);

View file

@ -20,7 +20,7 @@ void NetworkMaterialResource::downloadFinished(const QByteArray& data) {
parsedMaterials.reset(); parsedMaterials.reset();
if (_url.toString().contains(".json")) { if (_url.toString().contains(".json")) {
parsedMaterials = parseJSONMaterials(QJsonDocument::fromJson(data)); parsedMaterials = parseJSONMaterials(QJsonDocument::fromJson(data), _url);
} }
// TODO: parse other material types // TODO: parse other material types
@ -75,7 +75,7 @@ bool NetworkMaterialResource::parseJSONColor(const QJsonValue& array, glm::vec3&
* @property {number} materialVersion=1 - The version of the material. <em>Currently not used.</em> * @property {number} materialVersion=1 - The version of the material. <em>Currently not used.</em>
* @property {Material|Material[]} materials - The details of the material or materials. * @property {Material|Material[]} materials - The details of the material or materials.
*/ */
NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMaterials(const QJsonDocument& materialJSON) { NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMaterials(const QJsonDocument& materialJSON, const QUrl& baseUrl) {
ParsedMaterials toReturn; ParsedMaterials toReturn;
if (!materialJSON.isNull() && materialJSON.isObject()) { if (!materialJSON.isNull() && materialJSON.isObject()) {
QJsonObject materialJSONObject = materialJSON.object(); QJsonObject materialJSONObject = materialJSON.object();
@ -91,13 +91,13 @@ NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMater
QJsonArray materials = materialsValue.toArray(); QJsonArray materials = materialsValue.toArray();
for (auto material : materials) { for (auto material : materials) {
if (!material.isNull() && material.isObject()) { if (!material.isNull() && material.isObject()) {
auto parsedMaterial = parseJSONMaterial(material.toObject()); auto parsedMaterial = parseJSONMaterial(material.toObject(), baseUrl);
toReturn.networkMaterials[parsedMaterial.first] = parsedMaterial.second; toReturn.networkMaterials[parsedMaterial.first] = parsedMaterial.second;
toReturn.names.push_back(parsedMaterial.first); toReturn.names.push_back(parsedMaterial.first);
} }
} }
} else if (materialsValue.isObject()) { } else if (materialsValue.isObject()) {
auto parsedMaterial = parseJSONMaterial(materialsValue.toObject()); auto parsedMaterial = parseJSONMaterial(materialsValue.toObject(), baseUrl);
toReturn.networkMaterials[parsedMaterial.first] = parsedMaterial.second; toReturn.networkMaterials[parsedMaterial.first] = parsedMaterial.second;
toReturn.names.push_back(parsedMaterial.first); toReturn.names.push_back(parsedMaterial.first);
} }
@ -138,7 +138,7 @@ NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMater
* @property {string} lightMap - URL of light map texture image. <em>Currently not used.</em> * @property {string} lightMap - URL of light map texture image. <em>Currently not used.</em>
*/ */
// Note: See MaterialEntityItem.h for default values used in practice. // Note: See MaterialEntityItem.h for default values used in practice.
std::pair<std::string, std::shared_ptr<NetworkMaterial>> NetworkMaterialResource::parseJSONMaterial(const QJsonObject& materialJSON) { std::pair<std::string, std::shared_ptr<NetworkMaterial>> NetworkMaterialResource::parseJSONMaterial(const QJsonObject& materialJSON, const QUrl& baseUrl) {
std::string name = ""; std::string name = "";
std::shared_ptr<NetworkMaterial> material = std::make_shared<NetworkMaterial>(); std::shared_ptr<NetworkMaterial> material = std::make_shared<NetworkMaterial>();
for (auto& key : materialJSON.keys()) { for (auto& key : materialJSON.keys()) {
@ -199,57 +199,58 @@ std::pair<std::string, std::shared_ptr<NetworkMaterial>> NetworkMaterialResource
} else if (key == "albedoMap") { } else if (key == "albedoMap") {
auto value = materialJSON.value(key); auto value = materialJSON.value(key);
if (value.isString()) { if (value.isString()) {
QString urlString = value.toString();
bool useAlphaChannel = false; bool useAlphaChannel = false;
auto opacityMap = materialJSON.find("opacityMap"); auto opacityMap = materialJSON.find("opacityMap");
if (opacityMap != materialJSON.end() && opacityMap->isString() && opacityMap->toString() == value.toString()) { if (opacityMap != materialJSON.end() && opacityMap->isString() && opacityMap->toString() == urlString) {
useAlphaChannel = true; useAlphaChannel = true;
} }
material->setAlbedoMap(value.toString(), useAlphaChannel); material->setAlbedoMap(baseUrl.resolved(urlString), useAlphaChannel);
} }
} else if (key == "roughnessMap") { } else if (key == "roughnessMap") {
auto value = materialJSON.value(key); auto value = materialJSON.value(key);
if (value.isString()) { if (value.isString()) {
material->setRoughnessMap(value.toString(), false); material->setRoughnessMap(baseUrl.resolved(value.toString()), false);
} }
} else if (key == "glossMap") { } else if (key == "glossMap") {
auto value = materialJSON.value(key); auto value = materialJSON.value(key);
if (value.isString()) { if (value.isString()) {
material->setRoughnessMap(value.toString(), true); material->setRoughnessMap(baseUrl.resolved(value.toString()), true);
} }
} else if (key == "metallicMap") { } else if (key == "metallicMap") {
auto value = materialJSON.value(key); auto value = materialJSON.value(key);
if (value.isString()) { if (value.isString()) {
material->setMetallicMap(value.toString(), false); material->setMetallicMap(baseUrl.resolved(value.toString()), false);
} }
} else if (key == "specularMap") { } else if (key == "specularMap") {
auto value = materialJSON.value(key); auto value = materialJSON.value(key);
if (value.isString()) { if (value.isString()) {
material->setMetallicMap(value.toString(), true); material->setMetallicMap(baseUrl.resolved(value.toString()), true);
} }
} else if (key == "normalMap") { } else if (key == "normalMap") {
auto value = materialJSON.value(key); auto value = materialJSON.value(key);
if (value.isString()) { if (value.isString()) {
material->setNormalMap(value.toString(), false); material->setNormalMap(baseUrl.resolved(value.toString()), false);
} }
} else if (key == "bumpMap") { } else if (key == "bumpMap") {
auto value = materialJSON.value(key); auto value = materialJSON.value(key);
if (value.isString()) { if (value.isString()) {
material->setNormalMap(value.toString(), true); material->setNormalMap(baseUrl.resolved(value.toString()), true);
} }
} else if (key == "occlusionMap") { } else if (key == "occlusionMap") {
auto value = materialJSON.value(key); auto value = materialJSON.value(key);
if (value.isString()) { if (value.isString()) {
material->setOcclusionMap(value.toString()); material->setOcclusionMap(baseUrl.resolved(value.toString()));
} }
} else if (key == "scatteringMap") { } else if (key == "scatteringMap") {
auto value = materialJSON.value(key); auto value = materialJSON.value(key);
if (value.isString()) { if (value.isString()) {
material->setScatteringMap(value.toString()); material->setScatteringMap(baseUrl.resolved(value.toString()));
} }
} else if (key == "lightMap") { } else if (key == "lightMap") {
auto value = materialJSON.value(key); auto value = materialJSON.value(key);
if (value.isString()) { if (value.isString()) {
material->setLightmapMap(value.toString()); material->setLightmapMap(baseUrl.resolved(value.toString()));
} }
} }
} }

View file

@ -37,8 +37,8 @@ public:
ParsedMaterials parsedMaterials; ParsedMaterials parsedMaterials;
static ParsedMaterials parseJSONMaterials(const QJsonDocument& materialJSON); static ParsedMaterials parseJSONMaterials(const QJsonDocument& materialJSON, const QUrl& baseUrl);
static std::pair<std::string, std::shared_ptr<NetworkMaterial>> parseJSONMaterial(const QJsonObject& materialJSON); static std::pair<std::string, std::shared_ptr<NetworkMaterial>> parseJSONMaterial(const QJsonObject& materialJSON, const QUrl& baseUrl);
private: private:
static bool parseJSONColor(const QJsonValue& array, glm::vec3& color, bool& isSRGB); static bool parseJSONColor(const QJsonValue& array, glm::vec3& color, bool& isSRGB);

View file

@ -556,58 +556,58 @@ graphics::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& url, im
return nullptr; return nullptr;
} }
void NetworkMaterial::setAlbedoMap(const QString& url, bool useAlphaChannel) { void NetworkMaterial::setAlbedoMap(const QUrl& url, bool useAlphaChannel) {
auto map = fetchTextureMap(QUrl(url), image::TextureUsage::ALBEDO_TEXTURE, MapChannel::ALBEDO_MAP); auto map = fetchTextureMap(url, image::TextureUsage::ALBEDO_TEXTURE, MapChannel::ALBEDO_MAP);
if (map) { if (map) {
map->setUseAlphaChannel(useAlphaChannel); map->setUseAlphaChannel(useAlphaChannel);
setTextureMap(MapChannel::ALBEDO_MAP, map); setTextureMap(MapChannel::ALBEDO_MAP, map);
} }
} }
void NetworkMaterial::setNormalMap(const QString& url, bool isBumpmap) { void NetworkMaterial::setNormalMap(const QUrl& url, bool isBumpmap) {
auto map = fetchTextureMap(QUrl(url), isBumpmap ? image::TextureUsage::BUMP_TEXTURE : image::TextureUsage::NORMAL_TEXTURE, MapChannel::NORMAL_MAP); auto map = fetchTextureMap(url, isBumpmap ? image::TextureUsage::BUMP_TEXTURE : image::TextureUsage::NORMAL_TEXTURE, MapChannel::NORMAL_MAP);
if (map) { if (map) {
setTextureMap(MapChannel::NORMAL_MAP, map); setTextureMap(MapChannel::NORMAL_MAP, map);
} }
} }
void NetworkMaterial::setRoughnessMap(const QString& url, bool isGloss) { void NetworkMaterial::setRoughnessMap(const QUrl& url, bool isGloss) {
auto map = fetchTextureMap(QUrl(url), isGloss ? image::TextureUsage::GLOSS_TEXTURE : image::TextureUsage::ROUGHNESS_TEXTURE, MapChannel::ROUGHNESS_MAP); auto map = fetchTextureMap(url, isGloss ? image::TextureUsage::GLOSS_TEXTURE : image::TextureUsage::ROUGHNESS_TEXTURE, MapChannel::ROUGHNESS_MAP);
if (map) { if (map) {
setTextureMap(MapChannel::ROUGHNESS_MAP, map); setTextureMap(MapChannel::ROUGHNESS_MAP, map);
} }
} }
void NetworkMaterial::setMetallicMap(const QString& url, bool isSpecular) { void NetworkMaterial::setMetallicMap(const QUrl& url, bool isSpecular) {
auto map = fetchTextureMap(QUrl(url), isSpecular ? image::TextureUsage::SPECULAR_TEXTURE : image::TextureUsage::METALLIC_TEXTURE, MapChannel::METALLIC_MAP); auto map = fetchTextureMap(url, isSpecular ? image::TextureUsage::SPECULAR_TEXTURE : image::TextureUsage::METALLIC_TEXTURE, MapChannel::METALLIC_MAP);
if (map) { if (map) {
setTextureMap(MapChannel::METALLIC_MAP, map); setTextureMap(MapChannel::METALLIC_MAP, map);
} }
} }
void NetworkMaterial::setOcclusionMap(const QString& url) { void NetworkMaterial::setOcclusionMap(const QUrl& url) {
auto map = fetchTextureMap(QUrl(url), image::TextureUsage::OCCLUSION_TEXTURE, MapChannel::OCCLUSION_MAP); auto map = fetchTextureMap(url, image::TextureUsage::OCCLUSION_TEXTURE, MapChannel::OCCLUSION_MAP);
if (map) { if (map) {
setTextureMap(MapChannel::OCCLUSION_MAP, map); setTextureMap(MapChannel::OCCLUSION_MAP, map);
} }
} }
void NetworkMaterial::setEmissiveMap(const QString& url) { void NetworkMaterial::setEmissiveMap(const QUrl& url) {
auto map = fetchTextureMap(QUrl(url), image::TextureUsage::EMISSIVE_TEXTURE, MapChannel::EMISSIVE_MAP); auto map = fetchTextureMap(url, image::TextureUsage::EMISSIVE_TEXTURE, MapChannel::EMISSIVE_MAP);
if (map) { if (map) {
setTextureMap(MapChannel::EMISSIVE_MAP, map); setTextureMap(MapChannel::EMISSIVE_MAP, map);
} }
} }
void NetworkMaterial::setScatteringMap(const QString& url) { void NetworkMaterial::setScatteringMap(const QUrl& url) {
auto map = fetchTextureMap(QUrl(url), image::TextureUsage::SCATTERING_TEXTURE, MapChannel::SCATTERING_MAP); auto map = fetchTextureMap(url, image::TextureUsage::SCATTERING_TEXTURE, MapChannel::SCATTERING_MAP);
if (map) { if (map) {
setTextureMap(MapChannel::SCATTERING_MAP, map); setTextureMap(MapChannel::SCATTERING_MAP, map);
} }
} }
void NetworkMaterial::setLightmapMap(const QString& url) { void NetworkMaterial::setLightmapMap(const QUrl& url) {
auto map = fetchTextureMap(QUrl(url), image::TextureUsage::LIGHTMAP_TEXTURE, MapChannel::LIGHTMAP_MAP); auto map = fetchTextureMap(url, image::TextureUsage::LIGHTMAP_TEXTURE, MapChannel::LIGHTMAP_MAP);
if (map) { if (map) {
//map->setTextureTransform(_lightmapTransform); //map->setTextureTransform(_lightmapTransform);
//map->setLightmapOffsetScale(_lightmapParams.x, _lightmapParams.y); //map->setLightmapOffsetScale(_lightmapParams.x, _lightmapParams.y);

View file

@ -164,14 +164,14 @@ public:
NetworkMaterial(const FBXMaterial& material, const QUrl& textureBaseUrl); NetworkMaterial(const FBXMaterial& material, const QUrl& textureBaseUrl);
NetworkMaterial(const NetworkMaterial& material); NetworkMaterial(const NetworkMaterial& material);
void setAlbedoMap(const QString& url, bool useAlphaChannel); void setAlbedoMap(const QUrl& url, bool useAlphaChannel);
void setNormalMap(const QString& url, bool isBumpmap); void setNormalMap(const QUrl& url, bool isBumpmap);
void setRoughnessMap(const QString& url, bool isGloss); void setRoughnessMap(const QUrl& url, bool isGloss);
void setMetallicMap(const QString& url, bool isSpecular); void setMetallicMap(const QUrl& url, bool isSpecular);
void setOcclusionMap(const QString& url); void setOcclusionMap(const QUrl& url);
void setEmissiveMap(const QString& url); void setEmissiveMap(const QUrl& url);
void setScatteringMap(const QString& url); void setScatteringMap(const QUrl& url);
void setLightmapMap(const QString& url); void setLightmapMap(const QUrl& url);
protected: protected:
friend class Geometry; friend class Geometry;