mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Move asset baking on asset server to separate process
This commit is contained in:
parent
a5e671e0fd
commit
f3fc5769e8
8 changed files with 105 additions and 19 deletions
|
@ -12,16 +12,23 @@
|
|||
#include "BakeAssetTask.h"
|
||||
|
||||
#include <QtCore/QThread>
|
||||
#include <QProcess>
|
||||
|
||||
#include <FBXBaker.h>
|
||||
#include <PathUtils.h>
|
||||
#include <JSBaker.h>
|
||||
|
||||
static const int OVEN_STATUS_CODE_SUCCESS { 0 };
|
||||
static const int OVEN_STATUS_CODE_FAIL { 1 };
|
||||
static const int OVEN_STATUS_CODE_ABORT { 2 };
|
||||
|
||||
BakeAssetTask::BakeAssetTask(const AssetHash& assetHash, const AssetPath& assetPath, const QString& filePath) :
|
||||
_assetHash(assetHash),
|
||||
_assetPath(assetPath),
|
||||
_filePath(filePath)
|
||||
{
|
||||
qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
|
||||
qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus");
|
||||
|
||||
}
|
||||
|
||||
|
@ -43,22 +50,74 @@ void cleanupTempFiles(QString tempOutputDir, std::vector<QString> files) {
|
|||
void BakeAssetTask::run() {
|
||||
_isBaking.store(true);
|
||||
|
||||
QString tempOutputDir = PathUtils::generateTemporaryDir();
|
||||
_outputDir = tempOutputDir;
|
||||
auto base = QFileInfo(QCoreApplication::applicationFilePath()).absoluteDir();
|
||||
QString path = base.absolutePath() + "/../../tools/oven/RelWithDebInfo/oven.exe";
|
||||
path = base.absolutePath() + "/../tools/oven/oven";
|
||||
//path = "C:/Users/huffm/dev/hifi/build17/tools/oven/RelWithDebInfo/oven.exe";
|
||||
QString extension = _assetPath.mid(_assetPath.lastIndexOf('.') + 1);
|
||||
QStringList args {
|
||||
"-i", _filePath,
|
||||
"-o", tempOutputDir,
|
||||
"-t", extension,
|
||||
};
|
||||
|
||||
qDebug().noquote() << "Path: " << path << args.join(' ');
|
||||
QProcess* proc = new QProcess();
|
||||
|
||||
connect(proc, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
|
||||
this, [this, proc, tempOutputDir](int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
qDebug() << "Finished process: " << exitCode << exitStatus;
|
||||
qDebug() << "stdout: " << proc->readAllStandardOutput();
|
||||
|
||||
auto files = _outputDir.entryInfoList(QDir::Files);
|
||||
QVector<QString> outputFiles;
|
||||
for (auto& file : files) {
|
||||
qDebug() << "Output file: " << file.absoluteFilePath();
|
||||
outputFiles.push_back(file.absoluteFilePath());
|
||||
}
|
||||
|
||||
if (exitCode == OVEN_STATUS_CODE_SUCCESS) {
|
||||
emit bakeComplete(_assetHash, _assetPath, tempOutputDir, outputFiles);
|
||||
} else if (exitCode == OVEN_STATUS_CODE_ABORT) {
|
||||
emit bakeAborted(_assetHash, _assetPath);
|
||||
} else {
|
||||
QString errors;
|
||||
if (exitCode == OVEN_STATUS_CODE_FAIL) {
|
||||
}
|
||||
emit bakeFailed(_assetHash, _assetPath, errors);
|
||||
}
|
||||
|
||||
});
|
||||
connect(proc, &QProcess::errorOccurred, this, []() {
|
||||
qDebug() << "Error occurred :(";
|
||||
});
|
||||
connect(proc, &QProcess::started, this, []() {
|
||||
qDebug() << "Process started";
|
||||
});
|
||||
|
||||
qDebug() << "Starting process!";
|
||||
proc->start(path, args, QIODevice::ReadOnly);
|
||||
proc->waitForStarted();
|
||||
qDebug() << "Started";
|
||||
proc->waitForFinished();
|
||||
qDebug() << "Finished";
|
||||
|
||||
return;
|
||||
|
||||
qRegisterMetaType<QVector<QString> >("QVector<QString>");
|
||||
TextureBakerThreadGetter fn = []() -> QThread* { return QThread::currentThread(); };
|
||||
|
||||
QString tempOutputDir;
|
||||
|
||||
if (_assetPath.endsWith(".fbx")) {
|
||||
tempOutputDir = PathUtils::generateTemporaryDir();
|
||||
_baker = std::unique_ptr<FBXBaker> {
|
||||
new FBXBaker(QUrl("file:///" + _filePath), fn, tempOutputDir)
|
||||
};
|
||||
} else if (_assetPath.endsWith(".js", Qt::CaseInsensitive)) {
|
||||
_baker = std::unique_ptr<JSBaker>{
|
||||
new JSBaker(QUrl("file:///" + _filePath), PathUtils::generateTemporaryDir())
|
||||
new JSBaker(QUrl("file:///" + _filePath), tempOutputDir)
|
||||
};
|
||||
} else {
|
||||
tempOutputDir = PathUtils::generateTemporaryDir();
|
||||
_baker = std::unique_ptr<TextureBaker> {
|
||||
new TextureBaker(QUrl("file:///" + _filePath), image::TextureUsage::CUBE_TEXTURE,
|
||||
tempOutputDir)
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QRunnable>
|
||||
#include <QDir>
|
||||
|
||||
#include <AssetUtils.h>
|
||||
#include <Baker.h>
|
||||
|
@ -44,6 +45,7 @@ private:
|
|||
AssetHash _assetHash;
|
||||
AssetPath _assetPath;
|
||||
QString _filePath;
|
||||
QDir _outputDir;
|
||||
std::unique_ptr<Baker> _baker;
|
||||
std::atomic<bool> _wasAborted { false };
|
||||
std::atomic<bool> _didFinish { false };
|
||||
|
|
|
@ -1149,7 +1149,7 @@ bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoin
|
|||
if (model && model->isLoaded()) {
|
||||
if (!entity->_dimensionsInitialized || entity->_needsInitialSimulation) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if we need to update the model bounds
|
||||
if (entity->needsUpdateModelBounds()) {
|
||||
|
|
|
@ -17,4 +17,4 @@ if (UNIX)
|
|||
endif()
|
||||
endif ()
|
||||
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES EXCLUDE_FROM_ALL TRUE EXCLUDE_FROM_DEFAULT_BUILD TRUE)
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES EXCLUDE_FROM_ALL FALSE EXCLUDE_FROM_DEFAULT_BUILD FALSE)
|
||||
|
|
|
@ -22,22 +22,28 @@
|
|||
BakerCLI::BakerCLI(Oven* parent) : QObject(parent) {
|
||||
}
|
||||
|
||||
void BakerCLI::bakeFile(QUrl inputUrl, const QString outputPath) {
|
||||
void BakerCLI::bakeFile(QUrl inputUrl, const QString& outputPath, const QString& type) {
|
||||
|
||||
// if the URL doesn't have a scheme, assume it is a local file
|
||||
if (inputUrl.scheme() != "http" && inputUrl.scheme() != "https" && inputUrl.scheme() != "ftp") {
|
||||
inputUrl.setScheme("file");
|
||||
}
|
||||
|
||||
static const QString MODEL_EXTENSION { ".fbx" };
|
||||
qDebug() << "Type: " << type;
|
||||
|
||||
static const QString MODEL_EXTENSION { "fbx" };
|
||||
|
||||
QString extension = type;
|
||||
|
||||
if (extension.isNull()) {
|
||||
auto url = inputUrl.toDisplayString();
|
||||
extension = url.mid(url.lastIndexOf('.'));
|
||||
}
|
||||
|
||||
// check what kind of baker we should be creating
|
||||
bool isFBX = inputUrl.toDisplayString().endsWith(MODEL_EXTENSION, Qt::CaseInsensitive);
|
||||
bool isSupportedImage = false;
|
||||
bool isFBX = extension == MODEL_EXTENSION;//inputUrl.toDisplayString().endsWith(MODEL_EXTENSION, Qt::CaseInsensitive);
|
||||
|
||||
for (QByteArray format : QImageReader::supportedImageFormats()) {
|
||||
isSupportedImage |= inputUrl.toDisplayString().endsWith(format, Qt::CaseInsensitive);
|
||||
}
|
||||
bool isSupportedImage = QImageReader::supportedImageFormats().contains(extension.toLatin1());
|
||||
|
||||
// create our appropiate baker
|
||||
if (isFBX) {
|
||||
|
@ -60,5 +66,12 @@ void BakerCLI::bakeFile(QUrl inputUrl, const QString outputPath) {
|
|||
|
||||
void BakerCLI::handleFinishedBaker() {
|
||||
qCDebug(model_baking) << "Finished baking file.";
|
||||
QApplication::exit(_baker.get()->hasErrors());
|
||||
int exitCode = OVEN_STATUS_CODE_SUCCESS;
|
||||
// Do we need this?
|
||||
if (_baker.get()->wasAborted()) {
|
||||
exitCode = OVEN_STATUS_CODE_ABORT;
|
||||
} else if (_baker.get()->hasErrors()) {
|
||||
exitCode = OVEN_STATUS_CODE_FAIL;
|
||||
}
|
||||
QApplication::exit(exitCode);
|
||||
}
|
||||
|
|
|
@ -14,15 +14,23 @@
|
|||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "Baker.h"
|
||||
#include "Oven.h"
|
||||
|
||||
static const int OVEN_STATUS_CODE_SUCCESS { 0 };
|
||||
static const int OVEN_STATUS_CODE_FAIL { 1 };
|
||||
static const int OVEN_STATUS_CODE_ABORT { 2 };
|
||||
|
||||
static const QString OVEN_ERROR_FILENAME = "errors.txt";
|
||||
|
||||
class BakerCLI : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BakerCLI(Oven* parent);
|
||||
void bakeFile(QUrl inputUrl, const QString outputPath);
|
||||
void bakeFile(QUrl inputUrl, const QString& outputPath, const QString& type = QString::null);
|
||||
|
||||
private slots:
|
||||
void handleFinishedBaker();
|
||||
|
@ -31,4 +39,4 @@ private:
|
|||
std::unique_ptr<Baker> _baker;
|
||||
};
|
||||
|
||||
#endif // hifi_BakerCLI_h
|
||||
#endif // hifi_BakerCLI_h
|
||||
|
|
|
@ -24,6 +24,7 @@ static const QString OUTPUT_FOLDER = "/Users/birarda/code/hifi/lod/test-oven/exp
|
|||
|
||||
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)
|
||||
|
@ -39,7 +40,8 @@ Oven::Oven(int argc, char* argv[]) :
|
|||
|
||||
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_OUTPUT_PARAMETER, "Path to folder that will be used as output.", "output" },
|
||||
{ CLI_TYPE_PARAMETER, "Type of asset.", "type" }
|
||||
});
|
||||
parser.addHelpOption();
|
||||
parser.process(*this);
|
||||
|
@ -59,7 +61,8 @@ Oven::Oven(int argc, char* argv[]) :
|
|||
BakerCLI* cli = new BakerCLI(this);
|
||||
QUrl inputUrl(QDir::fromNativeSeparators(parser.value(CLI_INPUT_PARAMETER)));
|
||||
QUrl outputUrl(QDir::fromNativeSeparators(parser.value(CLI_OUTPUT_PARAMETER)));
|
||||
cli->bakeFile(inputUrl, outputUrl.toString());
|
||||
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();
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#define hifi_BakeWidget_h
|
||||
|
||||
#include <QtWidgets/QWidget>
|
||||
#include <memory>
|
||||
|
||||
#include <Baker.h>
|
||||
|
||||
|
|
Loading…
Reference in a new issue