From 6be03ac3df6c9d4649811bb0656cb77ce1869ac6 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 18 Sep 2013 10:10:24 -0700 Subject: [PATCH] Working on downloading the faces. --- interface/src/Menu.cpp | 13 ++++++-- interface/src/avatar/Avatar.cpp | 2 ++ interface/src/avatar/BlendFace.cpp | 50 +++++++++++++++++++++++++++++- interface/src/avatar/BlendFace.h | 15 +++++++++ 4 files changed, 76 insertions(+), 4 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 44bb2e24ff..b0abb4d1cc 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -708,6 +708,10 @@ void Menu::editPreferences() { avatarURL->setMinimumWidth(QLINE_MINIMUM_WIDTH); form->addRow("Avatar URL:", avatarURL); + QLineEdit* faceURL = new QLineEdit(applicationInstance->getAvatar()->getHead().getBlendFace().getModelURL().toString()); + faceURL->setMinimumWidth(QLINE_MINIMUM_WIDTH); + form->addRow("Face URL:", faceURL); + QSpinBox* fieldOfView = new QSpinBox(); fieldOfView->setMaximum(180); fieldOfView->setMinimum(1); @@ -764,9 +768,12 @@ void Menu::editPreferences() { NodeList::getInstance()->setDomainHostname(newHostname.constData()); } - QUrl url(avatarURL->text()); - applicationInstance->getAvatar()->getVoxels()->setVoxelURL(url); - Avatar::sendAvatarVoxelURLMessage(url); + QUrl avatarVoxelURL(avatarURL->text()); + applicationInstance->getAvatar()->getVoxels()->setVoxelURL(avatarVoxelURL); + Avatar::sendAvatarVoxelURLMessage(avatarVoxelURL); + + QUrl faceModelURL(faceURL->text()); + applicationInstance->getAvatar()->getHead().getBlendFace().setModelURL(faceModelURL); _gyroCameraSensitivity = gyroCameraSensitivity->value(); diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 0df2f2d41c..cdfefedaac 100755 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -786,6 +786,7 @@ void Avatar::loadData(QSettings* settings) { _position.z = loadSetting(settings, "position_z", 0.0f); _voxels.setVoxelURL(settings->value("voxelURL").toUrl()); + _head.getBlendFace().setModelURL(settings->value("faceModelURL").toUrl()); _leanScale = loadSetting(settings, "leanScale", 0.05f); @@ -837,6 +838,7 @@ void Avatar::saveData(QSettings* set) { set->setValue("position_z", _position.z); set->setValue("voxelURL", _voxels.getVoxelURL()); + set->setValue("faceModelURL", _head.getBlendFace().getModelURL()); set->setValue("leanScale", _leanScale); set->setValue("scale", _newScale); diff --git a/interface/src/avatar/BlendFace.cpp b/interface/src/avatar/BlendFace.cpp index 15863e59a9..ef3e6ff6af 100644 --- a/interface/src/avatar/BlendFace.cpp +++ b/interface/src/avatar/BlendFace.cpp @@ -6,8 +6,9 @@ // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // -#include +#include +#include "Application.h" #include "BlendFace.h" #include "Head.h" @@ -16,6 +17,7 @@ using namespace std; BlendFace::BlendFace(Head* owningHead) : _owningHead(owningHead), + _modelReply(NULL), _iboID(0) { } @@ -97,6 +99,30 @@ bool BlendFace::render(float alpha) { return true; } +void BlendFace::setModelURL(const QUrl& url) { + // don't restart the download if it's the same URL + if (_modelURL == url) { + return; + } + + // cancel any current download + if (_modelReply != 0) { + delete _modelReply; + _modelReply = 0; + } + + // remember the URL + _modelURL = url; + + // load the URL data asynchronously + if (!url.isValid()) { + return; + } + _modelReply = Application::getInstance()->getNetworkAccessManager()->get(QNetworkRequest(url)); + connect(_modelReply, SIGNAL(downloadProgress(qint64,qint64)), SLOT(handleModelDownloadProgress(qint64,qint64))); + connect(_modelReply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(handleModelReplyError())); +} + void BlendFace::setRig(const fsMsgRig& rig) { if (rig.mesh().m_tris.empty()) { // clear any existing geometry @@ -143,3 +169,25 @@ void BlendFace::setRig(const fsMsgRig& rig) { } } } + +void BlendFace::handleModelDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) { + if (bytesReceived < bytesTotal) { + return; + } + + QByteArray entirety = _modelReply->readAll(); + _modelReply->disconnect(this); + _modelReply->deleteLater(); + _modelReply = 0; + + qDebug("Got %d bytes.\n", entirety.size()); +} + +void BlendFace::handleModelReplyError() { + qDebug("%s\n", _modelReply->errorString().toLocal8Bit().constData()); + + _modelReply->disconnect(this); + _modelReply->deleteLater(); + _modelReply = 0; +} + diff --git a/interface/src/avatar/BlendFace.h b/interface/src/avatar/BlendFace.h index fc13cbfca5..184b31a236 100644 --- a/interface/src/avatar/BlendFace.h +++ b/interface/src/avatar/BlendFace.h @@ -10,11 +10,14 @@ #define __interface__BlendFace__ #include +#include #include #include "InterfaceConfig.h" +class QNetworkReply; + class Head; /// A face formed from a linear mix of blendshapes according to a set of coefficients. @@ -28,14 +31,26 @@ public: bool render(float alpha); + Q_INVOKABLE void setModelURL(const QUrl& url); + const QUrl& getModelURL() const { return _modelURL; } + public slots: void setRig(const fs::fsMsgRig& rig); + +private slots: + + void handleModelDownloadProgress(qint64 bytesReceived, qint64 bytesTotal); + void handleModelReplyError(); private: Head* _owningHead; + QUrl _modelURL; + + QNetworkReply* _modelReply; + GLuint _iboID; GLuint _vboID;