From e601f6c59f798c1730fe24c54abc27842e451b6b Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 7 Feb 2019 14:10:09 -0800 Subject: [PATCH] move material mapping to hfm prep step --- libraries/fbx/src/FBXSerializer.cpp | 2 +- libraries/fbx/src/FBXSerializer.h | 2 +- libraries/fbx/src/FBXSerializer_Material.cpp | 27 +-------- .../model-baker/ApplyMaterialMappingTask.cpp | 55 +++++++++++++++++++ .../model-baker/ApplyMaterialMappingTask.h | 27 +++++++++ .../model-baker/src/model-baker/Baker.cpp | 10 +++- 6 files changed, 93 insertions(+), 30 deletions(-) create mode 100644 libraries/model-baker/src/model-baker/ApplyMaterialMappingTask.cpp create mode 100644 libraries/model-baker/src/model-baker/ApplyMaterialMappingTask.h diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index 207ee2982d..9e7f422b40 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -1326,7 +1326,7 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr hfmModel.meshExtents.reset(); // Create the Material Library - consolidateHFMMaterials(mapping); + consolidateHFMMaterials(); // We can't allow the scaling of a given image to different sizes, because the hash used for the KTX cache is based on the original image // Allowing scaling of the same image to different sizes would cause different KTX files to target the same cache key diff --git a/libraries/fbx/src/FBXSerializer.h b/libraries/fbx/src/FBXSerializer.h index b95bb729e7..379b1ac743 100644 --- a/libraries/fbx/src/FBXSerializer.h +++ b/libraries/fbx/src/FBXSerializer.h @@ -153,7 +153,7 @@ public: QHash _hfmMaterials; QHash _materialParams; - void consolidateHFMMaterials(const QVariantHash& mapping); + void consolidateHFMMaterials(); bool _loadLightmaps { true }; float _lightmapOffset { 0.0f }; diff --git a/libraries/fbx/src/FBXSerializer_Material.cpp b/libraries/fbx/src/FBXSerializer_Material.cpp index 9caf713e75..b47329e483 100644 --- a/libraries/fbx/src/FBXSerializer_Material.cpp +++ b/libraries/fbx/src/FBXSerializer_Material.cpp @@ -75,15 +75,7 @@ HFMTexture FBXSerializer::getTexture(const QString& textureID, const QString& ma return texture; } -void FBXSerializer::consolidateHFMMaterials(const QVariantHash& mapping) { - QJsonObject materialMap; - if (mapping.contains("materialMap")) { - QByteArray materialMapValue = mapping.value("materialMap").toByteArray(); - materialMap = QJsonDocument::fromJson(materialMapValue).object(); - if (materialMap.isEmpty()) { - qCDebug(modelformat) << "fbx Material Map found but did not produce valid JSON:" << materialMapValue; - } - } +void FBXSerializer::consolidateHFMMaterials() { for (QHash::iterator it = _hfmMaterials.begin(); it != _hfmMaterials.end(); it++) { HFMMaterial& material = (*it); @@ -266,23 +258,6 @@ void FBXSerializer::consolidateHFMMaterials(const QVariantHash& mapping) { } qCDebug(modelformat) << " fbx material Name:" << material.name; - if (materialMap.contains(material.name)) { - QJsonObject materialOptions = materialMap.value(material.name).toObject(); - qCDebug(modelformat) << "Mapping fbx material:" << material.name << " with HifiMaterial: " << materialOptions; - - if (materialOptions.contains("scattering")) { - float scattering = (float) materialOptions.value("scattering").toDouble(); - material._material->setScattering(scattering); - } - - if (materialOptions.contains("scatteringMap")) { - QByteArray scatteringMap = materialOptions.value("scatteringMap").toVariant().toByteArray(); - material.scatteringTexture = HFMTexture(); - material.scatteringTexture.name = material.name + ".scatteringMap"; - material.scatteringTexture.filename = scatteringMap; - } - } - if (material.opacity <= 0.0f) { material._material->setOpacity(1.0f); } else { diff --git a/libraries/model-baker/src/model-baker/ApplyMaterialMappingTask.cpp b/libraries/model-baker/src/model-baker/ApplyMaterialMappingTask.cpp new file mode 100644 index 0000000000..c9b4fec1e1 --- /dev/null +++ b/libraries/model-baker/src/model-baker/ApplyMaterialMappingTask.cpp @@ -0,0 +1,55 @@ +// +// Created by Sam Gondelman on 2/7/2019 +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "ApplyMaterialMappingTask.h" + +#include "ModelBakerLogging.h" + +void ApplyMaterialMappingTask::run(const baker::BakeContextPointer& context, const Input& input, Output& output) { + const auto& materialsIn = input.get0(); + const auto& mapping = input.get1(); + + auto materialsOut = materialsIn; + + auto mappingIter = mapping.find("materialMap"); + if (mappingIter != mapping.end()) { + QByteArray materialMapValue = mappingIter.value().toByteArray(); + QJsonObject materialMap = QJsonDocument::fromJson(materialMapValue).object(); + if (materialMap.isEmpty()) { + qCDebug(model_baker) << "Material Map found but did not produce valid JSON:" << materialMapValue; + } else { + for (auto& material : materialsOut) { + auto materialMapIter = materialMap.find(material.name); + if (materialMapIter != materialMap.end()) { + QJsonObject materialOptions = materialMapIter.value().toObject(); + qCDebug(model_baker) << "Mapping material:" << material.name << " with HFMaterial: " << materialOptions; + + { + auto scatteringIter = materialOptions.find("scattering"); + if (scatteringIter != materialOptions.end()) { + float scattering = (float)scatteringIter.value().toDouble(); + material._material->setScattering(scattering); + } + } + + { + auto scatteringMapIter = materialOptions.find("scatteringMap"); + if (scatteringMapIter != materialOptions.end()) { + QByteArray scatteringMap = scatteringMapIter.value().toVariant().toByteArray(); + material.scatteringTexture = HFMTexture(); + material.scatteringTexture.name = material.name + ".scatteringMap"; + material.scatteringTexture.filename = scatteringMap; + } + } + } + } + } + } + + output = materialsOut; +} diff --git a/libraries/model-baker/src/model-baker/ApplyMaterialMappingTask.h b/libraries/model-baker/src/model-baker/ApplyMaterialMappingTask.h new file mode 100644 index 0000000000..271c80fe67 --- /dev/null +++ b/libraries/model-baker/src/model-baker/ApplyMaterialMappingTask.h @@ -0,0 +1,27 @@ +// +// Created by Sam Gondelman on 2/7/2019 +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_ApplyMaterialMappingTask_h +#define hifi_ApplyMaterialMappingTask_h + +#include + +#include + +#include "Engine.h" + +class ApplyMaterialMappingTask { +public: + using Input = baker::VaryingSet2, QVariantHash>; + using Output = QHash; + using JobModel = baker::Job::ModelIO; + + void run(const baker::BakeContextPointer& context, const Input& input, Output& output); +}; + +#endif // hifi_ApplyMaterialMappingTask_h \ No newline at end of file diff --git a/libraries/model-baker/src/model-baker/Baker.cpp b/libraries/model-baker/src/model-baker/Baker.cpp index 1c2a2f5c63..981d799f12 100644 --- a/libraries/model-baker/src/model-baker/Baker.cpp +++ b/libraries/model-baker/src/model-baker/Baker.cpp @@ -20,6 +20,7 @@ #include "CalculateBlendshapeNormalsTask.h" #include "CalculateBlendshapeTangentsTask.h" #include "PrepareJointsTask.h" +#include "ApplyMaterialMappingTask.h" namespace baker { @@ -101,7 +102,7 @@ namespace baker { class BuildModelTask { public: - using Input = VaryingSet5, std::vector, QMap /*jointRotationOffsets*/, QHash /*jointIndices*/>; + using Input = VaryingSet6, std::vector, QMap, QHash, QHash>; using Output = hfm::Model::Pointer; using JobModel = Job::ModelIO; @@ -111,6 +112,7 @@ namespace baker { hfmModelOut->joints = QVector::fromStdVector(input.get2()); hfmModelOut->jointRotationOffsets = input.get3(); hfmModelOut->jointIndices = input.get4(); + hfmModelOut->materials = input.get5(); output = hfmModelOut; } }; @@ -154,12 +156,16 @@ namespace baker { const auto jointRotationOffsets = jointInfoOut.getN(1); const auto jointIndices = jointInfoOut.getN(2); + // Apply material mapping + const auto materialMappingInputs = ApplyMaterialMappingTask::Input(materials, mapping).asVarying(); + const auto materialsOut = model.addJob("ApplyMaterialMapping", materialMappingInputs); + // Combine the outputs into a new hfm::Model const auto buildBlendshapesInputs = BuildBlendshapesTask::Input(blendshapesPerMeshIn, normalsPerBlendshapePerMesh, tangentsPerBlendshapePerMesh).asVarying(); const auto blendshapesPerMeshOut = model.addJob("BuildBlendshapes", buildBlendshapesInputs); const auto buildMeshesInputs = BuildMeshesTask::Input(meshesIn, graphicsMeshes, normalsPerMesh, tangentsPerMesh, blendshapesPerMeshOut).asVarying(); const auto meshesOut = model.addJob("BuildMeshes", buildMeshesInputs); - const auto buildModelInputs = BuildModelTask::Input(hfmModelIn, meshesOut, jointsOut, jointRotationOffsets, jointIndices).asVarying(); + const auto buildModelInputs = BuildModelTask::Input(hfmModelIn, meshesOut, jointsOut, jointRotationOffsets, jointIndices, materialsOut).asVarying(); hfmModelOut = model.addJob("BuildModel", buildModelInputs); } };