From aaf191b6dc5b27bb6d32a4c1e15191dae9689e31 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 3 Apr 2015 14:31:43 -0700 Subject: [PATCH 01/15] first cut at new avatar preferences UI --- interface/src/Application.cpp | 29 +--- interface/src/Application.h | 5 +- interface/src/avatar/MyAvatar.cpp | 71 +++++++- interface/src/avatar/MyAvatar.h | 24 ++- interface/src/ui/PreferencesDialog.cpp | 125 ++++++++++---- interface/src/ui/PreferencesDialog.h | 18 +- interface/ui/preferencesDialog.ui | 223 ++++++++++++++++++++++++- 7 files changed, 418 insertions(+), 77 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f0324b7361..c2560a9a54 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3743,30 +3743,16 @@ bool Application::askToSetAvatarUrl(const QString& url) { if (msgBox.clickedButton() == headButton) { qDebug() << "Chose to use for head: " << url; - _myAvatar->setFaceModelURL(url); - UserActivityLogger::getInstance().changedModel("head", url); - _myAvatar->sendIdentityPacket(); - emit faceURLChanged(url); + _myAvatar->useHeadURL(url); + emit headURLChanged(url); } else if (msgBox.clickedButton() == bodyButton) { qDebug() << "Chose to use for body: " << url; - _myAvatar->setSkeletonModelURL(url); - // if the head is empty, reset it to the default head. - if (_myAvatar->getFaceModelURLString().isEmpty()) { - _myAvatar->setFaceModelURL(DEFAULT_HEAD_MODEL_URL); - emit faceURLChanged(DEFAULT_HEAD_MODEL_URL.toString()); - UserActivityLogger::getInstance().changedModel("head", DEFAULT_HEAD_MODEL_URL.toString()); - } - UserActivityLogger::getInstance().changedModel("skeleton", url); - _myAvatar->sendIdentityPacket(); - emit skeletonURLChanged(url); + _myAvatar->useBodyURL(url); + emit bodyURLChanged(url); } else if (msgBox.clickedButton() == bodyAndHeadButton) { qDebug() << "Chose to use for body + head: " << url; - _myAvatar->setFaceModelURL(QString()); - _myAvatar->setSkeletonModelURL(url); - UserActivityLogger::getInstance().changedModel("skeleton", url); - _myAvatar->sendIdentityPacket(); - emit faceURLChanged(QString()); - emit skeletonURLChanged(url); + _myAvatar->useFullAvatarURL(url); + emit fullAvatarURLChanged(url); } else { qDebug() << "Declined to use the avatar: " << url; } @@ -4281,8 +4267,7 @@ void Application::checkSkeleton() { msgBox.setIcon(QMessageBox::Warning); msgBox.exec(); - _myAvatar->setSkeletonModelURL(DEFAULT_BODY_MODEL_URL); - _myAvatar->sendIdentityPacket(); + _myAvatar->useBodyURL(DEFAULT_BODY_MODEL_URL); } else { _myAvatar->updateCharacterController(); _physicsEngine.setCharacterController(_myAvatar->getCharacterController()); diff --git a/interface/src/Application.h b/interface/src/Application.h index e9b8deff55..387de78e49 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -335,8 +335,9 @@ signals: void checkBackgroundDownloads(); void domainConnectionRefused(const QString& reason); - void faceURLChanged(const QString& newValue); - void skeletonURLChanged(const QString& newValue); + void headURLChanged(const QString& newValue); + void bodyURLChanged(const QString& newValue); + void fullAvatarURLChanged(const QString& newValue); public slots: void domainChanged(const QString& domainHostname); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index f92523c58f..418f978451 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include "Application.h" #include "AvatarManager.h" @@ -604,9 +605,11 @@ void MyAvatar::saveData() { settings.setValue("leanScale", _leanScale); settings.setValue("scale", _targetScale); - - settings.setValue("faceModelURL", _faceModelURL); - settings.setValue("skeletonModelURL", _skeletonModelURL); + + settings.setValue("useFullAvatar", _useFullAvatar); + settings.setValue("fullAvatarURL", _fullAvatarURLFromPreferences); + settings.setValue("faceModelURL", _headURLFromPreferences); + settings.setValue("skeletonModelURL", _skeletonURLFromPreferences); settings.beginWriteArray("attachmentData"); for (int i = 0; i < _attachmentData.size(); i++) { @@ -667,9 +670,26 @@ void MyAvatar::loadData() { _targetScale = loadSetting(settings, "scale", 1.0f); setScale(_scale); Application::getInstance()->getCamera()->setScale(_scale); + + + // The old preferences only stored the face and skeleton URLs, we didn't track if the user wanted to use 1 or 2 urls + // for their avatar, So we need to attempt to detect this old case and set our new preferences accordingly. If + // the head URL is empty, then we will assume they are using a full url... + _headURLFromPreferences = settings.value("faceModelURL", DEFAULT_HEAD_MODEL_URL).toUrl(); - setFaceModelURL(settings.value("faceModelURL", DEFAULT_HEAD_MODEL_URL).toUrl()); - setSkeletonModelURL(settings.value("skeletonModelURL").toUrl()); + bool assumeFullAvatar = _headURLFromPreferences.isEmpty(); + + _useFullAvatar = settings.value("useFullAvatar", assumeFullAvatar).toBool(); + _fullAvatarURLFromPreferences = settings.value("fullAvatarURL").toUrl(); + _skeletonURLFromPreferences = settings.value("skeletonModelURL").toUrl(); + + if (_useFullAvatar) { + setFaceModelURL(QUrl()); + setSkeletonModelURL(_fullAvatarURLFromPreferences); + } else { + setFaceModelURL(_headURLFromPreferences); + setSkeletonModelURL(_skeletonURLFromPreferences); + } QVector attachmentData; int attachmentCount = settings.beginReadArray("attachmentData"); @@ -902,6 +922,47 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { _billboardValid = false; } +void MyAvatar::useFullAvatarURL(const QUrl& fullAvatarURL) { + _useFullAvatar = true; + _fullAvatarURLFromPreferences = fullAvatarURL; + + if (!getFaceModelURLString().isEmpty()) { + setFaceModelURL(QString()); + } + + if (fullAvatarURL != getSkeletonModelURL()) { + setSkeletonModelURL(fullAvatarURL); + UserActivityLogger::getInstance().changedModel("skeleton", fullAvatarURL.toString()); + } + sendIdentityPacket(); +} + +void MyAvatar::useHeadURL(const QUrl& headURL) { + useHeadAndBodyURLs(headURL, _skeletonURLFromPreferences); +} + +void MyAvatar::useBodyURL(const QUrl& bodyURL) { + useHeadAndBodyURLs(_headURLFromPreferences, bodyURL); +} + +void MyAvatar::useHeadAndBodyURLs(const QUrl& headURL, const QUrl& bodyURL) { + _useFullAvatar = false; + _headURLFromPreferences = headURL; + _skeletonURLFromPreferences = bodyURL; + + if (headURL != getFaceModelURL()) { + setFaceModelURL(headURL); + UserActivityLogger::getInstance().changedModel("head", headURL.toString()); + } + + if (bodyURL != getSkeletonModelURL()) { + setSkeletonModelURL(bodyURL); + UserActivityLogger::getInstance().changedModel("skeleton", bodyURL.toString()); + } + sendIdentityPacket(); +} + + void MyAvatar::setAttachmentData(const QVector& attachmentData) { Avatar::setAttachmentData(attachmentData); if (QThread::currentThread() != thread()) { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 2bc3a4e4ba..57c8ca9e96 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -116,8 +116,17 @@ public: virtual void setJointData(int index, const glm::quat& rotation); virtual void clearJointData(int index); virtual void clearJointsData(); - virtual void setFaceModelURL(const QUrl& faceModelURL); - virtual void setSkeletonModelURL(const QUrl& skeletonModelURL); + + void useFullAvatarURL(const QUrl& fullAvatarURL); + void useHeadURL(const QUrl& headURL); + void useBodyURL(const QUrl& bodyURL); + void useHeadAndBodyURLs(const QUrl& headURL, const QUrl& bodyURL); + + bool getUseFullAvatar() const { return _useFullAvatar; } + const QUrl& getFullAvatarURLFromPreferences() const { return _fullAvatarURLFromPreferences; } + const QUrl& getHeadURLFromPreferences() const { return _headURLFromPreferences; } + const QUrl& getBodyURLFromPreferences() const { return _skeletonURLFromPreferences; } + virtual void setAttachmentData(const QVector& attachmentData); virtual glm::vec3 getSkeletonPosition() const; @@ -185,6 +194,11 @@ protected: virtual void renderAttachments(RenderMode renderMode, RenderArgs* args); private: + + // These are made private for MyAvatar so that you will use the "use" methods instead + virtual void setFaceModelURL(const QUrl& faceModelURL); + virtual void setSkeletonModelURL(const QUrl& skeletonModelURL); + float _turningKeyPressTime; glm::vec3 _gravity; @@ -229,6 +243,12 @@ private: void updatePosition(float deltaTime); void updateCollisionSound(const glm::vec3& penetration, float deltaTime, float frequency); void maybeUpdateBillboard(); + + // Avatar Preferences + bool _useFullAvatar = false; + QUrl _fullAvatarURLFromPreferences; + QUrl _headURLFromPreferences; + QUrl _skeletonURLFromPreferences; }; #endif // hifi_MyAvatar_h diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index bd32fc7c34..4879bbfffc 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -43,28 +43,71 @@ PreferencesDialog::PreferencesDialog(QWidget* parent) : connect(ui.buttonBrowseHead, &QPushButton::clicked, this, &PreferencesDialog::openHeadModelBrowser); connect(ui.buttonBrowseBody, &QPushButton::clicked, this, &PreferencesDialog::openBodyModelBrowser); + connect(ui.buttonBrowseFullAvatar, &QPushButton::clicked, this, &PreferencesDialog::openFullAvatarModelBrowser); + connect(ui.buttonBrowseLocation, &QPushButton::clicked, this, &PreferencesDialog::openSnapshotLocationBrowser); connect(ui.buttonBrowseScriptsLocation, &QPushButton::clicked, this, &PreferencesDialog::openScriptsLocationBrowser); - connect(ui.buttonReloadDefaultScripts, &QPushButton::clicked, - Application::getInstance(), &Application::loadDefaultScripts); + connect(ui.buttonReloadDefaultScripts, &QPushButton::clicked, Application::getInstance(), &Application::loadDefaultScripts); - - connect(Application::getInstance(), &Application::faceURLChanged, this, &PreferencesDialog::faceURLChanged); - connect(Application::getInstance(), &Application::skeletonURLChanged, this, &PreferencesDialog::skeletonURLChanged); + connect(ui.useSeparateBodyAndHead, &QRadioButton::clicked, this, &PreferencesDialog::useSeparateBodyAndHead); + connect(ui.useFullAvatar, &QRadioButton::clicked, this, &PreferencesDialog::useFullAvatar); + + + connect(Application::getInstance(), &Application::headURLChanged, this, &PreferencesDialog::headURLChanged); + connect(Application::getInstance(), &Application::bodyURLChanged, this, &PreferencesDialog::bodyURLChanged); + connect(Application::getInstance(), &Application::fullAvatarURLChanged, this, &PreferencesDialog::fullAvatarURLChanged); // move dialog to left side move(parentWidget()->geometry().topLeft()); setFixedHeight(parentWidget()->size().height() - PREFERENCES_HEIGHT_PADDING); + + ui.bodyNameLabel->setText("Body - name of model here"); + ui.headNameLabel->setText("Head - name of model here"); + ui.fullAvatarNameLabel->setText("Full Avatar - name of model here"); + + UIUtil::scaleWidgetFontSizes(this); } -void PreferencesDialog::faceURLChanged(const QString& newValue) { - ui.faceURLEdit->setText(newValue); +void PreferencesDialog::useSeparateBodyAndHead(bool checked) { + setUseFullAvatar(!checked); + + QUrl headURL(ui.faceURLEdit->text()); + QUrl bodyURL(ui.skeletonURLEdit->text()); + + DependencyManager::get()->getMyAvatar()->useHeadAndBodyURLs(headURL, bodyURL); } -void PreferencesDialog::skeletonURLChanged(const QString& newValue) { +void PreferencesDialog::useFullAvatar(bool checked) { + setUseFullAvatar(checked); + QUrl fullAvatarURL(ui.fullAvatarURLEdit->text()); + DependencyManager::get()->getMyAvatar()->useFullAvatarURL(fullAvatarURL); +} + +void PreferencesDialog::setUseFullAvatar(bool useFullAvatar) { + _useFullAvatar = useFullAvatar; + ui.faceURLEdit->setEnabled(!_useFullAvatar); + ui.skeletonURLEdit->setEnabled(!_useFullAvatar); + ui.fullAvatarURLEdit->setEnabled(_useFullAvatar); + + ui.useFullAvatar->setChecked(_useFullAvatar); + ui.useSeparateBodyAndHead->setChecked(!_useFullAvatar); +} + +void PreferencesDialog::headURLChanged(const QString& newValue) { + ui.faceURLEdit->setText(newValue); + setUseFullAvatar(false); +} + +void PreferencesDialog::bodyURLChanged(const QString& newValue) { ui.skeletonURLEdit->setText(newValue); + setUseFullAvatar(false); +} + +void PreferencesDialog::fullAvatarURLChanged(const QString& newValue) { + ui.fullAvatarURLEdit->setText(newValue); + setUseFullAvatar(true); } void PreferencesDialog::accept() { @@ -82,6 +125,16 @@ void PreferencesDialog::setSkeletonUrl(QString modelUrl) { ui.skeletonURLEdit->setText(modelUrl); } +void PreferencesDialog::openFullAvatarModelBrowser() { + auto MARKETPLACE_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/marketplace?category=avatars"; + auto WIDTH = 900; + auto HEIGHT = 700; + if (!_marketplaceWindow) { + _marketplaceWindow = new WebWindowClass("Marketplace", MARKETPLACE_URL, WIDTH, HEIGHT, false); + } + _marketplaceWindow->setVisible(true); +} + void PreferencesDialog::openHeadModelBrowser() { auto MARKETPLACE_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/marketplace?category=avatars"; auto WIDTH = 900; @@ -143,11 +196,18 @@ void PreferencesDialog::loadPreferences() { _displayNameString = myAvatar->getDisplayName(); ui.displayNameEdit->setText(_displayNameString); - _faceURLString = myAvatar->getHead()->getFaceModel().getURL().toString(); - ui.faceURLEdit->setText(_faceURLString); - _skeletonURLString = myAvatar->getSkeletonModel().getURL().toString(); - ui.skeletonURLEdit->setText(_skeletonURLString); + _useFullAvatar = myAvatar->getUseFullAvatar(); + _fullAvatarURLString = myAvatar->getFullAvatarURLFromPreferences().toString(); + _headURLString = myAvatar->getHeadURLFromPreferences().toString(); + _bodyURLString = myAvatar->getBodyURLFromPreferences().toString(); + + ui.fullAvatarURLEdit->setText(_fullAvatarURLString); + ui.faceURLEdit->setText(_headURLString); + ui.skeletonURLEdit->setText(_bodyURLString); + setUseFullAvatar(_useFullAvatar); + + // TODO: load the names for the models. ui.sendDataCheckBox->setChecked(!menuInstance->isOptionChecked(MenuOption::DisableActivityLogger)); @@ -217,31 +277,26 @@ void PreferencesDialog::savePreferences() { shouldDispatchIdentityPacket = true; } - auto AVATAR_FILE_EXTENSION = ".fst"; - - QUrl faceModelURL(ui.faceURLEdit->text()); - QString faceModelURLString = faceModelURL.toString(); - if (faceModelURLString != _faceURLString) { - if (faceModelURLString.isEmpty() || faceModelURLString.toLower().contains(AVATAR_FILE_EXTENSION)) { - // change the faceModelURL in the profile, it will also update this user's BlendFace - myAvatar->setFaceModelURL(faceModelURL); - UserActivityLogger::getInstance().changedModel("head", faceModelURLString); - shouldDispatchIdentityPacket = true; - } else { - qDebug() << "ERROR: Head model not FST or blank - " << faceModelURLString; - } - } + QUrl headURL(ui.faceURLEdit->text()); + QString headURLString = headURL.toString(); - QUrl skeletonModelURL(ui.skeletonURLEdit->text()); - QString skeletonModelURLString = skeletonModelURL.toString(); - if (skeletonModelURLString != _skeletonURLString) { - if (skeletonModelURLString.isEmpty() || skeletonModelURLString.toLower().contains(AVATAR_FILE_EXTENSION)) { - // change the skeletonModelURL in the profile, it will also update this user's Body - myAvatar->setSkeletonModelURL(skeletonModelURL); - UserActivityLogger::getInstance().changedModel("skeleton", skeletonModelURLString); - shouldDispatchIdentityPacket = true; + QUrl bodyURL(ui.skeletonURLEdit->text()); + QString bodyURLString = bodyURL.toString(); + + QUrl fullAvatarURL(ui.fullAvatarURLEdit->text()); + QString fullAvatarURLString = fullAvatarURL.toString(); + + bool somethingChanged = + _useFullAvatar != myAvatar->getUseFullAvatar() || + fullAvatarURLString != myAvatar->getFullAvatarURLFromPreferences().toString() || + headURLString != myAvatar->getHeadURLFromPreferences().toString() || + bodyURLString != myAvatar->getBodyURLFromPreferences().toString(); + + if (somethingChanged) { + if (_useFullAvatar) { + myAvatar->useFullAvatarURL(fullAvatarURL); } else { - qDebug() << "ERROR: Skeleton model not FST or blank - " << skeletonModelURLString; + myAvatar->useHeadAndBodyURLs(headURL, bodyURL); } } diff --git a/interface/src/ui/PreferencesDialog.h b/interface/src/ui/PreferencesDialog.h index 4daa2d9696..961ef6287d 100644 --- a/interface/src/ui/PreferencesDialog.h +++ b/interface/src/ui/PreferencesDialog.h @@ -33,10 +33,17 @@ private: void savePreferences(); void openHeadModelBrowser(); void openBodyModelBrowser(); + void openFullAvatarModelBrowser(); + void setUseFullAvatar(bool useFullAvatar); Ui_PreferencesDialog ui; - QString _faceURLString; - QString _skeletonURLString; + + bool _useFullAvatar; + QString _headURLString; + QString _bodyURLString; + QString _fullAvatarURLString; + + QString _displayNameString; WebWindowClass* _marketplaceWindow = NULL; @@ -47,8 +54,11 @@ private slots: void setSkeletonUrl(QString modelUrl); void openSnapshotLocationBrowser(); void openScriptsLocationBrowser(); - void faceURLChanged(const QString& newValue); - void skeletonURLChanged(const QString& newValue); + void headURLChanged(const QString& newValue); + void bodyURLChanged(const QString& newValue); + void fullAvatarURLChanged(const QString& newValue); + void useSeparateBodyAndHead(bool checked); + void useFullAvatar(bool checked); }; diff --git a/interface/ui/preferencesDialog.ui b/interface/ui/preferencesDialog.ui index d295d094c2..4a0b1e961a 100644 --- a/interface/ui/preferencesDialog.ui +++ b/interface/ui/preferencesDialog.ui @@ -198,8 +198,194 @@ 7 + + + + + + + + 0 + 0 + + + + + 32 + 28 + + + + + 0 + 0 + + + + + Arial + + + + Use single avatar with Body and Head + + + + 0 + 0 + + + + + + + + + + + 0 + + + 10 + + + 7 + + + 7 + + + - + + + + Arial + + + + Full Avatar + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + fullAvatarURLEdit + + + + + + + + 0 + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 5 + 20 + + + + + + + + + Arial + + + + Browse + + + + 0 + 0 + + + + + + + + + + + + + + 0 + 0 + + + + + 32 + 28 + + + + + 0 + 0 + + + + + Arial + + + + Use separate Body and Head avatar files + + + + 0 + 0 + + + + + + + + + + 0 + + + 10 + + + 7 + + + 7 + + + + + + Arial @@ -211,11 +397,11 @@ Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - - snapshotLocationEdit - + + + @@ -260,21 +446,28 @@ + + + - + 0 + + 10 + 7 7 + - + Arial @@ -290,9 +483,10 @@ skeletonURLEdit + - + 0 @@ -344,6 +538,20 @@ + + + + + + + + + + + + + + @@ -665,6 +873,7 @@ + From 1a463a025697043d9848b83275231c58cdf0ea0a Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 3 Apr 2015 17:03:22 -0700 Subject: [PATCH 02/15] more work on improved avatar UI adding model names and backward compatible support --- interface/src/Application.cpp | 33 +++++-------- interface/src/Application.h | 6 +-- interface/src/avatar/MyAvatar.cpp | 66 +++++++++++++++++++------- interface/src/avatar/MyAvatar.h | 16 +++++-- interface/src/ui/PreferencesDialog.cpp | 19 ++++---- interface/src/ui/PreferencesDialog.h | 6 +-- libraries/avatars/src/AvatarData.h | 2 + libraries/fbx/src/FSTReader.cpp | 21 ++++++++ libraries/fbx/src/FSTReader.h | 1 + 9 files changed, 115 insertions(+), 55 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c2560a9a54..c2bab11065 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3689,17 +3689,7 @@ bool Application::askToSetAvatarUrl(const QString& url) { } // Download the FST file, to attempt to determine its model type - QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); - QNetworkRequest networkRequest = QNetworkRequest(url); - networkRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT); - QNetworkReply* reply = networkAccessManager.get(networkRequest); - qDebug() << "Downloading avatar file at " << url; - QEventLoop loop; - QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); - loop.exec(); - QByteArray fstContents = reply->readAll(); - delete reply; - QVariantHash fstMapping = FSTReader::readMapping(fstContents); + QVariantHash fstMapping = FSTReader::downloadMapping(url); FSTReader::ModelType modelType = FSTReader::predictModelType(fstMapping); @@ -3710,26 +3700,27 @@ bool Application::askToSetAvatarUrl(const QString& url) { QPushButton* bodyButton = NULL; QPushButton* bodyAndHeadButton = NULL; + QString modelName = fstMapping["name"].toString(); QString message; QString typeInfo; switch (modelType) { case FSTReader::HEAD_MODEL: - message = QString("Would you like to use '") + fstMapping["name"].toString() + QString("' for your avatar head?"); + message = QString("Would you like to use '") + modelName + QString("' for your avatar head?"); headButton = msgBox.addButton(tr("Yes"), QMessageBox::ActionRole); break; case FSTReader::BODY_ONLY_MODEL: - message = QString("Would you like to use '") + fstMapping["name"].toString() + QString("' for your avatar body?"); + message = QString("Would you like to use '") + modelName + QString("' for your avatar body?"); bodyButton = msgBox.addButton(tr("Yes"), QMessageBox::ActionRole); break; case FSTReader::HEAD_AND_BODY_MODEL: - message = QString("Would you like to use '") + fstMapping["name"].toString() + QString("' for your avatar?"); + message = QString("Would you like to use '") + modelName + QString("' for your avatar?"); bodyAndHeadButton = msgBox.addButton(tr("Yes"), QMessageBox::ActionRole); break; default: - message = QString("Would you like to use '") + fstMapping["name"].toString() + QString("' for some part of your avatar head?"); + message = QString("Would you like to use '") + modelName + QString("' for some part of your avatar head?"); headButton = msgBox.addButton(tr("Use for Head"), QMessageBox::ActionRole); bodyButton = msgBox.addButton(tr("Use for Body"), QMessageBox::ActionRole); bodyAndHeadButton = msgBox.addButton(tr("Use for Body and Head"), QMessageBox::ActionRole); @@ -3743,16 +3734,16 @@ bool Application::askToSetAvatarUrl(const QString& url) { if (msgBox.clickedButton() == headButton) { qDebug() << "Chose to use for head: " << url; - _myAvatar->useHeadURL(url); - emit headURLChanged(url); + _myAvatar->useHeadURL(url, modelName); + emit headURLChanged(url, modelName); } else if (msgBox.clickedButton() == bodyButton) { qDebug() << "Chose to use for body: " << url; - _myAvatar->useBodyURL(url); - emit bodyURLChanged(url); + _myAvatar->useBodyURL(url, modelName); + emit bodyURLChanged(url, modelName); } else if (msgBox.clickedButton() == bodyAndHeadButton) { qDebug() << "Chose to use for body + head: " << url; - _myAvatar->useFullAvatarURL(url); - emit fullAvatarURLChanged(url); + _myAvatar->useFullAvatarURL(url, modelName); + emit fullAvatarURLChanged(url, modelName); } else { qDebug() << "Declined to use the avatar: " << url; } diff --git a/interface/src/Application.h b/interface/src/Application.h index 387de78e49..57a2f07216 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -335,9 +335,9 @@ signals: void checkBackgroundDownloads(); void domainConnectionRefused(const QString& reason); - void headURLChanged(const QString& newValue); - void bodyURLChanged(const QString& newValue); - void fullAvatarURLChanged(const QString& newValue); + void headURLChanged(const QString& newValue, const QString& modelName); + void bodyURLChanged(const QString& newValue, const QString& modelName); + void fullAvatarURLChanged(const QString& newValue, const QString& modelName); public slots: void domainChanged(const QString& domainHostname); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 418f978451..085b7bccab 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -610,7 +610,10 @@ void MyAvatar::saveData() { settings.setValue("fullAvatarURL", _fullAvatarURLFromPreferences); settings.setValue("faceModelURL", _headURLFromPreferences); settings.setValue("skeletonModelURL", _skeletonURLFromPreferences); - + settings.setValue("headModelName", _headModelName); + settings.setValue("bodyModelName", _bodyModelName); + settings.setValue("fullAvatarModelName", _fullAvatarModelName); + settings.beginWriteArray("attachmentData"); for (int i = 0; i < _attachmentData.size(); i++) { settings.setArrayIndex(i); @@ -675,20 +678,48 @@ void MyAvatar::loadData() { // The old preferences only stored the face and skeleton URLs, we didn't track if the user wanted to use 1 or 2 urls // for their avatar, So we need to attempt to detect this old case and set our new preferences accordingly. If // the head URL is empty, then we will assume they are using a full url... - _headURLFromPreferences = settings.value("faceModelURL", DEFAULT_HEAD_MODEL_URL).toUrl(); - - bool assumeFullAvatar = _headURLFromPreferences.isEmpty(); + bool isOldSettings = !(settings.contains("useFullAvatar") || settings.contains("fullAvatarURL")); - _useFullAvatar = settings.value("useFullAvatar", assumeFullAvatar).toBool(); + _useFullAvatar = settings.value("useFullAvatar").toBool(); + _headURLFromPreferences = settings.value("faceModelURL", DEFAULT_HEAD_MODEL_URL).toUrl(); _fullAvatarURLFromPreferences = settings.value("fullAvatarURL").toUrl(); _skeletonURLFromPreferences = settings.value("skeletonModelURL").toUrl(); - + _headModelName = settings.value("headModelName").toString(); + _bodyModelName = settings.value("bodyModelName").toString(); + _fullAvatarModelName = settings.value("fullAvatarModelName").toString();; + + if (isOldSettings) { + bool assumeFullAvatar = _headURLFromPreferences.isEmpty(); + _useFullAvatar = assumeFullAvatar; + + if (_useFullAvatar) { + _fullAvatarURLFromPreferences = settings.value("skeletonModelURL").toUrl(); + _headURLFromPreferences = DEFAULT_HEAD_MODEL_URL; + _skeletonURLFromPreferences = DEFAULT_BODY_MODEL_URL; + + QVariantHash fullAvatarFST = FSTReader::downloadMapping(_fullAvatarURLFromPreferences.toString()); + + _headModelName = "Default"; + _bodyModelName = "Default"; + _fullAvatarModelName = fullAvatarFST["name"].toString(); + + } else { + _fullAvatarURLFromPreferences = DEFAULT_FULL_AVATAR_MODEL_URL; + _skeletonURLFromPreferences = settings.value("skeletonModelURL").toUrl(); + + QVariantHash headFST = FSTReader::downloadMapping(_headURLFromPreferences.toString()); + QVariantHash bodyFST = FSTReader::downloadMapping(_skeletonURLFromPreferences.toString()); + + _headModelName = headFST["name"].toString(); + _bodyModelName = bodyFST["name"].toString(); + _fullAvatarModelName = "Default"; + } + } + if (_useFullAvatar) { - setFaceModelURL(QUrl()); - setSkeletonModelURL(_fullAvatarURLFromPreferences); + useFullAvatarURL(_fullAvatarURLFromPreferences, _fullAvatarModelName); } else { - setFaceModelURL(_headURLFromPreferences); - setSkeletonModelURL(_skeletonURLFromPreferences); + useHeadAndBodyURLs(_headURLFromPreferences, _skeletonURLFromPreferences, _headModelName, _bodyModelName); } QVector attachmentData; @@ -922,9 +953,10 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { _billboardValid = false; } -void MyAvatar::useFullAvatarURL(const QUrl& fullAvatarURL) { +void MyAvatar::useFullAvatarURL(const QUrl& fullAvatarURL, const QString& modelName) { _useFullAvatar = true; _fullAvatarURLFromPreferences = fullAvatarURL; + _fullAvatarModelName = modelName; if (!getFaceModelURLString().isEmpty()) { setFaceModelURL(QString()); @@ -937,18 +969,20 @@ void MyAvatar::useFullAvatarURL(const QUrl& fullAvatarURL) { sendIdentityPacket(); } -void MyAvatar::useHeadURL(const QUrl& headURL) { - useHeadAndBodyURLs(headURL, _skeletonURLFromPreferences); +void MyAvatar::useHeadURL(const QUrl& headURL, const QString& modelName) { + useHeadAndBodyURLs(headURL, _skeletonURLFromPreferences, modelName, _bodyModelName); } -void MyAvatar::useBodyURL(const QUrl& bodyURL) { - useHeadAndBodyURLs(_headURLFromPreferences, bodyURL); +void MyAvatar::useBodyURL(const QUrl& bodyURL, const QString& modelName) { + useHeadAndBodyURLs(_headURLFromPreferences, bodyURL, _headModelName, modelName); } -void MyAvatar::useHeadAndBodyURLs(const QUrl& headURL, const QUrl& bodyURL) { +void MyAvatar::useHeadAndBodyURLs(const QUrl& headURL, const QUrl& bodyURL, const QString& headName, const QString& bodyName) { _useFullAvatar = false; _headURLFromPreferences = headURL; _skeletonURLFromPreferences = bodyURL; + _headModelName = headName; + _bodyModelName = bodyName; if (headURL != getFaceModelURL()) { setFaceModelURL(headURL); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 57c8ca9e96..9c1f78c696 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -117,16 +117,20 @@ public: virtual void clearJointData(int index); virtual void clearJointsData(); - void useFullAvatarURL(const QUrl& fullAvatarURL); - void useHeadURL(const QUrl& headURL); - void useBodyURL(const QUrl& bodyURL); - void useHeadAndBodyURLs(const QUrl& headURL, const QUrl& bodyURL); + void useFullAvatarURL(const QUrl& fullAvatarURL, const QString& modelName = QString()); + void useHeadURL(const QUrl& headURL, const QString& modelName = QString()); + void useBodyURL(const QUrl& bodyURL, const QString& modelName = QString()); + void useHeadAndBodyURLs(const QUrl& headURL, const QUrl& bodyURL, const QString& headName = QString(), const QString& bodyName = QString()); bool getUseFullAvatar() const { return _useFullAvatar; } const QUrl& getFullAvatarURLFromPreferences() const { return _fullAvatarURLFromPreferences; } const QUrl& getHeadURLFromPreferences() const { return _headURLFromPreferences; } const QUrl& getBodyURLFromPreferences() const { return _skeletonURLFromPreferences; } + const QString& getHeadModelName() const { return _headModelName; } + const QString& getBodyModelName() const { return _bodyModelName; } + const QString& getFullAvartarModelName() const { return _fullAvatarModelName; } + virtual void setAttachmentData(const QVector& attachmentData); virtual glm::vec3 getSkeletonPosition() const; @@ -249,6 +253,10 @@ private: QUrl _fullAvatarURLFromPreferences; QUrl _headURLFromPreferences; QUrl _skeletonURLFromPreferences; + + QString _headModelName; + QString _bodyModelName; + QString _fullAvatarModelName; }; #endif // hifi_MyAvatar_h diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 4879bbfffc..9b6cd03dfa 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -61,11 +61,11 @@ PreferencesDialog::PreferencesDialog(QWidget* parent) : move(parentWidget()->geometry().topLeft()); setFixedHeight(parentWidget()->size().height() - PREFERENCES_HEIGHT_PADDING); - - ui.bodyNameLabel->setText("Body - name of model here"); - ui.headNameLabel->setText("Head - name of model here"); - ui.fullAvatarNameLabel->setText("Full Avatar - name of model here"); - + auto myAvatar = DependencyManager::get()->getMyAvatar(); + + ui.bodyNameLabel->setText("Body - " + myAvatar->getBodyModelName()); + ui.headNameLabel->setText("Head - " + myAvatar->getHeadModelName()); + ui.fullAvatarNameLabel->setText("Full Avatar - " + myAvatar->getFullAvartarModelName()); UIUtil::scaleWidgetFontSizes(this); } @@ -95,19 +95,22 @@ void PreferencesDialog::setUseFullAvatar(bool useFullAvatar) { ui.useSeparateBodyAndHead->setChecked(!_useFullAvatar); } -void PreferencesDialog::headURLChanged(const QString& newValue) { +void PreferencesDialog::headURLChanged(const QString& newValue, const QString& modelName) { ui.faceURLEdit->setText(newValue); setUseFullAvatar(false); + ui.headNameLabel->setText("Head - " + modelName); } -void PreferencesDialog::bodyURLChanged(const QString& newValue) { +void PreferencesDialog::bodyURLChanged(const QString& newValue, const QString& modelName) { ui.skeletonURLEdit->setText(newValue); setUseFullAvatar(false); + ui.bodyNameLabel->setText("Body - " + modelName); } -void PreferencesDialog::fullAvatarURLChanged(const QString& newValue) { +void PreferencesDialog::fullAvatarURLChanged(const QString& newValue, const QString& modelName) { ui.fullAvatarURLEdit->setText(newValue); setUseFullAvatar(true); + ui.fullAvatarNameLabel->setText("Full Avatar - " + modelName); } void PreferencesDialog::accept() { diff --git a/interface/src/ui/PreferencesDialog.h b/interface/src/ui/PreferencesDialog.h index 961ef6287d..3f097ca9ab 100644 --- a/interface/src/ui/PreferencesDialog.h +++ b/interface/src/ui/PreferencesDialog.h @@ -54,9 +54,9 @@ private slots: void setSkeletonUrl(QString modelUrl); void openSnapshotLocationBrowser(); void openScriptsLocationBrowser(); - void headURLChanged(const QString& newValue); - void bodyURLChanged(const QString& newValue); - void fullAvatarURLChanged(const QString& newValue); + void headURLChanged(const QString& newValue, const QString& modelName); + void bodyURLChanged(const QString& newValue, const QString& modelName); + void fullAvatarURLChanged(const QString& newValue, const QString& modelName); void useSeparateBodyAndHead(bool checked); void useFullAvatar(bool checked); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index ad90c88aaa..eb94557bd5 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -103,6 +103,8 @@ const int AVATAR_BILLBOARD_PACKET_SEND_INTERVAL_MSECS = 5000; const QUrl DEFAULT_HEAD_MODEL_URL = QUrl("http://public.highfidelity.io/models/heads/defaultAvatar_head.fst"); const QUrl DEFAULT_BODY_MODEL_URL = QUrl("http://public.highfidelity.io/models/skeletons/defaultAvatar_body.fst"); +const QUrl DEFAULT_FULL_AVATAR_MODEL_URL = QUrl("http://public.highfidelity.io/marketplace/contents/029db3d4-da2c-4cb2-9c08-b9612ba576f5/02949063e7c4aed42ad9d1a58461f56d.fst"); + // Where one's own Avatar begins in the world (will be overwritten if avatar data file is found). // This is the start location in the Sandbox (xyz: 6270, 211, 6000). diff --git a/libraries/fbx/src/FSTReader.cpp b/libraries/fbx/src/FSTReader.cpp index 6a5cc2bd53..d7f0ff4e70 100644 --- a/libraries/fbx/src/FSTReader.cpp +++ b/libraries/fbx/src/FSTReader.cpp @@ -10,6 +10,13 @@ // #include +#include +#include +#include + +#include +#include +#include #include "FSTReader.h" @@ -169,3 +176,17 @@ FSTReader::ModelType FSTReader::predictModelType(const QVariantHash& mapping) { return ENTITY_MODEL; } + +QVariantHash FSTReader::downloadMapping(const QString& url) { + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkRequest networkRequest = QNetworkRequest(url); + networkRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT); + QNetworkReply* reply = networkAccessManager.get(networkRequest); + qDebug() << "Downloading avatar file at " << url; + QEventLoop loop; + QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); + loop.exec(); + QByteArray fstContents = reply->readAll(); + delete reply; + return FSTReader::readMapping(fstContents); +} \ No newline at end of file diff --git a/libraries/fbx/src/FSTReader.h b/libraries/fbx/src/FSTReader.h index 5752a224c6..981bae4feb 100644 --- a/libraries/fbx/src/FSTReader.h +++ b/libraries/fbx/src/FSTReader.h @@ -51,6 +51,7 @@ public: static QString getNameFromType(ModelType modelType); static FSTReader::ModelType getTypeFromName(const QString& name); + static QVariantHash downloadMapping(const QString& url); private: static void writeVariant(QBuffer& buffer, QVariantHash::const_iterator& it); From 50479d5d5e831b8179fde125c2f3922ecbec1735 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 3 Apr 2015 17:06:54 -0700 Subject: [PATCH 03/15] set name to Default when using default url --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c2bab11065..1f044a5a0f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4258,7 +4258,7 @@ void Application::checkSkeleton() { msgBox.setIcon(QMessageBox::Warning); msgBox.exec(); - _myAvatar->useBodyURL(DEFAULT_BODY_MODEL_URL); + _myAvatar->useBodyURL(DEFAULT_BODY_MODEL_URL, "Default"); } else { _myAvatar->updateCharacterController(); _physicsEngine.setCharacterController(_myAvatar->getCharacterController()); From 0bc1b028954c586d828a27b3e4517f9288185993 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 3 Apr 2015 17:24:53 -0700 Subject: [PATCH 04/15] improvements to tracking model names --- interface/src/Application.cpp | 1 + interface/src/avatar/MyAvatar.cpp | 36 +++++++++++++++++++++----- interface/src/ui/PreferencesDialog.cpp | 1 + 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1f044a5a0f..6befbe2555 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3747,6 +3747,7 @@ bool Application::askToSetAvatarUrl(const QString& url) { } else { qDebug() << "Declined to use the avatar: " << url; } + return true; } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 085b7bccab..3073bbb219 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -955,8 +955,16 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { void MyAvatar::useFullAvatarURL(const QUrl& fullAvatarURL, const QString& modelName) { _useFullAvatar = true; - _fullAvatarURLFromPreferences = fullAvatarURL; - _fullAvatarModelName = modelName; + + if (_fullAvatarURLFromPreferences != fullAvatarURL) { + _fullAvatarURLFromPreferences = fullAvatarURL; + if (modelName.isEmpty()) { + QVariantHash fullAvatarFST = FSTReader::downloadMapping(_fullAvatarURLFromPreferences.toString()); + _fullAvatarModelName = fullAvatarFST["name"].toString(); + } else { + _fullAvatarModelName = modelName; + } + } if (!getFaceModelURLString().isEmpty()) { setFaceModelURL(QString()); @@ -979,10 +987,26 @@ void MyAvatar::useBodyURL(const QUrl& bodyURL, const QString& modelName) { void MyAvatar::useHeadAndBodyURLs(const QUrl& headURL, const QUrl& bodyURL, const QString& headName, const QString& bodyName) { _useFullAvatar = false; - _headURLFromPreferences = headURL; - _skeletonURLFromPreferences = bodyURL; - _headModelName = headName; - _bodyModelName = bodyName; + + if (_headURLFromPreferences != headURL) { + _headURLFromPreferences = headURL; + if (headName.isEmpty()) { + QVariantHash headFST = FSTReader::downloadMapping(_headURLFromPreferences.toString()); + _headModelName = headFST["name"].toString(); + } else { + _headModelName = headName; + } + } + + if (_skeletonURLFromPreferences != bodyURL) { + _skeletonURLFromPreferences = bodyURL; + if (bodyName.isEmpty()) { + QVariantHash bodyFST = FSTReader::downloadMapping(_skeletonURLFromPreferences.toString()); + _bodyModelName = bodyFST["name"].toString(); + } else { + _bodyModelName = bodyName; + } + } if (headURL != getFaceModelURL()) { setFaceModelURL(headURL); diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 9b6cd03dfa..bc10109c36 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -271,6 +271,7 @@ void PreferencesDialog::loadPreferences() { void PreferencesDialog::savePreferences() { MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); + bool shouldDispatchIdentityPacket = false; QString displayNameStr(ui.displayNameEdit->text()); From 7f4c577e8073d2398ae8498407ef6f60280059b4 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 3 Apr 2015 17:25:39 -0700 Subject: [PATCH 05/15] end of file --- libraries/fbx/src/FSTReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/fbx/src/FSTReader.cpp b/libraries/fbx/src/FSTReader.cpp index d7f0ff4e70..32be82b392 100644 --- a/libraries/fbx/src/FSTReader.cpp +++ b/libraries/fbx/src/FSTReader.cpp @@ -189,4 +189,4 @@ QVariantHash FSTReader::downloadMapping(const QString& url) { QByteArray fstContents = reply->readAll(); delete reply; return FSTReader::readMapping(fstContents); -} \ No newline at end of file +} From d2b643d389833bc7479f7cd1f278b02b4061e872 Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Mon, 13 Apr 2015 23:57:08 +0100 Subject: [PATCH 06/15] Add targetVelocity into MyAvatar simulation MyAvatar sets a target velocity to achieve, this is parsed in the preSimulation controller step. --- interface/src/avatar/MyAvatar.cpp | 14 +++++++------- libraries/avatars/src/AvatarData.cpp | 1 + libraries/avatars/src/AvatarData.h | 2 ++ .../physics/src/DynamicCharacterController.cpp | 3 ++- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 6b70577754..be438f3297 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -126,7 +126,7 @@ void MyAvatar::reset() { _skeletonModel.reset(); getHead()->reset(); - _velocity = glm::vec3(0.0f); + _targetVelocity = glm::vec3(0.0f); setThrust(glm::vec3(0.0f)); // Reset the pitch and roll components of the avatar's orientation, preserve yaw direction glm::vec3 eulers = safeEulerAngles(getOrientation()); @@ -1240,28 +1240,28 @@ glm::vec3 MyAvatar::applyScriptedMotor(float deltaTime, const glm::vec3& localVe void MyAvatar::updatePosition(float deltaTime) { // rotate velocity into camera frame glm::quat rotation = getHead()->getCameraOrientation(); - glm::vec3 localVelocity = glm::inverse(rotation) * _velocity; + glm::vec3 localVelocity = glm::inverse(rotation) * _targetVelocity; bool isHovering = _characterController.isHovering(); glm::vec3 newLocalVelocity = applyKeyboardMotor(deltaTime, localVelocity, isHovering); newLocalVelocity = applyScriptedMotor(deltaTime, newLocalVelocity); // rotate back into world-frame - _velocity = rotation * newLocalVelocity; + _targetVelocity = rotation * newLocalVelocity; - _velocity += _thrust * deltaTime; + _targetVelocity += _thrust * deltaTime; _thrust = glm::vec3(0.0f); // cap avatar speed - float speed = glm::length(_velocity); + float speed = glm::length(_targetVelocity); if (speed > MAX_AVATAR_SPEED) { - _velocity *= MAX_AVATAR_SPEED / speed; + _targetVelocity *= MAX_AVATAR_SPEED / speed; speed = MAX_AVATAR_SPEED; } if (speed > MIN_AVATAR_SPEED && !_characterController.isEnabled()) { // update position ourselves - applyPositionDelta(deltaTime * _velocity); + applyPositionDelta(deltaTime * _targetVelocity); measureMotionDerivatives(deltaTime); } // else physics will move avatar later diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index bc49fb3514..a8d2c209c3 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -60,6 +60,7 @@ AvatarData::AvatarData() : _owningAvatarMixer(), _lastUpdateTimer(), _velocity(0.0f), + _targetVelocity(0.0f), _localAABox(DEFAULT_LOCAL_AABOX_CORNER, DEFAULT_LOCAL_AABOX_SCALE) { } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index ad90c88aaa..881b68d52f 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -294,6 +294,7 @@ public: void setVelocity(const glm::vec3 velocity) { _velocity = velocity; } Q_INVOKABLE glm::vec3 getVelocity() const { return _velocity; } + glm::vec3 getTargetVelocity() const { return _targetVelocity; } public slots: void sendAvatarDataPacket(); @@ -384,6 +385,7 @@ protected: void changeReferential(Referential* ref); glm::vec3 _velocity; + glm::vec3 _targetVelocity; AABox _localAABox; diff --git a/libraries/physics/src/DynamicCharacterController.cpp b/libraries/physics/src/DynamicCharacterController.cpp index db84bea540..15b7eb86b6 100644 --- a/libraries/physics/src/DynamicCharacterController.cpp +++ b/libraries/physics/src/DynamicCharacterController.cpp @@ -386,7 +386,7 @@ void DynamicCharacterController::preSimulation(btScalar timeStep) { setHovering(true); } - _walkVelocity = glmToBullet(_avatarData->getVelocity()); + _walkVelocity = glmToBullet(_avatarData->getTargetVelocity()); if (_pendingFlags & PENDING_FLAG_JUMP) { _pendingFlags &= ~ PENDING_FLAG_JUMP; @@ -408,6 +408,7 @@ void DynamicCharacterController::postSimulation() { _avatarData->setOrientation(rotation); _avatarData->setPosition(position - rotation * _shapeLocalOffset); + _avatarData->setVelocity(bulletToGLM(_rigidBody->getLinearVelocity())); } } From 9262585bab80a823fb88898721f573c60d7f354e Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 14 Apr 2015 10:38:22 -0700 Subject: [PATCH 07/15] first cut at moving avatar appearance into separate dialog box --- interface/src/ui/AvatarAppearanceDialog.cpp | 212 +++++++++ interface/src/ui/AvatarAppearanceDialog.h | 63 +++ interface/src/ui/DialogsManager.cpp | 10 + interface/src/ui/DialogsManager.h | 3 + interface/src/ui/PreferencesDialog.cpp | 127 +----- interface/src/ui/PreferencesDialog.h | 15 - interface/ui/avatarAppearance.ui | 471 ++++++++++++++++++++ interface/ui/preferencesDialog.ui | 461 ++++--------------- 8 files changed, 865 insertions(+), 497 deletions(-) create mode 100644 interface/src/ui/AvatarAppearanceDialog.cpp create mode 100644 interface/src/ui/AvatarAppearanceDialog.h create mode 100644 interface/ui/avatarAppearance.ui diff --git a/interface/src/ui/AvatarAppearanceDialog.cpp b/interface/src/ui/AvatarAppearanceDialog.cpp new file mode 100644 index 0000000000..1200c71cac --- /dev/null +++ b/interface/src/ui/AvatarAppearanceDialog.cpp @@ -0,0 +1,212 @@ +// +// AvatarAppearanceDialog.cpp +// interface/src/ui +// +// Created by Stojce Slavkovski on 2/20/14. +// Copyright 2014 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 +#include +#include +#include +#include + +#include "Application.h" +#include "MainWindow.h" +#include "LODManager.h" +#include "Menu.h" +#include "AvatarAppearanceDialog.h" +#include "Snapshot.h" +#include "UserActivityLogger.h" +#include "UIUtil.h" + + +const int PREFERENCES_HEIGHT_PADDING = 20; + +AvatarAppearanceDialog::AvatarAppearanceDialog(QWidget* parent) : + QDialog(parent) { + + setAttribute(Qt::WA_DeleteOnClose); + + ui.setupUi(this); + + loadAvatarAppearance(); + + connect(ui.defaultButton, &QPushButton::clicked, this, &AvatarAppearanceDialog::accept); + + connect(ui.buttonBrowseHead, &QPushButton::clicked, this, &AvatarAppearanceDialog::openHeadModelBrowser); + connect(ui.buttonBrowseBody, &QPushButton::clicked, this, &AvatarAppearanceDialog::openBodyModelBrowser); + connect(ui.buttonBrowseFullAvatar, &QPushButton::clicked, this, &AvatarAppearanceDialog::openFullAvatarModelBrowser); + + connect(ui.useSeparateBodyAndHead, &QRadioButton::clicked, this, &AvatarAppearanceDialog::useSeparateBodyAndHead); + connect(ui.useFullAvatar, &QRadioButton::clicked, this, &AvatarAppearanceDialog::useFullAvatar); + + connect(Application::getInstance(), &Application::headURLChanged, this, &AvatarAppearanceDialog::headURLChanged); + connect(Application::getInstance(), &Application::bodyURLChanged, this, &AvatarAppearanceDialog::bodyURLChanged); + connect(Application::getInstance(), &Application::fullAvatarURLChanged, this, &AvatarAppearanceDialog::fullAvatarURLChanged); + + // move dialog to left side + //move(parentWidget()->geometry().topLeft()); + //setFixedHeight(parentWidget()->size().height() - PREFERENCES_HEIGHT_PADDING); + + auto myAvatar = DependencyManager::get()->getMyAvatar(); + + ui.bodyNameLabel->setText("Body - " + myAvatar->getBodyModelName()); + ui.headNameLabel->setText("Head - " + myAvatar->getHeadModelName()); + ui.fullAvatarNameLabel->setText("Full Avatar - " + myAvatar->getFullAvartarModelName()); + + UIUtil::scaleWidgetFontSizes(this); +} + +void AvatarAppearanceDialog::useSeparateBodyAndHead(bool checked) { + setUseFullAvatar(!checked); + + QUrl headURL(ui.faceURLEdit->text()); + QUrl bodyURL(ui.skeletonURLEdit->text()); + + DependencyManager::get()->getMyAvatar()->useHeadAndBodyURLs(headURL, bodyURL); +} + +void AvatarAppearanceDialog::useFullAvatar(bool checked) { + setUseFullAvatar(checked); + QUrl fullAvatarURL(ui.fullAvatarURLEdit->text()); + DependencyManager::get()->getMyAvatar()->useFullAvatarURL(fullAvatarURL); +} + +void AvatarAppearanceDialog::setUseFullAvatar(bool useFullAvatar) { + _useFullAvatar = useFullAvatar; + ui.faceURLEdit->setEnabled(!_useFullAvatar); + ui.skeletonURLEdit->setEnabled(!_useFullAvatar); + ui.fullAvatarURLEdit->setEnabled(_useFullAvatar); + + ui.useFullAvatar->setChecked(_useFullAvatar); + ui.useSeparateBodyAndHead->setChecked(!_useFullAvatar); +} + +void AvatarAppearanceDialog::headURLChanged(const QString& newValue, const QString& modelName) { + ui.faceURLEdit->setText(newValue); + setUseFullAvatar(false); + ui.headNameLabel->setText("Head - " + modelName); +} + +void AvatarAppearanceDialog::bodyURLChanged(const QString& newValue, const QString& modelName) { + ui.skeletonURLEdit->setText(newValue); + setUseFullAvatar(false); + ui.bodyNameLabel->setText("Body - " + modelName); +} + +void AvatarAppearanceDialog::fullAvatarURLChanged(const QString& newValue, const QString& modelName) { + ui.fullAvatarURLEdit->setText(newValue); + setUseFullAvatar(true); + ui.fullAvatarNameLabel->setText("Full Avatar - " + modelName); +} + +void AvatarAppearanceDialog::accept() { + saveAvatarAppearance(); + close(); + delete _marketplaceWindow; + _marketplaceWindow = NULL; +} + +void AvatarAppearanceDialog::setHeadUrl(QString modelUrl) { + ui.faceURLEdit->setText(modelUrl); +} + +void AvatarAppearanceDialog::setSkeletonUrl(QString modelUrl) { + ui.skeletonURLEdit->setText(modelUrl); +} + +void AvatarAppearanceDialog::openFullAvatarModelBrowser() { + auto MARKETPLACE_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/marketplace?category=avatars"; + auto WIDTH = 900; + auto HEIGHT = 700; + if (!_marketplaceWindow) { + _marketplaceWindow = new WebWindowClass("Marketplace", MARKETPLACE_URL, WIDTH, HEIGHT, false); + } + _marketplaceWindow->setVisible(true); +} + +void AvatarAppearanceDialog::openHeadModelBrowser() { + auto MARKETPLACE_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/marketplace?category=avatars"; + auto WIDTH = 900; + auto HEIGHT = 700; + if (!_marketplaceWindow) { + _marketplaceWindow = new WebWindowClass("Marketplace", MARKETPLACE_URL, WIDTH, HEIGHT, false); + } + _marketplaceWindow->setVisible(true); +} + +void AvatarAppearanceDialog::openBodyModelBrowser() { + auto MARKETPLACE_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/marketplace?category=avatars"; + auto WIDTH = 900; + auto HEIGHT = 700; + if (!_marketplaceWindow) { + _marketplaceWindow = new WebWindowClass("Marketplace", MARKETPLACE_URL, WIDTH, HEIGHT, false); + } + _marketplaceWindow->setVisible(true); +} + +void AvatarAppearanceDialog::resizeEvent(QResizeEvent *resizeEvent) { + + // keep buttons panel at the bottom + ui.buttonsPanel->setGeometry(0, + size().height() - ui.buttonsPanel->height(), + size().width(), + ui.buttonsPanel->height()); + + // set width and height of srcollarea to match bottom panel and width + ui.scrollArea->setGeometry(ui.scrollArea->geometry().x(), ui.scrollArea->geometry().y(), + size().width(), + size().height() - ui.buttonsPanel->height() - ui.scrollArea->geometry().y()); + +} + +void AvatarAppearanceDialog::loadAvatarAppearance() { + + MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); + + _useFullAvatar = myAvatar->getUseFullAvatar(); + _fullAvatarURLString = myAvatar->getFullAvatarURLFromPreferences().toString(); + _headURLString = myAvatar->getHeadURLFromPreferences().toString(); + _bodyURLString = myAvatar->getBodyURLFromPreferences().toString(); + + ui.fullAvatarURLEdit->setText(_fullAvatarURLString); + ui.faceURLEdit->setText(_headURLString); + ui.skeletonURLEdit->setText(_bodyURLString); + setUseFullAvatar(_useFullAvatar); +} + +void AvatarAppearanceDialog::saveAvatarAppearance() { + + MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); + + QUrl headURL(ui.faceURLEdit->text()); + QString headURLString = headURL.toString(); + + QUrl bodyURL(ui.skeletonURLEdit->text()); + QString bodyURLString = bodyURL.toString(); + + QUrl fullAvatarURL(ui.fullAvatarURLEdit->text()); + QString fullAvatarURLString = fullAvatarURL.toString(); + + bool somethingChanged = + _useFullAvatar != myAvatar->getUseFullAvatar() || + fullAvatarURLString != myAvatar->getFullAvatarURLFromPreferences().toString() || + headURLString != myAvatar->getHeadURLFromPreferences().toString() || + bodyURLString != myAvatar->getBodyURLFromPreferences().toString(); + + if (somethingChanged) { + if (_useFullAvatar) { + myAvatar->useFullAvatarURL(fullAvatarURL); + } else { + myAvatar->useHeadAndBodyURLs(headURL, bodyURL); + } + } +} diff --git a/interface/src/ui/AvatarAppearanceDialog.h b/interface/src/ui/AvatarAppearanceDialog.h new file mode 100644 index 0000000000..f7a735e611 --- /dev/null +++ b/interface/src/ui/AvatarAppearanceDialog.h @@ -0,0 +1,63 @@ +// +// AvatarAppearanceDialog.h +// interface/src/ui +// +// Created by Stojce Slavkovski on 2/20/14. +// Copyright 2014 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_AvatarAppearanceDialog_h +#define hifi_AvatarAppearanceDialog_h + +#include "ui_avatarAppearance.h" + +#include +#include + +#include "scripting/WebWindowClass.h" + +class AvatarAppearanceDialog : public QDialog { + Q_OBJECT + +public: + AvatarAppearanceDialog(QWidget* parent = nullptr); + +protected: + void resizeEvent(QResizeEvent* resizeEvent); + +private: + void loadAvatarAppearance(); + void saveAvatarAppearance(); + void openHeadModelBrowser(); + void openBodyModelBrowser(); + void openFullAvatarModelBrowser(); + void setUseFullAvatar(bool useFullAvatar); + + Ui_AvatarAppearanceDialog ui; + + bool _useFullAvatar; + QString _headURLString; + QString _bodyURLString; + QString _fullAvatarURLString; + + + QString _displayNameString; + + WebWindowClass* _marketplaceWindow = NULL; + +private slots: + void accept(); + void setHeadUrl(QString modelUrl); + void setSkeletonUrl(QString modelUrl); + void headURLChanged(const QString& newValue, const QString& modelName); + void bodyURLChanged(const QString& newValue, const QString& modelName); + void fullAvatarURLChanged(const QString& newValue, const QString& modelName); + void useSeparateBodyAndHead(bool checked); + void useFullAvatar(bool checked); + +}; + +#endif // hifi_AvatarAppearanceDialog_h diff --git a/interface/src/ui/DialogsManager.cpp b/interface/src/ui/DialogsManager.cpp index 701ceb0189..ad86e83ec0 100644 --- a/interface/src/ui/DialogsManager.cpp +++ b/interface/src/ui/DialogsManager.cpp @@ -18,6 +18,7 @@ #include "AddressBarDialog.h" #include "AnimationsDialog.h" #include "AttachmentsDialog.h" +#include "AvatarAppearanceDialog.h" #include "BandwidthDialog.h" #include "CachesSizeDialog.h" #include "DiskCacheEditor.h" @@ -85,6 +86,15 @@ void DialogsManager::editPreferences() { } } +void DialogsManager::changeAvatarAppearance() { + if (!_avatarAppearanceDialog) { + maybeCreateDialog(_avatarAppearanceDialog); + _avatarAppearanceDialog->show(); + } else { + _avatarAppearanceDialog->close(); + } +} + void DialogsManager::editAttachments() { if (!_attachmentsDialog) { maybeCreateDialog(_attachmentsDialog); diff --git a/interface/src/ui/DialogsManager.h b/interface/src/ui/DialogsManager.h index 897215cbff..e7f017d54d 100644 --- a/interface/src/ui/DialogsManager.h +++ b/interface/src/ui/DialogsManager.h @@ -33,6 +33,7 @@ class OctreeStatsDialog; class PreferencesDialog; class ScriptEditorWindow; class QMessageBox; +class AvatarAppearanceDialog; class DialogsManager : public QObject, public Dependency { Q_OBJECT @@ -59,6 +60,7 @@ public slots: void hmdTools(bool showTools); void showScriptEditor(); void showIRCLink(); + void changeAvatarAppearance(); private slots: void toggleToolWindow(); @@ -94,6 +96,7 @@ private: QPointer _octreeStatsDialog; QPointer _preferencesDialog; QPointer _scriptEditor; + QPointer _avatarAppearanceDialog; }; #endif // hifi_DialogsManager_h \ No newline at end of file diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index bc10109c36..99ad98ef2d 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -19,6 +19,7 @@ #include #include "Application.h" +#include "DialogsManager.h" #include "MainWindow.h" #include "LODManager.h" #include "Menu.h" @@ -41,18 +42,13 @@ PreferencesDialog::PreferencesDialog(QWidget* parent) : ui.outputBufferSizeSpinner->setMinimum(MIN_AUDIO_OUTPUT_BUFFER_SIZE_FRAMES); ui.outputBufferSizeSpinner->setMaximum(MAX_AUDIO_OUTPUT_BUFFER_SIZE_FRAMES); - connect(ui.buttonBrowseHead, &QPushButton::clicked, this, &PreferencesDialog::openHeadModelBrowser); - connect(ui.buttonBrowseBody, &QPushButton::clicked, this, &PreferencesDialog::openBodyModelBrowser); - connect(ui.buttonBrowseFullAvatar, &QPushButton::clicked, this, &PreferencesDialog::openFullAvatarModelBrowser); - connect(ui.buttonBrowseLocation, &QPushButton::clicked, this, &PreferencesDialog::openSnapshotLocationBrowser); connect(ui.buttonBrowseScriptsLocation, &QPushButton::clicked, this, &PreferencesDialog::openScriptsLocationBrowser); connect(ui.buttonReloadDefaultScripts, &QPushButton::clicked, Application::getInstance(), &Application::loadDefaultScripts); - connect(ui.useSeparateBodyAndHead, &QRadioButton::clicked, this, &PreferencesDialog::useSeparateBodyAndHead); - connect(ui.useFullAvatar, &QRadioButton::clicked, this, &PreferencesDialog::useFullAvatar); - - + DialogsManager* dialogsManager = DependencyManager::get().data(); + connect(ui.buttonChangeApperance, &QPushButton::clicked, dialogsManager, &DialogsManager::changeAvatarAppearance); + connect(Application::getInstance(), &Application::headURLChanged, this, &PreferencesDialog::headURLChanged); connect(Application::getInstance(), &Application::bodyURLChanged, this, &PreferencesDialog::bodyURLChanged); connect(Application::getInstance(), &Application::fullAvatarURLChanged, this, &PreferencesDialog::fullAvatarURLChanged); @@ -63,54 +59,21 @@ PreferencesDialog::PreferencesDialog(QWidget* parent) : auto myAvatar = DependencyManager::get()->getMyAvatar(); - ui.bodyNameLabel->setText("Body - " + myAvatar->getBodyModelName()); - ui.headNameLabel->setText("Head - " + myAvatar->getHeadModelName()); - ui.fullAvatarNameLabel->setText("Full Avatar - " + myAvatar->getFullAvartarModelName()); + ui.apperanceDescription->setText("Body - " + myAvatar->getBodyModelName()); UIUtil::scaleWidgetFontSizes(this); } -void PreferencesDialog::useSeparateBodyAndHead(bool checked) { - setUseFullAvatar(!checked); - - QUrl headURL(ui.faceURLEdit->text()); - QUrl bodyURL(ui.skeletonURLEdit->text()); - - DependencyManager::get()->getMyAvatar()->useHeadAndBodyURLs(headURL, bodyURL); -} - -void PreferencesDialog::useFullAvatar(bool checked) { - setUseFullAvatar(checked); - QUrl fullAvatarURL(ui.fullAvatarURLEdit->text()); - DependencyManager::get()->getMyAvatar()->useFullAvatarURL(fullAvatarURL); -} - -void PreferencesDialog::setUseFullAvatar(bool useFullAvatar) { - _useFullAvatar = useFullAvatar; - ui.faceURLEdit->setEnabled(!_useFullAvatar); - ui.skeletonURLEdit->setEnabled(!_useFullAvatar); - ui.fullAvatarURLEdit->setEnabled(_useFullAvatar); - - ui.useFullAvatar->setChecked(_useFullAvatar); - ui.useSeparateBodyAndHead->setChecked(!_useFullAvatar); -} - void PreferencesDialog::headURLChanged(const QString& newValue, const QString& modelName) { - ui.faceURLEdit->setText(newValue); - setUseFullAvatar(false); - ui.headNameLabel->setText("Head - " + modelName); + ui.apperanceDescription->setText("Head - " + modelName); } void PreferencesDialog::bodyURLChanged(const QString& newValue, const QString& modelName) { - ui.skeletonURLEdit->setText(newValue); - setUseFullAvatar(false); - ui.bodyNameLabel->setText("Body - " + modelName); + ui.apperanceDescription->setText("Body - " + modelName); } void PreferencesDialog::fullAvatarURLChanged(const QString& newValue, const QString& modelName) { - ui.fullAvatarURLEdit->setText(newValue); - setUseFullAvatar(true); - ui.fullAvatarNameLabel->setText("Full Avatar - " + modelName); + ui.apperanceDescription->setText("Full Avatar - " + modelName); } void PreferencesDialog::accept() { @@ -120,44 +83,6 @@ void PreferencesDialog::accept() { _marketplaceWindow = NULL; } -void PreferencesDialog::setHeadUrl(QString modelUrl) { - ui.faceURLEdit->setText(modelUrl); -} - -void PreferencesDialog::setSkeletonUrl(QString modelUrl) { - ui.skeletonURLEdit->setText(modelUrl); -} - -void PreferencesDialog::openFullAvatarModelBrowser() { - auto MARKETPLACE_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/marketplace?category=avatars"; - auto WIDTH = 900; - auto HEIGHT = 700; - if (!_marketplaceWindow) { - _marketplaceWindow = new WebWindowClass("Marketplace", MARKETPLACE_URL, WIDTH, HEIGHT, false); - } - _marketplaceWindow->setVisible(true); -} - -void PreferencesDialog::openHeadModelBrowser() { - auto MARKETPLACE_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/marketplace?category=avatars"; - auto WIDTH = 900; - auto HEIGHT = 700; - if (!_marketplaceWindow) { - _marketplaceWindow = new WebWindowClass("Marketplace", MARKETPLACE_URL, WIDTH, HEIGHT, false); - } - _marketplaceWindow->setVisible(true); -} - -void PreferencesDialog::openBodyModelBrowser() { - auto MARKETPLACE_URL = NetworkingConstants::METAVERSE_SERVER_URL.toString() + "/marketplace?category=avatars"; - auto WIDTH = 900; - auto HEIGHT = 700; - if (!_marketplaceWindow) { - _marketplaceWindow = new WebWindowClass("Marketplace", MARKETPLACE_URL, WIDTH, HEIGHT, false); - } - _marketplaceWindow->setVisible(true); -} - void PreferencesDialog::openSnapshotLocationBrowser() { QString dir = QFileDialog::getExistingDirectory(this, tr("Snapshots Location"), QStandardPaths::writableLocation(QStandardPaths::DesktopLocation), @@ -199,19 +124,6 @@ void PreferencesDialog::loadPreferences() { _displayNameString = myAvatar->getDisplayName(); ui.displayNameEdit->setText(_displayNameString); - - _useFullAvatar = myAvatar->getUseFullAvatar(); - _fullAvatarURLString = myAvatar->getFullAvatarURLFromPreferences().toString(); - _headURLString = myAvatar->getHeadURLFromPreferences().toString(); - _bodyURLString = myAvatar->getBodyURLFromPreferences().toString(); - - ui.fullAvatarURLEdit->setText(_fullAvatarURLString); - ui.faceURLEdit->setText(_headURLString); - ui.skeletonURLEdit->setText(_bodyURLString); - setUseFullAvatar(_useFullAvatar); - - // TODO: load the names for the models. - ui.sendDataCheckBox->setChecked(!menuInstance->isOptionChecked(MenuOption::DisableActivityLogger)); ui.snapshotLocationEdit->setText(Snapshot::snapshotsLocation.get()); @@ -281,29 +193,6 @@ void PreferencesDialog::savePreferences() { shouldDispatchIdentityPacket = true; } - QUrl headURL(ui.faceURLEdit->text()); - QString headURLString = headURL.toString(); - - QUrl bodyURL(ui.skeletonURLEdit->text()); - QString bodyURLString = bodyURL.toString(); - - QUrl fullAvatarURL(ui.fullAvatarURLEdit->text()); - QString fullAvatarURLString = fullAvatarURL.toString(); - - bool somethingChanged = - _useFullAvatar != myAvatar->getUseFullAvatar() || - fullAvatarURLString != myAvatar->getFullAvatarURLFromPreferences().toString() || - headURLString != myAvatar->getHeadURLFromPreferences().toString() || - bodyURLString != myAvatar->getBodyURLFromPreferences().toString(); - - if (somethingChanged) { - if (_useFullAvatar) { - myAvatar->useFullAvatarURL(fullAvatarURL); - } else { - myAvatar->useHeadAndBodyURLs(headURL, bodyURL); - } - } - if (shouldDispatchIdentityPacket) { myAvatar->sendIdentityPacket(); } diff --git a/interface/src/ui/PreferencesDialog.h b/interface/src/ui/PreferencesDialog.h index 3f097ca9ab..22efe3489d 100644 --- a/interface/src/ui/PreferencesDialog.h +++ b/interface/src/ui/PreferencesDialog.h @@ -31,35 +31,20 @@ protected: private: void loadPreferences(); void savePreferences(); - void openHeadModelBrowser(); - void openBodyModelBrowser(); - void openFullAvatarModelBrowser(); - void setUseFullAvatar(bool useFullAvatar); Ui_PreferencesDialog ui; - bool _useFullAvatar; - QString _headURLString; - QString _bodyURLString; - QString _fullAvatarURLString; - - QString _displayNameString; WebWindowClass* _marketplaceWindow = NULL; private slots: void accept(); - void setHeadUrl(QString modelUrl); - void setSkeletonUrl(QString modelUrl); void openSnapshotLocationBrowser(); void openScriptsLocationBrowser(); void headURLChanged(const QString& newValue, const QString& modelName); void bodyURLChanged(const QString& newValue, const QString& modelName); void fullAvatarURLChanged(const QString& newValue, const QString& modelName); - void useSeparateBodyAndHead(bool checked); - void useFullAvatar(bool checked); - }; #endif // hifi_PreferencesDialog_h diff --git a/interface/ui/avatarAppearance.ui b/interface/ui/avatarAppearance.ui new file mode 100644 index 0000000000..5ebf2c705b --- /dev/null +++ b/interface/ui/avatarAppearance.ui @@ -0,0 +1,471 @@ + + + AvatarAppearanceDialog + + + + 0 + 0 + 500 + 350 + + + + + 0 + 0 + + + + + 500 + 350 + + + + + 500 + 16777215 + + + + + 13 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + QFrame::NoFrame + + + QFrame::Plain + + + 0 + + + true + + + + + 0 + -107 + 485 + 1550 + + + + + 0 + + + 30 + + + 0 + + + 30 + + + 10 + + + + + + + 0 + + + 7 + + + 7 + + + + + + + + + Arial + + + + Use single avatar with Body and Head + + + + + + + + + + 0 + + + 10 + + + 0 + + + 0 + + + + + + + + Arial + + + + Full Avatar + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + fullAvatarURLEdit + + + + + + + + + + + + 0 + 0 + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 5 + 0 + + + + + + + + + + Arial + + + + Browse + + + + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + Arial + + + + Use separate Body and Head avatar files + + + + + + + + + 0 + + + 10 + + + 7 + + + 7 + + + + + + + + + Arial + + + + Head + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + + + + + 0 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 5 + 20 + + + + + + + + + Arial + + + + Browse + + + + 0 + 0 + + + + + + + + + + + + + + + 0 + + + 10 + + + 7 + + + 7 + + + + + + + Arial + + + + Body + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + skeletonURLEdit + + + + + + + + 0 + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 5 + 20 + + + + + + + + + Arial + + + + Browse + + + + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + Arial + + + + Close + + + true + + + false + + + + + + + + + + + + diff --git a/interface/ui/preferencesDialog.ui b/interface/ui/preferencesDialog.ui index 4a0b1e961a..6f0ec7d792 100644 --- a/interface/ui/preferencesDialog.ui +++ b/interface/ui/preferencesDialog.ui @@ -128,6 +128,8 @@ + + @@ -187,370 +189,98 @@ - - - - 0 - - - 7 - - - 7 - - - - - - - - - 0 - 0 - - - - - 32 - 28 - - - - - 0 - 0 - - - - - Arial - - - - Use single avatar with Body and Head - - - - 0 - 0 - - - - - - - - - - - 0 - - - 10 - - - 7 - - - 7 - - - - - - - - Arial - - - - Full Avatar - - - Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - - - fullAvatarURLEdit - - - - - - - - 0 - - - - - - 0 - 0 - - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 5 - 20 - - - - - - - - - Arial - - - - Browse - - - - 0 - 0 - - - - - - - - - - - - - - 0 - 0 - - - - - 32 - 28 - - - - - 0 - 0 - - - - - Arial - - - - Use separate Body and Head avatar files - - - - 0 - 0 - - - - - - - - - - 0 - - - 10 - - - 7 - - - 7 - - - - - - - - - Arial - - - - Head - - - Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - - - - - - - - - - 0 - - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 5 - 20 - - - - - - - - - Arial - - - - Browse - - - - 0 - 0 - - - - - - - - - - - - - - - 0 - - - 10 - - - 7 - - - 7 - - - - - - - Arial - - - - Body - - - Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - - - skeletonURLEdit - - - - - - - - 0 - - - - - - 0 - 0 - - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 5 - 20 - - - - - - - - - Arial - - - - Browse - - - - 0 - 0 - - - - - - - - - - - - - - - - - - - - + + + + 0 + + + 7 + + + 7 + + + + + + Arial + + + + <html><head/><body><p>Appearance</p></body></html> + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + apperanceDescription + + + + + + + + + + 0 + + + + + + Arial + + + + + false + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 5 + 20 + + + + + + + + + Arial + + + + Change + + + + 0 + 0 + + + + + + + + + + @@ -621,6 +351,7 @@ + @@ -671,6 +402,10 @@ + + + + From 4d34ba7bdf646dff089b2d8ebe50949828dd8b67 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 14 Apr 2015 10:57:47 -0700 Subject: [PATCH 08/15] Update main window to quit app when closed --- interface/src/MainWindow.cpp | 4 ++++ interface/src/MainWindow.h | 1 + 2 files changed, 5 insertions(+) diff --git a/interface/src/MainWindow.cpp b/interface/src/MainWindow.cpp index 41b1249af1..f60716dc48 100644 --- a/interface/src/MainWindow.cpp +++ b/interface/src/MainWindow.cpp @@ -55,6 +55,10 @@ void MainWindow::saveGeometry() { } } +void MainWindow::closeEvent(QCloseEvent* event) { + qApp->quit(); +} + void MainWindow::moveEvent(QMoveEvent* event) { emit windowGeometryChanged(QRect(event->pos(), size())); QMainWindow::moveEvent(event); diff --git a/interface/src/MainWindow.h b/interface/src/MainWindow.h index 4437fa6a1f..c6faf8e01a 100644 --- a/interface/src/MainWindow.h +++ b/interface/src/MainWindow.h @@ -30,6 +30,7 @@ signals: void windowShown(bool shown); protected: + virtual void closeEvent(QCloseEvent* event); virtual void moveEvent(QMoveEvent* event); virtual void resizeEvent(QResizeEvent* event); virtual void showEvent(QShowEvent* event); From 174e9f21333eecb7a9a93f9c1efae3a89e5b7db5 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 14 Apr 2015 12:38:29 -0700 Subject: [PATCH 09/15] more tweaks to preferences UI --- interface/src/avatar/MyAvatar.cpp | 23 +++++++++++++++++++++ interface/src/avatar/MyAvatar.h | 2 ++ interface/src/ui/AvatarAppearanceDialog.cpp | 20 ++++++++---------- interface/src/ui/AvatarAppearanceDialog.h | 1 + interface/src/ui/DialogsManager.h | 1 + interface/src/ui/PreferencesDialog.cpp | 14 +++++++------ interface/src/ui/PreferencesDialog.h | 2 ++ 7 files changed, 46 insertions(+), 17 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 3073bbb219..5a372ae274 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -943,6 +943,29 @@ void MyAvatar::clearJointAnimationPriorities() { } } +QString MyAvatar::getModelDescription() const { + QString result; + if (_useFullAvatar) { + if (!getFullAvartarModelName().isEmpty()) { + result = "Full Avatar \"" + getFullAvartarModelName() + "\""; + } else { + result = "Full Avatar \"" + _fullAvatarURLFromPreferences.fileName() + "\""; + } + } else { + if (!getHeadModelName().isEmpty()) { + result = "Head \"" + getHeadModelName() + "\""; + } else { + result = "Head \"" + _headURLFromPreferences.fileName() + "\""; + } + if (!getBodyModelName().isEmpty()) { + result += " and Body \"" + getBodyModelName() + "\""; + } else { + result += " and Body \"" + _skeletonURLFromPreferences.fileName() + "\""; + } + } + return result; +} + void MyAvatar::setFaceModelURL(const QUrl& faceModelURL) { Avatar::setFaceModelURL(faceModelURL); _billboardValid = false; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 9c1f78c696..066bfdd930 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -131,6 +131,8 @@ public: const QString& getBodyModelName() const { return _bodyModelName; } const QString& getFullAvartarModelName() const { return _fullAvatarModelName; } + QString getModelDescription() const; + virtual void setAttachmentData(const QVector& attachmentData); virtual glm::vec3 getSkeletonPosition() const; diff --git a/interface/src/ui/AvatarAppearanceDialog.cpp b/interface/src/ui/AvatarAppearanceDialog.cpp index 1200c71cac..ceaaf140c4 100644 --- a/interface/src/ui/AvatarAppearanceDialog.cpp +++ b/interface/src/ui/AvatarAppearanceDialog.cpp @@ -26,9 +26,8 @@ #include "Snapshot.h" #include "UserActivityLogger.h" #include "UIUtil.h" - - -const int PREFERENCES_HEIGHT_PADDING = 20; +#include "ui/DialogsManager.h" +#include "ui/PreferencesDialog.h" AvatarAppearanceDialog::AvatarAppearanceDialog(QWidget* parent) : QDialog(parent) { @@ -52,10 +51,6 @@ AvatarAppearanceDialog::AvatarAppearanceDialog(QWidget* parent) : connect(Application::getInstance(), &Application::bodyURLChanged, this, &AvatarAppearanceDialog::bodyURLChanged); connect(Application::getInstance(), &Application::fullAvatarURLChanged, this, &AvatarAppearanceDialog::fullAvatarURLChanged); - // move dialog to left side - //move(parentWidget()->geometry().topLeft()); - //setFixedHeight(parentWidget()->size().height() - PREFERENCES_HEIGHT_PADDING); - auto myAvatar = DependencyManager::get()->getMyAvatar(); ui.bodyNameLabel->setText("Body - " + myAvatar->getBodyModelName()); @@ -66,18 +61,16 @@ AvatarAppearanceDialog::AvatarAppearanceDialog(QWidget* parent) : } void AvatarAppearanceDialog::useSeparateBodyAndHead(bool checked) { - setUseFullAvatar(!checked); - QUrl headURL(ui.faceURLEdit->text()); QUrl bodyURL(ui.skeletonURLEdit->text()); - DependencyManager::get()->getMyAvatar()->useHeadAndBodyURLs(headURL, bodyURL); + setUseFullAvatar(!checked); } void AvatarAppearanceDialog::useFullAvatar(bool checked) { - setUseFullAvatar(checked); QUrl fullAvatarURL(ui.fullAvatarURLEdit->text()); DependencyManager::get()->getMyAvatar()->useFullAvatarURL(fullAvatarURL); + setUseFullAvatar(checked); } void AvatarAppearanceDialog::setUseFullAvatar(bool useFullAvatar) { @@ -88,6 +81,8 @@ void AvatarAppearanceDialog::setUseFullAvatar(bool useFullAvatar) { ui.useFullAvatar->setChecked(_useFullAvatar); ui.useSeparateBodyAndHead->setChecked(!_useFullAvatar); + + DependencyManager::get()->getPreferencesDialog()->avatarDescriptionChanged(); } void AvatarAppearanceDialog::headURLChanged(const QString& newValue, const QString& modelName) { @@ -110,6 +105,9 @@ void AvatarAppearanceDialog::fullAvatarURLChanged(const QString& newValue, const void AvatarAppearanceDialog::accept() { saveAvatarAppearance(); + + DependencyManager::get()->getPreferencesDialog()->avatarDescriptionChanged(); + close(); delete _marketplaceWindow; _marketplaceWindow = NULL; diff --git a/interface/src/ui/AvatarAppearanceDialog.h b/interface/src/ui/AvatarAppearanceDialog.h index f7a735e611..be30caeedb 100644 --- a/interface/src/ui/AvatarAppearanceDialog.h +++ b/interface/src/ui/AvatarAppearanceDialog.h @@ -58,6 +58,7 @@ private slots: void useSeparateBodyAndHead(bool checked); void useFullAvatar(bool checked); + }; #endif // hifi_AvatarAppearanceDialog_h diff --git a/interface/src/ui/DialogsManager.h b/interface/src/ui/DialogsManager.h index e7f017d54d..d5d9c33a9a 100644 --- a/interface/src/ui/DialogsManager.h +++ b/interface/src/ui/DialogsManager.h @@ -44,6 +44,7 @@ public: QPointer getHMDToolsDialog() const { return _hmdToolsDialog; } QPointer getLodToolsDialog() const { return _lodToolsDialog; } QPointer getOctreeStatsDialog() const { return _octreeStatsDialog; } + QPointer getPreferencesDialog() const { return _preferencesDialog; } public slots: void toggleAddressBar(); diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 99ad98ef2d..98f7382097 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -57,23 +57,25 @@ PreferencesDialog::PreferencesDialog(QWidget* parent) : move(parentWidget()->geometry().topLeft()); setFixedHeight(parentWidget()->size().height() - PREFERENCES_HEIGHT_PADDING); - auto myAvatar = DependencyManager::get()->getMyAvatar(); - - ui.apperanceDescription->setText("Body - " + myAvatar->getBodyModelName()); + ui.apperanceDescription->setText(DependencyManager::get()->getMyAvatar()->getModelDescription()); UIUtil::scaleWidgetFontSizes(this); } +void PreferencesDialog::avatarDescriptionChanged() { + ui.apperanceDescription->setText(DependencyManager::get()->getMyAvatar()->getModelDescription()); +} + void PreferencesDialog::headURLChanged(const QString& newValue, const QString& modelName) { - ui.apperanceDescription->setText("Head - " + modelName); + ui.apperanceDescription->setText(DependencyManager::get()->getMyAvatar()->getModelDescription()); } void PreferencesDialog::bodyURLChanged(const QString& newValue, const QString& modelName) { - ui.apperanceDescription->setText("Body - " + modelName); + ui.apperanceDescription->setText(DependencyManager::get()->getMyAvatar()->getModelDescription()); } void PreferencesDialog::fullAvatarURLChanged(const QString& newValue, const QString& modelName) { - ui.apperanceDescription->setText("Full Avatar - " + modelName); + ui.apperanceDescription->setText(DependencyManager::get()->getMyAvatar()->getModelDescription()); } void PreferencesDialog::accept() { diff --git a/interface/src/ui/PreferencesDialog.h b/interface/src/ui/PreferencesDialog.h index 22efe3489d..8e699c80a2 100644 --- a/interface/src/ui/PreferencesDialog.h +++ b/interface/src/ui/PreferencesDialog.h @@ -25,6 +25,8 @@ class PreferencesDialog : public QDialog { public: PreferencesDialog(QWidget* parent = nullptr); + void avatarDescriptionChanged(); + protected: void resizeEvent(QResizeEvent* resizeEvent); From 2c5201f116880c072e4f1b60f4ce6d09bc2a558b Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 14 Apr 2015 16:54:14 -0700 Subject: [PATCH 10/15] Fix animation not automatically starting at start-up --- interface/src/avatar/MyAvatar.cpp | 6 +----- libraries/render-utils/src/AnimationHandle.cpp | 5 +++-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 6b70577754..201dc3d48d 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -640,7 +640,6 @@ void MyAvatar::saveData() { settings.setValue("firstFrame", pointer->getFirstFrame()); settings.setValue("lastFrame", pointer->getLastFrame()); settings.setValue("maskedJoints", pointer->getMaskedJoints()); - settings.setValue("running", pointer->getLoop() && pointer->isRunning()); } settings.endArray(); @@ -710,13 +709,10 @@ void MyAvatar::loadData() { handle->setPriority(loadSetting(settings, "priority", 1.0f)); handle->setLoop(settings.value("loop", true).toBool()); handle->setHold(settings.value("hold", false).toBool()); - handle->setStartAutomatically(settings.value("startAutomatically", true).toBool()); handle->setFirstFrame(settings.value("firstFrame", 0.0f).toFloat()); handle->setLastFrame(settings.value("lastFrame", INT_MAX).toFloat()); handle->setMaskedJoints(settings.value("maskedJoints").toStringList()); - if (settings.value("loop", true).toBool() && settings.value("running", false).toBool()) { - handle->setRunning(true); - } + handle->setStartAutomatically(settings.value("startAutomatically", true).toBool()); } settings.endArray(); diff --git a/libraries/render-utils/src/AnimationHandle.cpp b/libraries/render-utils/src/AnimationHandle.cpp index 1cb3d4654f..037c84ae02 100644 --- a/libraries/render-utils/src/AnimationHandle.cpp +++ b/libraries/render-utils/src/AnimationHandle.cpp @@ -47,10 +47,11 @@ void AnimationHandle::setPriority(float priority) { } void AnimationHandle::setStartAutomatically(bool startAutomatically) { - _animationLoop.setStartAutomatically(startAutomatically); - if (getStartAutomatically() && !isRunning()) { + if (startAutomatically && !isRunning()) { + // Start before setting _animationLoop value so that code in setRunning() is executed start(); } + _animationLoop.setStartAutomatically(startAutomatically); } void AnimationHandle::setMaskedJoints(const QStringList& maskedJoints) { From 85e5216fc1b713113e29ed74dfeb6a4620dbdab5 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 14 Apr 2015 16:54:29 -0700 Subject: [PATCH 11/15] Condense logic --- libraries/render-utils/src/AnimationHandle.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/libraries/render-utils/src/AnimationHandle.cpp b/libraries/render-utils/src/AnimationHandle.cpp index 037c84ae02..55995b87d8 100644 --- a/libraries/render-utils/src/AnimationHandle.cpp +++ b/libraries/render-utils/src/AnimationHandle.cpp @@ -60,13 +60,10 @@ void AnimationHandle::setMaskedJoints(const QStringList& maskedJoints) { } void AnimationHandle::setRunning(bool running) { - if (isRunning() == running) { + if (running && isRunning()) { // if we're already running, this is the same as a restart - if (running) { - // move back to the beginning - setFrameIndex(getFirstFrame()); - return; - } + setFrameIndex(getFirstFrame()); + return; } _animationLoop.setRunning(running); if (isRunning()) { From 9213561977ba1c9c2d4744c8b461b0b129a92906 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 15 Apr 2015 11:34:59 -0700 Subject: [PATCH 12/15] add vim plugin files to gitignore --- .gitignore | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 3b44b99e68..f2f259a0c2 100644 --- a/.gitignore +++ b/.gitignore @@ -46,4 +46,8 @@ libraries/audio-client/external/*/* gvr-interface/assets/oculussig* gvr-interface/libs/* -TAGS \ No newline at end of file +# ignore files for various dev environments +TAGS +.ycm_extra_conf.* +*.taghl +*.swp From faf7850d7c0af3e36754f22fa98822460bf8f402 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 15 Apr 2015 12:38:24 -0700 Subject: [PATCH 13/15] remove plugin specific ignored files --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index f2f259a0c2..44561daabc 100644 --- a/.gitignore +++ b/.gitignore @@ -48,6 +48,4 @@ gvr-interface/libs/* # ignore files for various dev environments TAGS -.ycm_extra_conf.* -*.taghl *.swp From 1a1fe11111658d59a886593ac37be57c271c3d4e Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 15 Apr 2015 17:00:20 -0700 Subject: [PATCH 14/15] switch HMD tools hot-key --- interface/src/Menu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index da0c669f35..d50cb48118 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -256,7 +256,7 @@ Menu::Menu() { addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H, false, qApp, SLOT(cameraMenuChanged())); - addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::HMDTools, Qt::META | Qt::Key_H, + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::HMDTools, Qt::CTRL | Qt::Key_H, false, dialogsManager.data(), SLOT(hmdTools(bool))); From ffb5ea50b1240882d6b1aa272c0b313117d6692d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 15 Apr 2015 17:00:50 -0700 Subject: [PATCH 15/15] expose avatar settings to JS --- interface/src/avatar/MyAvatar.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index f12941d748..886d8ad590 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -117,21 +117,21 @@ public: virtual void clearJointData(int index); virtual void clearJointsData(); - void useFullAvatarURL(const QUrl& fullAvatarURL, const QString& modelName = QString()); - void useHeadURL(const QUrl& headURL, const QString& modelName = QString()); - void useBodyURL(const QUrl& bodyURL, const QString& modelName = QString()); - void useHeadAndBodyURLs(const QUrl& headURL, const QUrl& bodyURL, const QString& headName = QString(), const QString& bodyName = QString()); + Q_INVOKABLE void useFullAvatarURL(const QUrl& fullAvatarURL, const QString& modelName = QString()); + Q_INVOKABLE void useHeadURL(const QUrl& headURL, const QString& modelName = QString()); + Q_INVOKABLE void useBodyURL(const QUrl& bodyURL, const QString& modelName = QString()); + Q_INVOKABLE void useHeadAndBodyURLs(const QUrl& headURL, const QUrl& bodyURL, const QString& headName = QString(), const QString& bodyName = QString()); - bool getUseFullAvatar() const { return _useFullAvatar; } - const QUrl& getFullAvatarURLFromPreferences() const { return _fullAvatarURLFromPreferences; } - const QUrl& getHeadURLFromPreferences() const { return _headURLFromPreferences; } - const QUrl& getBodyURLFromPreferences() const { return _skeletonURLFromPreferences; } + Q_INVOKABLE bool getUseFullAvatar() const { return _useFullAvatar; } + Q_INVOKABLE const QUrl& getFullAvatarURLFromPreferences() const { return _fullAvatarURLFromPreferences; } + Q_INVOKABLE const QUrl& getHeadURLFromPreferences() const { return _headURLFromPreferences; } + Q_INVOKABLE const QUrl& getBodyURLFromPreferences() const { return _skeletonURLFromPreferences; } - const QString& getHeadModelName() const { return _headModelName; } - const QString& getBodyModelName() const { return _bodyModelName; } - const QString& getFullAvartarModelName() const { return _fullAvatarModelName; } + Q_INVOKABLE const QString& getHeadModelName() const { return _headModelName; } + Q_INVOKABLE const QString& getBodyModelName() const { return _bodyModelName; } + Q_INVOKABLE const QString& getFullAvartarModelName() const { return _fullAvatarModelName; } - QString getModelDescription() const; + Q_INVOKABLE QString getModelDescription() const; virtual void setAttachmentData(const QVector& attachmentData);