From 2a597eb7154d99679da744c7282e2326371d1afc Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 20 Feb 2018 17:00:28 -0800 Subject: [PATCH 1/9] use QCoreApplication for oven when headless version is used --- tools/oven/src/BakerCLI.cpp | 19 +++++--- tools/oven/src/BakerCLI.h | 6 +-- tools/oven/src/DomainBaker.cpp | 6 +-- tools/oven/src/Oven.cpp | 62 +++++++------------------- tools/oven/src/Oven.h | 23 +++------- tools/oven/src/OvenCLIApplication.cpp | 49 ++++++++++++++++++++ tools/oven/src/OvenCLIApplication.h | 27 +++++++++++ tools/oven/src/OvenGUIApplication.cpp | 19 ++++++++ tools/oven/src/OvenGUIApplication.h | 33 ++++++++++++++ tools/oven/src/main.cpp | 13 ++++-- tools/oven/src/ui/BakeWidget.cpp | 5 +-- tools/oven/src/ui/DomainBakeWidget.cpp | 11 +++-- tools/oven/src/ui/ModelBakeWidget.cpp | 11 +++-- tools/oven/src/ui/SkyboxBakeWidget.cpp | 9 ++-- 14 files changed, 193 insertions(+), 100 deletions(-) create mode 100644 tools/oven/src/OvenCLIApplication.cpp create mode 100644 tools/oven/src/OvenCLIApplication.h create mode 100644 tools/oven/src/OvenGUIApplication.cpp create mode 100644 tools/oven/src/OvenGUIApplication.h diff --git a/tools/oven/src/BakerCLI.cpp b/tools/oven/src/BakerCLI.cpp index 5af65c4dc0..f5af5455fb 100644 --- a/tools/oven/src/BakerCLI.cpp +++ b/tools/oven/src/BakerCLI.cpp @@ -14,13 +14,14 @@ #include #include +#include "OvenCLIApplication.h" #include "ModelBakingLoggingCategory.h" -#include "Oven.h" #include "BakerCLI.h" #include "FBXBaker.h" #include "TextureBaker.h" -BakerCLI::BakerCLI(Oven* parent) : QObject(parent) { +BakerCLI::BakerCLI(OvenCLIApplication* parent) : QObject(parent) { + } void BakerCLI::bakeFile(QUrl inputUrl, const QString& outputPath, const QString& type) { @@ -50,14 +51,18 @@ void BakerCLI::bakeFile(QUrl inputUrl, const QString& outputPath, const QString& // create our appropiate baker if (isFBX) { - _baker = std::unique_ptr { new FBXBaker(inputUrl, []() -> QThread* { return qApp->getNextWorkerThread(); }, outputPath) }; - _baker->moveToThread(qApp->getNextWorkerThread()); + _baker = std::unique_ptr { + new FBXBaker(inputUrl, + []() -> QThread* { return Oven::instance().getNextWorkerThread(); }, + outputPath) + }; + _baker->moveToThread(Oven::instance().getNextWorkerThread()); } else if (isSupportedImage) { _baker = std::unique_ptr { new TextureBaker(inputUrl, image::TextureUsage::CUBE_TEXTURE, outputPath) }; - _baker->moveToThread(qApp->getNextWorkerThread()); + _baker->moveToThread(Oven::instance().getNextWorkerThread()); } else { qCDebug(model_baking) << "Failed to determine baker type for file" << inputUrl; - QApplication::exit(OVEN_STATUS_CODE_FAIL); + QCoreApplication::exit(OVEN_STATUS_CODE_FAIL); } // invoke the bake method on the baker thread @@ -81,5 +86,5 @@ void BakerCLI::handleFinishedBaker() { errorFile.close(); } } - QApplication::exit(exitCode); + QCoreApplication::exit(exitCode); } diff --git a/tools/oven/src/BakerCLI.h b/tools/oven/src/BakerCLI.h index 7d362eb898..4f5b6607b0 100644 --- a/tools/oven/src/BakerCLI.h +++ b/tools/oven/src/BakerCLI.h @@ -18,7 +18,7 @@ #include #include "Baker.h" -#include "Oven.h" +#include "OvenCLIApplication.h" static const int OVEN_STATUS_CODE_SUCCESS { 0 }; static const int OVEN_STATUS_CODE_FAIL { 1 }; @@ -27,10 +27,10 @@ static const int OVEN_STATUS_CODE_ABORT { 2 }; static const QString OVEN_ERROR_FILENAME = "errors.txt"; class BakerCLI : public QObject { - Q_OBJECT + Q_OBJECT public: - BakerCLI(Oven* parent); + BakerCLI(OvenCLIApplication* parent); void bakeFile(QUrl inputUrl, const QString& outputPath, const QString& type = QString::null); private slots: diff --git a/tools/oven/src/DomainBaker.cpp b/tools/oven/src/DomainBaker.cpp index edc2492e82..28ede982a0 100644 --- a/tools/oven/src/DomainBaker.cpp +++ b/tools/oven/src/DomainBaker.cpp @@ -201,7 +201,7 @@ void DomainBaker::enumerateEntities() { } QSharedPointer baker { new FBXBaker(modelURL, []() -> QThread* { - return qApp->getNextWorkerThread(); + return Oven::instance().getNextWorkerThread(); }, _contentOutputPath + subDirName + "/baked", _contentOutputPath + subDirName + "/original"), &FBXBaker::deleteLater }; @@ -214,7 +214,7 @@ void DomainBaker::enumerateEntities() { // move the baker to the baker thread // and kickoff the bake - baker->moveToThread(qApp->getNextWorkerThread()); + baker->moveToThread(Oven::instance().getNextWorkerThread()); QMetaObject::invokeMethod(baker.data(), "bake"); // keep track of the total number of baking entities @@ -285,7 +285,7 @@ void DomainBaker::bakeSkybox(QUrl skyboxURL, QJsonValueRef entity) { _skyboxBakers.insert(skyboxURL, skyboxBaker); // move the baker to a worker thread and kickoff the bake - skyboxBaker->moveToThread(qApp->getNextWorkerThread()); + skyboxBaker->moveToThread(Oven::instance().getNextWorkerThread()); QMetaObject::invokeMethod(skyboxBaker.data(), "bake"); // keep track of the total number of baking entities diff --git a/tools/oven/src/Oven.cpp b/tools/oven/src/Oven.cpp index 69d2ef84ce..e8d4c01f63 100644 --- a/tools/oven/src/Oven.cpp +++ b/tools/oven/src/Oven.cpp @@ -11,33 +11,15 @@ #include #include -#include #include -#include "ui/OvenMainWindow.h" #include "Oven.h" -#include "BakerCLI.h" -static const QString OUTPUT_FOLDER = "/Users/birarda/code/hifi/lod/test-oven/export"; +Oven* Oven::_staticInstance { nullptr }; -static const QString CLI_INPUT_PARAMETER = "i"; -static const QString CLI_OUTPUT_PARAMETER = "o"; -static const QString CLI_TYPE_PARAMETER = "t"; - -Oven::Oven(int argc, char* argv[]) : - QApplication(argc, argv) -{ - // parse the command line parameters - QCommandLineParser parser; - - parser.addOptions({ - { CLI_INPUT_PARAMETER, "Path to file that you would like to bake.", "input" }, - { CLI_OUTPUT_PARAMETER, "Path to folder that will be used as output.", "output" }, - { CLI_TYPE_PARAMETER, "Type of asset.", "type" } - }); - parser.addHelpOption(); - parser.process(*this); +Oven::Oven() { + _staticInstance = this; // enable compression in image library image::setColorTexturesCompressionEnabled(true); @@ -47,41 +29,27 @@ Oven::Oven(int argc, char* argv[]) : // setup our worker threads setupWorkerThreads(QThread::idealThreadCount()); - - // check if we were passed any command line arguments that would tell us just to run without the GUI - if (parser.isSet(CLI_INPUT_PARAMETER) || parser.isSet(CLI_OUTPUT_PARAMETER)) { - if (parser.isSet(CLI_INPUT_PARAMETER) && parser.isSet(CLI_OUTPUT_PARAMETER)) { - BakerCLI* cli = new BakerCLI(this); - QUrl inputUrl(QDir::fromNativeSeparators(parser.value(CLI_INPUT_PARAMETER))); - QUrl outputUrl(QDir::fromNativeSeparators(parser.value(CLI_OUTPUT_PARAMETER))); - QString type = parser.isSet(CLI_TYPE_PARAMETER) ? parser.value(CLI_TYPE_PARAMETER) : QString::null; - cli->bakeFile(inputUrl, outputUrl.toString(), type); - } else { - parser.showHelp(); - QApplication::quit(); - } - } else { - // setup the GUI - _mainWindow = new OvenMainWindow; - _mainWindow->show(); - } } Oven::~Oven() { - // cleanup the worker threads - for (auto i = 0; i < _workerThreads.size(); ++i) { - _workerThreads[i]->quit(); - _workerThreads[i]->wait(); + // quit and wait on the worker threads + for (auto& thread : _workerThreads) { + thread->quit(); + thread->wait(); } + + _staticInstance = nullptr; } void Oven::setupWorkerThreads(int numWorkerThreads) { + _workerThreads.reserve(numWorkerThreads); + for (auto i = 0; i < numWorkerThreads; ++i) { // setup a worker thread yet and add it to our concurrent vector - auto newThread = new QThread(this); + auto newThread = std::unique_ptr { new QThread }; newThread->setObjectName("Oven Worker Thread " + QString::number(i + 1)); - _workerThreads.push_back(newThread); + _workerThreads.push_back(std::move(newThread)); } } @@ -92,13 +60,13 @@ QThread* Oven::getNextWorkerThread() { // (for the FBX Baker Thread to have room), and cycle through them to hand a usable running thread back to our callers. auto nextIndex = ++_nextWorkerThreadIndex; - auto nextThread = _workerThreads[nextIndex % _workerThreads.size()]; + auto& nextThread = _workerThreads[nextIndex % _workerThreads.size()]; // start the thread if it isn't running yet if (!nextThread->isRunning()) { nextThread->start(); } - return nextThread; + return nextThread.get(); } diff --git a/tools/oven/src/Oven.h b/tools/oven/src/Oven.h index 928ba4eb11..443def5cb1 100644 --- a/tools/oven/src/Oven.h +++ b/tools/oven/src/Oven.h @@ -12,27 +12,15 @@ #ifndef hifi_Oven_h #define hifi_Oven_h -#include - -#include - #include -#if defined(qApp) -#undef qApp -#endif -#define qApp (static_cast(QCoreApplication::instance())) - -class OvenMainWindow; - -class Oven : public QApplication { - Q_OBJECT +class Oven { public: - Oven(int argc, char* argv[]); + Oven(); ~Oven(); - OvenMainWindow* getMainWindow() const { return _mainWindow; } + static Oven& instance() { return *_staticInstance; } QThread* getNextWorkerThread(); @@ -40,11 +28,12 @@ private: void setupWorkerThreads(int numWorkerThreads); void setupFBXBakerThread(); - OvenMainWindow* _mainWindow; - QList _workerThreads; + std::vector> _workerThreads; std::atomic _nextWorkerThreadIndex; int _numWorkerThreads; + + static Oven* _staticInstance; }; diff --git a/tools/oven/src/OvenCLIApplication.cpp b/tools/oven/src/OvenCLIApplication.cpp new file mode 100644 index 0000000000..38d9963eeb --- /dev/null +++ b/tools/oven/src/OvenCLIApplication.cpp @@ -0,0 +1,49 @@ +// +// OvenCLIApplication.cpp +// tools/oven/src +// +// Created by Stephen Birarda on 2/20/18. +// Copyright 2018 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 +#include + +#include "BakerCLI.h" + +#include "OvenCLIApplication.h" + +static const QString CLI_INPUT_PARAMETER = "i"; +static const QString CLI_OUTPUT_PARAMETER = "o"; +static const QString CLI_TYPE_PARAMETER = "t"; + +OvenCLIApplication::OvenCLIApplication(int argc, char* argv[]) : + QCoreApplication(argc, argv) +{ + // parse the command line parameters + QCommandLineParser parser; + + parser.addOptions({ + { CLI_INPUT_PARAMETER, "Path to file that you would like to bake.", "input" }, + { CLI_OUTPUT_PARAMETER, "Path to folder that will be used as output.", "output" }, + { CLI_TYPE_PARAMETER, "Type of asset.", "type" } + }); + + parser.addHelpOption(); + parser.process(*this); + + if (parser.isSet(CLI_INPUT_PARAMETER) && parser.isSet(CLI_OUTPUT_PARAMETER)) { + BakerCLI* cli = new BakerCLI(this); + QUrl inputUrl(QDir::fromNativeSeparators(parser.value(CLI_INPUT_PARAMETER))); + QUrl outputUrl(QDir::fromNativeSeparators(parser.value(CLI_OUTPUT_PARAMETER))); + QString type = parser.isSet(CLI_TYPE_PARAMETER) ? parser.value(CLI_TYPE_PARAMETER) : QString::null; + cli->bakeFile(inputUrl, outputUrl.toString(), type); + } else { + parser.showHelp(); + QCoreApplication::quit(); + } + +} diff --git a/tools/oven/src/OvenCLIApplication.h b/tools/oven/src/OvenCLIApplication.h new file mode 100644 index 0000000000..5d81166f69 --- /dev/null +++ b/tools/oven/src/OvenCLIApplication.h @@ -0,0 +1,27 @@ +// +// OvenCLIApplication.h +// tools/oven/src +// +// Created by Stephen Birarda on 2/20/18. +// Copyright 2018 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_OvenCLIApplication_h +#define hifi_OvenCLIApplication_h + +#include + +#include "Oven.h" + +class OvenCLIApplication : public QCoreApplication, public Oven { + Q_OBJECT +public: + OvenCLIApplication(int argc, char* argv[]); + + static OvenCLIApplication* instance() { return dynamic_cast(QCoreApplication::instance()); } +}; + +#endif // hifi_OvenCLIApplication_h diff --git a/tools/oven/src/OvenGUIApplication.cpp b/tools/oven/src/OvenGUIApplication.cpp new file mode 100644 index 0000000000..33dc375634 --- /dev/null +++ b/tools/oven/src/OvenGUIApplication.cpp @@ -0,0 +1,19 @@ +// +// OvenGUIApplication.cpp +// tools/src/oven +// +// Created by Stephen Birarda on 2/20/18. +// Copyright 2018 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 "OvenGUIApplication.h" + +OvenGUIApplication::OvenGUIApplication(int argc, char* argv[]) : + QApplication(argc, argv) +{ + // setup the GUI + _mainWindow.show(); +} diff --git a/tools/oven/src/OvenGUIApplication.h b/tools/oven/src/OvenGUIApplication.h new file mode 100644 index 0000000000..7f5bbf3eaf --- /dev/null +++ b/tools/oven/src/OvenGUIApplication.h @@ -0,0 +1,33 @@ +// +// OvenGUIApplication.h +// tools/oven/src +// +// Created by Stephen Birarda on 2/20/18. +// Copyright 2018 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_OvenGUIApplication_h +#define hifi_OvenGUIApplication_h + +#include + +#include "ui/OvenMainWindow.h" + +#include "Oven.h" + +class OvenGUIApplication : public QApplication, public Oven { + Q_OBJECT +public: + OvenGUIApplication(int argc, char* argv[]); + + static OvenGUIApplication* instance() { return dynamic_cast(QApplication::instance()); } + + OvenMainWindow* getMainWindow() { return &_mainWindow; } +private: + OvenMainWindow _mainWindow; +}; + +#endif // hifi_OvenGUIApplication_h diff --git a/tools/oven/src/main.cpp b/tools/oven/src/main.cpp index 788470b75e..062cc63a0d 100644 --- a/tools/oven/src/main.cpp +++ b/tools/oven/src/main.cpp @@ -8,7 +8,8 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -#include "Oven.h" +#include "OvenCLIApplication.h" +#include "OvenGUIApplication.h" #include @@ -19,6 +20,12 @@ int main (int argc, char** argv) { // init the settings interface so we can save and load settings Setting::init(); - Oven app(argc, argv); - return app.exec(); + // figure out if we're launching our GUI application or just the simple command line interface + if (argc > 1) { + OvenCLIApplication app { argc, argv }; + return app.exec(); + } else { + OvenGUIApplication app { argc, argv }; + return app.exec(); + } } diff --git a/tools/oven/src/ui/BakeWidget.cpp b/tools/oven/src/ui/BakeWidget.cpp index 9fb8f2f880..22e1b1aaf9 100644 --- a/tools/oven/src/ui/BakeWidget.cpp +++ b/tools/oven/src/ui/BakeWidget.cpp @@ -11,8 +11,7 @@ #include -#include "../Oven.h" -#include "OvenMainWindow.h" +#include "../OvenGUIApplication.h" #include "BakeWidget.h" @@ -28,7 +27,7 @@ BakeWidget::~BakeWidget() { auto it = _bakers.begin(); while (it != _bakers.end()) { auto resultRow = it->second; - auto resultsWindow = qApp->getMainWindow()->showResultsWindow(); + auto resultsWindow = OvenGUIApplication::instance()->getMainWindow()->showResultsWindow(); resultsWindow->changeStatusForRow(resultRow, "Cancelled"); diff --git a/tools/oven/src/ui/DomainBakeWidget.cpp b/tools/oven/src/ui/DomainBakeWidget.cpp index 41452c7283..bf79319458 100644 --- a/tools/oven/src/ui/DomainBakeWidget.cpp +++ b/tools/oven/src/ui/DomainBakeWidget.cpp @@ -21,8 +21,7 @@ #include #include -#include "../Oven.h" -#include "OvenMainWindow.h" +#include "../OvenGUIApplication.h" #include "DomainBakeWidget.h" @@ -223,14 +222,14 @@ void DomainBakeWidget::bakeButtonClicked() { connect(domainBaker.get(), &DomainBaker::bakeProgress, this, &DomainBakeWidget::handleBakerProgress); // move the baker to the next available Oven worker thread - auto nextThread = qApp->getNextWorkerThread(); + auto nextThread = Oven::instance().getNextWorkerThread(); domainBaker->moveToThread(nextThread); // kickoff the domain baker on its thread QMetaObject::invokeMethod(domainBaker.get(), "bake"); // add a pending row to the results window to show that this bake is in process - auto resultsWindow = qApp->getMainWindow()->showResultsWindow(); + auto resultsWindow = OvenGUIApplication::instance()->getMainWindow()->showResultsWindow(); auto resultsRowName = _domainNameLineEdit->text().isEmpty() ? fileToBakeURL.fileName() : _domainNameLineEdit->text(); auto resultsRow = resultsWindow->addPendingResultRow(resultsRowName, outputDirectory); @@ -250,7 +249,7 @@ void DomainBakeWidget::handleBakerProgress(int baked, int total) { auto resultRow = it->second; // grab the results window, don't force it to be brought to the top - auto resultsWindow = qApp->getMainWindow()->showResultsWindow(false); + auto resultsWindow = OvenGUIApplication::instance()->getMainWindow()->showResultsWindow(false); int percentage = roundf(float(baked) / float(total) * 100.0f); @@ -269,7 +268,7 @@ void DomainBakeWidget::handleFinishedBaker() { if (it != _bakers.end()) { auto resultRow = it->second; - auto resultsWindow = qApp->getMainWindow()->showResultsWindow(); + auto resultsWindow = OvenGUIApplication::instance()->getMainWindow()->showResultsWindow(); if (baker->hasErrors()) { auto errors = baker->getErrors(); diff --git a/tools/oven/src/ui/ModelBakeWidget.cpp b/tools/oven/src/ui/ModelBakeWidget.cpp index 7963b3f3c4..61eea55917 100644 --- a/tools/oven/src/ui/ModelBakeWidget.cpp +++ b/tools/oven/src/ui/ModelBakeWidget.cpp @@ -21,8 +21,7 @@ #include #include -#include "../Oven.h" -#include "OvenMainWindow.h" +#include "../OvenGUIApplication.h" #include "ModelBakeWidget.h" @@ -208,12 +207,12 @@ void ModelBakeWidget::bakeButtonClicked() { // everything seems to be in place, kick off a bake for this model now auto baker = std::unique_ptr { new FBXBaker(modelToBakeURL, []() -> QThread* { - return qApp->getNextWorkerThread(); + return Oven::instance().getNextWorkerThread(); }, bakedOutputDirectory.absolutePath(), originalOutputDirectory.absolutePath()) }; // move the baker to the FBX baker thread - baker->moveToThread(qApp->getNextWorkerThread()); + baker->moveToThread(Oven::instance().getNextWorkerThread()); // invoke the bake method on the baker thread QMetaObject::invokeMethod(baker.get(), "bake"); @@ -222,7 +221,7 @@ void ModelBakeWidget::bakeButtonClicked() { connect(baker.get(), &FBXBaker::finished, this, &ModelBakeWidget::handleFinishedBaker); // add a pending row to the results window to show that this bake is in process - auto resultsWindow = qApp->getMainWindow()->showResultsWindow(); + auto resultsWindow = OvenGUIApplication::instance()->getMainWindow()->showResultsWindow(); auto resultsRow = resultsWindow->addPendingResultRow(modelToBakeURL.fileName(), outputDirectory); // keep a unique_ptr to this baker @@ -244,7 +243,7 @@ void ModelBakeWidget::handleFinishedBaker() { if (it != _bakers.end()) { auto resultRow = it->second; - auto resultsWindow = qApp->getMainWindow()->showResultsWindow(); + auto resultsWindow = OvenGUIApplication::instance()->getMainWindow()->showResultsWindow(); if (baker->hasErrors()) { resultsWindow->changeStatusForRow(resultRow, baker->getErrors().join("\n")); diff --git a/tools/oven/src/ui/SkyboxBakeWidget.cpp b/tools/oven/src/ui/SkyboxBakeWidget.cpp index cbaaa5ec0a..369b06c39f 100644 --- a/tools/oven/src/ui/SkyboxBakeWidget.cpp +++ b/tools/oven/src/ui/SkyboxBakeWidget.cpp @@ -21,8 +21,7 @@ #include #include -#include "../Oven.h" -#include "OvenMainWindow.h" +#include "../OvenGUIApplication.h" #include "SkyboxBakeWidget.h" @@ -184,7 +183,7 @@ void SkyboxBakeWidget::bakeButtonClicked() { }; // move the baker to a worker thread - baker->moveToThread(qApp->getNextWorkerThread()); + baker->moveToThread(Oven::instance().getNextWorkerThread()); // invoke the bake method on the baker thread QMetaObject::invokeMethod(baker.get(), "bake"); @@ -193,7 +192,7 @@ void SkyboxBakeWidget::bakeButtonClicked() { connect(baker.get(), &TextureBaker::finished, this, &SkyboxBakeWidget::handleFinishedBaker); // add a pending row to the results window to show that this bake is in process - auto resultsWindow = qApp->getMainWindow()->showResultsWindow(); + auto resultsWindow = OvenGUIApplication::instance()->getMainWindow()->showResultsWindow(); auto resultsRow = resultsWindow->addPendingResultRow(skyboxToBakeURL.fileName(), outputDirectory); // keep a unique_ptr to this baker @@ -211,7 +210,7 @@ void SkyboxBakeWidget::handleFinishedBaker() { if (it != _bakers.end()) { auto resultRow = it->second; - auto resultsWindow = qApp->getMainWindow()->showResultsWindow(); + auto resultsWindow = OvenGUIApplication::instance()->getMainWindow()->showResultsWindow(); if (baker->hasErrors()) { resultsWindow->changeStatusForRow(resultRow, baker->getErrors().join("\n")); From d4061c172ef8cb795b4b8409312ae1d41865686b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 20 Feb 2018 17:27:40 -0800 Subject: [PATCH 2/9] quit all threads before waiting on them (CR) --- tools/oven/src/Oven.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/oven/src/Oven.cpp b/tools/oven/src/Oven.cpp index e8d4c01f63..650683e1f0 100644 --- a/tools/oven/src/Oven.cpp +++ b/tools/oven/src/Oven.cpp @@ -32,9 +32,12 @@ Oven::Oven() { } Oven::~Oven() { - // quit and wait on the worker threads + // quit all worker threads and wait on them for (auto& thread : _workerThreads) { thread->quit(); + } + + for (auto& thread: _workerThreads) { thread->wait(); } From 79f5d0cee21161054b12d220b28d1d4bac546887 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 20 Feb 2018 18:49:38 -0800 Subject: [PATCH 3/9] include memory for unique_ptr in Oven --- tools/oven/src/Oven.h | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/oven/src/Oven.h b/tools/oven/src/Oven.h index 443def5cb1..effebb472e 100644 --- a/tools/oven/src/Oven.h +++ b/tools/oven/src/Oven.h @@ -13,6 +13,7 @@ #define hifi_Oven_h #include +#include class Oven { From b56f755034bcd578cf4c2e6419531d6ef24a317c Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 23 Feb 2018 15:10:49 -0800 Subject: [PATCH 4/9] material reflection --- interface/src/ui/overlays/ModelOverlay.cpp | 4 + .../src/avatars-renderer/Avatar.cpp | 4 + .../src/RenderableModelEntityItem.cpp | 4 + .../src/RenderableShapeEntityItem.cpp | 8 +- libraries/gpu/src/gpu/Texture.cpp | 10 -- libraries/gpu/src/gpu/Texture.h | 7 +- libraries/graphics-scripting/CMakeLists.txt | 2 +- .../src/graphics-scripting/Forward.h | 43 +++++- .../src/graphics-scripting/ScriptableMesh.cpp | 58 ++++++++ .../graphics-scripting/ScriptableModel.cpp | 124 ++++++++++++++++++ .../src/graphics-scripting/ScriptableModel.h | 7 +- libraries/graphics/src/graphics/Material.h | 1 + .../src/model-networking/MaterialCache.cpp | 7 + .../src/model-networking/TextureCache.cpp | 4 +- .../render-utils/src/CauterizedModel.cpp | 2 + libraries/render-utils/src/Model.cpp | 8 ++ 16 files changed, 272 insertions(+), 21 deletions(-) diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index ffcc18032c..47dd8f45f9 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -671,5 +671,9 @@ scriptable::ScriptableModelBase ModelOverlay::getScriptableModel() { } auto result = _model->getScriptableModel(); result.objectID = getID(); + { + std::lock_guard lock(_materialsLock); + result.appendMaterials(_materials); + } return result; } diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 25ddfba670..db20f9144d 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -1801,5 +1801,9 @@ scriptable::ScriptableModelBase Avatar::getScriptableModel() { } auto result = _skeletonModel->getScriptableModel(); result.objectID = getSessionUUID(); + { + std::lock_guard lock(_materialsLock); + result.appendMaterials(_materials); + } return result; } \ No newline at end of file diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index f3c99cde2d..5c95d1e556 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -970,6 +970,10 @@ scriptable::ScriptableModelBase render::entities::ModelEntityRenderer::getScript auto result = _model->getScriptableModel(); result.objectID = getEntity()->getID(); + { + std::lock_guard lock(_materialsLock); + result.appendMaterials(_materials); + } return result; } diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index 22cd98b08a..e5cbfdb59d 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -169,8 +169,12 @@ scriptable::ScriptableModelBase ShapeEntityRenderer::getScriptableModel() { auto geometryCache = DependencyManager::get(); auto geometryShape = geometryCache->getShapeForEntityShape(_shape); glm::vec3 vertexColor; - if (_materials["0"].top().material) { - vertexColor = _materials["0"].top().material->getAlbedo(); + { + std::lock_guard lock(_materialsLock); + result.appendMaterials(_materials); + if (_materials["0"].top().material) { + vertexColor = _materials["0"].top().material->getAlbedo(); + } } if (auto mesh = geometryCache->meshFromShape(geometryShape, vertexColor)) { result.objectID = getEntity()->getID(); diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index 4a588c3c84..ed9505766b 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -868,16 +868,6 @@ void SphericalHarmonics::evalFromTexture(const Texture& texture) { // TextureSource -TextureSource::TextureSource() { -} - -TextureSource::~TextureSource() { -} - -void TextureSource::reset(const QUrl& url) { - _imageUrl = url; -} - void TextureSource::resetTexture(gpu::TexturePointer texture) { _gpuTexture = texture; } diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index ad3dc5fada..a03b894e0d 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -647,13 +647,11 @@ typedef std::vector TextureViews; // It provides the mechanism to create a texture using a customizable TextureLoader class TextureSource { public: - TextureSource(); - ~TextureSource(); + TextureSource(const QUrl& url, int type = 0) : _imageUrl(url), _type(type) {} const QUrl& getUrl() const { return _imageUrl; } const gpu::TexturePointer getGPUTexture() const { return _gpuTexture; } - - void reset(const QUrl& url); + int getType() const { return _type; } void resetTexture(gpu::TexturePointer texture); @@ -662,6 +660,7 @@ public: protected: gpu::TexturePointer _gpuTexture; QUrl _imageUrl; + int _type { 0 }; }; typedef std::shared_ptr< TextureSource > TextureSourcePointer; diff --git a/libraries/graphics-scripting/CMakeLists.txt b/libraries/graphics-scripting/CMakeLists.txt index ad8055b647..0f59fb41f8 100644 --- a/libraries/graphics-scripting/CMakeLists.txt +++ b/libraries/graphics-scripting/CMakeLists.txt @@ -1,4 +1,4 @@ set(TARGET_NAME graphics-scripting) setup_hifi_library() -link_hifi_libraries(shared networking graphics fbx model-networking script-engine) +link_hifi_libraries(shared networking graphics fbx image model-networking script-engine) include_hifi_library_headers(gpu) diff --git a/libraries/graphics-scripting/src/graphics-scripting/Forward.h b/libraries/graphics-scripting/src/graphics-scripting/Forward.h index 94a96446a0..b07c25ee02 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/Forward.h +++ b/libraries/graphics-scripting/src/graphics-scripting/Forward.h @@ -6,9 +6,14 @@ #include #include #include +#include #include #include + +#include "graphics/Material.h" +#include "graphics/TextureMap.h" + namespace graphics { class Mesh; } @@ -31,6 +36,38 @@ namespace scriptable { using ModelProviderPointer = std::shared_ptr; using WeakModelProviderPointer = std::weak_ptr; + class ScriptableMaterial { + public: + ScriptableMaterial() {} + ScriptableMaterial(const graphics::MaterialLayer& materialLayer); + ScriptableMaterial(const ScriptableMaterial& material) { *this = material; } + ScriptableMaterial& operator=(const ScriptableMaterial& material); + + QString name; + QString model; + float opacity; + float roughness; + float metallic; + float scattering; + bool unlit; + glm::vec3 emissive; + glm::vec3 albedo; + QString emissiveMap; + QString albedoMap; + QString opacityMap; + QString metallicMap; + QString specularMap; + QString roughnessMap; + QString glossMap; + QString normalMap; + QString bumpMap; + QString occlusionMap; + QString lightmapMap; + QString scatteringMap; + quint16 priority; + }; + typedef QHash> MultiMaterialMap; + class ScriptableMeshBase : public QObject { Q_OBJECT public: @@ -55,6 +92,8 @@ namespace scriptable { WeakModelProviderPointer provider; QUuid objectID; // spatially nestable ID QVector meshes; + MultiMaterialMap materials; + QVector materialNames; ScriptableModelBase(QObject* parent = nullptr) : QObject(parent) {} ScriptableModelBase(const ScriptableModelBase& other) : QObject(other.parent()) { *this = other; } @@ -63,9 +102,11 @@ namespace scriptable { void append(const ScriptableMeshBase& mesh); void append(scriptable::WeakMeshPointer mesh); + void appendMaterial(const graphics::MaterialLayer& material, int shapeID, std::string materialName); + void appendMaterials(const std::unordered_map& materialsToAppend); + void appendMaterialNames(const std::vector& names); // TODO: in future containers for these could go here // QVariantMap shapes; - // QVariantMap materials; // QVariantMap armature; }; diff --git a/libraries/graphics-scripting/src/graphics-scripting/ScriptableMesh.cpp b/libraries/graphics-scripting/src/graphics-scripting/ScriptableMesh.cpp index 76741947fd..7da69fcad2 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/ScriptableMesh.cpp +++ b/libraries/graphics-scripting/src/graphics-scripting/ScriptableMesh.cpp @@ -554,6 +554,57 @@ namespace { qScriptValueToSequence(array, result); } + QScriptValue qVectorScriptableMaterialToScriptValue(QScriptEngine* engine, const QVector& vector) { + return qScriptValueFromSequence(engine, vector); + } + + void qVectorScriptableMaterialFromScriptValue(const QScriptValue& array, QVector& result) { + qScriptValueToSequence(array, result); + } + + QScriptValue scriptableMaterialToScriptValue(QScriptEngine* engine, const scriptable::ScriptableMaterial &material) { + QScriptValue obj = engine->newObject(); + obj.setProperty("name", material.name); + obj.setProperty("model", material.model); + obj.setProperty("opacity", material.opacity); + obj.setProperty("roughness", material.roughness); + obj.setProperty("metallic", material.metallic); + obj.setProperty("scattering", material.scattering); + obj.setProperty("unlit", material.unlit); + obj.setProperty("emissive", vec3toScriptValue(engine, material.emissive)); + obj.setProperty("albedo", vec3toScriptValue(engine, material.albedo)); + obj.setProperty("emissiveMap", material.emissiveMap); + obj.setProperty("albedoMap", material.albedoMap); + obj.setProperty("opacityMap", material.opacityMap); + obj.setProperty("metallicMap", material.metallicMap); + obj.setProperty("specularMap", material.specularMap); + obj.setProperty("roughnessMap", material.roughnessMap); + obj.setProperty("glossMap", material.glossMap); + obj.setProperty("normalMap", material.normalMap); + obj.setProperty("bumpMap", material.bumpMap); + obj.setProperty("occlusionMap", material.occlusionMap); + obj.setProperty("lightmapMap", material.lightmapMap); + obj.setProperty("scatteringMap", material.scatteringMap); + obj.setProperty("priority", material.priority); + return obj; + } + + void scriptableMaterialFromScriptValue(const QScriptValue &object, scriptable::ScriptableMaterial& material) { + // No need to convert from QScriptValue to ScriptableMaterial + } + + QScriptValue multiMaterialMapToScriptValue(QScriptEngine* engine, const scriptable::MultiMaterialMap& map) { + QScriptValue obj = engine->newObject(); + for (auto key : map.keys()) { + obj.setProperty(key, qVectorScriptableMaterialToScriptValue(engine, map[key])); + } + return obj; + } + + void multiMaterialMapFromScriptValue(const QScriptValue& map, scriptable::MultiMaterialMap& result) { + // No need to convert from QScriptValue to MultiMaterialMap + } + QVector metaTypeIds{ qRegisterMetaType("uint32"), qRegisterMetaType("scriptable::uint32"), @@ -562,6 +613,9 @@ namespace { qRegisterMetaType(), qRegisterMetaType(), qRegisterMetaType(), + qRegisterMetaType(), + qRegisterMetaType>(), + qRegisterMetaType() }; } @@ -570,11 +624,15 @@ namespace scriptable { qScriptRegisterSequenceMetaType>(engine); qScriptRegisterSequenceMetaType>(engine); qScriptRegisterSequenceMetaType>(engine); + qScriptRegisterSequenceMetaType>(engine); qScriptRegisterMetaType(engine, qVectorUInt32ToScriptValue, qVectorUInt32FromScriptValue); qScriptRegisterMetaType(engine, modelPointerToScriptValue, modelPointerFromScriptValue); qScriptRegisterMetaType(engine, meshPointerToScriptValue, meshPointerFromScriptValue); qScriptRegisterMetaType(engine, meshPartPointerToScriptValue, meshPartPointerFromScriptValue); + qScriptRegisterMetaType(engine, scriptableMaterialToScriptValue, scriptableMaterialFromScriptValue); + qScriptRegisterMetaType(engine, qVectorScriptableMaterialToScriptValue, qVectorScriptableMaterialFromScriptValue); + qScriptRegisterMetaType(engine, multiMaterialMapToScriptValue, multiMaterialMapFromScriptValue); return metaTypeIds.size(); } diff --git a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp index 8ceb7de6a2..9a4bfe60b6 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp +++ b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp @@ -14,14 +14,115 @@ #include +#include "graphics/Material.h" + +#include "image/Image.h" + // #define SCRIPTABLE_MESH_DEBUG 1 +scriptable::ScriptableMaterial& scriptable::ScriptableMaterial::operator=(const scriptable::ScriptableMaterial& material) { + name = material.name; + model = material.model; + opacity = material.opacity; + roughness = material.roughness; + metallic = material.metallic; + scattering = material.scattering; + unlit = material.unlit; + emissive = material.emissive; + albedo = material.albedo; + emissiveMap = material.emissiveMap; + albedoMap = material.albedoMap; + opacityMap = material.opacityMap; + metallicMap = material.metallicMap; + specularMap = material.specularMap; + roughnessMap = material.roughnessMap; + glossMap = material.glossMap; + normalMap = material.normalMap; + bumpMap = material.bumpMap; + occlusionMap = material.occlusionMap; + lightmapMap = material.lightmapMap; + scatteringMap = material.scatteringMap; + priority = material.priority; + + return *this; +} + +scriptable::ScriptableMaterial::ScriptableMaterial(const graphics::MaterialLayer& materialLayer) : + name(materialLayer.material->getName().c_str()), + model(materialLayer.material->getModel().c_str()), + opacity(materialLayer.material->getOpacity()), + roughness(materialLayer.material->getRoughness()), + metallic(materialLayer.material->getMetallic()), + scattering(materialLayer.material->getScattering()), + unlit(materialLayer.material->isUnlit()), + emissive(materialLayer.material->getEmissive()), + albedo(materialLayer.material->getAlbedo()), + priority(materialLayer.priority) +{ + auto map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::EMISSIVE_MAP); + if (map && map->getTextureSource()) { + emissiveMap = map->getTextureSource()->getUrl().toString(); + } + + map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::ALBEDO_MAP); + if (map && map->getTextureSource()) { + albedoMap = map->getTextureSource()->getUrl().toString(); + if (map->useAlphaChannel()) { + opacityMap = albedoMap; + } + } + + map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::METALLIC_MAP); + if (map && map->getTextureSource()) { + if (map->getTextureSource()->getType() == image::TextureUsage::Type::METALLIC_TEXTURE) { + metallicMap = map->getTextureSource()->getUrl().toString(); + } else if (map->getTextureSource()->getType() == image::TextureUsage::Type::SPECULAR_TEXTURE) { + specularMap = map->getTextureSource()->getUrl().toString(); + } + } + + map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::ROUGHNESS_MAP); + if (map && map->getTextureSource()) { + if (map->getTextureSource()->getType() == image::TextureUsage::Type::ROUGHNESS_TEXTURE) { + roughnessMap = map->getTextureSource()->getUrl().toString(); + } else if (map->getTextureSource()->getType() == image::TextureUsage::Type::GLOSS_TEXTURE) { + glossMap = map->getTextureSource()->getUrl().toString(); + } + } + + map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::NORMAL_MAP); + if (map && map->getTextureSource()) { + if (map->getTextureSource()->getType() == image::TextureUsage::Type::NORMAL_TEXTURE) { + normalMap = map->getTextureSource()->getUrl().toString(); + } else if (map->getTextureSource()->getType() == image::TextureUsage::Type::BUMP_TEXTURE) { + bumpMap = map->getTextureSource()->getUrl().toString(); + } + } + + map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::OCCLUSION_MAP); + if (map && map->getTextureSource()) { + occlusionMap = map->getTextureSource()->getUrl().toString(); + } + + map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::LIGHTMAP_MAP); + if (map && map->getTextureSource()) { + lightmapMap = map->getTextureSource()->getUrl().toString(); + } + + map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::SCATTERING_MAP); + if (map && map->getTextureSource()) { + scatteringMap = map->getTextureSource()->getUrl().toString(); + } +} + scriptable::ScriptableModelBase& scriptable::ScriptableModelBase::operator=(const scriptable::ScriptableModelBase& other) { provider = other.provider; objectID = other.objectID; for (const auto& mesh : other.meshes) { append(mesh); } + materials = other.materials; + materialNames = other.materialNames; return *this; } @@ -34,6 +135,8 @@ scriptable::ScriptableModelBase::~ScriptableModelBase() { m.strongMesh.reset(); } meshes.clear(); + materials.clear(); + materialNames.clear(); } void scriptable::ScriptableModelBase::append(scriptable::WeakMeshPointer mesh) { @@ -47,6 +150,27 @@ void scriptable::ScriptableModelBase::append(const ScriptableMeshBase& mesh) { meshes << mesh; } +void scriptable::ScriptableModelBase::appendMaterial(const graphics::MaterialLayer& material, int shapeID, std::string materialName) { + materials[QString::number(shapeID)].push_back(ScriptableMaterial(material)); + materials["mat::" + QString::fromStdString(materialName)].push_back(ScriptableMaterial(material)); +} + +void scriptable::ScriptableModelBase::appendMaterials(const std::unordered_map& materialsToAppend) { + auto materialsToAppendCopy = materialsToAppend; + for (auto& multiMaterial : materialsToAppendCopy) { + while (!multiMaterial.second.empty()) { + materials[QString(multiMaterial.first.c_str())].push_back(ScriptableMaterial(multiMaterial.second.top())); + multiMaterial.second.pop(); + } + } +} + +void scriptable::ScriptableModelBase::appendMaterialNames(const std::vector& names) { + for (auto& name : names) { + materialNames.append(QString::fromStdString(name)); + } +} + QString scriptable::ScriptableModel::toString() const { return QString("[ScriptableModel%1%2 numMeshes=%3]") .arg(objectID.isNull() ? "" : " objectID="+objectID.toString()) diff --git a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h index 4ed1cc9554..9dc4c6f1ca 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h +++ b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h @@ -19,6 +19,8 @@ namespace scriptable { Q_PROPERTY(QUuid objectID MEMBER objectID CONSTANT) Q_PROPERTY(uint32 numMeshes READ getNumMeshes) Q_PROPERTY(QVector meshes READ getMeshes) + Q_PROPERTY(scriptable::MultiMaterialMap materials READ getMaterials) + Q_PROPERTY(QVector materialNames READ getMaterialNames) ScriptableModel(QObject* parent = nullptr) : ScriptableModelBase(parent) {} ScriptableModel(const ScriptableModel& other) : ScriptableModelBase(other) {} @@ -28,7 +30,6 @@ namespace scriptable { Q_INVOKABLE scriptable::ScriptableModelPointer cloneModel(const QVariantMap& options = QVariantMap()); // TODO: in future accessors for these could go here // QVariantMap shapes; - // QVariantMap materials; // QVariantMap armature; QVector getMeshes(); @@ -37,6 +38,8 @@ namespace scriptable { return QPointer(qobject_cast(this)); } + scriptable::MultiMaterialMap getMaterials() { return materials; } + QVector getMaterialNames() { return materialNames; } // QScriptEngine-specific wrappers Q_INVOKABLE uint32 mapAttributeValues(QScriptValue callback); @@ -51,3 +54,5 @@ Q_DECLARE_METATYPE(scriptable::WeakMeshPointer) Q_DECLARE_METATYPE(scriptable::ScriptableModelPointer) Q_DECLARE_METATYPE(scriptable::ScriptableModelBase) Q_DECLARE_METATYPE(scriptable::ScriptableModelBasePointer) +Q_DECLARE_METATYPE(scriptable::ScriptableMaterial) +Q_DECLARE_METATYPE(scriptable::MultiMaterialMap) diff --git a/libraries/graphics/src/graphics/Material.h b/libraries/graphics/src/graphics/Material.h index 632cf99391..f34f68c04a 100755 --- a/libraries/graphics/src/graphics/Material.h +++ b/libraries/graphics/src/graphics/Material.h @@ -358,6 +358,7 @@ public: const std::string& getName() { return _name; } + const std::string& getModel() { return _model; } void setModel(const std::string& model) { _model = model; } protected: diff --git a/libraries/model-networking/src/model-networking/MaterialCache.cpp b/libraries/model-networking/src/model-networking/MaterialCache.cpp index 8d9d6571f8..85f2f43652 100644 --- a/libraries/model-networking/src/model-networking/MaterialCache.cpp +++ b/libraries/model-networking/src/model-networking/MaterialCache.cpp @@ -11,6 +11,8 @@ #include "QJsonDocument" #include "QJsonArray" +#include "RegisteredMetaTypes.h" + NetworkMaterialResource::NetworkMaterialResource(const QUrl& url) : Resource(url) {} @@ -39,6 +41,11 @@ bool NetworkMaterialResource::parseJSONColor(const QJsonValue& array, glm::vec3& color = glm::vec3(colorArray[0].toDouble(), colorArray[1].toDouble(), colorArray[2].toDouble()); return true; } + } else if (array.isObject()) { + bool toReturn; + isSRGB = true; + color = vec3FromVariant(array.toObject(), toReturn); + return toReturn; } return false; } diff --git a/libraries/model-networking/src/model-networking/TextureCache.cpp b/libraries/model-networking/src/model-networking/TextureCache.cpp index 3a29139ee7..9b12c34f87 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.cpp +++ b/libraries/model-networking/src/model-networking/TextureCache.cpp @@ -291,7 +291,7 @@ _type(), _sourceIsKTX(false), _maxNumPixels(100) { - _textureSource = std::make_shared(); + _textureSource = std::make_shared(url); _lowestRequestedMipLevel = 0; _loaded = true; } @@ -303,7 +303,7 @@ NetworkTexture::NetworkTexture(const QUrl& url, image::TextureUsage::Type type, _sourceIsKTX(url.path().endsWith(".ktx")), _maxNumPixels(maxNumPixels) { - _textureSource = std::make_shared(); + _textureSource = std::make_shared(url, (int)type); _lowestRequestedMipLevel = 0; _shouldFailOnRedirect = !_sourceIsKTX; diff --git a/libraries/render-utils/src/CauterizedModel.cpp b/libraries/render-utils/src/CauterizedModel.cpp index 54dfd96a00..5685a85349 100644 --- a/libraries/render-utils/src/CauterizedModel.cpp +++ b/libraries/render-utils/src/CauterizedModel.cpp @@ -57,6 +57,7 @@ void CauterizedModel::createVisibleRenderItemSet() { Q_ASSERT(_modelMeshRenderItems.isEmpty()); _modelMeshRenderItems.clear(); + _modelMeshMaterialNames.clear(); _modelMeshRenderItemShapes.clear(); Transform transform; @@ -81,6 +82,7 @@ void CauterizedModel::createVisibleRenderItemSet() { for (int partIndex = 0; partIndex < numParts; partIndex++) { auto ptr = std::make_shared(shared_from_this(), i, partIndex, shapeID, transform, offset); _modelMeshRenderItems << std::static_pointer_cast(ptr); + _modelMeshMaterialNames.push_back(getGeometry()->getShapeMaterial(shapeID)->getName()); _modelMeshRenderItemShapes.emplace_back(ShapeInfo{ (int)i }); shapeID++; } diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 6d735497c0..f55b3c598d 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -629,12 +629,20 @@ scriptable::ScriptableModelBase Model::getScriptableModel() { const FBXGeometry& geometry = getFBXGeometry(); int numberOfMeshes = geometry.meshes.size(); + int shapeID = 0; for (int i = 0; i < numberOfMeshes; i++) { const FBXMesh& fbxMesh = geometry.meshes.at(i); if (auto mesh = fbxMesh._mesh) { result.append(mesh); + + int numParts = (int)mesh->getNumParts(); + for (int partIndex = 0; partIndex < numParts; partIndex++) { + result.appendMaterial(graphics::MaterialLayer(getGeometry()->getShapeMaterial(shapeID), 0), shapeID, _modelMeshMaterialNames[shapeID]); + shapeID++; + } } } + result.appendMaterialNames(_modelMeshMaterialNames); return result; } From a66125fbb781af8faf8fa1cef32628974291e5b0 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 1 Mar 2018 16:56:51 -0800 Subject: [PATCH 5/9] scriptablematerial -> scriptablemateriallayer --- .../src/graphics-scripting/Forward.h | 17 ++++-- .../GraphicsScriptingInterface.cpp | 26 ++++++--- .../graphics-scripting/ScriptableModel.cpp | 57 ++++++++++--------- .../src/graphics-scripting/ScriptableModel.h | 5 +- libraries/graphics/src/graphics/Material.h | 4 +- 5 files changed, 68 insertions(+), 41 deletions(-) diff --git a/libraries/graphics-scripting/src/graphics-scripting/Forward.h b/libraries/graphics-scripting/src/graphics-scripting/Forward.h index 650e4104e7..3d710b41b4 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/Forward.h +++ b/libraries/graphics-scripting/src/graphics-scripting/Forward.h @@ -39,7 +39,7 @@ namespace scriptable { class ScriptableMaterial { public: ScriptableMaterial() {} - ScriptableMaterial(const graphics::MaterialLayer& materialLayer); + ScriptableMaterial(const graphics::MaterialPointer& material); ScriptableMaterial(const ScriptableMaterial& material) { *this = material; } ScriptableMaterial& operator=(const ScriptableMaterial& material); @@ -64,9 +64,18 @@ namespace scriptable { QString occlusionMap; QString lightmapMap; QString scatteringMap; + }; + class ScriptableMaterialLayer { + public: + ScriptableMaterialLayer() {} + ScriptableMaterialLayer(const graphics::MaterialLayer& materialLayer) : material(materialLayer.material), priority(materialLayer.priority) {} + ScriptableMaterialLayer(const ScriptableMaterialLayer& materialLayer) { *this = materialLayer; } + ScriptableMaterialLayer& operator=(const ScriptableMaterialLayer& materialLayer); + + ScriptableMaterial material; quint16 priority; }; - typedef QHash> MultiMaterialMap; + typedef QHash> MultiMaterialMap; class ScriptableMeshBase : public QObject { Q_OBJECT @@ -92,7 +101,7 @@ namespace scriptable { WeakModelProviderPointer provider; QUuid objectID; // spatially nestable ID QVector meshes; - MultiMaterialMap materials; + MultiMaterialMap materialLayers; QVector materialNames; ScriptableModelBase(QObject* parent = nullptr) : QObject(parent) {} @@ -102,7 +111,7 @@ namespace scriptable { void append(const ScriptableMeshBase& mesh); void append(scriptable::WeakMeshPointer mesh); - void appendMaterial(const graphics::MaterialLayer& material, int shapeID, std::string materialName); + void appendMaterial(const graphics::MaterialLayer& materialLayer, int shapeID, std::string materialName); void appendMaterials(const std::unordered_map& materialsToAppend); void appendMaterialNames(const std::vector& names); // TODO: in future containers for these could go here diff --git a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp index ff0170f07d..20b54b02c9 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp +++ b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp @@ -298,7 +298,8 @@ namespace { qRegisterMetaType(), qRegisterMetaType(), qRegisterMetaType(), - qRegisterMetaType>(), + qRegisterMetaType(), + qRegisterMetaType>(), qRegisterMetaType(), qRegisterMetaType(), }; @@ -338,11 +339,11 @@ namespace scriptable { ); } - QScriptValue qVectorScriptableMaterialToScriptValue(QScriptEngine* engine, const QVector& vector) { + QScriptValue qVectorScriptableMaterialLayerToScriptValue(QScriptEngine* engine, const QVector& vector) { return qScriptValueFromSequence(engine, vector); } - void qVectorScriptableMaterialFromScriptValue(const QScriptValue& array, QVector& result) { + void qVectorScriptableMaterialLayerFromScriptValue(const QScriptValue& array, QVector& result) { qScriptValueToSequence(array, result); } @@ -369,7 +370,6 @@ namespace scriptable { obj.setProperty("occlusionMap", material.occlusionMap); obj.setProperty("lightmapMap", material.lightmapMap); obj.setProperty("scatteringMap", material.scatteringMap); - obj.setProperty("priority", material.priority); return obj; } @@ -377,10 +377,21 @@ namespace scriptable { // No need to convert from QScriptValue to ScriptableMaterial } + QScriptValue scriptableMaterialLayerToScriptValue(QScriptEngine* engine, const scriptable::ScriptableMaterialLayer &materialLayer) { + QScriptValue obj = engine->newObject(); + obj.setProperty("material", scriptableMaterialToScriptValue(engine, materialLayer.material)); + obj.setProperty("priority", materialLayer.priority); + return obj; + } + + void scriptableMaterialLayerFromScriptValue(const QScriptValue &object, scriptable::ScriptableMaterialLayer& materialLayer) { + // No need to convert from QScriptValue to ScriptableMaterialLayer + } + QScriptValue multiMaterialMapToScriptValue(QScriptEngine* engine, const scriptable::MultiMaterialMap& map) { QScriptValue obj = engine->newObject(); for (auto key : map.keys()) { - obj.setProperty(key, qVectorScriptableMaterialToScriptValue(engine, map[key])); + obj.setProperty(key, qVectorScriptableMaterialLayerToScriptValue(engine, map[key])); } return obj; } @@ -405,7 +416,7 @@ namespace scriptable { void GraphicsScriptingInterface::registerMetaTypes(QScriptEngine* engine) { qScriptRegisterSequenceMetaType>(engine); - qScriptRegisterSequenceMetaType>(engine); + qScriptRegisterSequenceMetaType>(engine); scriptable::registerQPointerMetaType(engine); scriptable::registerQPointerMetaType(engine); @@ -417,7 +428,8 @@ void GraphicsScriptingInterface::registerMetaTypes(QScriptEngine* engine) { scriptable::registerDebugEnum(engine, gpu::DIMENSIONS); qScriptRegisterMetaType(engine, scriptable::scriptableMaterialToScriptValue, scriptable::scriptableMaterialFromScriptValue); - qScriptRegisterMetaType(engine, scriptable::qVectorScriptableMaterialToScriptValue, scriptable::qVectorScriptableMaterialFromScriptValue); + qScriptRegisterMetaType(engine, scriptable::scriptableMaterialLayerToScriptValue, scriptable::scriptableMaterialLayerFromScriptValue); + qScriptRegisterMetaType(engine, scriptable::qVectorScriptableMaterialLayerToScriptValue, scriptable::qVectorScriptableMaterialLayerFromScriptValue); qScriptRegisterMetaType(engine, scriptable::multiMaterialMapToScriptValue, scriptable::multiMaterialMapFromScriptValue); Q_UNUSED(metaTypeIds); diff --git a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp index a713d42012..c65764a225 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp +++ b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.cpp @@ -42,29 +42,27 @@ scriptable::ScriptableMaterial& scriptable::ScriptableMaterial::operator=(const occlusionMap = material.occlusionMap; lightmapMap = material.lightmapMap; scatteringMap = material.scatteringMap; - priority = material.priority; return *this; } -scriptable::ScriptableMaterial::ScriptableMaterial(const graphics::MaterialLayer& materialLayer) : - name(materialLayer.material->getName().c_str()), - model(materialLayer.material->getModel().c_str()), - opacity(materialLayer.material->getOpacity()), - roughness(materialLayer.material->getRoughness()), - metallic(materialLayer.material->getMetallic()), - scattering(materialLayer.material->getScattering()), - unlit(materialLayer.material->isUnlit()), - emissive(materialLayer.material->getEmissive()), - albedo(materialLayer.material->getAlbedo()), - priority(materialLayer.priority) +scriptable::ScriptableMaterial::ScriptableMaterial(const graphics::MaterialPointer& material) : + name(material->getName().c_str()), + model(material->getModel().c_str()), + opacity(material->getOpacity()), + roughness(material->getRoughness()), + metallic(material->getMetallic()), + scattering(material->getScattering()), + unlit(material->isUnlit()), + emissive(material->getEmissive()), + albedo(material->getAlbedo()) { - auto map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::EMISSIVE_MAP); + auto map = material->getTextureMap(graphics::Material::MapChannel::EMISSIVE_MAP); if (map && map->getTextureSource()) { emissiveMap = map->getTextureSource()->getUrl().toString(); } - map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::ALBEDO_MAP); + map = material->getTextureMap(graphics::Material::MapChannel::ALBEDO_MAP); if (map && map->getTextureSource()) { albedoMap = map->getTextureSource()->getUrl().toString(); if (map->useAlphaChannel()) { @@ -72,7 +70,7 @@ scriptable::ScriptableMaterial::ScriptableMaterial(const graphics::MaterialLayer } } - map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::METALLIC_MAP); + map = material->getTextureMap(graphics::Material::MapChannel::METALLIC_MAP); if (map && map->getTextureSource()) { if (map->getTextureSource()->getType() == image::TextureUsage::Type::METALLIC_TEXTURE) { metallicMap = map->getTextureSource()->getUrl().toString(); @@ -81,7 +79,7 @@ scriptable::ScriptableMaterial::ScriptableMaterial(const graphics::MaterialLayer } } - map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::ROUGHNESS_MAP); + map = material->getTextureMap(graphics::Material::MapChannel::ROUGHNESS_MAP); if (map && map->getTextureSource()) { if (map->getTextureSource()->getType() == image::TextureUsage::Type::ROUGHNESS_TEXTURE) { roughnessMap = map->getTextureSource()->getUrl().toString(); @@ -90,7 +88,7 @@ scriptable::ScriptableMaterial::ScriptableMaterial(const graphics::MaterialLayer } } - map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::NORMAL_MAP); + map = material->getTextureMap(graphics::Material::MapChannel::NORMAL_MAP); if (map && map->getTextureSource()) { if (map->getTextureSource()->getType() == image::TextureUsage::Type::NORMAL_TEXTURE) { normalMap = map->getTextureSource()->getUrl().toString(); @@ -99,29 +97,36 @@ scriptable::ScriptableMaterial::ScriptableMaterial(const graphics::MaterialLayer } } - map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::OCCLUSION_MAP); + map = material->getTextureMap(graphics::Material::MapChannel::OCCLUSION_MAP); if (map && map->getTextureSource()) { occlusionMap = map->getTextureSource()->getUrl().toString(); } - map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::LIGHTMAP_MAP); + map = material->getTextureMap(graphics::Material::MapChannel::LIGHTMAP_MAP); if (map && map->getTextureSource()) { lightmapMap = map->getTextureSource()->getUrl().toString(); } - map = materialLayer.material->getTextureMap(graphics::Material::MapChannel::SCATTERING_MAP); + map = material->getTextureMap(graphics::Material::MapChannel::SCATTERING_MAP); if (map && map->getTextureSource()) { scatteringMap = map->getTextureSource()->getUrl().toString(); } } +scriptable::ScriptableMaterialLayer& scriptable::ScriptableMaterialLayer::operator=(const scriptable::ScriptableMaterialLayer& materialLayer) { + material = materialLayer.material; + priority = materialLayer.priority; + + return *this; +} + scriptable::ScriptableModelBase& scriptable::ScriptableModelBase::operator=(const scriptable::ScriptableModelBase& other) { provider = other.provider; objectID = other.objectID; for (const auto& mesh : other.meshes) { append(mesh); } - materials = other.materials; + materialLayers = other.materialLayers; materialNames = other.materialNames; return *this; } @@ -135,7 +140,7 @@ scriptable::ScriptableModelBase::~ScriptableModelBase() { m.strongMesh.reset(); } meshes.clear(); - materials.clear(); + materialLayers.clear(); materialNames.clear(); } @@ -150,16 +155,16 @@ void scriptable::ScriptableModelBase::append(const ScriptableMeshBase& mesh) { meshes << mesh; } -void scriptable::ScriptableModelBase::appendMaterial(const graphics::MaterialLayer& material, int shapeID, std::string materialName) { - materials[QString::number(shapeID)].push_back(ScriptableMaterial(material)); - materials["mat::" + QString::fromStdString(materialName)].push_back(ScriptableMaterial(material)); +void scriptable::ScriptableModelBase::appendMaterial(const graphics::MaterialLayer& materialLayer, int shapeID, std::string materialName) { + materialLayers[QString::number(shapeID)].push_back(ScriptableMaterialLayer(materialLayer)); + materialLayers["mat::" + QString::fromStdString(materialName)].push_back(ScriptableMaterialLayer(materialLayer)); } void scriptable::ScriptableModelBase::appendMaterials(const std::unordered_map& materialsToAppend) { auto materialsToAppendCopy = materialsToAppend; for (auto& multiMaterial : materialsToAppendCopy) { while (!multiMaterial.second.empty()) { - materials[QString(multiMaterial.first.c_str())].push_back(ScriptableMaterial(multiMaterial.second.top())); + materialLayers[QString(multiMaterial.first.c_str())].push_back(ScriptableMaterialLayer(multiMaterial.second.top())); multiMaterial.second.pop(); } } diff --git a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h index b1fe29447f..a1278132ca 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h +++ b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h @@ -28,7 +28,7 @@ namespace scriptable { Q_PROPERTY(QUuid objectID MEMBER objectID CONSTANT) Q_PROPERTY(glm::uint32 numMeshes READ getNumMeshes) Q_PROPERTY(ScriptableMeshes meshes READ getMeshes) - Q_PROPERTY(scriptable::MultiMaterialMap materials READ getMaterials) + Q_PROPERTY(scriptable::MultiMaterialMap materialLayers READ getMaterialLayers) Q_PROPERTY(QVector materialNames READ getMaterialNames) public: @@ -43,7 +43,7 @@ namespace scriptable { ScriptableMeshes getMeshes(); const ScriptableMeshes getConstMeshes() const; - scriptable::MultiMaterialMap getMaterials() { return materials; } + scriptable::MultiMaterialMap getMaterialLayers() { return materialLayers; } QVector getMaterialNames() { return materialNames; } public slots: @@ -60,4 +60,5 @@ namespace scriptable { Q_DECLARE_METATYPE(scriptable::ScriptableModelPointer) Q_DECLARE_METATYPE(QVector) Q_DECLARE_METATYPE(scriptable::ScriptableMaterial) +Q_DECLARE_METATYPE(scriptable::ScriptableMaterialLayer) Q_DECLARE_METATYPE(scriptable::MultiMaterialMap) diff --git a/libraries/graphics/src/graphics/Material.h b/libraries/graphics/src/graphics/Material.h index f34f68c04a..f9e83a0324 100755 --- a/libraries/graphics/src/graphics/Material.h +++ b/libraries/graphics/src/graphics/Material.h @@ -356,9 +356,9 @@ public: void setTextureTransforms(const Transform& transform); - const std::string& getName() { return _name; } + const std::string& getName() const { return _name; } - const std::string& getModel() { return _model; } + const std::string& getModel() const { return _model; } void setModel(const std::string& model) { _model = model; } protected: From a23884d0e03407841616b4d0bfc6109cc961bcac Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 2 Mar 2018 17:33:28 -0800 Subject: [PATCH 6/9] Prevent crash during long backup web requests --- domain-server/src/DomainServer.cpp | 54 ++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index d2ef1a4156..178345a144 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1937,6 +1937,8 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url const QString UUID_REGEX_STRING = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"; + QPointer connectionPtr { connection }; + auto nodeList = DependencyManager::get(); auto getSetting = [this](QString keyPath, QVariant value) -> bool { @@ -2120,30 +2122,38 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url return true; } else if (url.path() == URI_API_BACKUPS) { auto deferred = makePromise("getAllBackupsAndStatus"); - deferred->then([connection, JSON_MIME_TYPE](QString error, QVariantMap result) { + deferred->then([connectionPtr, JSON_MIME_TYPE](QString error, QVariantMap result) { + if (!connectionPtr) { + return; + } + QJsonDocument docJSON(QJsonObject::fromVariantMap(result)); - connection->respond(HTTPConnection::StatusCode200, docJSON.toJson(), JSON_MIME_TYPE.toUtf8()); + connectionPtr->respond(HTTPConnection::StatusCode200, docJSON.toJson(), JSON_MIME_TYPE.toUtf8()); }); _contentManager->getAllBackupsAndStatus(deferred); return true; } else if (url.path().startsWith(URI_API_BACKUPS_ID)) { auto id = url.path().mid(QString(URI_API_BACKUPS_ID).length()); auto deferred = makePromise("consolidateBackup"); - deferred->then([connection, JSON_MIME_TYPE](QString error, QVariantMap result) { + deferred->then([connectionPtr, JSON_MIME_TYPE](QString error, QVariantMap result) { + if (!connectionPtr) { + return; + } + QJsonObject rootJSON; auto success = result["success"].toBool(); if (success) { auto path = result["backupFilePath"].toString(); auto file { std::unique_ptr(new QFile(path)) }; if (file->open(QIODevice::ReadOnly)) { - connection->respond(HTTPConnection::StatusCode200, std::move(file)); + connectionPtr->respond(HTTPConnection::StatusCode200, std::move(file)); } else { qCritical(domain_server) << "Unable to load consolidated backup at:" << path << result; - connection->respond(HTTPConnection::StatusCode500, "Error opening backup"); + connectionPtr->respond(HTTPConnection::StatusCode500, "Error opening backup"); } } else { - connection->respond(HTTPConnection::StatusCode400); + connectionPtr->respond(HTTPConnection::StatusCode400); } }); _contentManager->consolidateBackup(deferred, id); @@ -2264,12 +2274,16 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url } else if (uploadedFilename.endsWith(".zip", Qt::CaseInsensitive)) { auto deferred = makePromise("recoverFromUploadedBackup"); - deferred->then([connection, JSON_MIME_TYPE](QString error, QVariantMap result) { + deferred->then([connectionPtr, JSON_MIME_TYPE](QString error, QVariantMap result) { + if (!connectionPtr) { + return; + } + QJsonObject rootJSON; auto success = result["success"].toBool(); rootJSON["success"] = success; QJsonDocument docJSON(rootJSON); - connection->respond(success ? HTTPConnection::StatusCode200 : HTTPConnection::StatusCode400, docJSON.toJson(), + connectionPtr->respond(success ? HTTPConnection::StatusCode200 : HTTPConnection::StatusCode400, docJSON.toJson(), JSON_MIME_TYPE.toUtf8()); }); @@ -2297,12 +2311,16 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url } auto deferred = makePromise("createManualBackup"); - deferred->then([connection, JSON_MIME_TYPE](QString error, QVariantMap result) { + deferred->then([connectionPtr, JSON_MIME_TYPE](QString error, QVariantMap result) { + if (!connectionPtr) { + return; + } + QJsonObject rootJSON; auto success = result["success"].toBool(); rootJSON["success"] = success; QJsonDocument docJSON(rootJSON); - connection->respond(success ? HTTPConnection::StatusCode200 : HTTPConnection::StatusCode400, docJSON.toJson(), + connectionPtr->respond(success ? HTTPConnection::StatusCode200 : HTTPConnection::StatusCode400, docJSON.toJson(), JSON_MIME_TYPE.toUtf8()); }); _contentManager->createManualBackup(deferred, it.value()); @@ -2322,12 +2340,16 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url } else if (url.path().startsWith(URI_API_BACKUPS_RECOVER)) { auto id = url.path().mid(QString(URI_API_BACKUPS_RECOVER).length()); auto deferred = makePromise("recoverFromBackup"); - deferred->then([connection, JSON_MIME_TYPE](QString error, QVariantMap result) { + deferred->then([connectionPtr, JSON_MIME_TYPE](QString error, QVariantMap result) { + if (!connectionPtr) { + return; + } + QJsonObject rootJSON; auto success = result["success"].toBool(); rootJSON["success"] = success; QJsonDocument docJSON(rootJSON); - connection->respond(success ? HTTPConnection::StatusCode200 : HTTPConnection::StatusCode400, docJSON.toJson(), + connectionPtr->respond(success ? HTTPConnection::StatusCode200 : HTTPConnection::StatusCode400, docJSON.toJson(), JSON_MIME_TYPE.toUtf8()); }); _contentManager->recoverFromBackup(deferred, id); @@ -2423,12 +2445,16 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url if (url.path().startsWith(URI_API_BACKUPS_ID)) { auto id = url.path().mid(QString(URI_API_BACKUPS_ID).length()); auto deferred = makePromise("deleteBackup"); - deferred->then([connection, JSON_MIME_TYPE](QString error, QVariantMap result) { + deferred->then([connectionPtr, JSON_MIME_TYPE](QString error, QVariantMap result) { + if (!connectionPtr) { + return; + } + QJsonObject rootJSON; auto success = result["success"].toBool(); rootJSON["success"] = success; QJsonDocument docJSON(rootJSON); - connection->respond(success ? HTTPConnection::StatusCode200 : HTTPConnection::StatusCode400, docJSON.toJson(), + connectionPtr->respond(success ? HTTPConnection::StatusCode200 : HTTPConnection::StatusCode400, docJSON.toJson(), JSON_MIME_TYPE.toUtf8()); }); _contentManager->deleteBackup(deferred, id); From a83b54e10dd63f312d143b6b9ac1b850410f7900 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 6 Mar 2018 13:52:41 -0800 Subject: [PATCH 7/9] fix for getSetting QVariant ref in DomainServer --- domain-server/src/DomainServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index d2ef1a4156..cf99ca4344 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1939,7 +1939,7 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url auto nodeList = DependencyManager::get(); - auto getSetting = [this](QString keyPath, QVariant value) -> bool { + auto getSetting = [this](QString keyPath, QVariant& value) -> bool { value = _settingsManager.valueForKeyPath(keyPath); if (!value.isValid()) { From 17c12fde9c66ca0fd723b478eee7aa4b93fab588 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Tue, 6 Mar 2018 16:32:04 -0800 Subject: [PATCH 8/9] Fix for HandshakeRequest logic --- libraries/networking/src/udt/Connection.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/networking/src/udt/Connection.cpp b/libraries/networking/src/udt/Connection.cpp index 77ed589e0b..b34c05106f 100644 --- a/libraries/networking/src/udt/Connection.cpp +++ b/libraries/networking/src/udt/Connection.cpp @@ -578,6 +578,7 @@ void Connection::processControl(ControlPacketPointer controlPacket) { #ifdef UDT_CONNECTION_DEBUG qCDebug(networking) << "Got handshake request, stopping SendQueue"; #endif + _hasReceivedHandshakeACK = false; stopSendQueue(); } break; From 0aacdcd5580f4d63530023d694d2c9a8ec5c72a0 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 7 Mar 2018 13:33:39 -0800 Subject: [PATCH 9/9] docs --- .../graphics-scripting/src/graphics-scripting/Forward.h | 6 ++++++ .../src/graphics-scripting/ScriptableModel.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/libraries/graphics-scripting/src/graphics-scripting/Forward.h b/libraries/graphics-scripting/src/graphics-scripting/Forward.h index 3d710b41b4..ed8e96a12f 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/Forward.h +++ b/libraries/graphics-scripting/src/graphics-scripting/Forward.h @@ -65,6 +65,12 @@ namespace scriptable { QString lightmapMap; QString scatteringMap; }; + + /**jsdoc + * @typedef {object} Graphics.MaterialLayer + * @property {Material} material - This layer's material. + * @property {number} priority - The priority of this layer. If multiple materials are applied to a mesh part, only the highest priority layer is used. + */ class ScriptableMaterialLayer { public: ScriptableMaterialLayer() {} diff --git a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h index a1278132ca..ac0b7b9623 100644 --- a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h +++ b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h @@ -21,6 +21,8 @@ namespace scriptable { * @property {Uuid} objectID - UUID of corresponding inworld object (if model is associated) * @property {number} numMeshes - The number of submeshes contained in the model. * @property {Graphics.Mesh[]} meshes - Array of submesh references. + * @property {Object.} materialLayers - Map of materials layer lists. You can look up a material layer list by mesh part number or by material name. + * @property {string[]} materialNames - Array of all the material names used by the mesh parts of this model, in order (e.g. materialNames[0] is the name of the first mesh part's material). */ class ScriptableModel : public ScriptableModelBase {