From 52df77b4b560005aece460c907058fc055ac054b Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 2 Apr 2014 16:25:35 -0700 Subject: [PATCH 1/9] Final work on models metadata support --- interface/src/ui/ModelsBrowser.cpp | 114 +++++++++++++++++------- interface/src/ui/ModelsBrowser.h | 14 ++- libraries/shared/src/FileDownloader.cpp | 45 ---------- libraries/shared/src/FileDownloader.h | 41 --------- 4 files changed, 87 insertions(+), 127 deletions(-) delete mode 100644 libraries/shared/src/FileDownloader.cpp delete mode 100644 libraries/shared/src/FileDownloader.h diff --git a/interface/src/ui/ModelsBrowser.cpp b/interface/src/ui/ModelsBrowser.cpp index 15f1e9111e..e128d047ef 100644 --- a/interface/src/ui/ModelsBrowser.cpp +++ b/interface/src/ui/ModelsBrowser.cpp @@ -8,11 +8,10 @@ #include #include -#include #include #include #include -#include +#include #include #include @@ -33,27 +32,39 @@ static const QString KEY_NAME = "Key"; static const QString LOADING_MSG = "Loading..."; static const QString ERROR_MSG = "Error loading files"; +static const QString DO_NOT_MODIFY_TAG = "DoNotModify"; + enum ModelMetaData { NAME, - CREATOR, - UPLOAD_DATE, TYPE, GENDER, + CREATOR, + UPLOAD_DATE, MODEL_METADATA_COUNT }; static const QString propertiesNames[MODEL_METADATA_COUNT] = { "Name", - "Creator", - "Upload Date", "Type", - "Gender" + "Gender", + "Creator", + "Last Modified" +}; +static const QString propertiesIds[MODEL_METADATA_COUNT] = { + DO_NOT_MODIFY_TAG, + "Type", + "Gender", + "x-amz-request-id", + "Last-Modified" }; ModelsBrowser::ModelsBrowser(ModelType modelsType, QWidget* parent) : QWidget(parent), _handler(new ModelHandler(modelsType)) { + connect(_handler, SIGNAL(doneDownloading()), SLOT(resizeView())); + connect(_handler, SIGNAL(updated()), SLOT(resizeView())); + // Connect handler _handler->connect(this, SIGNAL(startDownloading()), SLOT(download())); _handler->connect(_handler, SIGNAL(doneDownloading()), SLOT(update())); @@ -106,6 +117,12 @@ void ModelsBrowser::applyFilter(const QString &filter) { _handler->unlockModel(); } +void ModelsBrowser::resizeView() { + for (int i = 0; i < MODEL_METADATA_COUNT; ++i) { + _view.resizeColumnToContents(i); + } +} + void ModelsBrowser::browse() { QDialog dialog; dialog.setWindowTitle("Browse models"); @@ -145,8 +162,6 @@ ModelHandler::ModelHandler(ModelType modelsType, QWidget* parent) : _initiateExit(false), _type(modelsType) { - connect(&_downloader, SIGNAL(done(QNetworkReply::NetworkError)), SLOT(downloadFinished())); - // set headers data QStringList headerData; for (int i = 0; i < MODEL_METADATA_COUNT; ++i) { @@ -156,9 +171,6 @@ ModelHandler::ModelHandler(ModelType modelsType, QWidget* parent) : } void ModelHandler::download() { - // Query models list - queryNewFiles(); - _lock.lockForWrite(); if (_initiateExit) { _lock.unlock(); @@ -169,10 +181,25 @@ void ModelHandler::download() { loadingItem->setEnabled(false); _model.appendRow(loadingItem); _lock.unlock(); + + // Query models list + queryNewFiles(); } void ModelHandler::update() { - // Will be implemented in my next PR + _lock.lockForWrite(); + if (_initiateExit) { + _lock.unlock(); + return; + } + for (int i = 0; i < _model.rowCount(); ++i) { + QUrl url(_model.item(i,0)->data(Qt::UserRole).toString()); + QNetworkAccessManager* accessManager = new QNetworkAccessManager(this); + QNetworkRequest request(url); + accessManager->head(request); + connect(accessManager, SIGNAL(finished(QNetworkReply*)), SLOT(downloadFinished(QNetworkReply*))); + } + _lock.unlock(); } void ModelHandler::exit() { @@ -180,7 +207,6 @@ void ModelHandler::exit() { _initiateExit = true; // Disconnect everything - _downloader.disconnect(); disconnect(); thread()->disconnect(); @@ -191,12 +217,16 @@ void ModelHandler::exit() { _lock.unlock(); } -void ModelHandler::downloadFinished() { - if (_downloader.getData().startsWith("readAll(); + + if (!data.isEmpty()) { + parseXML(data); } else { - qDebug() << _downloader.getData(); + parseHeaders(reply); } + reply->deleteLater(); + sender()->deleteLater(); } void ModelHandler::queryNewFiles(QString marker) { @@ -219,7 +249,11 @@ void ModelHandler::queryNewFiles(QString marker) { // Download url.setQuery(query); - _downloader.download(url); + QNetworkAccessManager* accessManager = new QNetworkAccessManager(this); + QNetworkRequest request(url); + accessManager->get(request); + connect(accessManager, SIGNAL(finished(QNetworkReply*)), SLOT(downloadFinished(QNetworkReply*))); + } bool ModelHandler::parseXML(QByteArray xmlFile) { @@ -266,18 +300,9 @@ bool ModelHandler::parseXML(QByteArray xmlFile) { QList model; model << new QStandardItem(QFileInfo(xml.text().toString()).baseName()); model.first()->setData(PUBLIC_URL + "/" + xml.text().toString(), Qt::UserRole); - - // Rand properties for now (Will be taken out in the next PR) - static QString creator[] = {"Ryan", "Philip", "Andzrej"}; - static QString type[] = {"human", "beast", "pet", "elfe"}; - static QString gender[] = {"male", "female", "none"}; - model << new QStandardItem(creator[randIntInRange(0, 2)]); - model << new QStandardItem(QDate(randIntInRange(2013, 2014), - randIntInRange(1, 12), - randIntInRange(1, 30)).toString()); - model << new QStandardItem(type[randIntInRange(0, 3)]); - model << new QStandardItem(gender[randIntInRange(0, 2)]); - //////////////////////////////////////////////////////////// + for (int i = 1; i < MODEL_METADATA_COUNT; ++i) { + model << new QStandardItem(); + } _model.appendRow(model); } @@ -312,9 +337,32 @@ bool ModelHandler::parseXML(QByteArray xmlFile) { _lock.unlock(); if (!truncated) { - qDebug() << "Emitting..."; emit doneDownloading(); } return true; -} \ No newline at end of file +} + +bool ModelHandler::parseHeaders(QNetworkReply* reply) { + _lock.lockForWrite(); + + QList items = _model.findItems(QFileInfo(reply->url().toString()).baseName()); + if (items.isEmpty() || items.first()->text() == DO_NOT_MODIFY_TAG) { + return false; + } + + for (int i = 0; i < MODEL_METADATA_COUNT; ++i) { + for (int k = 1; k < reply->rawHeaderPairs().count(); ++k) { + QString key = reply->rawHeaderPairs().at(k).first.data(); + QString item = reply->rawHeaderPairs().at(k).second.data(); + if (key == propertiesIds[i]) { + _model.item(_model.indexFromItem(items.first()).row(), i)->setText(item); + } + } + } + _lock.unlock(); + + emit updated(); + return true; +} + diff --git a/interface/src/ui/ModelsBrowser.h b/interface/src/ui/ModelsBrowser.h index 9bc239ba18..30320de1c1 100644 --- a/interface/src/ui/ModelsBrowser.h +++ b/interface/src/ui/ModelsBrowser.h @@ -9,13 +9,10 @@ #ifndef __hifi__ModelsBrowser__ #define __hifi__ModelsBrowser__ -#include -#include -#include -#include #include +#include +#include -#include "FileDownloader.h" enum ModelType { Head, @@ -33,7 +30,7 @@ public: signals: void doneDownloading(); - void doneUpdating(); + void updated(); public slots: void download(); @@ -41,17 +38,17 @@ public slots: void exit(); private slots: - void downloadFinished(); + void downloadFinished(QNetworkReply* reply); private: bool _initiateExit; ModelType _type; - FileDownloader _downloader; QReadWriteLock _lock; QStandardItemModel _model; void queryNewFiles(QString marker = QString()); bool parseXML(QByteArray xmlFile); + bool parseHeaders(QNetworkReply* reply); }; @@ -71,6 +68,7 @@ public slots: private slots: void applyFilter(const QString& filter); + void resizeView(); private: ModelHandler* _handler; diff --git a/libraries/shared/src/FileDownloader.cpp b/libraries/shared/src/FileDownloader.cpp deleted file mode 100644 index 8b13b129fe..0000000000 --- a/libraries/shared/src/FileDownloader.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// -// FileDownloader.cpp -// hifi -// -// Created by Clement Brisset on 3/14/14. -// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. -// -// - -#include -#include -#include -#include - -#include "FileDownloader.h" - -FileDownloader::FileDownloader(QObject* parent) : QObject(parent) { - connect(&_networkAccessManager, SIGNAL(finished(QNetworkReply*)), SLOT(processReply(QNetworkReply*))); -} - -void FileDownloader::download(const QUrl& dataURL, QNetworkAccessManager::Operation operation) { - QNetworkRequest request(dataURL); - - _downloadedData.clear(); - switch (operation) { - case QNetworkAccessManager::GetOperation: - _networkAccessManager.get(request); - break; - case QNetworkAccessManager::HeadOperation: - _networkAccessManager.head(request); - break; - default: - emit done(QNetworkReply::ProtocolInvalidOperationError); - break; - } -} - -void FileDownloader::processReply(QNetworkReply *reply) { - if (reply->error() == QNetworkReply::NoError) { - _downloadedData = reply->readAll(); - } - - reply->deleteLater(); - emit done(reply->error()); -} \ No newline at end of file diff --git a/libraries/shared/src/FileDownloader.h b/libraries/shared/src/FileDownloader.h deleted file mode 100644 index ad1351a575..0000000000 --- a/libraries/shared/src/FileDownloader.h +++ /dev/null @@ -1,41 +0,0 @@ -// -// FileDownloader.h -// hifi -// -// Created by Clement Brisset on 3/14/14. -// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. -// -// - -#ifndef __hifi__FileDownloader__ -#define __hifi__FileDownloader__ - -#include -#include -#include -#include - -class FileDownloader : public QObject { - Q_OBJECT - -public: - FileDownloader(QObject* parent = NULL); - QByteArray getData() const { return _downloadedData; } - - -signals: - void done(QNetworkReply::NetworkError error); - -public slots: - void download(const QUrl& dataURL, QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation); - -private slots: - void processReply(QNetworkReply* reply); - -private: - QNetworkAccessManager _networkAccessManager; - QByteArray _downloadedData; -}; - - -#endif /* defined(__hifi__FileDownloader__) */ From cf20c448a3100ab1ca51bbee858b4f15d7d70d6f Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 2 Apr 2014 16:46:03 -0700 Subject: [PATCH 2/9] Few tweaks before PR --- interface/src/ui/ModelsBrowser.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/ModelsBrowser.cpp b/interface/src/ui/ModelsBrowser.cpp index e128d047ef..276fdd24c1 100644 --- a/interface/src/ui/ModelsBrowser.cpp +++ b/interface/src/ui/ModelsBrowser.cpp @@ -54,7 +54,7 @@ static const QString propertiesIds[MODEL_METADATA_COUNT] = { DO_NOT_MODIFY_TAG, "Type", "Gender", - "x-amz-request-id", + "Creator", "Last-Modified" }; @@ -97,7 +97,7 @@ void ModelsBrowser::applyFilter(const QString &filter) { for (int k = 0; k < filters.count(); ++k) { match = false; for (int j = 0; j < MODEL_METADATA_COUNT; ++j) { - if (model->item(i, j)->text().contains(filters.at(k))) { + if (model->item(i, j)->text().contains(filters.at(k), Qt::CaseInsensitive)) { match = true; break; } @@ -359,6 +359,22 @@ bool ModelHandler::parseHeaders(QNetworkReply* reply) { _model.item(_model.indexFromItem(items.first()).row(), i)->setText(item); } } + + // Rand properties for now (Will be taken out when we have real metadata on the server) + if (_model.item(_model.indexFromItem(items.first()).row(), i)->text().isEmpty()) { + if (i == CREATOR) { + static QString creator[] = {"Ryan", "Philip", "Andzrej", "Phteven", "Brad"}; + _model.item(_model.indexFromItem(items.first()).row(), i)->setText(creator[randIntInRange(0, 4)]); + } else if (i == TYPE) { + static QString type[] = {"human", "beast", "pet", "elfe"}; + _model.item(_model.indexFromItem(items.first()).row(), i)->setText(type[randIntInRange(0, 3)]); + } else if (i == GENDER) { + static QString gender[] = {"male", "female", "none"}; + _model.item(_model.indexFromItem(items.first()).row(), i)->setText(gender[randIntInRange(0, 2)]); + } + } + //////////////////////////////////////////////////////////// + } _lock.unlock(); From c2f0545d96c3af7fc1c1f047a3b42d66d0a58826 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 2 Apr 2014 17:12:11 -0700 Subject: [PATCH 3/9] Setup for actual metadata --- interface/src/ui/ModelsBrowser.cpp | 37 ++++++++++-------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/interface/src/ui/ModelsBrowser.cpp b/interface/src/ui/ModelsBrowser.cpp index 276fdd24c1..616aba3881 100644 --- a/interface/src/ui/ModelsBrowser.cpp +++ b/interface/src/ui/ModelsBrowser.cpp @@ -36,26 +36,29 @@ static const QString DO_NOT_MODIFY_TAG = "DoNotModify"; enum ModelMetaData { NAME, - TYPE, - GENDER, CREATOR, - UPLOAD_DATE, + DATE_ADDED, + TOTAL_SIZE, + POLY_NUM, + TAGS, MODEL_METADATA_COUNT }; static const QString propertiesNames[MODEL_METADATA_COUNT] = { "Name", - "Type", - "Gender", "Creator", - "Last Modified" + "Date Added", + "Total Size", + "Poly#", + "Tags" }; static const QString propertiesIds[MODEL_METADATA_COUNT] = { DO_NOT_MODIFY_TAG, - "Type", - "Gender", "Creator", - "Last-Modified" + "Date-Added", + "Total-Size", + "Poly-Num", + "Tags" }; ModelsBrowser::ModelsBrowser(ModelType modelsType, QWidget* parent) : @@ -359,22 +362,6 @@ bool ModelHandler::parseHeaders(QNetworkReply* reply) { _model.item(_model.indexFromItem(items.first()).row(), i)->setText(item); } } - - // Rand properties for now (Will be taken out when we have real metadata on the server) - if (_model.item(_model.indexFromItem(items.first()).row(), i)->text().isEmpty()) { - if (i == CREATOR) { - static QString creator[] = {"Ryan", "Philip", "Andzrej", "Phteven", "Brad"}; - _model.item(_model.indexFromItem(items.first()).row(), i)->setText(creator[randIntInRange(0, 4)]); - } else if (i == TYPE) { - static QString type[] = {"human", "beast", "pet", "elfe"}; - _model.item(_model.indexFromItem(items.first()).row(), i)->setText(type[randIntInRange(0, 3)]); - } else if (i == GENDER) { - static QString gender[] = {"male", "female", "none"}; - _model.item(_model.indexFromItem(items.first()).row(), i)->setText(gender[randIntInRange(0, 2)]); - } - } - //////////////////////////////////////////////////////////// - } _lock.unlock(); From 3bb6d9b3b33caa7fb28665fdce2992d7518daa74 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 3 Apr 2014 16:07:25 -0700 Subject: [PATCH 4/9] Added call back to model upload. --- libraries/shared/src/FstReader.cpp | 24 ++++++++++++++++++++++-- libraries/shared/src/FstReader.h | 7 +++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/libraries/shared/src/FstReader.cpp b/libraries/shared/src/FstReader.cpp index fa71679dd2..4a299fd757 100644 --- a/libraries/shared/src/FstReader.cpp +++ b/libraries/shared/src/FstReader.cpp @@ -172,14 +172,34 @@ bool FstReader::send() { return false; } - AccountManager::getInstance().authenticatedRequest(MODEL_URL, QNetworkAccessManager::PostOperation, JSONCallbackParameters(), QByteArray(), _dataMultiPart); + JSONCallbackParameters callbackParams; + callbackParams.jsonCallbackReceiver = this; + callbackParams.jsonCallbackMethod = "uploadSuccess"; + callbackParams.errorCallbackReceiver = this; + callbackParams.errorCallbackMethod = "uploadFailed"; + + AccountManager::getInstance().authenticatedRequest(MODEL_URL, QNetworkAccessManager::PostOperation, callbackParams, QByteArray(), _dataMultiPart); _zipDir = NULL; _dataMultiPart = NULL; - qDebug() << "Model sent."; return true; } +void FstReader::uploadSuccess(const QJsonObject& jsonResponse) { + qDebug() << "Model sent with success to the data server."; + qDebug() << "It might take a few minute for it to appear in your model browser."; + deleteLater(); +} + +void FstReader::uploadFailed(QNetworkReply::NetworkError errorCode, const QString& errorString) { + QMessageBox::warning(NULL, + QString("ModelUploader::uploadFailed()"), + QString("Model could not be sent to the data server."), + QMessageBox::Ok); + qDebug() << "Model upload failed (" << errorCode << "): " << errorString; + deleteLater(); +} + bool FstReader::addTextures(const QFileInfo& texdir) { QStringList filter; filter << "*.png" << "*.tif" << "*.jpg" << "*.jpeg"; diff --git a/libraries/shared/src/FstReader.h b/libraries/shared/src/FstReader.h index 6d1cac01c4..2ccf21a3b0 100644 --- a/libraries/shared/src/FstReader.h +++ b/libraries/shared/src/FstReader.h @@ -12,8 +12,11 @@ class TemporaryDir; class QHttpMultiPart; +class QFileInfo; class FstReader : public QObject { + Q_OBJECT + public: FstReader(bool isHead); ~FstReader(); @@ -21,6 +24,10 @@ public: bool zip(); bool send(); +private slots: + void uploadSuccess(const QJsonObject& jsonResponse); + void uploadFailed(QNetworkReply::NetworkError errorCode, const QString& errorString); + private: TemporaryDir* _zipDir; int _lodCount; From 9166dea02eadb04a2810d28c2b7771dd99f494e7 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 3 Apr 2014 16:16:58 -0700 Subject: [PATCH 5/9] Changed FstReader name to ModelUploader --- interface/src/Application.cpp | 8 +++---- .../src/{FstReader.cpp => ModelUploader.cpp} | 22 +++++++++---------- .../src/{FstReader.h => ModelUploader.h} | 14 ++++++------ 3 files changed, 22 insertions(+), 22 deletions(-) rename libraries/shared/src/{FstReader.cpp => ModelUploader.cpp} (94%) rename libraries/shared/src/{FstReader.h => ModelUploader.h} (78%) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 18a3a228d6..83eab37318 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -63,7 +63,7 @@ #include #include #include -#include +#include #include "Application.h" #include "InterfaceVersion.h" @@ -3244,9 +3244,9 @@ void Application::toggleRunningScriptsWidget() } void Application::uploadFST(bool isHead) { - FstReader reader(isHead); - if (reader.zip()) { - reader.send(); + ModelUploader* uploader = new ModelUploader(isHead); + if (uploader->zip()) { + uploader->send(); } } diff --git a/libraries/shared/src/FstReader.cpp b/libraries/shared/src/ModelUploader.cpp similarity index 94% rename from libraries/shared/src/FstReader.cpp rename to libraries/shared/src/ModelUploader.cpp index 4a299fd757..aeeb3f642e 100644 --- a/libraries/shared/src/FstReader.cpp +++ b/libraries/shared/src/ModelUploader.cpp @@ -1,5 +1,5 @@ // -// FstReader.cpp +// ModelUploader.cpp // hifi // // Created by Clément Brisset on 3/4/14. @@ -18,7 +18,7 @@ #include #include "AccountManager.h" -#include "FstReader.h" +#include "ModelUploader.h" static const QString NAME_FIELD = "name"; @@ -38,7 +38,7 @@ public: } }; -FstReader::FstReader(bool isHead) : +ModelUploader::ModelUploader(bool isHead) : _zipDir(new TemporaryDir()), _lodCount(-1), _texturesCount(-1), @@ -51,11 +51,11 @@ FstReader::FstReader(bool isHead) : } -FstReader::~FstReader() { +ModelUploader::~ModelUploader() { delete _dataMultiPart; } -bool FstReader::zip() { +bool ModelUploader::zip() { // File Dialog QString filename = QFileDialog::getOpenFileName(NULL, "Select your .fst file ...", @@ -167,7 +167,7 @@ bool FstReader::zip() { return true; } -bool FstReader::send() { +bool ModelUploader::send() { if (!_readyToSend) { return false; } @@ -185,13 +185,13 @@ bool FstReader::send() { return true; } -void FstReader::uploadSuccess(const QJsonObject& jsonResponse) { +void ModelUploader::uploadSuccess(const QJsonObject& jsonResponse) { qDebug() << "Model sent with success to the data server."; qDebug() << "It might take a few minute for it to appear in your model browser."; deleteLater(); } -void FstReader::uploadFailed(QNetworkReply::NetworkError errorCode, const QString& errorString) { +void ModelUploader::uploadFailed(QNetworkReply::NetworkError errorCode, const QString& errorString) { QMessageBox::warning(NULL, QString("ModelUploader::uploadFailed()"), QString("Model could not be sent to the data server."), @@ -200,7 +200,7 @@ void FstReader::uploadFailed(QNetworkReply::NetworkError errorCode, const QStrin deleteLater(); } -bool FstReader::addTextures(const QFileInfo& texdir) { +bool ModelUploader::addTextures(const QFileInfo& texdir) { QStringList filter; filter << "*.png" << "*.tif" << "*.jpg" << "*.jpeg"; @@ -229,7 +229,7 @@ bool FstReader::addTextures(const QFileInfo& texdir) { return true; } -bool FstReader::compressFile(const QString &inFileName, const QString &outFileName) { +bool ModelUploader::compressFile(const QString &inFileName, const QString &outFileName) { QFile inFile(inFileName); inFile.open(QIODevice::ReadOnly); QByteArray buffer = inFile.readAll(); @@ -253,7 +253,7 @@ bool FstReader::compressFile(const QString &inFileName, const QString &outFileNa } -bool FstReader::addPart(const QString &path, const QString& name) { +bool ModelUploader::addPart(const QString &path, const QString& name) { QFile* file = new QFile(path); if (!file->open(QIODevice::ReadOnly)) { QMessageBox::warning(NULL, diff --git a/libraries/shared/src/FstReader.h b/libraries/shared/src/ModelUploader.h similarity index 78% rename from libraries/shared/src/FstReader.h rename to libraries/shared/src/ModelUploader.h index 2ccf21a3b0..f127008f44 100644 --- a/libraries/shared/src/FstReader.h +++ b/libraries/shared/src/ModelUploader.h @@ -1,5 +1,5 @@ // -// FstReader.h +// ModelUploader.h // hifi // // Created by Clément Brisset on 3/4/14. @@ -7,19 +7,19 @@ // // -#ifndef __hifi__FstReader__ -#define __hifi__FstReader__ +#ifndef __hifi__ModelUploader__ +#define __hifi__ModelUploader__ class TemporaryDir; class QHttpMultiPart; class QFileInfo; -class FstReader : public QObject { +class ModelUploader : public QObject { Q_OBJECT public: - FstReader(bool isHead); - ~FstReader(); + ModelUploader(bool isHead); + ~ModelUploader(); bool zip(); bool send(); @@ -44,4 +44,4 @@ private: bool addPart(const QString& path, const QString& name); }; -#endif /* defined(__hifi__FstReader__) */ +#endif /* defined(__hifi__ModelUploader__) */ From ba4ccc22efa19e7d5e296e03b3ddce47b3bdf9c0 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 3 Apr 2014 16:16:58 -0700 Subject: [PATCH 6/9] Changed FstReader name to ModelUploader --- interface/src/Application.cpp | 8 +++---- .../src/{FstReader.cpp => ModelUploader.cpp} | 23 ++++++++++--------- .../src/{FstReader.h => ModelUploader.h} | 14 +++++------ 3 files changed, 23 insertions(+), 22 deletions(-) rename libraries/shared/src/{FstReader.cpp => ModelUploader.cpp} (94%) rename libraries/shared/src/{FstReader.h => ModelUploader.h} (78%) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 18a3a228d6..83eab37318 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -63,7 +63,7 @@ #include #include #include -#include +#include #include "Application.h" #include "InterfaceVersion.h" @@ -3244,9 +3244,9 @@ void Application::toggleRunningScriptsWidget() } void Application::uploadFST(bool isHead) { - FstReader reader(isHead); - if (reader.zip()) { - reader.send(); + ModelUploader* uploader = new ModelUploader(isHead); + if (uploader->zip()) { + uploader->send(); } } diff --git a/libraries/shared/src/FstReader.cpp b/libraries/shared/src/ModelUploader.cpp similarity index 94% rename from libraries/shared/src/FstReader.cpp rename to libraries/shared/src/ModelUploader.cpp index 4a299fd757..71514c8b0f 100644 --- a/libraries/shared/src/FstReader.cpp +++ b/libraries/shared/src/ModelUploader.cpp @@ -1,5 +1,5 @@ // -// FstReader.cpp +// ModelUploader.cpp // hifi // // Created by Clément Brisset on 3/4/14. @@ -18,7 +18,7 @@ #include #include "AccountManager.h" -#include "FstReader.h" +#include "ModelUploader.h" static const QString NAME_FIELD = "name"; @@ -38,7 +38,7 @@ public: } }; -FstReader::FstReader(bool isHead) : +ModelUploader::ModelUploader(bool isHead) : _zipDir(new TemporaryDir()), _lodCount(-1), _texturesCount(-1), @@ -51,11 +51,11 @@ FstReader::FstReader(bool isHead) : } -FstReader::~FstReader() { +ModelUploader::~ModelUploader() { delete _dataMultiPart; } -bool FstReader::zip() { +bool ModelUploader::zip() { // File Dialog QString filename = QFileDialog::getOpenFileName(NULL, "Select your .fst file ...", @@ -167,7 +167,7 @@ bool FstReader::zip() { return true; } -bool FstReader::send() { +bool ModelUploader::send() { if (!_readyToSend) { return false; } @@ -181,17 +181,18 @@ bool FstReader::send() { AccountManager::getInstance().authenticatedRequest(MODEL_URL, QNetworkAccessManager::PostOperation, callbackParams, QByteArray(), _dataMultiPart); _zipDir = NULL; _dataMultiPart = NULL; + qDebug() << "Sending model..."; return true; } -void FstReader::uploadSuccess(const QJsonObject& jsonResponse) { +void ModelUploader::uploadSuccess(const QJsonObject& jsonResponse) { qDebug() << "Model sent with success to the data server."; qDebug() << "It might take a few minute for it to appear in your model browser."; deleteLater(); } -void FstReader::uploadFailed(QNetworkReply::NetworkError errorCode, const QString& errorString) { +void ModelUploader::uploadFailed(QNetworkReply::NetworkError errorCode, const QString& errorString) { QMessageBox::warning(NULL, QString("ModelUploader::uploadFailed()"), QString("Model could not be sent to the data server."), @@ -200,7 +201,7 @@ void FstReader::uploadFailed(QNetworkReply::NetworkError errorCode, const QStrin deleteLater(); } -bool FstReader::addTextures(const QFileInfo& texdir) { +bool ModelUploader::addTextures(const QFileInfo& texdir) { QStringList filter; filter << "*.png" << "*.tif" << "*.jpg" << "*.jpeg"; @@ -229,7 +230,7 @@ bool FstReader::addTextures(const QFileInfo& texdir) { return true; } -bool FstReader::compressFile(const QString &inFileName, const QString &outFileName) { +bool ModelUploader::compressFile(const QString &inFileName, const QString &outFileName) { QFile inFile(inFileName); inFile.open(QIODevice::ReadOnly); QByteArray buffer = inFile.readAll(); @@ -253,7 +254,7 @@ bool FstReader::compressFile(const QString &inFileName, const QString &outFileNa } -bool FstReader::addPart(const QString &path, const QString& name) { +bool ModelUploader::addPart(const QString &path, const QString& name) { QFile* file = new QFile(path); if (!file->open(QIODevice::ReadOnly)) { QMessageBox::warning(NULL, diff --git a/libraries/shared/src/FstReader.h b/libraries/shared/src/ModelUploader.h similarity index 78% rename from libraries/shared/src/FstReader.h rename to libraries/shared/src/ModelUploader.h index 2ccf21a3b0..f127008f44 100644 --- a/libraries/shared/src/FstReader.h +++ b/libraries/shared/src/ModelUploader.h @@ -1,5 +1,5 @@ // -// FstReader.h +// ModelUploader.h // hifi // // Created by Clément Brisset on 3/4/14. @@ -7,19 +7,19 @@ // // -#ifndef __hifi__FstReader__ -#define __hifi__FstReader__ +#ifndef __hifi__ModelUploader__ +#define __hifi__ModelUploader__ class TemporaryDir; class QHttpMultiPart; class QFileInfo; -class FstReader : public QObject { +class ModelUploader : public QObject { Q_OBJECT public: - FstReader(bool isHead); - ~FstReader(); + ModelUploader(bool isHead); + ~ModelUploader(); bool zip(); bool send(); @@ -44,4 +44,4 @@ private: bool addPart(const QString& path, const QString& name); }; -#endif /* defined(__hifi__FstReader__) */ +#endif /* defined(__hifi__ModelUploader__) */ From 3a125db1f8241999e0457141a1fe14c728eb688d Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 4 Apr 2014 14:31:30 -0700 Subject: [PATCH 7/9] Increase the rate at which we increase detail and put a limit on the LOD multiplier so that it never takes more than about five seconds to return to default detail. Also, since there seems to be a weird issue where OS X throttles the frame rate to 30 fps (independent of our own throttling), use that as the lower adjustment range. --- interface/src/Menu.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 5530c57281..5deb9474cf 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -1260,20 +1260,22 @@ void Menu::autoAdjustLOD(float currentFPS) { quint64 now = usecTimestampNow(); + const float ADJUST_AVATAR_LOD_DOWN_FPS = 30.0f; const quint64 ADJUST_AVATAR_LOD_DOWN_DELAY = 1000 * 1000; - if (_fastFPSAverage.getAverage() < ADJUST_LOD_DOWN_FPS) { + if (_fastFPSAverage.getAverage() < ADJUST_AVATAR_LOD_DOWN_FPS) { if (now - _lastAvatarDetailDrop > ADJUST_AVATAR_LOD_DOWN_DELAY) { // attempt to lower the detail in proportion to the fps difference - float targetFps = (ADJUST_LOD_DOWN_FPS + ADJUST_LOD_UP_FPS) * 0.5f; + float targetFps = (ADJUST_AVATAR_LOD_DOWN_FPS + ADJUST_LOD_UP_FPS) * 0.5f; float averageFps = _fastFPSAverage.getAverage(); const float MAXIMUM_MULTIPLIER_SCALE = 2.0f; - _avatarLODDistanceMultiplier *= (averageFps < EPSILON) ? MAXIMUM_MULTIPLIER_SCALE : - qMin(MAXIMUM_MULTIPLIER_SCALE, targetFps / averageFps); + const float MAXIMUM_DISTANCE_MULTIPLIER = 15.0f; + _avatarLODDistanceMultiplier = qMin(MAXIMUM_DISTANCE_MULTIPLIER, _avatarLODDistanceMultiplier * + (averageFps < EPSILON ? MAXIMUM_MULTIPLIER_SCALE : qMin(MAXIMUM_MULTIPLIER_SCALE, targetFps / averageFps))); _lastAvatarDetailDrop = now; } } else if (_fastFPSAverage.getAverage() > ADJUST_LOD_UP_FPS) { // let the detail level creep slowly upwards - const float DISTANCE_DECREASE_RATE = 0.02f; + const float DISTANCE_DECREASE_RATE = 0.05f; const float MINIMUM_DISTANCE_MULTIPLIER = 0.1f; _avatarLODDistanceMultiplier = qMax(MINIMUM_DISTANCE_MULTIPLIER, _avatarLODDistanceMultiplier - DISTANCE_DECREASE_RATE); From 01c42c741c57ecd01c51238ab3996228a45d2e0c Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 4 Apr 2014 14:46:54 -0700 Subject: [PATCH 8/9] fix #2567 thrust + oculus doesn't change body rot --- interface/src/Application.cpp | 2 +- interface/src/avatar/Head.cpp | 4 ++++ interface/src/avatar/MyAvatar.cpp | 28 +--------------------------- 3 files changed, 6 insertions(+), 28 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 83eab37318..d54cceb245 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -510,7 +510,7 @@ void Application::paintGL() { _myCamera.setDistance(0.0f); _myCamera.setTightness(0.0f); // Camera is directly connected to head without smoothing _myCamera.setTargetPosition(_myAvatar->getHead()->calculateAverageEyePosition()); - _myCamera.setTargetRotation(_myAvatar->getHead()->getOrientation()); + _myCamera.setTargetRotation(_myAvatar->getHead()->getCameraOrientation()); } else if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { _myCamera.setTightness(0.0f); // In first person, camera follows (untweaked) head exactly without delay diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index ffa0975ccb..8a25c14574 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -14,6 +14,7 @@ #include "Head.h" #include "Menu.h" #include "Util.h" +#include "devices/OculusManager.h" using namespace std; @@ -198,6 +199,9 @@ glm::quat Head::getFinalOrientation() const { } glm::quat Head::getCameraOrientation () const { + if (OculusManager::isConnected()) { + return getOrientation(); + } Avatar* owningAvatar = static_cast(_owningAvatar); return owningAvatar->getWorldAlignedOrientation() * glm::quat(glm::radians(glm::vec3(_basePitch, 0.f, 0.0f))); } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 9dcfaa09ba..1ff93794c5 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -169,9 +169,6 @@ void MyAvatar::simulate(float deltaTime) { // Collect thrust forces from keyboard and devices updateThrust(deltaTime); - // copy velocity so we can use it later for acceleration - glm::vec3 oldVelocity = getVelocity(); - // calculate speed _speed = glm::length(_velocity); @@ -231,29 +228,6 @@ void MyAvatar::simulate(float deltaTime) { // update the euler angles setOrientation(orientation); - // Compute instantaneous acceleration - float forwardAcceleration = glm::length(glm::dot(getBodyFrontDirection(), getVelocity() - oldVelocity)) / deltaTime; - const float OCULUS_ACCELERATION_PULL_THRESHOLD = 1.0f; - const int OCULUS_YAW_OFFSET_THRESHOLD = 10; - - if (!Application::getInstance()->getFaceshift()->isActive() && OculusManager::isConnected() && - fabsf(forwardAcceleration) > OCULUS_ACCELERATION_PULL_THRESHOLD && - fabs(getHead()->getBaseYaw()) > OCULUS_YAW_OFFSET_THRESHOLD) { - - // if we're wearing the oculus - // and this acceleration is above the pull threshold - // and the head yaw if off the body by more than OCULUS_YAW_OFFSET_THRESHOLD - - // match the body yaw to the oculus yaw - _bodyYaw = getAbsoluteHeadYaw(); - - // set the head yaw to zero for this draw - getHead()->setBaseYaw(0); - - // correct the oculus yaw offset - OculusManager::updateYawOffset(); - } - const float WALKING_SPEED_THRESHOLD = 0.2f; // use speed and angular velocity to determine walking vs. standing if (_speed + fabs(_bodyYawDelta) > WALKING_SPEED_THRESHOLD) { @@ -308,7 +282,7 @@ void MyAvatar::simulate(float deltaTime) { head->simulate(deltaTime, true); // Zero thrust out now that we've added it to velocity in this frame - _thrust = glm::vec3(0, 0, 0); + _thrust = glm::vec3(0.f); // now that we're done stepping the avatar forward in time, compute new collisions if (_collisionFlags != 0) { From 403ad5e984a8365353fe3b1a3371846fdcf7d0fb Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 4 Apr 2014 15:18:12 -0700 Subject: [PATCH 9/9] removing a warning about hidden virtual override --- interface/src/avatar/FaceModel.cpp | 2 +- interface/src/avatar/FaceModel.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/FaceModel.cpp b/interface/src/avatar/FaceModel.cpp index b0ef947f65..e81e1da117 100644 --- a/interface/src/avatar/FaceModel.cpp +++ b/interface/src/avatar/FaceModel.cpp @@ -18,7 +18,7 @@ FaceModel::FaceModel(Head* owningHead) : { } -void FaceModel::simulate(float deltaTime) { +void FaceModel::simulate(float deltaTime, bool fullUpdate) { updateGeometry(); Avatar* owningAvatar = static_cast(_owningHead->_owningAvatar); glm::vec3 neckPosition; diff --git a/interface/src/avatar/FaceModel.h b/interface/src/avatar/FaceModel.h index acf2d2baf4..d675495e6b 100644 --- a/interface/src/avatar/FaceModel.h +++ b/interface/src/avatar/FaceModel.h @@ -21,7 +21,7 @@ public: FaceModel(Head* owningHead); - void simulate(float deltaTime); + virtual void simulate(float deltaTime, bool fullUpdate = true); protected: