From 5f73b76be755175c766e709e6965fe4e4b651b6e Mon Sep 17 00:00:00 2001 From: stojce Date: Sun, 2 Mar 2014 14:36:01 +0100 Subject: [PATCH 01/31] Share dialog --- interface/src/ui/Snapshot.cpp | 3 + interface/src/ui/SnapshotShareDialog.cpp | 13 ++++ interface/src/ui/SnapshotShareDialog.h | 14 ++++ interface/ui/shareSnapshot.ui | 99 ++++++++++++++++++++++++ snapshotShareDialog.cpp | 9 +++ snapshotShareDialog.h | 14 ++++ 6 files changed, 152 insertions(+) create mode 100644 interface/src/ui/SnapshotShareDialog.cpp create mode 100644 interface/src/ui/SnapshotShareDialog.h create mode 100644 interface/ui/shareSnapshot.ui create mode 100644 snapshotShareDialog.cpp create mode 100644 snapshotShareDialog.h diff --git a/interface/src/ui/Snapshot.cpp b/interface/src/ui/Snapshot.cpp index f0fef33cee..89b0d56a0b 100644 --- a/interface/src/ui/Snapshot.cpp +++ b/interface/src/ui/Snapshot.cpp @@ -9,6 +9,7 @@ #include "Snapshot.h" #include +#include #include #include @@ -41,6 +42,8 @@ void Snapshot::saveSnapshot(QGLWidget* widget, QString username, glm::vec3 locat QString fileName = FileUtils::standardPath(SNAPSHOTS_DIRECTORY); fileName.append(QString(FILENAME_PATH_FORMAT.arg(username, now.toString(DATETIME_FORMAT), formattedLocation))); shot.save(fileName, 0, 100); + + } diff --git a/interface/src/ui/SnapshotShareDialog.cpp b/interface/src/ui/SnapshotShareDialog.cpp new file mode 100644 index 0000000000..76556e0222 --- /dev/null +++ b/interface/src/ui/SnapshotShareDialog.cpp @@ -0,0 +1,13 @@ +// +// snapshotShareDialog.cpp +// hifi +// +// Created by Stojce Slavkovski on 2/16/14. +// +// + +#include "snapshotShareDialog.h" + +#include "ui_shareSnapshot.h" + + diff --git a/interface/src/ui/SnapshotShareDialog.h b/interface/src/ui/SnapshotShareDialog.h new file mode 100644 index 0000000000..77e92216fd --- /dev/null +++ b/interface/src/ui/SnapshotShareDialog.h @@ -0,0 +1,14 @@ +// +// snapshotShareDialog.h +// hifi +// +// Created by Stojce Slavkovski on 2/16/14. +// +// + +#ifndef __hifi__snapshotShareDialog__ +#define __hifi__snapshotShareDialog__ + +#include + +#endif /* defined(__hifi__snapshotShareDialog__) */ diff --git a/interface/ui/shareSnapshot.ui b/interface/ui/shareSnapshot.ui new file mode 100644 index 0000000000..94c1b4220e --- /dev/null +++ b/interface/ui/shareSnapshot.ui @@ -0,0 +1,99 @@ + + + Dialog + + + Qt::NonModal + + + + 0 + 0 + 808 + 577 + + + + PointingHandCursor + + + Share with community + + + background-color: rgb(255, 255, 255); + + + + + -1 + -1 + 681 + 511 + + + + + + + + 0 + 0 + + + + background-color: #000; + + + + + + + + 0 + 0 + + + + Notes about this image + + + + + + + + + + 0 + 0 + + + + + + + + background-color: #333333; + border-width: 0; + border-radius: 9px; + border-radius: 9px; + font-family: Arial; + font-size: 18px; + font-weight: 100; + color: #FFFFFF; + width: 120px; + height: 50px; + + + Share + + + + + + + + + + + diff --git a/snapshotShareDialog.cpp b/snapshotShareDialog.cpp new file mode 100644 index 0000000000..53a445292f --- /dev/null +++ b/snapshotShareDialog.cpp @@ -0,0 +1,9 @@ +// +// snapshotShareDialog.cpp +// hifi +// +// Created by Stojce Slavkovski on 2/16/14. +// +// + +#include "snapshotShareDialog.h" diff --git a/snapshotShareDialog.h b/snapshotShareDialog.h new file mode 100644 index 0000000000..77e92216fd --- /dev/null +++ b/snapshotShareDialog.h @@ -0,0 +1,14 @@ +// +// snapshotShareDialog.h +// hifi +// +// Created by Stojce Slavkovski on 2/16/14. +// +// + +#ifndef __hifi__snapshotShareDialog__ +#define __hifi__snapshotShareDialog__ + +#include + +#endif /* defined(__hifi__snapshotShareDialog__) */ From e2eb34b6c997bb428004a56f12930b80d7d6645a Mon Sep 17 00:00:00 2001 From: stojce Date: Sun, 23 Mar 2014 07:03:20 +0100 Subject: [PATCH 02/31] Layout setup image ratio fixed image centre position --- interface/interface_en.ts | 33 +++- interface/src/Application.cpp | 7 +- interface/src/Application.h | 2 + interface/src/ui/Snapshot.cpp | 5 +- interface/src/ui/Snapshot.h | 2 +- interface/src/ui/SnapshotShareDialog.cpp | 23 ++- interface/src/ui/SnapshotShareDialog.h | 15 +- interface/ui/shareSnapshot.ui | 187 +++++++++++++++++++++-- 8 files changed, 247 insertions(+), 27 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index 34e3614716..f8de770fca 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -14,12 +14,12 @@ - + Open Script - + JavaScript Files (*.js) @@ -113,18 +113,18 @@ Menu - + Open .ini config file - - + + Text files (*.ini) - + Save .ini config file @@ -158,4 +158,25 @@ + + SnapshotShareDialog + + + + Share with community + + + + + + Notes about this image + + + + + + Share + + + diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9563cbf3b4..e819422d46 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3671,5 +3671,10 @@ void Application::takeSnapshot() { player->setMedia(QUrl::fromLocalFile(inf.absoluteFilePath())); player->play(); - Snapshot::saveSnapshot(_glWidget, _myAvatar); + QString fileName = Snapshot::saveSnapshot(_glWidget, _myAvatar); + + if (!_snapshotShareDialog) { + _snapshotShareDialog = new SnapshotShareDialog(fileName, _glWidget); + } + _snapshotShareDialog->exec(); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 28060113a9..bc401c7de5 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -66,6 +66,7 @@ #include "ui/BandwidthDialog.h" #include "ui/OctreeStatsDialog.h" #include "ui/RearMirrorTools.h" +#include "ui/SnapshotShareDialog.h" #include "ui/LodToolsDialog.h" #include "ui/LogDialog.h" #include "ui/UpdateDialog.h" @@ -473,6 +474,7 @@ private: std::vector _voxelFades; ControllerScriptingInterface _controllerScriptingInterface; QPointer _logDialog; + QPointer _snapshotShareDialog; FileLogger* _logger; diff --git a/interface/src/ui/Snapshot.cpp b/interface/src/ui/Snapshot.cpp index 998aef82e4..90a226c594 100644 --- a/interface/src/ui/Snapshot.cpp +++ b/interface/src/ui/Snapshot.cpp @@ -11,7 +11,6 @@ #include #include -#include #include "Snapshot.h" @@ -61,7 +60,7 @@ SnapshotMetaData* Snapshot::parseSnapshotData(QString snapshotPath) { return data; } -void Snapshot::saveSnapshot(QGLWidget* widget, Avatar* avatar) { +QString Snapshot::saveSnapshot(QGLWidget* widget, Avatar* avatar) { QImage shot = widget->grabFrameBuffer(); glm::vec3 location = avatar->getPosition(); @@ -93,7 +92,7 @@ void Snapshot::saveSnapshot(QGLWidget* widget, Avatar* avatar) { fileName.append(QString(FILENAME_PATH_FORMAT.arg(username, now.toString(DATETIME_FORMAT), formattedLocation))); shot.save(fileName, 0, 100); - + return fileName; } diff --git a/interface/src/ui/Snapshot.h b/interface/src/ui/Snapshot.h index 1b78e8328e..83cfe5bc85 100644 --- a/interface/src/ui/Snapshot.h +++ b/interface/src/ui/Snapshot.h @@ -38,7 +38,7 @@ private: class Snapshot { public: - static void saveSnapshot(QGLWidget* widget, Avatar* avatar); + static QString saveSnapshot(QGLWidget* widget, Avatar* avatar); static SnapshotMetaData* parseSnapshotData(QString snapshotPath); }; diff --git a/interface/src/ui/SnapshotShareDialog.cpp b/interface/src/ui/SnapshotShareDialog.cpp index 76556e0222..2af564ff0b 100644 --- a/interface/src/ui/SnapshotShareDialog.cpp +++ b/interface/src/ui/SnapshotShareDialog.cpp @@ -1,13 +1,30 @@ // -// snapshotShareDialog.cpp +// SnapshotShareDialog.cpp // hifi // // Created by Stojce Slavkovski on 2/16/14. // // -#include "snapshotShareDialog.h" +#include "SnapshotShareDialog.h" -#include "ui_shareSnapshot.h" +SnapshotShareDialog::SnapshotShareDialog(QString fileName, QWidget* parent) : QDialog(parent), _fileName(fileName) { + setAttribute(Qt::WA_DeleteOnClose); + ui.setupUi(this); + + QPixmap snaphsotPixmap(fileName); + float snapshotRatio = static_cast(snaphsotPixmap.size().width()) / snaphsotPixmap.size().height(); + float labelRatio = static_cast(ui.snapshotWidget->size().width()) / ui.snapshotWidget->size().height(); + + // set the same aspect ratio of label as of snapshot + if (snapshotRatio > labelRatio) { + ui.snapshotWidget->setFixedHeight(ui.snapshotWidget->size().width() / snapshotRatio); + } else { + ui.snapshotWidget->setFixedWidth(ui.snapshotWidget->size().height() * snapshotRatio); + } + + ui.snapshotWidget->setPixmap(snaphsotPixmap); + ui.snapshotWidget->adjustSize(); +} diff --git a/interface/src/ui/SnapshotShareDialog.h b/interface/src/ui/SnapshotShareDialog.h index 77e92216fd..077acd182b 100644 --- a/interface/src/ui/SnapshotShareDialog.h +++ b/interface/src/ui/SnapshotShareDialog.h @@ -1,5 +1,5 @@ // -// snapshotShareDialog.h +// SnapshotShareDialog.h // hifi // // Created by Stojce Slavkovski on 2/16/14. @@ -9,6 +9,17 @@ #ifndef __hifi__snapshotShareDialog__ #define __hifi__snapshotShareDialog__ -#include +#include "ui_shareSnapshot.h" + +class SnapshotShareDialog : public QDialog { + Q_OBJECT + +public: + SnapshotShareDialog(QString fileName, QWidget* parent = 0); + +private: + QString _fileName; + Ui_SnapshotShareDialog ui; +}; #endif /* defined(__hifi__snapshotShareDialog__) */ diff --git a/interface/ui/shareSnapshot.ui b/interface/ui/shareSnapshot.ui index 94c1b4220e..039e611115 100644 --- a/interface/ui/shareSnapshot.ui +++ b/interface/ui/shareSnapshot.ui @@ -1,7 +1,7 @@ - Dialog - + SnapshotShareDialog + Qt::NonModal @@ -9,10 +9,28 @@ 0 0 - 808 - 577 + 789 + 645 + + + 0 + 0 + + + + + 789 + 645 + + + + + 789 + 645 + + PointingHandCursor @@ -22,33 +40,149 @@ background-color: rgb(255, 255, 255); + + true + -1 -1 - 681 - 511 + 792 + 645 - + - + 0 0 - - background-color: #000; + + + 790 + 510 + + + background-color: #333; + + + QFrame::StyledPanel + + + QFrame::Raised + + + 0 + + + + + -1 + 1 + 791 + 512 + + + + + 0 + + + + + + 0 + 0 + + + + + 790 + 510 + + + + background-color: #ccc; + + + 0 + + + true + + + Qt::AlignCenter + + + 0 + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + - + 0 0 @@ -56,10 +190,25 @@ Notes about this image + + 0 + + + 20 + + + 0 + + + 20 + + + 20 + @@ -70,6 +219,22 @@ + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + From 0a0515b652d359bc833faacecea08ce3b42aa330 Mon Sep 17 00:00:00 2001 From: stojce Date: Mon, 24 Mar 2014 20:35:28 +0100 Subject: [PATCH 03/31] layout / font changes --- interface/interface_en.ts | 10 +++++----- interface/ui/shareSnapshot.ui | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index f8de770fca..ce777b8551 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -162,19 +162,19 @@ SnapshotShareDialog - + Share with community - - + + Notes about this image - - + + Share diff --git a/interface/ui/shareSnapshot.ui b/interface/ui/shareSnapshot.ui index 039e611115..3d729cf9df 100644 --- a/interface/ui/shareSnapshot.ui +++ b/interface/ui/shareSnapshot.ui @@ -53,6 +53,9 @@ + + 0 + @@ -68,13 +71,13 @@ - background-color: #333; + background-color: #000 - QFrame::StyledPanel + QFrame::NoFrame - QFrame::Raised + QFrame::Plain 0 @@ -84,7 +87,7 @@ -1 1 - 791 + 792 512 @@ -187,9 +190,28 @@ 0 + + + 0 + 30 + + + + + Helvetica + 75 + true + + + + color: #666; + Notes about this image + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + 0 @@ -217,6 +239,11 @@ 0 + + + Helvetica + + From 63a29cad0a591c1c6598dd6520f4b2788ffcfb0c Mon Sep 17 00:00:00 2001 From: stojce Date: Mon, 24 Mar 2014 20:39:13 +0100 Subject: [PATCH 04/31] layout fixes --- interface/interface_en.ts | 10 +++--- interface/ui/shareSnapshot.ui | 68 ++++++++--------------------------- 2 files changed, 19 insertions(+), 59 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index ce777b8551..2d2f4c1c07 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -162,19 +162,19 @@ SnapshotShareDialog - + Share with community - - + + Notes about this image - - + + Share diff --git a/interface/ui/shareSnapshot.ui b/interface/ui/shareSnapshot.ui index 3d729cf9df..85334cbc65 100644 --- a/interface/ui/shareSnapshot.ui +++ b/interface/ui/shareSnapshot.ui @@ -59,7 +59,7 @@ - + 0 0 @@ -70,6 +70,12 @@ 510 + + + 790 + 510 + + background-color: #000 @@ -95,7 +101,7 @@ 0 - + @@ -109,6 +115,12 @@ 510 + + + 790 + 510 + + background-color: #ccc; @@ -126,58 +138,6 @@ - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - From e5a66ddb90909210635a1a4596e10fafdcf1abd2 Mon Sep 17 00:00:00 2001 From: stojce Date: Tue, 25 Mar 2014 21:56:20 +0100 Subject: [PATCH 05/31] New layout behaviour --- interface/interface_en.ts | 21 ++ interface/src/ui/SnapshotShareDialog.cpp | 16 + interface/ui/shareSnapshot.ui | 374 +++++++++++------------ 3 files changed, 214 insertions(+), 197 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index beada5df43..0a5b7e4057 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -158,4 +158,25 @@ + + SnapshotShareDialog + + + + Share with community + + + + + + Notes about this image + + + + + + Share + + + diff --git a/interface/src/ui/SnapshotShareDialog.cpp b/interface/src/ui/SnapshotShareDialog.cpp index 2af564ff0b..d57951a484 100644 --- a/interface/src/ui/SnapshotShareDialog.cpp +++ b/interface/src/ui/SnapshotShareDialog.cpp @@ -6,6 +6,9 @@ // // +const int NARROW_SNAPSHOT_DIALOG_SIZE = 500; +const int WIDE_SNAPSHOT_DIALOG_WIDTH = 650; + #include "SnapshotShareDialog.h" SnapshotShareDialog::SnapshotShareDialog(QString fileName, QWidget* parent) : QDialog(parent), _fileName(fileName) { @@ -16,11 +19,24 @@ SnapshotShareDialog::SnapshotShareDialog(QString fileName, QWidget* parent) : QD QPixmap snaphsotPixmap(fileName); float snapshotRatio = static_cast(snaphsotPixmap.size().width()) / snaphsotPixmap.size().height(); + + // narrow snapshot + if (snapshotRatio > 1) { + setFixedWidth(WIDE_SNAPSHOT_DIALOG_WIDTH); + ui.snapshotWidget->setFixedWidth(WIDE_SNAPSHOT_DIALOG_WIDTH); + } + float labelRatio = static_cast(ui.snapshotWidget->size().width()) / ui.snapshotWidget->size().height(); // set the same aspect ratio of label as of snapshot if (snapshotRatio > labelRatio) { + int oldHeight = ui.snapshotWidget->size().height(); ui.snapshotWidget->setFixedHeight(ui.snapshotWidget->size().width() / snapshotRatio); + + // if height is less then original, resize the window as well + if (ui.snapshotWidget->size().height() < NARROW_SNAPSHOT_DIALOG_SIZE) { + setFixedHeight(size().height() - (oldHeight - ui.snapshotWidget->size().height())); + } } else { ui.snapshotWidget->setFixedWidth(ui.snapshotWidget->size().height() * snapshotRatio); } diff --git a/interface/ui/shareSnapshot.ui b/interface/ui/shareSnapshot.ui index 85334cbc65..cb8754a46d 100644 --- a/interface/ui/shareSnapshot.ui +++ b/interface/ui/shareSnapshot.ui @@ -9,26 +9,26 @@ 0 0 - 789 - 645 + 502 + 625 - + 0 0 - 789 - 645 + 500 + 625 - 789 - 645 + 502 + 625 @@ -43,189 +43,168 @@ true - - - - -1 - -1 - 792 - 645 - + + + 0 - - - 0 - - - - - - 0 - 0 - - - - - 790 - 510 - - - - - 790 - 510 - - - - background-color: #000 - - - QFrame::NoFrame - - - QFrame::Plain - - - 0 - - - - - -1 - 1 - 792 - 512 - + + 0 + + + 0 + + + 0 + + + 0 + + + + + QLayout::SetMinAndMaxSize + + + + + + 0 + 0 + + + + + 500 + 500 + + + + + 30 + 2000 + + + + background-color: #ccc; + + + 0 + + + true + + + Qt::AlignCenter + + + 0 - - - 0 - - - - - - 0 - 0 - - - - - 790 - 510 - - - - - 790 - 510 - - - - background-color: #ccc; - - - 0 - - - true - - - Qt::AlignCenter - - - 0 - - - - - - - - - - - 0 - 0 - - - - - 0 - 30 - - - - - Helvetica - 75 - true - - - - color: #666; - - - Notes about this image - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - 0 - - - 20 - - - - - - - 0 - - - 20 - - - 20 - - - - - - 0 - 0 - - - - - Helvetica - - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - - - - - background-color: #333333; + + + + + + 0 + 0 + + + + + 0 + 30 + + + + + Helvetica + 75 + true + + + + color: #666; +padding-left:20px; + + + 0 + + + Notes about this image + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + 0 + + + 0 + + + + + + + 0 + + + QLayout::SetFixedSize + + + 20 + + + 20 + + + + + + 0 + 0 + + + + + 16777215 + 60 + + + + + Helvetica + 14 + + + + QFrame::Box + + + QFrame::Plain + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + background-color: #333333; border-width: 0; border-radius: 9px; border-radius: 9px; @@ -235,16 +214,17 @@ color: #FFFFFF; width: 120px; height: 50px; - - - Share - - - - - - - + + + Share + + + + + + + + From b223d10e700d40a53455196fc1b6cca4d87ca23d Mon Sep 17 00:00:00 2001 From: stojce Date: Wed, 26 Mar 2014 21:24:18 +0100 Subject: [PATCH 06/31] Layout fixes --- interface/interface_en.ts | 39 ++++++++----- interface/ui/shareSnapshot.ui | 106 ++++++++++++++++++++++++++++++---- 2 files changed, 120 insertions(+), 25 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index 39e9142400..6baf4e7054 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -4,22 +4,22 @@ Application - + Export Voxels - + Sparse Voxel Octree Files (*.svo) - + Open Script - + JavaScript Files (*.js) @@ -113,18 +113,18 @@ Menu - + Open .ini config file - - + + Text files (*.ini) - + Save .ini config file @@ -162,19 +162,30 @@ SnapshotShareDialog - - Share with community + + Share with Alphas + Share with community - - + + Notes about this image - - + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Helvetica'; font-size:14pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + + + Share diff --git a/interface/ui/shareSnapshot.ui b/interface/ui/shareSnapshot.ui index cb8754a46d..988acfcd56 100644 --- a/interface/ui/shareSnapshot.ui +++ b/interface/ui/shareSnapshot.ui @@ -10,7 +10,7 @@ 0 0 502 - 625 + 616 @@ -22,20 +22,20 @@ 500 - 625 + 616 502 - 625 + 616 PointingHandCursor - Share with community + Share with Alphas background-color: rgb(255, 255, 255); @@ -61,6 +61,9 @@ + + 0 + QLayout::SetMinAndMaxSize @@ -101,10 +104,26 @@ + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 9 + + + + - + 0 0 @@ -112,12 +131,13 @@ 0 - 30 + 19 Helvetica + 14 75 true @@ -126,6 +146,9 @@ color: #666; padding-left:20px; + + QFrame::NoFrame + 0 @@ -152,11 +175,27 @@ padding-left:20px; QLayout::SetFixedSize - 20 + 0 - 20 + 0 + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 19 + 20 + + + + @@ -177,12 +216,25 @@ padding-left:20px; 14 + + border-color: #c00 + - QFrame::Box + QFrame::StyledPanel QFrame::Plain + + 1 + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Helvetica'; font-size:14pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + @@ -195,8 +247,8 @@ padding-left:20px; - 20 - 20 + 25 + 19 @@ -220,8 +272,40 @@ padding-left:20px; + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 25 + 20 + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 11 + + + + From 9f05d71796d47f0899ef2f81cbfbdea7fecc7ecd Mon Sep 17 00:00:00 2001 From: stojce Date: Wed, 26 Mar 2014 21:30:02 +0100 Subject: [PATCH 07/31] fixed QTextEdit border color --- interface/ui/shareSnapshot.ui | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/ui/shareSnapshot.ui b/interface/ui/shareSnapshot.ui index 988acfcd56..19857bfb28 100644 --- a/interface/ui/shareSnapshot.ui +++ b/interface/ui/shareSnapshot.ui @@ -217,16 +217,16 @@ padding-left:20px; - border-color: #c00 + border: 1px solid #c5c5c5; - QFrame::StyledPanel + QFrame::NoFrame QFrame::Plain - 1 + 0 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> From d90e15ad5801928bd788460f0ea5e4194ddb1407 Mon Sep 17 00:00:00 2001 From: stojce Date: Thu, 27 Mar 2014 17:56:42 +0100 Subject: [PATCH 08/31] Don't show share dialog for anonymous users --- interface/src/Application.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 42c8efb952..1e0976c021 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3715,6 +3715,11 @@ void Application::takeSnapshot() { QString fileName = Snapshot::saveSnapshot(_glWidget, _myAvatar); + AccountManager& accountManager = AccountManager::getInstance(); + if (!accountManager.isLoggedIn()) { + return; + } + if (!_snapshotShareDialog) { _snapshotShareDialog = new SnapshotShareDialog(fileName, _glWidget); } From d3fecd7a31b503c9bf820b1f3c03cb2ff5eb932b Mon Sep 17 00:00:00 2001 From: Stojce Slavkovski Date: Fri, 2 May 2014 22:16:19 +0200 Subject: [PATCH 09/31] store discourse api key --- interface/src/ui/SnapshotShareDialog.cpp | 6 ++++++ interface/src/ui/SnapshotShareDialog.h | 3 +++ interface/ui/shareSnapshot.ui | 19 ++++++++++++++++++- .../networking/src/DataServerAccountInfo.cpp | 10 +++++++++- .../networking/src/DataServerAccountInfo.h | 6 +++++- 5 files changed, 41 insertions(+), 3 deletions(-) diff --git a/interface/src/ui/SnapshotShareDialog.cpp b/interface/src/ui/SnapshotShareDialog.cpp index d57951a484..081d3518b2 100644 --- a/interface/src/ui/SnapshotShareDialog.cpp +++ b/interface/src/ui/SnapshotShareDialog.cpp @@ -44,3 +44,9 @@ SnapshotShareDialog::SnapshotShareDialog(QString fileName, QWidget* parent) : QD ui.snapshotWidget->setPixmap(snaphsotPixmap); ui.snapshotWidget->adjustSize(); } + +void SnapshotShareDialog::accept() { + // post to Discourse forum + + close(); +} diff --git a/interface/src/ui/SnapshotShareDialog.h b/interface/src/ui/SnapshotShareDialog.h index 077acd182b..2823c8b78d 100644 --- a/interface/src/ui/SnapshotShareDialog.h +++ b/interface/src/ui/SnapshotShareDialog.h @@ -20,6 +20,9 @@ public: private: QString _fileName; Ui_SnapshotShareDialog ui; + +private slots: + void accept(); }; #endif /* defined(__hifi__snapshotShareDialog__) */ diff --git a/interface/ui/shareSnapshot.ui b/interface/ui/shareSnapshot.ui index 19857bfb28..0f59349442 100644 --- a/interface/ui/shareSnapshot.ui +++ b/interface/ui/shareSnapshot.ui @@ -311,5 +311,22 @@ p, li { white-space: pre-wrap; } - + + + shareButton + clicked() + SnapshotShareDialog + accept() + + + 420 + 565 + + + 250 + 307 + + + + diff --git a/libraries/networking/src/DataServerAccountInfo.cpp b/libraries/networking/src/DataServerAccountInfo.cpp index 87d3b694a7..d7cbd91e78 100644 --- a/libraries/networking/src/DataServerAccountInfo.cpp +++ b/libraries/networking/src/DataServerAccountInfo.cpp @@ -16,7 +16,8 @@ DataServerAccountInfo::DataServerAccountInfo() : _accessToken(), _username(), - _xmppPassword() + _xmppPassword(), + _discourseApiKey() { } @@ -29,6 +30,7 @@ DataServerAccountInfo::DataServerAccountInfo(const QJsonObject& jsonObject) : QJsonObject userJSONObject = jsonObject["user"].toObject(); setUsername(userJSONObject["username"].toString()); setXMPPPassword(userJSONObject["xmpp_password"].toString()); + setDiscourseApiKey(userJSONObject["discourse_api_key"].toString()); } DataServerAccountInfo::DataServerAccountInfo(const DataServerAccountInfo& otherInfo) { @@ -65,6 +67,12 @@ void DataServerAccountInfo::setXMPPPassword(const QString& xmppPassword) { } } +void DataServerAccountInfo::setDiscourseApiKey(const QString& discourseApiKey) { + if (_discourseApiKey != discourseApiKey) { + _discourseApiKey = discourseApiKey; + } +} + QDataStream& operator<<(QDataStream &out, const DataServerAccountInfo& info) { out << info._accessToken << info._username << info._xmppPassword; return out; diff --git a/libraries/networking/src/DataServerAccountInfo.h b/libraries/networking/src/DataServerAccountInfo.h index 21380c0855..a7d1fa9cb0 100644 --- a/libraries/networking/src/DataServerAccountInfo.h +++ b/libraries/networking/src/DataServerAccountInfo.h @@ -31,7 +31,10 @@ public: const QString& getXMPPPassword() const { return _xmppPassword; } void setXMPPPassword(const QString& xmppPassword); - + + const QString& getDiscourseApiKey() const { return _discourseApiKey; } + void setDiscourseApiKey(const QString& discourseApiKey); + friend QDataStream& operator<<(QDataStream &out, const DataServerAccountInfo& info); friend QDataStream& operator>>(QDataStream &in, DataServerAccountInfo& info); private: @@ -40,6 +43,7 @@ private: OAuthAccessToken _accessToken; QString _username; QString _xmppPassword; + QString _discourseApiKey; }; #endif // hifi_DataServerAccountInfo_h From c400630bc440e13171ea06397b0bc9660bf9761a Mon Sep 17 00:00:00 2001 From: Stojce Slavkovski Date: Sat, 3 May 2014 21:12:20 +0200 Subject: [PATCH 10/31] make post --- interface/src/ui/SnapshotShareDialog.cpp | 60 +++++++++++++++++-- interface/src/ui/SnapshotShareDialog.h | 6 ++ .../networking/src/DataServerAccountInfo.cpp | 2 + 3 files changed, 64 insertions(+), 4 deletions(-) diff --git a/interface/src/ui/SnapshotShareDialog.cpp b/interface/src/ui/SnapshotShareDialog.cpp index 081d3518b2..921400ba1e 100644 --- a/interface/src/ui/SnapshotShareDialog.cpp +++ b/interface/src/ui/SnapshotShareDialog.cpp @@ -6,10 +6,17 @@ // // +#include "SnapshotShareDialog.h" +#include "AccountManager.h" + +#include +#include +#include +#include + const int NARROW_SNAPSHOT_DIALOG_SIZE = 500; const int WIDE_SNAPSHOT_DIALOG_WIDTH = 650; - -#include "SnapshotShareDialog.h" +const QString FORUM_POST_URL = "http://localhost:4000"; SnapshotShareDialog::SnapshotShareDialog(QString fileName, QWidget* parent) : QDialog(parent), _fileName(fileName) { @@ -46,7 +53,52 @@ SnapshotShareDialog::SnapshotShareDialog(QString fileName, QWidget* parent) : QD } void SnapshotShareDialog::accept() { - // post to Discourse forum - + close(); + + // post to Discourse forum +// AccountManager& accountManager = AccountManager::getInstance(); + QNetworkAccessManager* _networkAccessManager = NULL; + + if (!_networkAccessManager) { + _networkAccessManager = new QNetworkAccessManager(this); + } + + QNetworkRequest request; + + QUrl grantURL(FORUM_POST_URL); + grantURL.setPath("/posts"); + + + QByteArray postData; + // postData.append("api_key=" + accountManager.getAccountInfo().getDiscourseApiKey() + "&"); + postData.append("api_key=9168f53930b2fc69ec278414d6ff04fed723ef717867a25954143150d3e2dfe8&"); + postData.append("topic_id=64&"); + postData.append("raw=" + QUrl::toPercentEncoding(ui.textEdit->toPlainText())); + + request.setUrl(grantURL); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); + + QNetworkReply* requestReply = _networkAccessManager->post(request, postData); + connect(_networkAccessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(serviceRequestFinished(QNetworkReply*))); + + connect(requestReply, &QNetworkReply::finished, this, &SnapshotShareDialog::requestFinished); + connect(requestReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestError(QNetworkReply::NetworkError))); } + +void SnapshotShareDialog::serviceRequestFinished(QNetworkReply* reply) { + qDebug() << reply->errorString(); +} + +void SnapshotShareDialog::requestFinished() { + + QNetworkReply* requestReply = reinterpret_cast(sender()); + + qDebug() << requestReply->errorString(); + delete requestReply; +} + +void SnapshotShareDialog::requestError(QNetworkReply::NetworkError error) { + // TODO: error handling + qDebug() << "AccountManager requestError - " << error; +} \ No newline at end of file diff --git a/interface/src/ui/SnapshotShareDialog.h b/interface/src/ui/SnapshotShareDialog.h index 2823c8b78d..18a66616db 100644 --- a/interface/src/ui/SnapshotShareDialog.h +++ b/interface/src/ui/SnapshotShareDialog.h @@ -10,6 +10,7 @@ #define __hifi__snapshotShareDialog__ #include "ui_shareSnapshot.h" +#include class SnapshotShareDialog : public QDialog { Q_OBJECT @@ -21,6 +22,11 @@ private: QString _fileName; Ui_SnapshotShareDialog ui; +public slots: + void requestFinished(); + void requestError(QNetworkReply::NetworkError error); + void serviceRequestFinished(QNetworkReply* reply); + private slots: void accept(); }; diff --git a/libraries/networking/src/DataServerAccountInfo.cpp b/libraries/networking/src/DataServerAccountInfo.cpp index d7cbd91e78..a9522148a8 100644 --- a/libraries/networking/src/DataServerAccountInfo.cpp +++ b/libraries/networking/src/DataServerAccountInfo.cpp @@ -37,6 +37,7 @@ DataServerAccountInfo::DataServerAccountInfo(const DataServerAccountInfo& otherI _accessToken = otherInfo._accessToken; _username = otherInfo._username; _xmppPassword = otherInfo._xmppPassword; + _discourseApiKey = otherInfo._discourseApiKey; } DataServerAccountInfo& DataServerAccountInfo::operator=(const DataServerAccountInfo& otherInfo) { @@ -51,6 +52,7 @@ void DataServerAccountInfo::swap(DataServerAccountInfo& otherInfo) { swap(_accessToken, otherInfo._accessToken); swap(_username, otherInfo._username); swap(_xmppPassword, otherInfo._xmppPassword); + swap(_discourseApiKey, otherInfo._discourseApiKey); } void DataServerAccountInfo::setUsername(const QString& username) { From d93480458f0941281db882ee63db2f0b7fa461bd Mon Sep 17 00:00:00 2001 From: Stojce Slavkovski Date: Sun, 4 May 2014 18:30:58 +0200 Subject: [PATCH 11/31] Posting Image to forum --- interface/src/Application.cpp | 2 +- interface/src/ui/SnapshotShareDialog.cpp | 125 ++++++++++++++++------- interface/src/ui/SnapshotShareDialog.h | 23 +++-- 3 files changed, 102 insertions(+), 48 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0d99f60f58..a6fd36a0d8 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3663,7 +3663,7 @@ void Application::takeSnapshot() { if (!_snapshotShareDialog) { _snapshotShareDialog = new SnapshotShareDialog(fileName, _glWidget); } - _snapshotShareDialog->exec(); + _snapshotShareDialog->show(); } void Application::urlGoTo(int argc, const char * constArgv[]) { diff --git a/interface/src/ui/SnapshotShareDialog.cpp b/interface/src/ui/SnapshotShareDialog.cpp index 921400ba1e..a5d598dc8b 100644 --- a/interface/src/ui/SnapshotShareDialog.cpp +++ b/interface/src/ui/SnapshotShareDialog.cpp @@ -1,28 +1,41 @@ // // SnapshotShareDialog.cpp -// hifi +// interface/src/ui // // Created by Stojce Slavkovski on 2/16/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 "SnapshotShareDialog.h" #include "AccountManager.h" -#include +#include #include -#include #include const int NARROW_SNAPSHOT_DIALOG_SIZE = 500; const int WIDE_SNAPSHOT_DIALOG_WIDTH = 650; -const QString FORUM_POST_URL = "http://localhost:4000"; -SnapshotShareDialog::SnapshotShareDialog(QString fileName, QWidget* parent) : QDialog(parent), _fileName(fileName) { +const QString FORUM_URL = "http://localhost:4000"; +const QString FORUM_UPLOADS_URL = FORUM_URL + "/uploads"; +const QString FORUM_POST_URL = FORUM_URL + "/posts"; +const QString FORUM_REPLY_TO_TOPIC = "64"; +const QString FORUM_POST_TEMPLATE = "

%2

"; + +Q_DECLARE_METATYPE(QNetworkAccessManager::Operation) + +SnapshotShareDialog::SnapshotShareDialog(QString fileName, QWidget* parent) : + QDialog(parent), + _fileName(fileName), + _networkAccessManager(NULL) +{ setAttribute(Qt::WA_DeleteOnClose); - ui.setupUi(this); + _ui.setupUi(this); QPixmap snaphsotPixmap(fileName); float snapshotRatio = static_cast(snaphsotPixmap.size().width()) / snaphsotPixmap.size().height(); @@ -30,70 +43,104 @@ SnapshotShareDialog::SnapshotShareDialog(QString fileName, QWidget* parent) : QD // narrow snapshot if (snapshotRatio > 1) { setFixedWidth(WIDE_SNAPSHOT_DIALOG_WIDTH); - ui.snapshotWidget->setFixedWidth(WIDE_SNAPSHOT_DIALOG_WIDTH); + _ui.snapshotWidget->setFixedWidth(WIDE_SNAPSHOT_DIALOG_WIDTH); } - float labelRatio = static_cast(ui.snapshotWidget->size().width()) / ui.snapshotWidget->size().height(); + float labelRatio = static_cast(_ui.snapshotWidget->size().width()) / _ui.snapshotWidget->size().height(); // set the same aspect ratio of label as of snapshot if (snapshotRatio > labelRatio) { - int oldHeight = ui.snapshotWidget->size().height(); - ui.snapshotWidget->setFixedHeight(ui.snapshotWidget->size().width() / snapshotRatio); + int oldHeight = _ui.snapshotWidget->size().height(); + _ui.snapshotWidget->setFixedHeight((int) (_ui.snapshotWidget->size().width() / snapshotRatio)); // if height is less then original, resize the window as well - if (ui.snapshotWidget->size().height() < NARROW_SNAPSHOT_DIALOG_SIZE) { - setFixedHeight(size().height() - (oldHeight - ui.snapshotWidget->size().height())); + if (_ui.snapshotWidget->size().height() < NARROW_SNAPSHOT_DIALOG_SIZE) { + setFixedHeight(size().height() - (oldHeight - _ui.snapshotWidget->size().height())); } } else { - ui.snapshotWidget->setFixedWidth(ui.snapshotWidget->size().height() * snapshotRatio); + _ui.snapshotWidget->setFixedWidth((int) (_ui.snapshotWidget->size().height() * snapshotRatio)); } - ui.snapshotWidget->setPixmap(snaphsotPixmap); - ui.snapshotWidget->adjustSize(); + _ui.snapshotWidget->setPixmap(snaphsotPixmap); + _ui.snapshotWidget->adjustSize(); } void SnapshotShareDialog::accept() { - + uploadSnapshot(); + sendForumPost("/uploads/default/25/b607c8faea6de9c3.jpg"); close(); - - // post to Discourse forum -// AccountManager& accountManager = AccountManager::getInstance(); - QNetworkAccessManager* _networkAccessManager = NULL; +} + +void SnapshotShareDialog::uploadSnapshot() { if (!_networkAccessManager) { _networkAccessManager = new QNetworkAccessManager(this); } - QNetworkRequest request; + QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); - QUrl grantURL(FORUM_POST_URL); - grantURL.setPath("/posts"); + QHttpPart apiKeyPart; + apiKeyPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"api_key\"")); + apiKeyPart.setBody("9168f53930b2fc69ec278414d6ff04fed723ef717867a25954143150d3e2dfe8"); +// apiKeyPart.setBody(AccountManager::getInstance().getAccountInfo().getDiscourseApiKey().toLatin1()); + QFile *file = new QFile(_fileName); + file->open(QIODevice::ReadOnly); - QByteArray postData; - // postData.append("api_key=" + accountManager.getAccountInfo().getDiscourseApiKey() + "&"); - postData.append("api_key=9168f53930b2fc69ec278414d6ff04fed723ef717867a25954143150d3e2dfe8&"); - postData.append("topic_id=64&"); - postData.append("raw=" + QUrl::toPercentEncoding(ui.textEdit->toPlainText())); + QHttpPart imagePart; + imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg")); + imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, + QVariant("form-data; name=\"file\"; filename=\"" + file->fileName() +"\"")); + imagePart.setBodyDevice(file); + file->setParent(multiPart); // we cannot delete the file now, so delete it with the multiPart - request.setUrl(grantURL); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); + multiPart->append(apiKeyPart); + multiPart->append(imagePart); - QNetworkReply* requestReply = _networkAccessManager->post(request, postData); - connect(_networkAccessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(serviceRequestFinished(QNetworkReply*))); + QUrl url(FORUM_UPLOADS_URL); + QNetworkRequest request(url); - connect(requestReply, &QNetworkReply::finished, this, &SnapshotShareDialog::requestFinished); - connect(requestReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestError(QNetworkReply::NetworkError))); + QNetworkReply *reply = _networkAccessManager->post(request, multiPart); + bool check; + Q_UNUSED(check); + + check = connect(reply, SIGNAL(finished()), this, SLOT(requestFinished())); + Q_ASSERT(check); } -void SnapshotShareDialog::serviceRequestFinished(QNetworkReply* reply) { - qDebug() << reply->errorString(); +void SnapshotShareDialog::sendForumPost(QString snapshotPath) { + + if (!_networkAccessManager) { + _networkAccessManager = new QNetworkAccessManager(this); + } + + // post to Discourse forum + QNetworkRequest request; + QUrl forumUrl(FORUM_POST_URL); + + QUrlQuery query; +// query.addQueryItem("api_key", accountManager.getAccountInfo().getDiscourseApiKey(); + query.addQueryItem("api_key", "9168f53930b2fc69ec278414d6ff04fed723ef717867a25954143150d3e2dfe8"); + query.addQueryItem("topic_id", FORUM_REPLY_TO_TOPIC); + query.addQueryItem("raw", FORUM_POST_TEMPLATE.arg(snapshotPath, _ui.textEdit->toPlainText())); + forumUrl.setQuery(query); + + QByteArray postData = forumUrl.toEncoded(QUrl::RemoveFragment); + request.setUrl(forumUrl); + QNetworkReply* requestReply = _networkAccessManager->post(request, postData); + + bool check; + Q_UNUSED(check); + + check = connect(requestReply, &QNetworkReply::finished, this, &SnapshotShareDialog::requestFinished); + Q_ASSERT(check); + + check = connect(requestReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestError(QNetworkReply::NetworkError))); + Q_ASSERT(check); } void SnapshotShareDialog::requestFinished() { - QNetworkReply* requestReply = reinterpret_cast(sender()); - qDebug() << requestReply->errorString(); delete requestReply; } @@ -101,4 +148,4 @@ void SnapshotShareDialog::requestFinished() { void SnapshotShareDialog::requestError(QNetworkReply::NetworkError error) { // TODO: error handling qDebug() << "AccountManager requestError - " << error; -} \ No newline at end of file +} diff --git a/interface/src/ui/SnapshotShareDialog.h b/interface/src/ui/SnapshotShareDialog.h index 18a66616db..ea973022f3 100644 --- a/interface/src/ui/SnapshotShareDialog.h +++ b/interface/src/ui/SnapshotShareDialog.h @@ -1,16 +1,22 @@ // // SnapshotShareDialog.h -// hifi +// interface/src/ui // // Created by Stojce Slavkovski on 2/16/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__snapshotShareDialog__ -#define __hifi__snapshotShareDialog__ +#ifndef hifi_snapshotShareDialog +#define hifi_snapshotShareDialog #include "ui_shareSnapshot.h" + +#include #include +#include class SnapshotShareDialog : public QDialog { Q_OBJECT @@ -20,15 +26,16 @@ public: private: QString _fileName; - Ui_SnapshotShareDialog ui; + QNetworkAccessManager* _networkAccessManager; + Ui_SnapshotShareDialog _ui; + + void uploadSnapshot(); + void sendForumPost(QString snapshotPath); public slots: void requestFinished(); void requestError(QNetworkReply::NetworkError error); - void serviceRequestFinished(QNetworkReply* reply); - -private slots: void accept(); }; -#endif /* defined(__hifi__snapshotShareDialog__) */ +#endif // hifi_snapshotShareDialog From f668cc85812c33fb179be2dae88902c7eb2cfc8b Mon Sep 17 00:00:00 2001 From: Stojce Slavkovski Date: Mon, 5 May 2014 00:55:24 +0200 Subject: [PATCH 12/31] Discourse upload image - success message set - fixed signal/slots in QDialog w/QEventLoop - layout fixes --- interface/src/ui/SnapshotShareDialog.cpp | 100 +++++++++++++++++------ interface/src/ui/SnapshotShareDialog.h | 6 +- interface/ui/shareSnapshot.ui | 53 +++++++++++- 3 files changed, 125 insertions(+), 34 deletions(-) diff --git a/interface/src/ui/SnapshotShareDialog.cpp b/interface/src/ui/SnapshotShareDialog.cpp index a5d598dc8b..fc738c9761 100644 --- a/interface/src/ui/SnapshotShareDialog.cpp +++ b/interface/src/ui/SnapshotShareDialog.cpp @@ -13,17 +13,24 @@ #include "AccountManager.h" #include +#include +#include #include +#include #include + const int NARROW_SNAPSHOT_DIALOG_SIZE = 500; const int WIDE_SNAPSHOT_DIALOG_WIDTH = 650; +const int SUCCESS_LABEL_HEIGHT = 140; -const QString FORUM_URL = "http://localhost:4000"; +const QString FORUM_URL = "https://alphas.highfidelity.io"; const QString FORUM_UPLOADS_URL = FORUM_URL + "/uploads"; const QString FORUM_POST_URL = FORUM_URL + "/posts"; -const QString FORUM_REPLY_TO_TOPIC = "64"; +const QString FORUM_REPLY_TO_TOPIC = "244"; const QString FORUM_POST_TEMPLATE = "

%2

"; +const QString SHARE_DEFAULT_ERROR = "The server isn't responding. Please try again in a few minutes."; +const QString SUCCESS_LABEL_TEMPLATE = "Success!!! Go check out your image ...
%1"; Q_DECLARE_METATYPE(QNetworkAccessManager::Operation) @@ -67,12 +74,15 @@ SnapshotShareDialog::SnapshotShareDialog(QString fileName, QWidget* parent) : void SnapshotShareDialog::accept() { uploadSnapshot(); - sendForumPost("/uploads/default/25/b607c8faea6de9c3.jpg"); - close(); } void SnapshotShareDialog::uploadSnapshot() { + if (AccountManager::getInstance().getAccountInfo().getDiscourseApiKey().isEmpty()) { + QMessageBox::warning(this, "", "Your Discourse API key is missing, you cannot share snapshots."); + return; + } + if (!_networkAccessManager) { _networkAccessManager = new QNetworkAccessManager(this); } @@ -81,8 +91,7 @@ void SnapshotShareDialog::uploadSnapshot() { QHttpPart apiKeyPart; apiKeyPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"api_key\"")); - apiKeyPart.setBody("9168f53930b2fc69ec278414d6ff04fed723ef717867a25954143150d3e2dfe8"); -// apiKeyPart.setBody(AccountManager::getInstance().getAccountInfo().getDiscourseApiKey().toLatin1()); + apiKeyPart.setBody(AccountManager::getInstance().getAccountInfo().getDiscourseApiKey().toLatin1()); QFile *file = new QFile(_fileName); file->open(QIODevice::ReadOnly); @@ -101,11 +110,13 @@ void SnapshotShareDialog::uploadSnapshot() { QNetworkRequest request(url); QNetworkReply *reply = _networkAccessManager->post(request, multiPart); - bool check; - Q_UNUSED(check); - check = connect(reply, SIGNAL(finished()), this, SLOT(requestFinished())); - Q_ASSERT(check); + + connect(reply, &QNetworkReply::finished, this, &SnapshotShareDialog::uploadRequestFinished); + + QEventLoop loop; + connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); + loop.exec(); } void SnapshotShareDialog::sendForumPost(QString snapshotPath) { @@ -119,33 +130,68 @@ void SnapshotShareDialog::sendForumPost(QString snapshotPath) { QUrl forumUrl(FORUM_POST_URL); QUrlQuery query; -// query.addQueryItem("api_key", accountManager.getAccountInfo().getDiscourseApiKey(); - query.addQueryItem("api_key", "9168f53930b2fc69ec278414d6ff04fed723ef717867a25954143150d3e2dfe8"); + query.addQueryItem("api_key", AccountManager::getInstance().getAccountInfo().getDiscourseApiKey()); query.addQueryItem("topic_id", FORUM_REPLY_TO_TOPIC); query.addQueryItem("raw", FORUM_POST_TEMPLATE.arg(snapshotPath, _ui.textEdit->toPlainText())); forumUrl.setQuery(query); QByteArray postData = forumUrl.toEncoded(QUrl::RemoveFragment); request.setUrl(forumUrl); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); + QNetworkReply* requestReply = _networkAccessManager->post(request, postData); + connect(requestReply, &QNetworkReply::finished, this, &SnapshotShareDialog::postRequestFinished); - bool check; - Q_UNUSED(check); - - check = connect(requestReply, &QNetworkReply::finished, this, &SnapshotShareDialog::requestFinished); - Q_ASSERT(check); - - check = connect(requestReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(requestError(QNetworkReply::NetworkError))); - Q_ASSERT(check); + QEventLoop loop; + connect(requestReply, &QNetworkReply::finished, &loop, &QEventLoop::quit); + loop.exec(); } -void SnapshotShareDialog::requestFinished() { +void SnapshotShareDialog::postRequestFinished() { + QNetworkReply* requestReply = reinterpret_cast(sender()); - qDebug() << requestReply->errorString(); + QJsonDocument jsonResponse = QJsonDocument::fromJson(requestReply->readAll()); + const QJsonObject& responseObject = jsonResponse.object(); + + if (responseObject.contains("id")) { + _ui.textEdit->setHtml(""); + const QString urlTemplate = "%1/t/%2/%3/%4"; + QString link = urlTemplate.arg(FORUM_URL, + responseObject["topic_slug"].toString(), + QString::number(responseObject["topic_id"].toDouble()), + QString::number(responseObject["post_number"].toDouble())); + + _ui.successLabel->setText(SUCCESS_LABEL_TEMPLATE.arg(link)); + _ui.successLabel->setFixedHeight(SUCCESS_LABEL_HEIGHT); + + // hide input widgets + _ui.shareButton->hide(); + _ui.textEdit->hide(); + _ui.labelNotes->hide(); + + } else { + QString errorMessage(SHARE_DEFAULT_ERROR); + if (responseObject.contains("errors")) { + QJsonArray errorArray = responseObject["errors"].toArray(); + if (!errorArray.first().toString().isEmpty()) { + errorMessage = errorArray.first().toString(); + } + } + QMessageBox::warning(this, "", SHARE_DEFAULT_ERROR); + } +} + +void SnapshotShareDialog::uploadRequestFinished() { + + QNetworkReply* requestReply = reinterpret_cast(sender()); + QJsonDocument jsonResponse = QJsonDocument::fromJson(requestReply->readAll()); + const QJsonObject& responseObject = jsonResponse.object(); + + if (responseObject.contains("url")) { + sendForumPost(responseObject["url"].toString()); + } else { + QMessageBox::warning(this, "", SHARE_DEFAULT_ERROR); + } + delete requestReply; } - -void SnapshotShareDialog::requestError(QNetworkReply::NetworkError error) { - // TODO: error handling - qDebug() << "AccountManager requestError - " << error; -} diff --git a/interface/src/ui/SnapshotShareDialog.h b/interface/src/ui/SnapshotShareDialog.h index ea973022f3..bc92e63e4c 100644 --- a/interface/src/ui/SnapshotShareDialog.h +++ b/interface/src/ui/SnapshotShareDialog.h @@ -32,9 +32,9 @@ private: void uploadSnapshot(); void sendForumPost(QString snapshotPath); -public slots: - void requestFinished(); - void requestError(QNetworkReply::NetworkError error); +private slots: + void uploadRequestFinished(); + void postRequestFinished(); void accept(); }; diff --git a/interface/ui/shareSnapshot.ui b/interface/ui/shareSnapshot.ui index 0f59349442..df7fc4939f 100644 --- a/interface/ui/shareSnapshot.ui +++ b/interface/ui/shareSnapshot.ui @@ -31,9 +31,6 @@ 616 - - PointingHandCursor - Share with Alphas @@ -121,7 +118,55 @@ - + + + true + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 0 + + + + + Arial + + + + color: #666 + + + + + + Qt::RichText + + + Qt::AlignCenter + + + true + + + Qt::TextBrowserInteraction + + + + + 0 From ef67a72f23b55383c8da20bcb0a286e68a998881 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 8 May 2014 07:22:55 -0700 Subject: [PATCH 13/31] Remove icon paths from runningScriptsWidget.ui These icon paths are already set programmatically. --- interface/ui/runningScriptsWidget.ui | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/interface/ui/runningScriptsWidget.ui b/interface/ui/runningScriptsWidget.ui index 6abd0f2d5a..cb0106cd48 100644 --- a/interface/ui/runningScriptsWidget.ui +++ b/interface/ui/runningScriptsWidget.ui @@ -88,10 +88,6 @@ padding-top: 3px; Reload all - - - ../resources/images/reload.svg../resources/images/reload.svg - @@ -115,10 +111,6 @@ padding-top: 3px; Stop all - - - ../resources/images/stop.svg../resources/images/stop.svg - @@ -251,10 +243,6 @@ padding-top: 3px; Load script - - - ../resources/images/plus.svg../resources/images/plus.svg - widgetTitle currentlyRunningLabel From 96a9a478712a2052414b6476970dd2f3a0db93e2 Mon Sep 17 00:00:00 2001 From: Stojce Slavkovski Date: Thu, 8 May 2014 20:54:28 +0200 Subject: [PATCH 14/31] minor code fixes --- interface/src/ui/SnapshotShareDialog.cpp | 10 +++++----- interface/src/ui/SnapshotShareDialog.h | 4 ++-- snapshotShareDialog.cpp | 9 --------- snapshotShareDialog.h | 14 -------------- 4 files changed, 7 insertions(+), 30 deletions(-) delete mode 100644 snapshotShareDialog.cpp delete mode 100644 snapshotShareDialog.h diff --git a/interface/src/ui/SnapshotShareDialog.cpp b/interface/src/ui/SnapshotShareDialog.cpp index fc738c9761..5ba284618f 100644 --- a/interface/src/ui/SnapshotShareDialog.cpp +++ b/interface/src/ui/SnapshotShareDialog.cpp @@ -13,11 +13,11 @@ #include "AccountManager.h" #include -#include -#include -#include -#include #include +#include +#include +#include +#include const int NARROW_SNAPSHOT_DIALOG_SIZE = 500; @@ -177,7 +177,7 @@ void SnapshotShareDialog::postRequestFinished() { errorMessage = errorArray.first().toString(); } } - QMessageBox::warning(this, "", SHARE_DEFAULT_ERROR); + QMessageBox::warning(this, "", errorMessage); } } diff --git a/interface/src/ui/SnapshotShareDialog.h b/interface/src/ui/SnapshotShareDialog.h index bc92e63e4c..a8795d578a 100644 --- a/interface/src/ui/SnapshotShareDialog.h +++ b/interface/src/ui/SnapshotShareDialog.h @@ -14,9 +14,9 @@ #include "ui_shareSnapshot.h" -#include -#include #include +#include +#include class SnapshotShareDialog : public QDialog { Q_OBJECT diff --git a/snapshotShareDialog.cpp b/snapshotShareDialog.cpp deleted file mode 100644 index 53a445292f..0000000000 --- a/snapshotShareDialog.cpp +++ /dev/null @@ -1,9 +0,0 @@ -// -// snapshotShareDialog.cpp -// hifi -// -// Created by Stojce Slavkovski on 2/16/14. -// -// - -#include "snapshotShareDialog.h" diff --git a/snapshotShareDialog.h b/snapshotShareDialog.h deleted file mode 100644 index 77e92216fd..0000000000 --- a/snapshotShareDialog.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// snapshotShareDialog.h -// hifi -// -// Created by Stojce Slavkovski on 2/16/14. -// -// - -#ifndef __hifi__snapshotShareDialog__ -#define __hifi__snapshotShareDialog__ - -#include - -#endif /* defined(__hifi__snapshotShareDialog__) */ From 363f545f7cdc0d166af2649c30437b68478b5259 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 9 May 2014 17:50:08 -0700 Subject: [PATCH 15/31] After uploading, refresh the uploaded files so that they are immediately redownloaded. --- interface/src/ModelUploader.cpp | 25 +++++++---- interface/src/ModelUploader.h | 2 + interface/src/renderer/GeometryCache.cpp | 9 ++++ interface/src/renderer/GeometryCache.h | 1 + interface/src/renderer/Model.cpp | 3 ++ libraries/shared/src/ResourceCache.cpp | 55 ++++++++++++++++++------ libraries/shared/src/ResourceCache.h | 7 +++ 7 files changed, 79 insertions(+), 23 deletions(-) diff --git a/interface/src/ModelUploader.cpp b/interface/src/ModelUploader.cpp index ce8691998d..ec7fcee6f2 100644 --- a/interface/src/ModelUploader.cpp +++ b/interface/src/ModelUploader.cpp @@ -49,7 +49,7 @@ static const QString TRANSLATION_Z_FIELD = "tz"; static const QString JOINT_FIELD = "joint"; static const QString FREE_JOINT_FIELD = "freeJoint"; -static const QString S3_URL = "http://highfidelity-public.s3-us-west-1.amazonaws.com"; +static const QString S3_URL = "http://public.highfidelity.io"; static const QString DATA_SERVER_URL = "https://data-web.highfidelity.io"; static const QString MODEL_URL = "/api/v1/models"; @@ -201,12 +201,15 @@ bool ModelUploader::zip() { mapping = properties.getMapping(); QByteArray nameField = mapping.value(NAME_FIELD).toByteArray(); + QString urlBase; if (!nameField.isEmpty()) { QHttpPart textPart; textPart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"model_name\""); textPart.setBody(nameField); _dataMultiPart->append(textPart); - _url = S3_URL + "/models/" + MODEL_TYPE_NAMES[_modelType] + "/" + nameField + ".fst"; + urlBase = S3_URL + "/models/" + MODEL_TYPE_NAMES[_modelType] + "/" + nameField; + _url = urlBase + ".fst"; + } else { QMessageBox::warning(NULL, QString("ModelUploader::zip()"), @@ -218,6 +221,7 @@ bool ModelUploader::zip() { QByteArray texdirField = mapping.value(TEXDIR_FIELD).toByteArray(); QString texDir; + _textureBase = urlBase + "/textures/"; if (!texdirField.isEmpty()) { texDir = basePath + "/" + texdirField; QFileInfo texInfo(texDir); @@ -407,6 +411,10 @@ void ModelUploader::processCheck() { QString("ModelUploader::processCheck()"), QString("Your model is now available in the browser."), QMessageBox::Ok); + Application::getInstance()->getGeometryCache()->refresh(_url); + foreach (const QByteArray& filename, _textureFilenames) { + Application::getInstance()->getTextureCache()->refresh(_textureBase + filename); + } deleteLater(); break; case QNetworkReply::ContentNotFoundError: @@ -428,32 +436,31 @@ void ModelUploader::processCheck() { } bool ModelUploader::addTextures(const QString& texdir, const FBXGeometry& geometry) { - QSet added; foreach (FBXMesh mesh, geometry.meshes) { foreach (FBXMeshPart part, mesh.parts) { if (!part.diffuseTexture.filename.isEmpty() && part.diffuseTexture.content.isEmpty() && - !added.contains(part.diffuseTexture.filename)) { + !_textureFilenames.contains(part.diffuseTexture.filename)) { if (!addPart(texdir + "/" + part.diffuseTexture.filename, QString("texture%1").arg(++_texturesCount), true)) { return false; } - added.insert(part.diffuseTexture.filename); + _textureFilenames.insert(part.diffuseTexture.filename); } if (!part.normalTexture.filename.isEmpty() && part.normalTexture.content.isEmpty() && - !added.contains(part.normalTexture.filename)) { + !_textureFilenames.contains(part.normalTexture.filename)) { if (!addPart(texdir + "/" + part.normalTexture.filename, QString("texture%1").arg(++_texturesCount), true)) { return false; } - added.insert(part.normalTexture.filename); + _textureFilenames.insert(part.normalTexture.filename); } if (!part.specularTexture.filename.isEmpty() && part.specularTexture.content.isEmpty() && - !added.contains(part.specularTexture.filename)) { + !_textureFilenames.contains(part.specularTexture.filename)) { if (!addPart(texdir + "/" + part.specularTexture.filename, QString("texture%1").arg(++_texturesCount), true)) { return false; } - added.insert(part.specularTexture.filename); + _textureFilenames.insert(part.specularTexture.filename); } } } diff --git a/interface/src/ModelUploader.h b/interface/src/ModelUploader.h index 766bd55318..634de05640 100644 --- a/interface/src/ModelUploader.h +++ b/interface/src/ModelUploader.h @@ -49,6 +49,8 @@ private slots: private: QString _url; + QString _textureBase; + QSet _textureFilenames; int _lodCount; int _texturesCount; int _totalSize; diff --git a/interface/src/renderer/GeometryCache.cpp b/interface/src/renderer/GeometryCache.cpp index 8d31cdce1d..ec68c87a76 100644 --- a/interface/src/renderer/GeometryCache.cpp +++ b/interface/src/renderer/GeometryCache.cpp @@ -506,6 +506,15 @@ void GeometryReader::run() { _reply->deleteLater(); } +void NetworkGeometry::init() { + _mapping = QVariantHash(); + _geometry = FBXGeometry(); + _meshes.clear(); + _lods.clear(); + _request.setUrl(_url); + Resource::init(); +} + void NetworkGeometry::downloadFinished(QNetworkReply* reply) { QUrl url = reply->url(); if (url.path().toLower().endsWith(".fst")) { diff --git a/interface/src/renderer/GeometryCache.h b/interface/src/renderer/GeometryCache.h index a9b274fedc..deecfd56c5 100644 --- a/interface/src/renderer/GeometryCache.h +++ b/interface/src/renderer/GeometryCache.h @@ -96,6 +96,7 @@ public: protected: + virtual void init(); virtual void downloadFinished(QNetworkReply* reply); virtual void reinsert(); diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index f46fd48beb..e1bfd21bba 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -319,6 +319,9 @@ bool Model::updateGeometry() { _jointStates = createJointStates(fbxGeometry); needToRebuild = true; } + } else if (!geometry->isLoaded()) { + deleteGeometry(); + _dilatedTextures.clear(); } _geometry->setLoadPriority(this, -_lodDistance); _geometry->ensureLoading(); diff --git a/libraries/shared/src/ResourceCache.cpp b/libraries/shared/src/ResourceCache.cpp index 2f26e344fd..14998232d6 100644 --- a/libraries/shared/src/ResourceCache.cpp +++ b/libraries/shared/src/ResourceCache.cpp @@ -30,6 +30,13 @@ ResourceCache::~ResourceCache() { } } +void ResourceCache::refresh(const QUrl& url) { + QSharedPointer resource = _resources.value(url); + if (!resource.isNull()) { + resource->refresh(); + } +} + QSharedPointer ResourceCache::getResource(const QUrl& url, const QUrl& fallback, bool delayLoad, void* extra) { if (!url.isValid() && !url.isEmpty() && fallback.isValid()) { return getResource(fallback, QUrl(), delayLoad); @@ -107,25 +114,15 @@ QList ResourceCache::_loadingRequests; Resource::Resource(const QUrl& url, bool delayLoad) : _url(url), _request(url), - _startedLoading(false), - _failedToLoad(false), - _loaded(false), _lruKey(0), - _reply(NULL), - _attempts(0) { + _reply(NULL) { + + init(); - if (url.isEmpty()) { - _startedLoading = _loaded = true; - return; - - } else if (!(url.isValid() && ResourceCache::getNetworkAccessManager())) { - _startedLoading = _failedToLoad = true; - return; - } _request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); // start loading immediately unless instructed otherwise - if (!delayLoad) { + if (!(_startedLoading || delayLoad)) { attemptRequest(); } } @@ -178,6 +175,22 @@ float Resource::getLoadPriority() { return highestPriority; } +void Resource::refresh() { + if (_reply == NULL && !(_loaded || _failedToLoad)) { + return; + } + if (_reply) { + ResourceCache::requestCompleted(this); + delete _reply; + _reply = NULL; + } + init(); + _request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork); + if (!_startedLoading) { + attemptRequest(); + } +} + void Resource::allReferencesCleared() { if (QThread::currentThread() != thread()) { QMetaObject::invokeMethod(this, "allReferencesCleared"); @@ -197,6 +210,20 @@ void Resource::allReferencesCleared() { } } +void Resource::init() { + _startedLoading = false; + _failedToLoad = false; + _loaded = false; + _attempts = 0; + + if (_url.isEmpty()) { + _startedLoading = _loaded = true; + + } else if (!(_url.isValid() && ResourceCache::getNetworkAccessManager())) { + _startedLoading = _failedToLoad = true; + } +} + void Resource::attemptRequest() { _startedLoading = true; ResourceCache::attemptRequest(this); diff --git a/libraries/shared/src/ResourceCache.h b/libraries/shared/src/ResourceCache.h index 0cfabd26fc..2404485c46 100644 --- a/libraries/shared/src/ResourceCache.h +++ b/libraries/shared/src/ResourceCache.h @@ -47,6 +47,8 @@ public: ResourceCache(QObject* parent = NULL); virtual ~ResourceCache(); + void refresh(const QUrl& url); + protected: QMap > _unusedResources; @@ -119,6 +121,9 @@ public: /// For loading resources, returns the load progress. float getProgress() const { return (_bytesTotal == 0) ? 0.0f : (float)_bytesReceived / _bytesTotal; } + /// Refreshes the resource. + void refresh(); + void setSelf(const QWeakPointer& self) { _self = self; } void setCache(ResourceCache* cache) { _cache = cache; } @@ -131,6 +136,8 @@ protected slots: protected: + virtual void init(); + /// Called when the download has finished. The recipient should delete the reply when done with it. virtual void downloadFinished(QNetworkReply* reply) = 0; From 3b7e0814fe2d2572102e03e9447d29539840ae77 Mon Sep 17 00:00:00 2001 From: Stojce Slavkovski Date: Sun, 11 May 2014 09:57:43 +0200 Subject: [PATCH 16/31] CR fixes --- interface/src/XmppClient.cpp | 2 +- interface/src/ui/SnapshotShareDialog.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/XmppClient.cpp b/interface/src/XmppClient.cpp index 666906681c..2d421b1afa 100644 --- a/interface/src/XmppClient.cpp +++ b/interface/src/XmppClient.cpp @@ -16,7 +16,7 @@ #include "XmppClient.h" const QString DEFAULT_XMPP_SERVER = "chat.highfidelity.io"; -const QString DEFAULT_CHAT_ROOM = "public@public-chat.highfidelity.io"; +const QString DEFAULT_CHAT_ROOM = "test@public-chat.highfidelity.io"; XmppClient::XmppClient() : _xmppClient(), diff --git a/interface/src/ui/SnapshotShareDialog.cpp b/interface/src/ui/SnapshotShareDialog.cpp index 5ba284618f..2ac1c81f52 100644 --- a/interface/src/ui/SnapshotShareDialog.cpp +++ b/interface/src/ui/SnapshotShareDialog.cpp @@ -87,13 +87,13 @@ void SnapshotShareDialog::uploadSnapshot() { _networkAccessManager = new QNetworkAccessManager(this); } - QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); + QHttpMultiPart* multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); QHttpPart apiKeyPart; apiKeyPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"api_key\"")); apiKeyPart.setBody(AccountManager::getInstance().getAccountInfo().getDiscourseApiKey().toLatin1()); - QFile *file = new QFile(_fileName); + QFile* file = new QFile(_fileName); file->open(QIODevice::ReadOnly); QHttpPart imagePart; @@ -109,7 +109,7 @@ void SnapshotShareDialog::uploadSnapshot() { QUrl url(FORUM_UPLOADS_URL); QNetworkRequest request(url); - QNetworkReply *reply = _networkAccessManager->post(request, multiPart); + QNetworkReply* reply = _networkAccessManager->post(request, multiPart); connect(reply, &QNetworkReply::finished, this, &SnapshotShareDialog::uploadRequestFinished); From 070d9960961766c201b4b34c9c1b5082e8eab2ef Mon Sep 17 00:00:00 2001 From: Stojce Slavkovski Date: Mon, 12 May 2014 19:47:41 +0200 Subject: [PATCH 17/31] change `key missing` message --- interface/src/ui/SnapshotShareDialog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/SnapshotShareDialog.cpp b/interface/src/ui/SnapshotShareDialog.cpp index 2ac1c81f52..b5694b3e48 100644 --- a/interface/src/ui/SnapshotShareDialog.cpp +++ b/interface/src/ui/SnapshotShareDialog.cpp @@ -79,7 +79,8 @@ void SnapshotShareDialog::accept() { void SnapshotShareDialog::uploadSnapshot() { if (AccountManager::getInstance().getAccountInfo().getDiscourseApiKey().isEmpty()) { - QMessageBox::warning(this, "", "Your Discourse API key is missing, you cannot share snapshots."); + QMessageBox::warning(this, "", + "Your Discourse API key is missing, you cannot share snapshots. Please try to relog."); return; } From 47268fef32e264cd1d09af83c832d109b1b55276 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 12 May 2014 11:06:14 -0700 Subject: [PATCH 18/31] Fixed kooky conditional. --- interface/src/avatar/MyAvatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 52eff6e2ce..6778460ec0 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1490,7 +1490,7 @@ void MyAvatar::updateMotionBehaviorsFromMenu() { } void MyAvatar::renderAttachments(RenderMode renderMode) { - if (!Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_FIRST_PERSON || renderMode == MIRROR_RENDER_MODE) { + if (Application::getInstance()->getCamera()->getMode() != CAMERA_MODE_FIRST_PERSON || renderMode == MIRROR_RENDER_MODE) { Avatar::renderAttachments(renderMode); return; } From 49dedb72c97b3e44d5af3e9d80a929d136ea65e0 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 12 May 2014 11:09:12 -0700 Subject: [PATCH 19/31] remove FingerData class and related cleanup --- interface/src/BuckyBalls.cpp | 8 +- interface/src/avatar/Avatar.cpp | 16 +-- interface/src/avatar/Hand.cpp | 64 ++--------- interface/src/avatar/SkeletonModel.cpp | 26 +---- interface/src/devices/SixenseManager.cpp | 29 ++--- .../ControllerScriptingInterface.cpp | 4 +- libraries/avatars/src/HandData.cpp | 107 +++--------------- libraries/avatars/src/HandData.h | 82 +++----------- libraries/shared/src/SharedUtil.h | 1 + 9 files changed, 63 insertions(+), 274 deletions(-) diff --git a/interface/src/BuckyBalls.cpp b/interface/src/BuckyBalls.cpp index e1ec41dca1..68d1167071 100644 --- a/interface/src/BuckyBalls.cpp +++ b/interface/src/BuckyBalls.cpp @@ -60,15 +60,13 @@ BuckyBalls::BuckyBalls() { void BuckyBalls::grab(PalmData& palm, float deltaTime) { float penetration; - glm::vec3 diff; - FingerData& finger = palm.getFingers()[0]; // Sixense has only one finger - glm::vec3 fingerTipPosition = finger.getTipPosition(); + glm::vec3 fingerTipPosition = palm.getFingerTipPosition(); if (palm.getControllerButtons() & BUTTON_FWD) { if (!_bballIsGrabbed[palm.getSixenseID()]) { // Look for a ball to grab for (int i = 0; i < NUM_BBALLS; i++) { - diff = _bballPosition[i] - fingerTipPosition; + glm::vec3 diff = _bballPosition[i] - fingerTipPosition; penetration = glm::length(diff) - (_bballRadius[i] + COLLISION_RADIUS); if (penetration < 0.f) { _bballIsGrabbed[palm.getSixenseID()] = i; @@ -77,7 +75,7 @@ void BuckyBalls::grab(PalmData& palm, float deltaTime) { } if (_bballIsGrabbed[palm.getSixenseID()]) { // If ball being grabbed, move with finger - diff = _bballPosition[_bballIsGrabbed[palm.getSixenseID()]] - fingerTipPosition; + glm::vec3 diff = _bballPosition[_bballIsGrabbed[palm.getSixenseID()]] - fingerTipPosition; penetration = glm::length(diff) - (_bballRadius[_bballIsGrabbed[palm.getSixenseID()]] + COLLISION_RADIUS); _bballPosition[_bballIsGrabbed[palm.getSixenseID()]] -= glm::normalize(diff) * penetration; glm::vec3 fingerTipVelocity = palm.getTipVelocity(); diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 4de608fc6b..00b7b8c682 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -604,18 +604,6 @@ bool Avatar::findParticleCollisions(const glm::vec3& particleCenter, float parti const PalmData* palm = handData->getPalm(i); if (palm && palm->hasPaddle()) { // create a disk collision proxy where the hand is - glm::vec3 fingerAxis(0.0f); - for (size_t f = 0; f < palm->getNumFingers(); ++f) { - const FingerData& finger = (palm->getFingers())[f]; - if (finger.isActive()) { - // compute finger axis - glm::vec3 fingerTip = finger.getTipPosition(); - glm::vec3 fingerRoot = finger.getRootPosition(); - fingerAxis = glm::normalize(fingerTip - fingerRoot); - break; - } - } - int jointIndex = -1; glm::vec3 handPosition; if (i == 0) { @@ -626,8 +614,10 @@ bool Avatar::findParticleCollisions(const glm::vec3& particleCenter, float parti _skeletonModel.getRightHandPosition(handPosition); jointIndex = _skeletonModel.getRightHandJointIndex(); } + + glm::vec3 fingerAxis = palm->getFingerDirection(); glm::vec3 diskCenter = handPosition + HAND_PADDLE_OFFSET * fingerAxis; - glm::vec3 diskNormal = palm->getNormal(); + glm::vec3 diskNormal = palm->getPalmDirection(); const float DISK_THICKNESS = 0.08f; // collide against the disk diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 576790714e..78eab424ab 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -176,8 +176,7 @@ void Hand::renderHandTargets(bool isMine) { if (!palm.isActive()) { continue; } - glm::vec3 targetPosition; - palm.getBallHoldPosition(targetPosition); + glm::vec3 targetPosition = palm.getFingerTipPosition(); glPushMatrix(); glTranslatef(targetPosition.x, targetPosition.y, targetPosition.z); @@ -197,59 +196,20 @@ void Hand::renderHandTargets(bool isMine) { for (size_t i = 0; i < getNumPalms(); ++i) { PalmData& palm = getPalms()[i]; if (palm.isActive()) { - for (size_t f = 0; f < palm.getNumFingers(); ++f) { - FingerData& finger = palm.getFingers()[f]; - if (finger.isActive()) { - glColor4f(handColor.r, handColor.g, handColor.b, alpha); - glm::vec3 tip = finger.getTipPosition(); - glm::vec3 root = finger.getRootPosition(); - Avatar::renderJointConnectingCone(root, tip, PALM_FINGER_ROD_RADIUS, PALM_FINGER_ROD_RADIUS); - // Render sphere at palm/finger root - glm::vec3 palmNormal = root + palm.getNormal() * PALM_DISK_THICKNESS; - Avatar::renderJointConnectingCone(root, palmNormal, PALM_DISK_RADIUS, 0.0f); - glPushMatrix(); - glTranslatef(root.x, root.y, root.z); - glutSolidSphere(PALM_BALL_RADIUS, 20.0f, 20.0f); - glPopMatrix(); - - } - } + glColor4f(handColor.r, handColor.g, handColor.b, alpha); + glm::vec3 tip = palm.getFingerTipPosition(); + glm::vec3 root = palm.getPosition(); + Avatar::renderJointConnectingCone(root, tip, PALM_FINGER_ROD_RADIUS, PALM_FINGER_ROD_RADIUS); + // Render sphere at palm/finger root + glm::vec3 offsetFromPalm = root + palm.getPalmDirection() * PALM_DISK_THICKNESS; + Avatar::renderJointConnectingCone(root, offsetFromPalm, PALM_DISK_RADIUS, 0.0f); + glPushMatrix(); + glTranslatef(root.x, root.y, root.z); + glutSolidSphere(PALM_BALL_RADIUS, 20.0f, 20.0f); + glPopMatrix(); } } - /* - // Draw the hand paddles - int MAX_NUM_PADDLES = 2; // one for left and one for right - glColor4f(handColor.r, handColor.g, handColor.b, 0.3f); - for (int i = 0; i < MAX_NUM_PADDLES; i++) { - const PalmData* palm = getPalm(i); - if (palm) { - // compute finger axis - glm::vec3 fingerAxis(0.f); - for (size_t f = 0; f < palm->getNumFingers(); ++f) { - const FingerData& finger = (palm->getFingers())[f]; - if (finger.isActive()) { - glm::vec3 fingerTip = finger.getTipPosition(); - glm::vec3 fingerRoot = finger.getRootPosition(); - fingerAxis = glm::normalize(fingerTip - fingerRoot); - break; - } - } - // compute paddle position - glm::vec3 handPosition; - if (i == SIXENSE_CONTROLLER_ID_LEFT_HAND) { - _owningAvatar->getSkeletonModel().getLeftHandPosition(handPosition); - } else if (i == SIXENSE_CONTROLLER_ID_RIGHT_HAND) { - _owningAvatar->getSkeletonModel().getRightHandPosition(handPosition); - } - glm::vec3 tip = handPosition + HAND_PADDLE_OFFSET * fingerAxis; - glm::vec3 root = tip + palm->getNormal() * HAND_PADDLE_THICKNESS; - // render a very shallow cone as the paddle - Avatar::renderJointConnectingCone(root, tip, HAND_PADDLE_RADIUS, 0.f); - } - } - */ - glDepthMask(GL_TRUE); glEnable(GL_DEPTH_TEST); diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 8c21a3240f..7a6fadeb6b 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -159,29 +159,13 @@ void SkeletonModel::applyPalmData(int jointIndex, const QVector& fingerJoin } else { getJointRotation(jointIndex, palmRotation, true); } - palmRotation = rotationBetween(palmRotation * geometry.palmDirection, palm.getNormal()) * palmRotation; + palmRotation = rotationBetween(palmRotation * geometry.palmDirection, palm.getPalmDirection()) * palmRotation; - // sort the finger indices by raw x, get the average direction - QVector fingerIndices; - glm::vec3 direction; - for (size_t i = 0; i < palm.getNumFingers(); i++) { - glm::vec3 fingerVector = palm.getFingers()[i].getTipPosition() - palm.getPosition(); - float length = glm::length(fingerVector); - if (length > EPSILON) { - direction += fingerVector / length; - } - fingerVector = glm::inverse(palmRotation) * fingerVector * -sign; - IndexValue indexValue = { (int)i, atan2f(fingerVector.z, fingerVector.x) }; - fingerIndices.append(indexValue); - } - qSort(fingerIndices.begin(), fingerIndices.end()); - // rotate forearm according to average finger direction - float directionLength = glm::length(direction); - const unsigned int MIN_ROTATION_FINGERS = 3; - if (directionLength > EPSILON && palm.getNumFingers() >= MIN_ROTATION_FINGERS) { - palmRotation = rotationBetween(palmRotation * glm::vec3(-sign, 0.0f, 0.0f), direction) * palmRotation; - } + // NOTE: we're doing this in the avatar local frame, so we DON'T want to use Palm::getHandDirection() + // which returns the world-frame. + glm::vec3 direction = palm.getRawRotation() * glm::vec3(0.0f, 0.0f, 1.0f); + palmRotation = rotationBetween(palmRotation * glm::vec3(-sign, 0.0f, 0.0f), direction) * palmRotation; // set hand position, rotation if (Menu::getInstance()->isOptionChecked(MenuOption::AlignForearmsWithWrists)) { diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 0435519124..461b414b2b 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -106,7 +106,7 @@ void SixenseManager::update(float deltaTime) { palm->setControllerButtons(data->buttons); palm->setTrigger(data->trigger); palm->setJoystick(data->joystick_x, data->joystick_y); - + glm::vec3 position(data->pos[0], data->pos[1], data->pos[2]); // Transform the measured position into body frame. glm::vec3 neck = _neckBase; @@ -117,15 +117,12 @@ void SixenseManager::update(float deltaTime) { // Rotation of Palm glm::quat rotation(data->rot_quat[3], -data->rot_quat[0], data->rot_quat[1], -data->rot_quat[2]); rotation = glm::angleAxis(PI, glm::vec3(0.f, 1.f, 0.f)) * _orbRotation * rotation; - const glm::vec3 PALM_VECTOR(0.0f, -1.0f, 0.0f); - glm::vec3 newNormal = rotation * PALM_VECTOR; - palm->setRawNormal(newNormal); palm->setRawRotation(rotation); // Compute current velocity from position change glm::vec3 rawVelocity; if (deltaTime > 0.f) { - rawVelocity = (position - palm->getRawPosition()) / deltaTime / 1000.f; + rawVelocity = (position - palm->getRawPosition()) * (METERS_PER_MILLIMETER / deltaTime); } else { rawVelocity = glm::vec3(0.0f); } @@ -140,29 +137,17 @@ void SixenseManager::update(float deltaTime) { _amountMoved = glm::vec3(0.0f); } - // initialize the "finger" based on the direction - FingerData finger(palm, hand); - finger.setActive(true); - finger.setRawRootPosition(position); - const float FINGER_LENGTH = 300.0f; // Millimeters + // Store the one fingertip in the palm structure so we can track velocity + const float FINGER_LENGTH = 300.0f; // meters const glm::vec3 FINGER_VECTOR(0.0f, 0.0f, FINGER_LENGTH); const glm::vec3 newTipPosition = position + rotation * FINGER_VECTOR; - finger.setRawTipPosition(position + rotation * FINGER_VECTOR); - - // Store the one fingertip in the palm structure so we can track velocity glm::vec3 oldTipPosition = palm->getTipRawPosition(); if (deltaTime > 0.f) { - palm->setTipVelocity((newTipPosition - oldTipPosition) / deltaTime / 1000.f); + palm->setTipVelocity((newTipPosition - oldTipPosition) * (METERS_PER_MILLIMETER / deltaTime)); } else { palm->setTipVelocity(glm::vec3(0.f)); } palm->setTipPosition(newTipPosition); - - // three fingers indicates to the skeleton that we have enough data to determine direction - palm->getFingers().clear(); - palm->getFingers().push_back(finger); - palm->getFingers().push_back(finger); - palm->getFingers().push_back(finger); } if (numActiveControllers == 2) { @@ -171,7 +156,7 @@ void SixenseManager::update(float deltaTime) { // if the controllers haven't been moved in a while, disable const unsigned int MOVEMENT_DISABLE_SECONDS = 3; - if (usecTimestampNow() - _lastMovement > (MOVEMENT_DISABLE_SECONDS * 1000 * 1000)) { + if (usecTimestampNow() - _lastMovement > (MOVEMENT_DISABLE_SECONDS * USECS_PER_SECOND)) { for (std::vector::iterator it = hand->getPalms().begin(); it != hand->getPalms().end(); it++) { it->setActive(false); } @@ -236,7 +221,7 @@ void SixenseManager::updateCalibration(const sixenseControllerData* controllers) if (_calibrationState == CALIBRATION_STATE_IDLE) { float reach = glm::distance(positionLeft, positionRight); - if (reach > 2.f * MINIMUM_ARM_REACH) { + if (reach > 2.0f * MINIMUM_ARM_REACH) { qDebug("started: sixense calibration"); _averageLeft = positionLeft; _averageRight = positionRight; diff --git a/interface/src/scripting/ControllerScriptingInterface.cpp b/interface/src/scripting/ControllerScriptingInterface.cpp index aa14f769de..5e58ac66ea 100644 --- a/interface/src/scripting/ControllerScriptingInterface.cpp +++ b/interface/src/scripting/ControllerScriptingInterface.cpp @@ -198,9 +198,9 @@ glm::vec3 ControllerScriptingInterface::getSpatialControlNormal(int controlIndex if (palmData) { switch (controlOfPalm) { case PALM_SPATIALCONTROL: - return palmData->getNormal(); + return palmData->getPalmDirection(); case TIP_SPATIALCONTROL: - return palmData->getNormal(); // currently the tip doesn't have a unique normal, use the palm normal + return palmData->getFingerDirection(); } } return glm::vec3(0); // bad index diff --git a/libraries/avatars/src/HandData.cpp b/libraries/avatars/src/HandData.cpp index c2e3b51cb3..109eab5c5d 100644 --- a/libraries/avatars/src/HandData.cpp +++ b/libraries/avatars/src/HandData.cpp @@ -26,7 +26,7 @@ HandData::HandData(AvatarData* owningAvatar) : addNewPalm(); } -glm::vec3 HandData::worldVectorToLeapVector(const glm::vec3& worldVector) const { +glm::vec3 HandData::worldToLocalVector(const glm::vec3& worldVector) const { return glm::inverse(getBaseOrientation()) * worldVector / LEAP_UNIT_SCALE; } @@ -66,7 +66,6 @@ void HandData::getLeftRightPalmIndices(int& leftPalmIndex, int& rightPalmIndex) PalmData::PalmData(HandData* owningHandData) : _rawRotation(0.f, 0.f, 0.f, 1.f), _rawPosition(0.f), -_rawNormal(0.f, 1.f, 0.f), _rawVelocity(0.f), _rotationalVelocity(0.f), _totalPenetration(0.f), @@ -78,57 +77,11 @@ _numFramesWithoutData(0), _owningHandData(owningHandData), _isCollidingWithVoxel(false), _isCollidingWithPalm(false), -_collisionlessPaddleExpiry(0) -{ - for (int i = 0; i < NUM_FINGERS_PER_HAND; ++i) { - _fingers.push_back(FingerData(this, owningHandData)); - } +_collisionlessPaddleExpiry(0) { } void PalmData::addToPosition(const glm::vec3& delta) { - // convert to Leap coordinates, then add to palm and finger positions - glm::vec3 leapDelta = _owningHandData->worldVectorToLeapVector(delta); - _rawPosition += leapDelta; - for (size_t i = 0; i < getNumFingers(); i++) { - FingerData& finger = _fingers[i]; - if (finger.isActive()) { - finger.setRawTipPosition(finger.getTipRawPosition() + leapDelta); - finger.setRawRootPosition(finger.getRootRawPosition() + leapDelta); - } - } -} - -FingerData::FingerData(PalmData* owningPalmData, HandData* owningHandData) : -_tipRawPosition(0, 0, 0), -_rootRawPosition(0, 0, 0), -_isActive(false), -_leapID(LEAPID_INVALID), -_numFramesWithoutData(0), -_owningPalmData(owningPalmData), -_owningHandData(owningHandData) -{ - const int standardTrailLength = 10; - setTrailLength(standardTrailLength); -} - -void HandData::setFingerTrailLength(unsigned int length) { - for (size_t i = 0; i < getNumPalms(); ++i) { - PalmData& palm = getPalms()[i]; - for (size_t f = 0; f < palm.getNumFingers(); ++f) { - FingerData& finger = palm.getFingers()[f]; - finger.setTrailLength(length); - } - } -} - -void HandData::updateFingerTrails() { - for (size_t i = 0; i < getNumPalms(); ++i) { - PalmData& palm = getPalms()[i]; - for (size_t f = 0; f < palm.getNumFingers(); ++f) { - FingerData& finger = palm.getFingers()[f]; - finger.updateTrail(); - } - } + _rawPosition += _owningHandData->worldToLocalVector(delta); } bool HandData::findSpherePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, glm::vec3& penetration, @@ -157,54 +110,20 @@ glm::vec3 HandData::getBasePosition() const { return _owningAvatarData->getPosition(); } -void FingerData::setTrailLength(unsigned int length) { - _tipTrailPositions.resize(length); - _tipTrailCurrentStartIndex = 0; - _tipTrailCurrentValidLength = 0; +glm::vec3 PalmData::getFingerTipPosition() const { + glm::vec3 fingerOffset(0.0f, 0.0f, 0.03f); + glm::vec3 palmOffset(0.0f, -0.08f, 0.0f); + return getPosition() + _owningHandData->localToWorldDirection(_rawRotation * (fingerOffset + palmOffset)); } -void FingerData::updateTrail() { - if (_tipTrailPositions.size() == 0) - return; - - if (_isActive) { - // Add the next point in the trail. - _tipTrailCurrentStartIndex--; - if (_tipTrailCurrentStartIndex < 0) - _tipTrailCurrentStartIndex = _tipTrailPositions.size() - 1; - - _tipTrailPositions[_tipTrailCurrentStartIndex] = getTipPosition(); - - if (_tipTrailCurrentValidLength < (int)_tipTrailPositions.size()) - _tipTrailCurrentValidLength++; - } - else { - // It's not active, so just kill the trail. - _tipTrailCurrentValidLength = 0; - } +glm::vec3 PalmData::getFingerDirection() const { + const glm::vec3 LOCAL_FINGER_DIRECTION(0.0f, 0.0f, 1.0f); + return _owningHandData->localToWorldDirection(_rawRotation * LOCAL_FINGER_DIRECTION); } -int FingerData::getTrailNumPositions() { - return _tipTrailCurrentValidLength; -} - -const glm::vec3& FingerData::getTrailPosition(int index) { - if (index >= _tipTrailCurrentValidLength) { - static glm::vec3 zero(0,0,0); - return zero; - } - int posIndex = (index + _tipTrailCurrentStartIndex) % _tipTrailCurrentValidLength; - return _tipTrailPositions[posIndex]; -} - -void PalmData::getBallHoldPosition(glm::vec3& position) const { - const float BALL_FORWARD_OFFSET = 0.08f; // put the ball a bit forward of fingers - position = BALL_FORWARD_OFFSET * getNormal(); - if (_fingers.size() > 0) { - position += _fingers[0].getTipPosition(); - } else { - position += getPosition(); - } +glm::vec3 PalmData::getPalmDirection() const { + const glm::vec3 LOCAL_PALM_DIRECTION(0.0f, -1.0f, 0.0f); + return _owningHandData->localToWorldDirection(_rawRotation * LOCAL_PALM_DIRECTION); } diff --git a/libraries/avatars/src/HandData.h b/libraries/avatars/src/HandData.h index a37e3a5814..968d7bbe38 100755 --- a/libraries/avatars/src/HandData.h +++ b/libraries/avatars/src/HandData.h @@ -21,7 +21,6 @@ #include "SharedUtil.h" class AvatarData; -class FingerData; class PalmData; const int NUM_HANDS = 2; @@ -41,17 +40,16 @@ public: HandData(AvatarData* owningAvatar); virtual ~HandData() {} - // These methods return the positions in Leap-relative space. - // To convert to world coordinates, use Hand::leapPositionToWorldPosition. - // position conversion - glm::vec3 leapPositionToWorldPosition(const glm::vec3& leapPosition) { - return getBasePosition() + getBaseOrientation() * (leapPosition * LEAP_UNIT_SCALE); + glm::vec3 localToWorldPosition(const glm::vec3& localPosition) { + return getBasePosition() + getBaseOrientation() * localPosition * LEAP_UNIT_SCALE; } - glm::vec3 leapDirectionToWorldDirection(const glm::vec3& leapDirection) { - return getBaseOrientation() * leapDirection; - } - glm::vec3 worldVectorToLeapVector(const glm::vec3& worldVector) const; + + glm::vec3 localToWorldDirection(const glm::vec3& localVector) { + return getBaseOrientation() * localVector; + } + + glm::vec3 worldToLocalVector(const glm::vec3& worldVector) const; std::vector& getPalms() { return _palms; } const std::vector& getPalms() const { return _palms; } @@ -63,9 +61,6 @@ public: /// both is not found. void getLeftRightPalmIndices(int& leftPalmIndex, int& rightPalmIndex) const; - void setFingerTrailLength(unsigned int length); - void updateFingerTrails(); - /// Checks for penetration between the described sphere and the hand. /// \param penetratorCenter the center of the penetration test sphere /// \param penetratorRadius the radius of the penetration test sphere @@ -89,63 +84,18 @@ private: HandData& operator= (const HandData&); }; -class FingerData { -public: - FingerData(PalmData* owningPalmData, HandData* owningHandData); - - glm::vec3 getTipPosition() const { return _owningHandData->leapPositionToWorldPosition(_tipRawPosition); } - glm::vec3 getRootPosition() const { return _owningHandData->leapPositionToWorldPosition(_rootRawPosition); } - const glm::vec3& getTipRawPosition() const { return _tipRawPosition; } - const glm::vec3& getRootRawPosition() const { return _rootRawPosition; } - bool isActive() const { return _isActive; } - int getLeapID() const { return _leapID; } - - void setActive(bool active) { _isActive = active; } - void setLeapID(int id) { _leapID = id; } - void setRawTipPosition(const glm::vec3& pos) { _tipRawPosition = pos; } - void setRawRootPosition(const glm::vec3& pos) { _rootRawPosition = pos; } - - void setTrailLength(unsigned int length); - void updateTrail(); - - int getTrailNumPositions(); - const glm::vec3& getTrailPosition(int index); - - void incrementFramesWithoutData() { _numFramesWithoutData++; } - void resetFramesWithoutData() { _numFramesWithoutData = 0; } - int getFramesWithoutData() const { return _numFramesWithoutData; } - -private: - glm::vec3 _tipRawPosition; - glm::vec3 _rootRawPosition; - bool _isActive; // This has current valid data - int _leapID; // the Leap's serial id for this tracked object - int _numFramesWithoutData; // after too many frames without data, this tracked object assumed lost. - std::vector _tipTrailPositions; - int _tipTrailCurrentStartIndex; - int _tipTrailCurrentValidLength; - PalmData* _owningPalmData; - HandData* _owningHandData; -}; class PalmData { public: PalmData(HandData* owningHandData); - glm::vec3 getPosition() const { return _owningHandData->leapPositionToWorldPosition(_rawPosition); } - glm::vec3 getNormal() const { return _owningHandData->leapDirectionToWorldDirection(_rawNormal); } - glm::vec3 getVelocity() const { return _owningHandData->leapDirectionToWorldDirection(_rawVelocity); } + glm::vec3 getPosition() const { return _owningHandData->localToWorldPosition(_rawPosition); } + glm::vec3 getVelocity() const { return _owningHandData->localToWorldDirection(_rawVelocity); } const glm::vec3& getRawPosition() const { return _rawPosition; } - const glm::vec3& getRawNormal() const { return _rawNormal; } bool isActive() const { return _isActive; } int getLeapID() const { return _leapID; } int getSixenseID() const { return _sixenseID; } - - std::vector& getFingers() { return _fingers; } - const std::vector& getFingers() const { return _fingers; } - size_t getNumFingers() const { return _fingers.size(); } - void setActive(bool active) { _isActive = active; } void setLeapID(int id) { _leapID = id; } void setSixenseID(int id) { _sixenseID = id; } @@ -153,7 +103,6 @@ public: void setRawRotation(const glm::quat rawRotation) { _rawRotation = rawRotation; }; glm::quat getRawRotation() const { return _rawRotation; } void setRawPosition(const glm::vec3& pos) { _rawPosition = pos; } - void setRawNormal(const glm::vec3& normal) { _rawNormal = normal; } void setRawVelocity(const glm::vec3& velocity) { _rawVelocity = velocity; } const glm::vec3& getRawVelocity() const { return _rawVelocity; } void addToPosition(const glm::vec3& delta); @@ -162,11 +111,11 @@ public: void resolvePenetrations() { addToPosition(-_totalPenetration); _totalPenetration = glm::vec3(0.f); } void setTipPosition(const glm::vec3& position) { _tipPosition = position; } - const glm::vec3 getTipPosition() const { return _owningHandData->leapPositionToWorldPosition(_tipPosition); } + const glm::vec3 getTipPosition() const { return _owningHandData->localToWorldPosition(_tipPosition); } const glm::vec3& getTipRawPosition() const { return _tipPosition; } void setTipVelocity(const glm::vec3& velocity) { _tipVelocity = velocity; } - const glm::vec3 getTipVelocity() const { return _owningHandData->leapDirectionToWorldDirection(_tipVelocity); } + const glm::vec3 getTipVelocity() const { return _owningHandData->localToWorldDirection(_tipVelocity); } const glm::vec3& getTipRawVelocity() const { return _tipVelocity; } void incrementFramesWithoutData() { _numFramesWithoutData++; } @@ -198,11 +147,14 @@ public: /// Store position where the palm holds the ball. void getBallHoldPosition(glm::vec3& position) const; + // return world-frame: + glm::vec3 getFingerTipPosition() const; + glm::vec3 getFingerDirection() const; + glm::vec3 getPalmDirection() const; + private: - std::vector _fingers; glm::quat _rawRotation; glm::vec3 _rawPosition; - glm::vec3 _rawNormal; glm::vec3 _rawVelocity; glm::vec3 _rotationalVelocity; glm::quat _lastRotation; diff --git a/libraries/shared/src/SharedUtil.h b/libraries/shared/src/SharedUtil.h index 4a3fe2a129..d111439b7e 100644 --- a/libraries/shared/src/SharedUtil.h +++ b/libraries/shared/src/SharedUtil.h @@ -54,6 +54,7 @@ static const float SQUARE_ROOT_OF_3 = (float)sqrt(3.f); static const float METERS_PER_DECIMETER = 0.1f; static const float METERS_PER_CENTIMETER = 0.01f; static const float METERS_PER_MILLIMETER = 0.001f; +static const float MILLIMETERS_PER_METER = 1000.0f; static const quint64 USECS_PER_MSEC = 1000; static const quint64 MSECS_PER_SECOND = 1000; static const quint64 USECS_PER_SECOND = USECS_PER_MSEC * MSECS_PER_SECOND; From efb3edf4006de207c23a9ad65de4355eccb024c1 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 12 May 2014 11:39:21 -0700 Subject: [PATCH 20/31] Store sixense data in meters not millimeters --- interface/src/devices/SixenseManager.cpp | 22 ++++++++++++++-------- libraries/avatars/src/HandData.cpp | 2 +- libraries/avatars/src/HandData.h | 4 +--- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 461b414b2b..1698cebcf9 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -22,9 +22,9 @@ const int CALIBRATION_STATE_Z = 3; const int CALIBRATION_STATE_COMPLETE = 4; // default (expected) location of neck in sixense space -const float NECK_X = 250.f; // millimeters -const float NECK_Y = 300.f; // millimeters -const float NECK_Z = 300.f; // millimeters +const float NECK_X = 0.25f; // meters +const float NECK_Y = 0.3f; // meters +const float NECK_Z = 0.3f; // meters #endif SixenseManager::SixenseManager() { @@ -107,7 +107,10 @@ void SixenseManager::update(float deltaTime) { palm->setTrigger(data->trigger); palm->setJoystick(data->joystick_x, data->joystick_y); + // NOTE: Sixense API returns pos data in millimeters but we IMMEDIATELY convert to meters. glm::vec3 position(data->pos[0], data->pos[1], data->pos[2]); + position *= METERS_PER_MILLIMETER; + // Transform the measured position into body frame. glm::vec3 neck = _neckBase; // Zeroing y component of the "neck" effectively raises the measured position a little bit. @@ -122,7 +125,7 @@ void SixenseManager::update(float deltaTime) { // Compute current velocity from position change glm::vec3 rawVelocity; if (deltaTime > 0.f) { - rawVelocity = (position - palm->getRawPosition()) * (METERS_PER_MILLIMETER / deltaTime); + rawVelocity = (position - palm->getRawPosition()) / deltaTime; } else { rawVelocity = glm::vec3(0.0f); } @@ -138,12 +141,12 @@ void SixenseManager::update(float deltaTime) { } // Store the one fingertip in the palm structure so we can track velocity - const float FINGER_LENGTH = 300.0f; // meters + const float FINGER_LENGTH = 0.3f; // meters const glm::vec3 FINGER_VECTOR(0.0f, 0.0f, FINGER_LENGTH); const glm::vec3 newTipPosition = position + rotation * FINGER_VECTOR; glm::vec3 oldTipPosition = palm->getTipRawPosition(); if (deltaTime > 0.f) { - palm->setTipVelocity((newTipPosition - oldTipPosition) * (METERS_PER_MILLIMETER / deltaTime)); + palm->setTipVelocity((newTipPosition - oldTipPosition) / deltaTime); } else { palm->setTipVelocity(glm::vec3(0.f)); } @@ -173,8 +176,8 @@ void SixenseManager::update(float deltaTime) { // (4) move arms a bit forward (Z) // (5) release BUTTON_FWD on both hands -const float MINIMUM_ARM_REACH = 300.f; // millimeters -const float MAXIMUM_NOISE_LEVEL = 50.f; // millimeters +const float MINIMUM_ARM_REACH = 0.3f; // meters +const float MAXIMUM_NOISE_LEVEL = 0.05f; // meters const quint64 LOCK_DURATION = USECS_PER_SECOND / 4; // time for lock to be acquired void SixenseManager::updateCalibration(const sixenseControllerData* controllers) { @@ -214,10 +217,13 @@ void SixenseManager::updateCalibration(const sixenseControllerData* controllers) return; } + // NOTE: Sixense API returns pos data in millimeters but we IMMEDIATELY convert to meters. const float* pos = dataLeft->pos; glm::vec3 positionLeft(pos[0], pos[1], pos[2]); + positionLeft *= METERS_PER_MILLIMETER; pos = dataRight->pos; glm::vec3 positionRight(pos[0], pos[1], pos[2]); + positionRight *= METERS_PER_MILLIMETER; if (_calibrationState == CALIBRATION_STATE_IDLE) { float reach = glm::distance(positionLeft, positionRight); diff --git a/libraries/avatars/src/HandData.cpp b/libraries/avatars/src/HandData.cpp index 109eab5c5d..4dad06fa84 100644 --- a/libraries/avatars/src/HandData.cpp +++ b/libraries/avatars/src/HandData.cpp @@ -27,7 +27,7 @@ HandData::HandData(AvatarData* owningAvatar) : } glm::vec3 HandData::worldToLocalVector(const glm::vec3& worldVector) const { - return glm::inverse(getBaseOrientation()) * worldVector / LEAP_UNIT_SCALE; + return glm::inverse(getBaseOrientation()) * worldVector; } PalmData& HandData::addNewPalm() { diff --git a/libraries/avatars/src/HandData.h b/libraries/avatars/src/HandData.h index 968d7bbe38..d1e11aed8e 100755 --- a/libraries/avatars/src/HandData.h +++ b/libraries/avatars/src/HandData.h @@ -30,8 +30,6 @@ const int NUM_FINGERS = NUM_HANDS * NUM_FINGERS_PER_HAND; const int LEAPID_INVALID = -1; const int SIXENSEID_INVALID = -1; -const float LEAP_UNIT_SCALE = 0.001f; ///< convert mm to meters - const int SIXENSE_CONTROLLER_ID_LEFT_HAND = 0; const int SIXENSE_CONTROLLER_ID_RIGHT_HAND = 1; @@ -42,7 +40,7 @@ public: // position conversion glm::vec3 localToWorldPosition(const glm::vec3& localPosition) { - return getBasePosition() + getBaseOrientation() * localPosition * LEAP_UNIT_SCALE; + return getBasePosition() + getBaseOrientation() * localPosition; } glm::vec3 localToWorldDirection(const glm::vec3& localVector) { From cea472b7304b9498055d5b6ada716c8113644f0c Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 12 May 2014 11:48:56 -0700 Subject: [PATCH 21/31] remove the last of Leap specific cruft --- interface/src/avatar/SkeletonModel.cpp | 4 ++-- libraries/avatars/src/HandData.cpp | 1 - libraries/avatars/src/HandData.h | 3 --- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 7a6fadeb6b..a2e637f4e7 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -33,7 +33,7 @@ void SkeletonModel::simulate(float deltaTime, bool fullUpdate) { return; // only simulate for own avatar } - // find the left and rightmost active Leap palms + // find the left and rightmost active palms int leftPalmIndex, rightPalmIndex; Hand* hand = _owningAvatar->getHand(); hand->getLeftRightPalmIndices(leftPalmIndex, rightPalmIndex); @@ -42,7 +42,7 @@ void SkeletonModel::simulate(float deltaTime, bool fullUpdate) { const FBXGeometry& geometry = _geometry->getFBXGeometry(); if (leftPalmIndex == -1) { - // no Leap data; set hands from mouse + // palms are not yet set, use mouse if (_owningAvatar->getHandState() == HAND_STATE_NULL) { restoreRightHandPosition(HAND_RESTORATION_RATE); } else { diff --git a/libraries/avatars/src/HandData.cpp b/libraries/avatars/src/HandData.cpp index 4dad06fa84..446cf2bc2a 100644 --- a/libraries/avatars/src/HandData.cpp +++ b/libraries/avatars/src/HandData.cpp @@ -71,7 +71,6 @@ _rotationalVelocity(0.f), _totalPenetration(0.f), _controllerButtons(0), _isActive(false), -_leapID(LEAPID_INVALID), _sixenseID(SIXENSEID_INVALID), _numFramesWithoutData(0), _owningHandData(owningHandData), diff --git a/libraries/avatars/src/HandData.h b/libraries/avatars/src/HandData.h index d1e11aed8e..1f2d134c43 100755 --- a/libraries/avatars/src/HandData.h +++ b/libraries/avatars/src/HandData.h @@ -91,11 +91,9 @@ public: const glm::vec3& getRawPosition() const { return _rawPosition; } bool isActive() const { return _isActive; } - int getLeapID() const { return _leapID; } int getSixenseID() const { return _sixenseID; } void setActive(bool active) { _isActive = active; } - void setLeapID(int id) { _leapID = id; } void setSixenseID(int id) { _sixenseID = id; } void setRawRotation(const glm::quat rawRotation) { _rawRotation = rawRotation; }; @@ -166,7 +164,6 @@ private: float _joystickX, _joystickY; bool _isActive; // This has current valid data - int _leapID; // the Leap's serial id for this tracked object int _sixenseID; // Sixense controller ID for this palm int _numFramesWithoutData; // after too many frames without data, this tracked object assumed lost. HandData* _owningHandData; From e983be401354958de53788c311027566f8af64bc Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 12 May 2014 11:52:16 -0700 Subject: [PATCH 22/31] fix typo (finger length = 0.3m, not 0.03m) --- libraries/avatars/src/HandData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/avatars/src/HandData.cpp b/libraries/avatars/src/HandData.cpp index 446cf2bc2a..bd366f020a 100644 --- a/libraries/avatars/src/HandData.cpp +++ b/libraries/avatars/src/HandData.cpp @@ -110,7 +110,7 @@ glm::vec3 HandData::getBasePosition() const { } glm::vec3 PalmData::getFingerTipPosition() const { - glm::vec3 fingerOffset(0.0f, 0.0f, 0.03f); + glm::vec3 fingerOffset(0.0f, 0.0f, 0.3f); glm::vec3 palmOffset(0.0f, -0.08f, 0.0f); return getPosition() + _owningHandData->localToWorldDirection(_rawRotation * (fingerOffset + palmOffset)); } From 7ffb700564f028944224ebc1c5f19e77121e73b9 Mon Sep 17 00:00:00 2001 From: Stojce Slavkovski Date: Mon, 12 May 2014 20:55:24 +0200 Subject: [PATCH 23/31] fixed mention sounds dir for deployment --- .../mention => mention-sounds}/Mentioned A.wav | Bin .../mention => mention-sounds}/Mentioned B.wav | Bin .../mention => mention-sounds}/Mentioned C.wav | Bin interface/src/XmppClient.cpp | 2 +- interface/src/ui/ChatWindow.cpp | 2 +- 5 files changed, 2 insertions(+), 2 deletions(-) rename interface/resources/{sounds/mention => mention-sounds}/Mentioned A.wav (100%) rename interface/resources/{sounds/mention => mention-sounds}/Mentioned B.wav (100%) rename interface/resources/{sounds/mention => mention-sounds}/Mentioned C.wav (100%) diff --git a/interface/resources/sounds/mention/Mentioned A.wav b/interface/resources/mention-sounds/Mentioned A.wav similarity index 100% rename from interface/resources/sounds/mention/Mentioned A.wav rename to interface/resources/mention-sounds/Mentioned A.wav diff --git a/interface/resources/sounds/mention/Mentioned B.wav b/interface/resources/mention-sounds/Mentioned B.wav similarity index 100% rename from interface/resources/sounds/mention/Mentioned B.wav rename to interface/resources/mention-sounds/Mentioned B.wav diff --git a/interface/resources/sounds/mention/Mentioned C.wav b/interface/resources/mention-sounds/Mentioned C.wav similarity index 100% rename from interface/resources/sounds/mention/Mentioned C.wav rename to interface/resources/mention-sounds/Mentioned C.wav diff --git a/interface/src/XmppClient.cpp b/interface/src/XmppClient.cpp index 2d421b1afa..666906681c 100644 --- a/interface/src/XmppClient.cpp +++ b/interface/src/XmppClient.cpp @@ -16,7 +16,7 @@ #include "XmppClient.h" const QString DEFAULT_XMPP_SERVER = "chat.highfidelity.io"; -const QString DEFAULT_CHAT_ROOM = "test@public-chat.highfidelity.io"; +const QString DEFAULT_CHAT_ROOM = "public@public-chat.highfidelity.io"; XmppClient::XmppClient() : _xmppClient(), diff --git a/interface/src/ui/ChatWindow.cpp b/interface/src/ui/ChatWindow.cpp index fce900f352..611f955031 100644 --- a/interface/src/ui/ChatWindow.cpp +++ b/interface/src/ui/ChatWindow.cpp @@ -32,7 +32,7 @@ const int NUM_MESSAGES_TO_TIME_STAMP = 20; const QRegularExpression regexLinks("((?:(?:ftp)|(?:https?)|(?:hifi))://\\S+)"); const QRegularExpression regexHifiLinks("([#@]\\S+)"); -const QString mentionSoundsPath("/sounds/mention/"); +const QString mentionSoundsPath("/mention-sounds/"); const QString mentionRegex("@(\\b%1\\b)"); ChatWindow::ChatWindow(QWidget* parent) : From 8541df9c32093360cfd4b8aa5bbdf9cb2853864c Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 12 May 2014 12:16:30 -0700 Subject: [PATCH 24/31] Remember attachment parameters per joint (as well as the last joint used) so that the gun script correctly allows both guns' positions to be tweaked. --- interface/src/avatar/MyAvatar.cpp | 40 ++++++++++++------- interface/src/avatar/MyAvatar.h | 2 +- interface/src/ui/AttachmentsDialog.cpp | 55 ++++++++++++++++++++------ interface/src/ui/AttachmentsDialog.h | 4 ++ libraries/avatars/src/AvatarData.h | 2 + 5 files changed, 77 insertions(+), 26 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 6778460ec0..36c51dc9fd 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -520,8 +520,9 @@ void MyAvatar::saveAttachmentData(const AttachmentData& attachment) const { settings->beginGroup("savedAttachmentData"); settings->beginGroup(_skeletonModel.getURL().toString()); settings->beginGroup(attachment.modelURL.toString()); - settings->setValue("jointName", attachment.jointName); + + settings->beginGroup(attachment.jointName); settings->setValue("translation_x", attachment.translation.x); settings->setValue("translation_y", attachment.translation.y); settings->setValue("translation_z", attachment.translation.z); @@ -534,10 +535,11 @@ void MyAvatar::saveAttachmentData(const AttachmentData& attachment) const { settings->endGroup(); settings->endGroup(); settings->endGroup(); + settings->endGroup(); Application::getInstance()->unlockSettings(); } -AttachmentData MyAvatar::loadAttachmentData(const QUrl& modelURL) const { +AttachmentData MyAvatar::loadAttachmentData(const QUrl& modelURL, const QString& jointName) const { QSettings* settings = Application::getInstance()->lockSettings(); settings->beginGroup("savedAttachmentData"); settings->beginGroup(_skeletonModel.getURL().toString()); @@ -545,20 +547,30 @@ AttachmentData MyAvatar::loadAttachmentData(const QUrl& modelURL) const { AttachmentData attachment; attachment.modelURL = modelURL; - attachment.jointName = settings->value("jointName").toString(); - attachment.translation.x = loadSetting(settings, "translation_x", 0.0f); - attachment.translation.y = loadSetting(settings, "translation_y", 0.0f); - attachment.translation.z = loadSetting(settings, "translation_z", 0.0f); - glm::vec3 eulers; - eulers.x = loadSetting(settings, "rotation_x", 0.0f); - eulers.y = loadSetting(settings, "rotation_y", 0.0f); - eulers.z = loadSetting(settings, "rotation_z", 0.0f); - attachment.rotation = glm::quat(eulers); - attachment.scale = loadSetting(settings, "scale", 1.0f); + if (jointName.isEmpty()) { + attachment.jointName = settings->value("jointName").toString(); + } else { + attachment.jointName = jointName; + } + settings->beginGroup(attachment.jointName); + if (settings->contains("translation_x")) { + attachment.translation.x = loadSetting(settings, "translation_x", 0.0f); + attachment.translation.y = loadSetting(settings, "translation_y", 0.0f); + attachment.translation.z = loadSetting(settings, "translation_z", 0.0f); + glm::vec3 eulers; + eulers.x = loadSetting(settings, "rotation_x", 0.0f); + eulers.y = loadSetting(settings, "rotation_y", 0.0f); + eulers.z = loadSetting(settings, "rotation_z", 0.0f); + attachment.rotation = glm::quat(eulers); + attachment.scale = loadSetting(settings, "scale", 1.0f); + } else { + attachment = AttachmentData(); + } settings->endGroup(); settings->endGroup(); settings->endGroup(); + settings->endGroup(); Application::getInstance()->unlockSettings(); return attachment; @@ -650,8 +662,8 @@ void MyAvatar::attach(const QString& modelURL, const QString& jointName, const g return; } if (useSaved) { - AttachmentData attachment = loadAttachmentData(modelURL); - if (!attachment.jointName.isEmpty()) { + AttachmentData attachment = loadAttachmentData(modelURL, jointName); + if (attachment.isValid()) { Avatar::attach(modelURL, attachment.jointName, attachment.translation, attachment.rotation, attachment.scale, allowDuplicates, useSaved); return; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 2e47d9c973..d446c2e895 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -67,7 +67,7 @@ public: void loadData(QSettings* settings); void saveAttachmentData(const AttachmentData& attachment) const; - AttachmentData loadAttachmentData(const QUrl& modelURL) const; + AttachmentData loadAttachmentData(const QUrl& modelURL, const QString& jointName = QString()) const; // Set what driving keys are being pressed to control thrust levels void setDriveKeys(int key, float val) { _driveKeys[key] = val; }; diff --git a/interface/src/ui/AttachmentsDialog.cpp b/interface/src/ui/AttachmentsDialog.cpp index f9f49738e9..44dd2452e6 100644 --- a/interface/src/ui/AttachmentsDialog.cpp +++ b/interface/src/ui/AttachmentsDialog.cpp @@ -97,7 +97,8 @@ static QDoubleSpinBox* createRotationBox(AttachmentPanel* panel, float value) { } AttachmentPanel::AttachmentPanel(AttachmentsDialog* dialog, const AttachmentData& data) : - _dialog(dialog) { + _dialog(dialog), + _applying(false) { setFrameStyle(QFrame::StyledPanel); QFormLayout* layout = new QFormLayout(); @@ -121,7 +122,7 @@ AttachmentPanel::AttachmentPanel(AttachmentsDialog* dialog, const AttachmentData } } _jointName->setCurrentText(data.jointName); - connect(_jointName, SIGNAL(currentIndexChanged(int)), SLOT(updateAttachmentData())); + connect(_jointName, SIGNAL(currentIndexChanged(int)), SLOT(jointNameChanged())); QHBoxLayout* translationBox = new QHBoxLayout(); translationBox->addWidget(_translationX = createTranslationBox(this, data.translation.x)); @@ -171,25 +172,57 @@ void AttachmentPanel::setModelURL(const QString& url) { void AttachmentPanel::modelURLChanged() { // check for saved attachment data + if (_modelURL->text().isEmpty()) { + _dialog->updateAttachmentData(); + return; + } AttachmentData attachment = Application::getInstance()->getAvatar()->loadAttachmentData(_modelURL->text()); - if (!attachment.jointName.isEmpty()) { + if (attachment.isValid()) { + _applying = true; _jointName->setCurrentText(attachment.jointName); - _translationX->setValue(attachment.translation.x); - _translationY->setValue(attachment.translation.y); - _translationZ->setValue(attachment.translation.z); - glm::vec3 eulers = glm::degrees(safeEulerAngles(attachment.rotation)); - _rotationX->setValue(eulers.x); - _rotationY->setValue(eulers.y); - _rotationZ->setValue(eulers.z); - _scale->setValue(attachment.scale); + applyAttachmentData(attachment); } _dialog->updateAttachmentData(); } +void AttachmentPanel::jointNameChanged() { + if (_applying) { + return; + } + // check for saved attachment data specific to this joint + if (_modelURL->text().isEmpty()) { + _dialog->updateAttachmentData(); + return; + } + AttachmentData attachment = Application::getInstance()->getAvatar()->loadAttachmentData( + _modelURL->text(), _jointName->currentText()); + if (attachment.isValid()) { + applyAttachmentData(attachment); + } + updateAttachmentData(); +} + void AttachmentPanel::updateAttachmentData() { + if (_applying) { + return; + } // save the attachment data under the model URL (if any) if (!_modelURL->text().isEmpty()) { Application::getInstance()->getAvatar()->saveAttachmentData(getAttachmentData()); } _dialog->updateAttachmentData(); } + +void AttachmentPanel::applyAttachmentData(const AttachmentData& attachment) { + _applying = true; + _translationX->setValue(attachment.translation.x); + _translationY->setValue(attachment.translation.y); + _translationZ->setValue(attachment.translation.z); + glm::vec3 eulers = glm::degrees(safeEulerAngles(attachment.rotation)); + _rotationX->setValue(eulers.x); + _rotationY->setValue(eulers.y); + _rotationZ->setValue(eulers.z); + _scale->setValue(attachment.scale); + _applying = false; + _dialog->updateAttachmentData(); +} diff --git a/interface/src/ui/AttachmentsDialog.h b/interface/src/ui/AttachmentsDialog.h index 7e9319fba8..59696c96f1 100644 --- a/interface/src/ui/AttachmentsDialog.h +++ b/interface/src/ui/AttachmentsDialog.h @@ -61,10 +61,13 @@ private slots: void chooseModelURL(); void setModelURL(const QString& url); void modelURLChanged(); + void jointNameChanged(); void updateAttachmentData(); private: + void applyAttachmentData(const AttachmentData& attachment); + AttachmentsDialog* _dialog; QLineEdit* _modelURL; QComboBox* _jointName; @@ -75,6 +78,7 @@ private: QDoubleSpinBox* _rotationY; QDoubleSpinBox* _rotationZ; QDoubleSpinBox* _scale; + bool _applying; }; #endif // hifi_AttachmentsDialog_h diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index dd604d06f5..072070e98c 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -352,6 +352,8 @@ public: AttachmentData(); + bool isValid() const { return modelURL.isValid(); } + bool operator==(const AttachmentData& other) const; }; From a1a5372b7411d37b871c81afca42abae15359be9 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 12 May 2014 14:07:33 -0700 Subject: [PATCH 25/31] add missing glPushMatrix() --- interface/src/avatar/Hand.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 576790714e..4774e23cb2 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -162,9 +162,9 @@ void Hand::render(bool isMine, Model::RenderMode renderMode) { } void Hand::renderHandTargets(bool isMine) { + glPushMatrix(); const float alpha = 1.0f; - const glm::vec3 handColor(1.0, 0.0, 0.0); // Color the hand targets red to be different than skin glEnable(GL_DEPTH_TEST); From 90d577a48c4050e3a85b34ea054b7aa7cb78c727 Mon Sep 17 00:00:00 2001 From: Kai Ludwig Date: Tue, 13 May 2014 00:37:36 +0200 Subject: [PATCH 26/31] Stats area is now always right of mirror display, regardless if mirror display is enabled or not as there is always a remaining audio meter. Display, resize and click cases have been adapted by removing the condition for checking display status of mirror. --- interface/src/Application.cpp | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0b59fc3aa2..8858b6d324 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -686,11 +686,8 @@ void Application::resizeGL(int width, int height) { glLoadIdentity(); // update Stats width - int horizontalOffset = 0; - if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { - // mirror is enabled, let's set horizontal offset to give stats some margin - horizontalOffset += MIRROR_VIEW_WIDTH + MIRROR_VIEW_LEFT_PADDING * 2; - } + // let's set horizontal offset to give stats some margin to mirror + int horizontalOffset = MIRROR_VIEW_WIDTH + MIRROR_VIEW_LEFT_PADDING * 2; Stats::getInstance()->resetWidth(width, horizontalOffset); } @@ -1164,10 +1161,8 @@ void Application::mouseReleaseEvent(QMouseEvent* event) { _mousePressed = false; checkBandwidthMeterClick(); if (Menu::getInstance()->isOptionChecked(MenuOption::Stats)) { - int horizontalOffset = 0; - if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { - horizontalOffset = MIRROR_VIEW_WIDTH; - } + // let's set horizontal offset to give stats some margin to mirror + int horizontalOffset = MIRROR_VIEW_WIDTH; Stats::getInstance()->checkClick(_mouseX, _mouseY, _mouseDragStartedX, _mouseDragStartedY, horizontalOffset); } } @@ -2732,11 +2727,8 @@ void Application::displayOverlay() { glPointSize(1.0f); if (Menu::getInstance()->isOptionChecked(MenuOption::Stats)) { - int horizontalOffset = 0; - if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { - // mirror is enabled, let's set horizontal offset to give stats some margin - horizontalOffset += MIRROR_VIEW_WIDTH + MIRROR_VIEW_LEFT_PADDING * 2; - } + // let's set horizontal offset to give stats some margin to mirror + int horizontalOffset = MIRROR_VIEW_WIDTH + MIRROR_VIEW_LEFT_PADDING * 2; int voxelPacketsToProcess = _voxelProcessor.packetsToProcessCount(); // Onscreen text about position, servers, etc Stats::getInstance()->display(WHITE_TEXT, horizontalOffset, _fps, _packetsPerSecond, _bytesPerSecond, voxelPacketsToProcess); From 8b15873488f7003dcb0c7e5ca36e2538474a895b Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Mon, 12 May 2014 16:37:52 -0600 Subject: [PATCH 27/31] Change to Oculus find path in Windows --- cmake/modules/FindLibOVR.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/modules/FindLibOVR.cmake b/cmake/modules/FindLibOVR.cmake index c07b4c14c1..415eeeb1c5 100644 --- a/cmake/modules/FindLibOVR.cmake +++ b/cmake/modules/FindLibOVR.cmake @@ -49,7 +49,7 @@ else (LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIRS) set(WINDOWS_LIBOVR_NAME "libovr.lib") endif() - find_library(LIBOVR_LIBRARIES "Lib/Win32/${LIBOVR_NAME}" HINTS ${LIBOVR_SEARCH_DIRS}) + find_library(LIBOVR_LIBRARIES "Lib/Win32/VS2010/${LIBOVR_NAME}" HINTS ${LIBOVR_SEARCH_DIRS}) endif () if (LIBOVR_INCLUDE_DIRS AND LIBOVR_LIBRARIES) From 415bc64ce9cd9090c4eae9d8e3d8c58bddc7e085 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Mon, 12 May 2014 16:44:15 -0600 Subject: [PATCH 28/31] Moving stuff around --- cmake/modules/FindLibOVR.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/modules/FindLibOVR.cmake b/cmake/modules/FindLibOVR.cmake index 415eeeb1c5..a85e1bec55 100644 --- a/cmake/modules/FindLibOVR.cmake +++ b/cmake/modules/FindLibOVR.cmake @@ -24,7 +24,7 @@ if (LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIRS) else (LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIRS) set(LIBOVR_SEARCH_DIRS "${LIBOVR_ROOT_DIR}" "$ENV{HIFI_LIB_DIR}/oculus") - find_path(LIBOVR_INCLUDE_DIRS OVR.h PATH_SUFFIXES Include HINTS ${LIBOVR_SEARCH_DIRS}) + find_path(LIBOVR_INCLUDE_DIRS OVR.h PATH_SUFFIXES Include VS2010 HINTS ${LIBOVR_SEARCH_DIRS}) if (APPLE) find_library(LIBOVR_LIBRARIES "Lib/MacOS/Release/libovr.a" HINTS ${LIBOVR_SEARCH_DIRS}) @@ -49,7 +49,7 @@ else (LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIRS) set(WINDOWS_LIBOVR_NAME "libovr.lib") endif() - find_library(LIBOVR_LIBRARIES "Lib/Win32/VS2010/${LIBOVR_NAME}" HINTS ${LIBOVR_SEARCH_DIRS}) + find_library(LIBOVR_LIBRARIES "Lib/Win32/${LIBOVR_NAME}" HINTS ${LIBOVR_SEARCH_DIRS}) endif () if (LIBOVR_INCLUDE_DIRS AND LIBOVR_LIBRARIES) From 1869248351b8c73e5c5a271a7d28f2978f34798a Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Mon, 12 May 2014 16:46:24 -0600 Subject: [PATCH 29/31] Moving stuff around --- cmake/modules/FindLibOVR.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/modules/FindLibOVR.cmake b/cmake/modules/FindLibOVR.cmake index a85e1bec55..058dc0a228 100644 --- a/cmake/modules/FindLibOVR.cmake +++ b/cmake/modules/FindLibOVR.cmake @@ -24,7 +24,7 @@ if (LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIRS) else (LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIRS) set(LIBOVR_SEARCH_DIRS "${LIBOVR_ROOT_DIR}" "$ENV{HIFI_LIB_DIR}/oculus") - find_path(LIBOVR_INCLUDE_DIRS OVR.h PATH_SUFFIXES Include VS2010 HINTS ${LIBOVR_SEARCH_DIRS}) + find_path(LIBOVR_INCLUDE_DIRS OVR.h PATH_SUFFIXES Include HINTS ${LIBOVR_SEARCH_DIRS}) if (APPLE) find_library(LIBOVR_LIBRARIES "Lib/MacOS/Release/libovr.a" HINTS ${LIBOVR_SEARCH_DIRS}) @@ -49,7 +49,7 @@ else (LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIRS) set(WINDOWS_LIBOVR_NAME "libovr.lib") endif() - find_library(LIBOVR_LIBRARIES "Lib/Win32/${LIBOVR_NAME}" HINTS ${LIBOVR_SEARCH_DIRS}) + find_library(LIBOVR_LIBRARIES "Lib/Win32/${LIBOVR_NAME}" PATH_SUFFIXES VS2010 HINTS ${LIBOVR_SEARCH_DIRS}) endif () if (LIBOVR_INCLUDE_DIRS AND LIBOVR_LIBRARIES) From c7e103e98992e24d6faf3a7ed3e3bcac10b9ecc9 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Mon, 12 May 2014 19:43:56 -0600 Subject: [PATCH 30/31] Not working with path_suffixes, testing something else --- cmake/modules/FindLibOVR.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/modules/FindLibOVR.cmake b/cmake/modules/FindLibOVR.cmake index 058dc0a228..415eeeb1c5 100644 --- a/cmake/modules/FindLibOVR.cmake +++ b/cmake/modules/FindLibOVR.cmake @@ -49,7 +49,7 @@ else (LIBOVR_LIBRARIES AND LIBOVR_INCLUDE_DIRS) set(WINDOWS_LIBOVR_NAME "libovr.lib") endif() - find_library(LIBOVR_LIBRARIES "Lib/Win32/${LIBOVR_NAME}" PATH_SUFFIXES VS2010 HINTS ${LIBOVR_SEARCH_DIRS}) + find_library(LIBOVR_LIBRARIES "Lib/Win32/VS2010/${LIBOVR_NAME}" HINTS ${LIBOVR_SEARCH_DIRS}) endif () if (LIBOVR_INCLUDE_DIRS AND LIBOVR_LIBRARIES) From 55d96147578860f1898832be0549109f9fa3c374 Mon Sep 17 00:00:00 2001 From: Bennett Goble Date: Tue, 13 May 2014 00:58:49 -0400 Subject: [PATCH 31/31] Menu.cpp Typo: goToOrientation calling goToDestination. --- 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 e1d0c6a574..2daf5b0240 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -889,7 +889,7 @@ void Menu::goToDomainDialog() { } void Menu::goToOrientation(QString orientation) { - LocationManager::getInstance().goToDestination(orientation); + LocationManager::getInstance().goToOrientation(orientation); } bool Menu::goToDestination(QString destination) {