From 310d01feff9e62d5dd9a0f60d18bfe398006b453 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 27 Mar 2019 10:41:24 -0700 Subject: [PATCH] wip --- libraries/baking/src/FBXBaker.cpp | 4 +- libraries/baking/src/FBXBaker.h | 2 +- libraries/baking/src/ModelBaker.cpp | 40 +++++++++++++++++++- libraries/baking/src/ModelBaker.h | 6 ++- libraries/baking/src/baking/BakerLibrary.cpp | 12 +++--- libraries/baking/src/baking/BakerLibrary.h | 4 +- libraries/baking/src/baking/FSTBaker.cpp | 6 +-- libraries/baking/src/baking/FSTBaker.h | 2 +- libraries/fbx/src/OBJSerializer.cpp | 14 ++++--- tools/oven/src/BakerCLI.cpp | 5 ++- tools/oven/src/DomainBaker.cpp | 2 +- tools/oven/src/ui/ModelBakeWidget.cpp | 2 +- 12 files changed, 71 insertions(+), 28 deletions(-) diff --git a/libraries/baking/src/FBXBaker.cpp b/libraries/baking/src/FBXBaker.cpp index b7eb56c921..193b4d20ca 100644 --- a/libraries/baking/src/FBXBaker.cpp +++ b/libraries/baking/src/FBXBaker.cpp @@ -33,8 +33,8 @@ #include "ModelBakingLoggingCategory.h" #include "TextureBaker.h" -FBXBaker::FBXBaker(const QUrl& inputModelURL, const QString& bakedOutputDirectory, const QString& originalOutputDirectory, bool hasBeenBaked) : - ModelBaker(inputModelURL, bakedOutputDirectory, originalOutputDirectory, hasBeenBaked) { +FBXBaker::FBXBaker(const QUrl& inputModelURL, const QUrl& destinationPath, const QString& bakedOutputDirectory, const QString& originalOutputDirectory, bool hasBeenBaked) : + ModelBaker(inputModelURL, destinationPath, bakedOutputDirectory, originalOutputDirectory, hasBeenBaked) { if (hasBeenBaked) { // Look for the original model file one directory higher. Perhaps this is an oven output directory. QUrl originalRelativePath = QUrl("../original/" + inputModelURL.fileName().replace(BAKED_FBX_EXTENSION, FBX_EXTENSION)); diff --git a/libraries/baking/src/FBXBaker.h b/libraries/baking/src/FBXBaker.h index 5daf8a8adf..ae58a4687b 100644 --- a/libraries/baking/src/FBXBaker.h +++ b/libraries/baking/src/FBXBaker.h @@ -31,7 +31,7 @@ using TextureBakerThreadGetter = std::function; class FBXBaker : public ModelBaker { Q_OBJECT public: - FBXBaker(const QUrl& inputModelURL, const QString& bakedOutputDirectory, const QString& originalOutputDirectory = "", bool hasBeenBaked = false); + FBXBaker(const QUrl& inputModelURL, const QUrl& destinationPath, const QString& bakedOutputDirectory, const QString& originalOutputDirectory = "", bool hasBeenBaked = false); protected: virtual void bakeProcessedSource(const hfm::Model::Pointer& hfmModel, const std::vector& dracoMeshes, const std::vector>& dracoMaterialLists) override; diff --git a/libraries/baking/src/ModelBaker.cpp b/libraries/baking/src/ModelBaker.cpp index 56673398a7..66a3648579 100644 --- a/libraries/baking/src/ModelBaker.cpp +++ b/libraries/baking/src/ModelBaker.cpp @@ -42,8 +42,9 @@ #include "baking/BakerLibrary.h" -ModelBaker::ModelBaker(const QUrl& inputModelURL, const QString& bakedOutputDirectory, const QString& originalOutputDirectory, bool hasBeenBaked) : +ModelBaker::ModelBaker(const QUrl& inputModelURL, const QUrl& destinationPath, const QString& bakedOutputDirectory, const QString& originalOutputDirectory, bool hasBeenBaked) : _modelURL(inputModelURL), + _destinationPath(destinationPath), _bakedOutputDir(bakedOutputDirectory), _originalOutputDir(originalOutputDirectory), _hasBeenBaked(hasBeenBaked) @@ -255,6 +256,39 @@ void ModelBaker::bakeSourceCopy() { return; } + if (bakedModel->materials.size() > 0) { + _materialBaker = QSharedPointer( + new MaterialBaker(_modelURL.fileName(), true, _bakedOutputDir, _destinationPath), + &MaterialBaker::deleteLater + ); + connect(_materialBaker.data(), &MaterialBaker::finished, this, &ModelBaker::handleFinishedMaterialBaker); + _materialBaker->bake(); + } else { + outputBakedFST(); + } +} + +void ModelBaker::handleFinishedMaterialBaker() { + auto baker = qobject_cast(sender()); + + if (baker) { + if (!baker->hasErrors()) { + // this MaterialBaker is done and everything went according to plan + qCDebug(model_baking) << "Adding baked material to FST mapping " << baker->getBakedMaterialData(); + + } else { + // this material failed to bake - this doesn't fail the entire bake but we need to add the errors from + // the material to our warnings + _warningList << baker->getWarnings(); + } + } else { + handleWarning("Failed to bake the materials for model with URL " + _modelURL.toString()); + } + + outputBakedFST(); +} + +void ModelBaker::outputBakedFST() { // Output FST file, copying over input mappings if available QString outputFSTFilename = !_mappingURL.isEmpty() ? _mappingURL.fileName() : _modelURL.fileName(); auto extensionStart = outputFSTFilename.indexOf("."); @@ -289,7 +323,9 @@ void ModelBaker::bakeSourceCopy() { void ModelBaker::abort() { Baker::abort(); - _materialBaker->abort(); + if (_materialBaker) { + _materialBaker->abort(); + } } bool ModelBaker::buildDracoMeshNode(FBXNode& dracoMeshNode, const QByteArray& dracoMeshBytes, const std::vector& dracoMaterialList) { diff --git a/libraries/baking/src/ModelBaker.h b/libraries/baking/src/ModelBaker.h index 599ca2dbab..89243efda2 100644 --- a/libraries/baking/src/ModelBaker.h +++ b/libraries/baking/src/ModelBaker.h @@ -38,7 +38,7 @@ class ModelBaker : public Baker { Q_OBJECT public: - ModelBaker(const QUrl& inputModelURL, const QString& bakedOutputDirectory, const QString& originalOutputDirectory = "", bool hasBeenBaked = false); + ModelBaker(const QUrl& inputModelURL, const QUrl& destinationPath, const QString& bakedOutputDirectory, const QString& originalOutputDirectory = "", bool hasBeenBaked = false); void setOutputURLSuffix(const QUrl& urlSuffix); void setMappingURL(const QUrl& mappingURL); @@ -67,6 +67,7 @@ protected: FBXNode _rootNode; QUrl _modelURL; + QUrl _destinationPath; QUrl _outputURLSuffix; QUrl _mappingURL; hifi::VariantHash _mapping; @@ -79,8 +80,11 @@ protected: protected slots: void handleModelNetworkReply(); virtual void bakeSourceCopy(); + void handleFinishedMaterialBaker(); private: + void outputBakedFST(); + bool _hasBeenBaked { false }; QSharedPointer _materialBaker; diff --git a/libraries/baking/src/baking/BakerLibrary.cpp b/libraries/baking/src/baking/BakerLibrary.cpp index 356eb4cdb9..f2659b908a 100644 --- a/libraries/baking/src/baking/BakerLibrary.cpp +++ b/libraries/baking/src/baking/BakerLibrary.cpp @@ -45,7 +45,7 @@ bool isModelBaked(const QUrl& bakeableModelURL) { return beforeModelExtension.endsWith(".baked"); } -std::unique_ptr getModelBaker(const QUrl& bakeableModelURL, const QString& contentOutputPath) { +std::unique_ptr getModelBaker(const QUrl& bakeableModelURL, const QString& contentOutputPath, const QUrl& destinationPath) { auto filename = bakeableModelURL.fileName(); // Output in a sub-folder with the name of the model, potentially suffixed by a number to make it unique @@ -59,20 +59,20 @@ std::unique_ptr getModelBaker(const QUrl& bakeableModelURL, const QS QString bakedOutputDirectory = contentOutputPath + subDirName + "/baked"; QString originalOutputDirectory = contentOutputPath + subDirName + "/original"; - return getModelBakerWithOutputDirectories(bakeableModelURL, bakedOutputDirectory, originalOutputDirectory); + return getModelBakerWithOutputDirectories(bakeableModelURL, destinationPath, bakedOutputDirectory, originalOutputDirectory); } -std::unique_ptr getModelBakerWithOutputDirectories(const QUrl& bakeableModelURL, const QString& bakedOutputDirectory, const QString& originalOutputDirectory) { +std::unique_ptr getModelBakerWithOutputDirectories(const QUrl& bakeableModelURL, const QUrl& destinationPath, const QString& bakedOutputDirectory, const QString& originalOutputDirectory) { auto filename = bakeableModelURL.fileName(); std::unique_ptr baker; if (filename.endsWith(FST_EXTENSION, Qt::CaseInsensitive)) { - baker = std::make_unique(bakeableModelURL, bakedOutputDirectory, originalOutputDirectory, filename.endsWith(BAKED_FST_EXTENSION, Qt::CaseInsensitive)); + baker = std::make_unique(bakeableModelURL, destinationPath, bakedOutputDirectory, originalOutputDirectory, filename.endsWith(BAKED_FST_EXTENSION, Qt::CaseInsensitive)); } else if (filename.endsWith(FBX_EXTENSION, Qt::CaseInsensitive)) { - baker = std::make_unique(bakeableModelURL, bakedOutputDirectory, originalOutputDirectory, filename.endsWith(BAKED_FBX_EXTENSION, Qt::CaseInsensitive)); + baker = std::make_unique(bakeableModelURL, destinationPath, bakedOutputDirectory, originalOutputDirectory, filename.endsWith(BAKED_FBX_EXTENSION, Qt::CaseInsensitive)); } else if (filename.endsWith(OBJ_EXTENSION, Qt::CaseInsensitive)) { - baker = std::make_unique(bakeableModelURL, bakedOutputDirectory, originalOutputDirectory); + baker = std::make_unique(bakeableModelURL, destinationPath, bakedOutputDirectory, originalOutputDirectory); //} else if (filename.endsWith(GLTF_EXTENSION, Qt::CaseInsensitive)) { //baker = std::make_unique(bakeableModelURL, inputTextureThreadGetter, bakedOutputDirectory, originalOutputDirectory); } else { diff --git a/libraries/baking/src/baking/BakerLibrary.h b/libraries/baking/src/baking/BakerLibrary.h index 8f82661b25..bf5ee3eec5 100644 --- a/libraries/baking/src/baking/BakerLibrary.h +++ b/libraries/baking/src/baking/BakerLibrary.h @@ -23,9 +23,9 @@ bool isModelBaked(const QUrl& bakeableModelURL); // Assuming the URL is valid, gets the appropriate baker for the given URL, and creates the base directory where the baker's output will later be stored // Returns an empty pointer if a baker could not be created -std::unique_ptr getModelBaker(const QUrl& bakeableModelURL, const QString& contentOutputPath); +std::unique_ptr getModelBaker(const QUrl& bakeableModelURL, const QString& contentOutputPath, const QUrl& destinationPath); // Similar to getModelBaker, but gives control over where the output folders will be -std::unique_ptr getModelBakerWithOutputDirectories(const QUrl& bakeableModelURL, const QString& bakedOutputDirectory, const QString& originalOutputDirectory); +std::unique_ptr getModelBakerWithOutputDirectories(const QUrl& bakeableModelURL, const QUrl& destinationPath, const QString& bakedOutputDirectory, const QString& originalOutputDirectory); #endif // hifi_BakerLibrary_h diff --git a/libraries/baking/src/baking/FSTBaker.cpp b/libraries/baking/src/baking/FSTBaker.cpp index 176c35c059..77f53417d9 100644 --- a/libraries/baking/src/baking/FSTBaker.cpp +++ b/libraries/baking/src/baking/FSTBaker.cpp @@ -18,8 +18,8 @@ #include -FSTBaker::FSTBaker(const QUrl& inputMappingURL, const QString& bakedOutputDirectory, const QString& originalOutputDirectory, bool hasBeenBaked) : - ModelBaker(inputMappingURL, bakedOutputDirectory, originalOutputDirectory, hasBeenBaked) { +FSTBaker::FSTBaker(const QUrl& inputMappingURL, const QUrl& destinationPath, const QString& bakedOutputDirectory, const QString& originalOutputDirectory, bool hasBeenBaked) : + ModelBaker(inputMappingURL, destinationPath, bakedOutputDirectory, originalOutputDirectory, hasBeenBaked) { if (hasBeenBaked) { // Look for the original model file one directory higher. Perhaps this is an oven output directory. QUrl originalRelativePath = QUrl("../original/" + inputMappingURL.fileName().replace(BAKED_FST_EXTENSION, FST_EXTENSION)); @@ -69,7 +69,7 @@ void FSTBaker::bakeSourceCopy() { return; } - auto baker = getModelBakerWithOutputDirectories(bakeableModelURL, _bakedOutputDir, _originalOutputDir); + auto baker = getModelBakerWithOutputDirectories(bakeableModelURL, _destinationPath, _bakedOutputDir, _originalOutputDir); _modelBaker = std::unique_ptr(dynamic_cast(baker.release())); if (!_modelBaker) { handleError("The model url '" + bakeableModelURL.toString() + "' from the FST file '" + _originalOutputModelPath + "' (property: '" + FILENAME_FIELD + "') could not be used to initialize a valid model baker"); diff --git a/libraries/baking/src/baking/FSTBaker.h b/libraries/baking/src/baking/FSTBaker.h index 32997680f5..e8acc2addf 100644 --- a/libraries/baking/src/baking/FSTBaker.h +++ b/libraries/baking/src/baking/FSTBaker.h @@ -18,7 +18,7 @@ class FSTBaker : public ModelBaker { Q_OBJECT public: - FSTBaker(const QUrl& inputMappingURL, const QString& bakedOutputDirectory, const QString& originalOutputDirectory = "", bool hasBeenBaked = false); + FSTBaker(const QUrl& inputMappingURL, const QUrl& destinationPath, const QString& bakedOutputDirectory, const QString& originalOutputDirectory = "", bool hasBeenBaked = false); virtual QUrl getFullOutputMappingURL() const override; diff --git a/libraries/fbx/src/OBJSerializer.cpp b/libraries/fbx/src/OBJSerializer.cpp index c2e9c08463..416f343a47 100644 --- a/libraries/fbx/src/OBJSerializer.cpp +++ b/libraries/fbx/src/OBJSerializer.cpp @@ -891,12 +891,14 @@ HFMModel::Pointer OBJSerializer::read(const hifi::ByteArray& data, const hifi::V if (!objMaterial.used) { continue; } - hfmModel.materials[materialID] = HFMMaterial(objMaterial.diffuseColor, - objMaterial.specularColor, - objMaterial.emissiveColor, - objMaterial.shininess, - objMaterial.opacity); - HFMMaterial& hfmMaterial = hfmModel.materials[materialID]; + + HFMMaterial& hfmMaterial = hfmModel.materials[materialID] = HFMMaterial(objMaterial.diffuseColor, + objMaterial.specularColor, + objMaterial.emissiveColor, + objMaterial.shininess, + objMaterial.opacity); + + hfmMaterial.name = materialID; hfmMaterial.materialID = materialID; hfmMaterial._material = std::make_shared(); graphics::MaterialPointer modelMaterial = hfmMaterial._material; diff --git a/tools/oven/src/BakerCLI.cpp b/tools/oven/src/BakerCLI.cpp index ff8acf060e..05cd7ad324 100644 --- a/tools/oven/src/BakerCLI.cpp +++ b/tools/oven/src/BakerCLI.cpp @@ -44,12 +44,13 @@ void BakerCLI::bakeFile(QUrl inputUrl, const QString& outputPath, const QString& static const QString SCRIPT_EXTENSION { "js" }; _outputPath = outputPath; + QUrl destinationPath = QUrl(outputPath); // create our appropiate baker if (type == MODEL_EXTENSION || type == FBX_EXTENSION) { QUrl bakeableModelURL = getBakeableModelURL(inputUrl); if (!bakeableModelURL.isEmpty()) { - _baker = getModelBaker(bakeableModelURL, outputPath); + _baker = getModelBaker(bakeableModelURL, outputPath, destinationPath); if (_baker) { _baker->moveToThread(Oven::instance().getNextWorkerThread()); } @@ -58,7 +59,7 @@ void BakerCLI::bakeFile(QUrl inputUrl, const QString& outputPath, const QString& _baker = std::unique_ptr { new JSBaker(inputUrl, outputPath) }; _baker->moveToThread(Oven::instance().getNextWorkerThread()); } else if (type == MATERIAL_EXTENSION) { - _baker = std::unique_ptr { new MaterialBaker(inputUrl.toDisplayString(), true, outputPath, QUrl(outputPath)) }; + _baker = std::unique_ptr { new MaterialBaker(inputUrl.toDisplayString(), true, outputPath, destinationPath) }; _baker->moveToThread(Oven::instance().getNextWorkerThread()); } else { // If the type doesn't match the above, we assume we have a texture, and the type specified is the diff --git a/tools/oven/src/DomainBaker.cpp b/tools/oven/src/DomainBaker.cpp index 80ad410053..cff3203bad 100644 --- a/tools/oven/src/DomainBaker.cpp +++ b/tools/oven/src/DomainBaker.cpp @@ -152,7 +152,7 @@ void DomainBaker::addModelBaker(const QString& property, const QString& url, con // setup a ModelBaker for this URL, as long as we don't already have one bool haveBaker = _modelBakers.contains(bakeableModelURL); if (!haveBaker) { - QSharedPointer baker = QSharedPointer(getModelBaker(bakeableModelURL, _contentOutputPath).release(), &Baker::deleteLater); + QSharedPointer baker = QSharedPointer(getModelBaker(bakeableModelURL, _contentOutputPath, _destinationPath).release(), &Baker::deleteLater); if (baker) { // Hold on to the old url userinfo/query/fragment data so ModelBaker::getFullOutputMappingURL retains that data from the original model URL // Note: The ModelBaker currently doesn't store this in the FST because the equal signs mess up FST parsing. diff --git a/tools/oven/src/ui/ModelBakeWidget.cpp b/tools/oven/src/ui/ModelBakeWidget.cpp index 7561a8e009..b431d9f866 100644 --- a/tools/oven/src/ui/ModelBakeWidget.cpp +++ b/tools/oven/src/ui/ModelBakeWidget.cpp @@ -180,7 +180,7 @@ void ModelBakeWidget::bakeButtonClicked() { QUrl bakeableModelURL = getBakeableModelURL(modelToBakeURL); if (!bakeableModelURL.isEmpty()) { - std::unique_ptr baker = getModelBaker(bakeableModelURL, outputDirectory.path()); + std::unique_ptr baker = getModelBaker(bakeableModelURL, outputDirectory.path(), QUrl(outputDirectory.path())); if (baker) { // everything seems to be in place, kick off a bake for this model now