From 4fbb0949786cfed4138610a32bf8b6db798756a4 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 24 Nov 2014 15:39:34 -0800 Subject: [PATCH 01/57] No reason to change that... --- interface/resources/shaders/model_normal_map.frag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/shaders/model_normal_map.frag b/interface/resources/shaders/model_normal_map.frag index af107e9d3c..f5a1047b2b 100644 --- a/interface/resources/shaders/model_normal_map.frag +++ b/interface/resources/shaders/model_normal_map.frag @@ -4,7 +4,7 @@ // model_normal_map.frag // fragment shader // -// Created by Andrzej Kapolka on 10/14/13. +// Created by Andrzej Kapolka on 10/29/13. // Copyright 2013 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. From ce103acdf6c8b312d75d0234380c1eb4666ec832 Mon Sep 17 00:00:00 2001 From: dev Date: Mon, 24 Nov 2014 18:32:36 -0800 Subject: [PATCH 02/57] More debugging of the FBXReader in order to understand how to interpret the material fields --- interface/src/renderer/Model.cpp | 14 +++++++++++--- libraries/fbx/src/FBXReader.cpp | 22 ++++++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index ddcdfe3a84..e6dc3ce74e 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -2347,8 +2347,12 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod diffuseMap = (_dilatedTextures[i][j] = static_cast(diffuseMap)->getDilatedTexture(_pupilDilation)).data(); } - GLBATCH(glBindTexture)(GL_TEXTURE_2D, !diffuseMap ? - Application::getInstance()->getTextureCache()->getWhiteTextureID() : diffuseMap->getID()); + static bool showDiffuse = true; + if (showDiffuse && diffuseMap) { + GLBATCH(glBindTexture)(GL_TEXTURE_2D, diffuseMap->getID()); + } else { + GLBATCH(glBindTexture)(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getWhiteTextureID()); + } if (locations->texcoordMatrices >= 0) { glm::mat4 texcoordTransform[2]; @@ -2379,7 +2383,11 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod if (locations->emissiveTextureUnit >= 0) { assert(locations->emissiveParams >= 0); // we should have the emissiveParams defined in the shader - GLBATCH(glUniform2f)(locations->emissiveParams, 0.1f, 4.0f); + static float emissiveOffset = 0.1f; + static float emissiveScale = 1.0f; + //GLBATCH(glUniform2f)(locations->emissiveParams, 0.1f, 4.0f); + GLBATCH(glUniform2f)(locations->emissiveParams, emissiveOffset, emissiveScale); + GLBATCH(glActiveTexture)(GL_TEXTURE0 + locations->emissiveTextureUnit); Texture* emissiveMap = networkPart.emissiveTexture.data(); diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 0cebacf51a..b54abedc33 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -1597,9 +1597,28 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) } else if (property.properties.at(0) == "Opacity") { material.opacity = property.properties.at(index).value(); } +#if defined(DEBUG_FBXREADER) + else { + const std::string propname = property.properties.at(0).toString().toStdString(); + if (propname == "EmissiveFactor") { + } + } +#endif } } } +#if defined(DEBUG_FBXREADER) + else { + std::string propname = subobject.name.data(); + int unknown = 0; + if ( (propname == "Version") + ||(propname == "ShadingModel") + ||(propname == "Multilayer")) { + } else { + unknown++; + } + } +#endif } material.id = getID(object.properties); materials.insert(material.id, material); @@ -1687,7 +1706,10 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) } else if (type.contains("emissive")) { emissiveTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1)); + } else if (type.contains("ambient")) { + emissiveTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1)); } else { + std::string typenam = type.data(); counter++; } } From a28d74570d5d066d3bd454484617daf76a3637e1 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 25 Nov 2014 09:25:22 -0800 Subject: [PATCH 03/57] bug fixes in setFullscreen() and setEnableVRMode() --- interface/src/Application.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 58b28fcef9..cd7dc813a6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1568,6 +1568,10 @@ void Application::checkBandwidthMeterClick() { } void Application::setFullscreen(bool fullscreen) { + if (Menu::getInstance()->isOptionChecked(MenuOption::Fullscreen) != fullscreen) { + Menu::getInstance()->getActionForOption(MenuOption::Fullscreen)->setChecked(fullscreen); + } + if (Menu::getInstance()->isOptionChecked(MenuOption::EnableVRMode)) { if (fullscreen) { // Menu show() after hide() doesn't work with Rift VR display so set height instead. @@ -1578,6 +1582,7 @@ void Application::setFullscreen(bool fullscreen) { } _window->setWindowState(fullscreen ? (_window->windowState() | Qt::WindowFullScreen) : (_window->windowState() & ~Qt::WindowFullScreen)); + _window->show(); } void Application::setEnable3DTVMode(bool enable3DTVMode) { @@ -1585,6 +1590,10 @@ void Application::setEnable3DTVMode(bool enable3DTVMode) { } void Application::setEnableVRMode(bool enableVRMode) { + if (Menu::getInstance()->isOptionChecked(MenuOption::EnableVRMode) != enableVRMode) { + Menu::getInstance()->getActionForOption(MenuOption::EnableVRMode)->setChecked(enableVRMode); + } + if (enableVRMode) { if (!OculusManager::isConnected()) { // attempt to reconnect the Oculus manager - it's possible this was a workaround From e9812d060890d5a130a510378c66a812b91bb46d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 25 Nov 2014 09:25:49 -0800 Subject: [PATCH 04/57] added similarStrings() helper --- libraries/shared/src/SharedUtil.cpp | 21 +++++++++++++++++++++ libraries/shared/src/SharedUtil.h | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index c376836d24..7b5a0bb15d 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -655,3 +655,24 @@ QString formatSecondsElapsed(float seconds) { } return result; } + +bool similarStrings(const QString& stringA, const QString& stringB) { + QStringList aWords = stringA.split(" "); + QStringList bWords = stringB.split(" "); + float aWordsInB = 0.0f; + foreach(QString aWord, aWords) { + if (bWords.contains(aWord)) { + aWordsInB += 1.0f; + } + } + float bWordsInA = 0.0f; + foreach(QString bWord, bWords) { + if (aWords.contains(bWord)) { + bWordsInA += 1.0f; + } + } + float similarity = 0.5f * (aWordsInB / (float)bWords.size()) + 0.5f * (bWordsInA / (float)aWords.size()); + const float SIMILAR_ENOUGH = 0.5f; // half the words the same is similar enough for us + return similarity >= SIMILAR_ENOUGH; +} + diff --git a/libraries/shared/src/SharedUtil.h b/libraries/shared/src/SharedUtil.h index 01edcc01b9..61b7365877 100644 --- a/libraries/shared/src/SharedUtil.h +++ b/libraries/shared/src/SharedUtil.h @@ -131,6 +131,6 @@ bool isNaN(float value); QString formatUsecTime(float usecs, int prec = 3); QString formatSecondsElapsed(float seconds); - +bool similarStrings(const QString& stringA, const QString& stringB); #endif // hifi_SharedUtil_h From e35242345c2643b8f6c6c399abda7a0315e73994 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 25 Nov 2014 09:26:24 -0800 Subject: [PATCH 05/57] first cut at HMD Tools dialog --- interface/src/Application.h | 2 + interface/src/Menu.cpp | 18 ++++ interface/src/Menu.h | 6 ++ interface/src/devices/OculusManager.cpp | 64 +++++++++++- interface/src/devices/OculusManager.h | 4 + interface/src/ui/HMDToolsDialog.cpp | 131 ++++++++++++++++++++++++ interface/src/ui/HMDToolsDialog.h | 43 ++++++++ 7 files changed, 266 insertions(+), 2 deletions(-) create mode 100644 interface/src/ui/HMDToolsDialog.cpp create mode 100644 interface/src/ui/HMDToolsDialog.h diff --git a/interface/src/Application.h b/interface/src/Application.h index c75202d96f..9f2cdbd520 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -71,6 +71,7 @@ #include "scripting/ControllerScriptingInterface.h" #include "ui/BandwidthDialog.h" #include "ui/BandwidthMeter.h" +#include "ui/HMDToolsDialog.h" #include "ui/ModelsBrowser.h" #include "ui/NodeBounds.h" #include "ui/OctreeStatsDialog.h" @@ -395,6 +396,7 @@ private slots: void connectedToDomain(const QString& hostname); + friend class HMDToolsDialog; void setFullscreen(bool fullscreen); void setEnable3DTVMode(bool enable3DTVMode); void setEnableVRMode(bool enableVRMode); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index db5cd5170d..151e9682ed 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -97,6 +97,7 @@ Menu::Menu() : _jsConsole(NULL), _octreeStatsDialog(NULL), _lodToolsDialog(NULL), + _hmdToolsDialog(NULL), _newLocationDialog(NULL), _userLocationsDialog(NULL), #if defined(Q_OS_MAC) || defined(Q_OS_WIN) @@ -334,6 +335,7 @@ Menu::Menu() : appInstance, SLOT(cameraMenuChanged())); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::UserInterface, Qt::Key_Slash, true); + addActionToQMenuAndActionHash(viewMenu, MenuOption::HMDTools, 0, this, SLOT(hmdTools())); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::EnableVRMode, 0, false, appInstance, @@ -1646,6 +1648,22 @@ void Menu::lodToolsClosed() { } } +void Menu::hmdTools() { + if (!_hmdToolsDialog) { + _hmdToolsDialog = new HMDToolsDialog(Application::getInstance()->getGLWidget()); + connect(_hmdToolsDialog, SIGNAL(closed()), SLOT(hmdToolsClosed())); + _hmdToolsDialog->show(); + } + _hmdToolsDialog->raise(); +} + +void Menu::hmdToolsClosed() { + if (_hmdToolsDialog) { + delete _hmdToolsDialog; + _hmdToolsDialog = NULL; + } +} + void Menu::cycleFrustumRenderMode() { _frustumDrawMode = (FrustumDrawMode)((_frustumDrawMode + 1) % FRUSTUM_DRAW_MODE_COUNT); updateFrustumRenderModeAction(); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 7e153eba5e..e41e2f35ea 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -76,6 +76,7 @@ class QSettings; class AnimationsDialog; class AttachmentsDialog; class BandwidthDialog; +class HMDToolsDialog; class LodToolsDialog; class MetavoxelEditor; class MetavoxelNetworkSimulator; @@ -120,6 +121,7 @@ public: ViewFrustumOffset getViewFrustumOffset() const { return _viewFrustumOffset; } OctreeStatsDialog* getOctreeStatsDialog() const { return _octreeStatsDialog; } LodToolsDialog* getLodToolsDialog() const { return _lodToolsDialog; } + HMDToolsDialog* getHMDToolsDialog() const { return _hmdToolsDialog; } int getMaxVoxels() const { return _maxVoxels; } QAction* getUseVoxelShader() const { return _useVoxelShader; } @@ -183,6 +185,7 @@ public slots: void bandwidthDetails(); void octreeStatsDetails(); void lodTools(); + void hmdTools(); void loadSettings(QSettings* settings = NULL); void saveSettings(QSettings* settings = NULL); void importSettings(); @@ -217,6 +220,7 @@ private slots: void bandwidthDetailsClosed(); void octreeStatsDetailsClosed(); void lodToolsClosed(); + void hmdToolsClosed(); void cycleFrustumRenderMode(); void runTests(); void showMetavoxelEditor(); @@ -284,6 +288,7 @@ private: QDialog* _jsConsole; OctreeStatsDialog* _octreeStatsDialog; LodToolsDialog* _lodToolsDialog; + HMDToolsDialog* _hmdToolsDialog; QPointer _newLocationDialog; QPointer _userLocationsDialog; #if defined(Q_OS_MAC) || defined(Q_OS_WIN) @@ -412,6 +417,7 @@ namespace MenuOption { const QString NamesAboveHeads = "Names Above Heads"; const QString GoToUser = "Go To User"; const QString HeadMouse = "Head Mouse"; + const QString HMDTools = "HMD Tools"; const QString IncreaseAvatarSize = "Increase Avatar Size"; const QString IncreaseVoxelSize = "Increase Voxel Size"; const QString KeyboardMotorControl = "Enable Keyboard Motor Control"; diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index e68a08a8f4..dfec98c358 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -14,9 +14,14 @@ #include "OculusManager.h" +#include +#include #include +#include #include + +#include #include #include "Application.h" @@ -75,9 +80,7 @@ glm::vec3 OculusManager::_rightEyePosition = glm::vec3(); void OculusManager::connect() { #ifdef HAVE_LIBOVR _calibrationState = UNCALIBRATED; - qDebug() << "Oculus SDK" << OVR_VERSION_STRING; - ovr_Initialize(); _ovrHmd = ovrHmd_Create(0); @@ -86,6 +89,7 @@ void OculusManager::connect() { UserActivityLogger::getInstance().connectedDevice("hmd", "oculus"); } _isConnected = true; + #if defined(__APPLE__) || defined(_WIN32) _eyeFov[0] = _ovrHmd->DefaultEyeFov[0]; _eyeFov[1] = _ovrHmd->DefaultEyeFov[1]; @@ -715,3 +719,59 @@ void OculusManager::overrideOffAxisFrustum(float& left, float& right, float& bot } #endif } + +int OculusManager::getHMDScreen() { + int hmdScreenIndex = -1; // unknown +#ifdef HAVE_LIBOVR + // TODO: it might be smarter to handle multiple HMDs connected in this case. but for now, + // we will simply assume the initialization code that set up _ovrHmd picked the best hmd + + if (_ovrHmd) { + QString productNameFromOVR = _ovrHmd->ProductName; + + int hmdWidth = _ovrHmd->Resolution.w; + int hmdHeight = _ovrHmd->Resolution.h; + int hmdAtX = _ovrHmd->WindowsPos.x; + int hmdAtY = _ovrHmd->WindowsPos.y; + + // we will score the likelihood that each screen is a match based on the following + // rubrik of potential matching features + const int EXACT_NAME_MATCH = 100; + const int SIMILAR_NAMES = 10; + const int EXACT_LOCATION_MATCH = 50; + const int EXACT_RESOLUTION_MATCH = 25; + + int bestMatchScore = 0; + + // look at the display list and see if we can find the best match + QDesktopWidget* desktop = QApplication::desktop(); + int screenNumber = 0; + foreach (QScreen* screen, QGuiApplication::screens()) { + QString screenName = screen->name(); + QRect screenRect = desktop->screenGeometry(screenNumber); + + int screenScore = 0; + if (screenName == productNameFromOVR) { + screenScore += EXACT_NAME_MATCH; + } + if (similarStrings(screenName, productNameFromOVR)) { + screenScore += SIMILAR_NAMES; + } + if (hmdWidth == screenRect.width() && hmdHeight == screenRect.height()) { + screenScore += EXACT_RESOLUTION_MATCH; + } + if (hmdAtX == screenRect.x() && hmdAtY == screenRect.y()) { + screenScore += EXACT_LOCATION_MATCH; + } + if (screenScore > bestMatchScore) { + bestMatchScore = screenScore; + hmdScreenIndex = screenNumber; + } + + screenNumber++; + } + } +#endif + return hmdScreenIndex; +} + diff --git a/interface/src/devices/OculusManager.h b/interface/src/devices/OculusManager.h index 20e43d572c..2e0354f61a 100644 --- a/interface/src/devices/OculusManager.h +++ b/interface/src/devices/OculusManager.h @@ -52,11 +52,15 @@ public: static glm::vec3 getLeftEyePosition() { return _leftEyePosition; } static glm::vec3 getRightEyePosition() { return _rightEyePosition; } + static int getHMDScreen(); + private: #ifdef HAVE_LIBOVR static void generateDistortionMesh(); static void renderDistortionMesh(ovrPosef eyeRenderPose[ovrEye_Count]); + static bool similarNames(const QString& nameA,const QString& nameB); + struct DistortionVertex { glm::vec2 pos; glm::vec2 texR; diff --git a/interface/src/ui/HMDToolsDialog.cpp b/interface/src/ui/HMDToolsDialog.cpp new file mode 100644 index 0000000000..11cc652c37 --- /dev/null +++ b/interface/src/ui/HMDToolsDialog.cpp @@ -0,0 +1,131 @@ +// +// HMDToolsDialog.cpp +// interface/src/ui +// +// Created by Brad Hefta-Gaub on 7/19/13. +// Copyright 2013 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "Menu.h" +#include "devices/OculusManager.h" +#include "ui/HMDToolsDialog.h" + + +HMDToolsDialog::HMDToolsDialog(QWidget* parent) : + QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint) +{ + this->setWindowTitle("HMD Tools"); + + // Create layouter + QFormLayout* form = new QFormLayout(); + + // Add a button to enter + QPushButton* enterModeButton = new QPushButton("Enter HMD Mode"); + form->addRow("", enterModeButton); + connect(enterModeButton,SIGNAL(clicked(bool)),this,SLOT(enterModeClicked(bool))); + + // Add a button to leave + QPushButton* leaveModeButton = new QPushButton("Leave HMD Mode"); + form->addRow("", leaveModeButton); + connect(leaveModeButton,SIGNAL(clicked(bool)),this,SLOT(leaveModeClicked(bool))); + + this->QDialog::setLayout(form); + + + _wasMoved = false; + + _previousRect = Application::getInstance()->getWindow()->rect(); + + + // QDesktopWidget::screenCountChanged() SIGNAL +} + +HMDToolsDialog::~HMDToolsDialog() { +} + +void HMDToolsDialog::enterModeClicked(bool checked) { + qDebug() << "enterModeClicked"; + + int hmdScreen = OculusManager::getHMDScreen(); + + // hack to test... + if (hmdScreen == -1) { + hmdScreen = 0; + } + + if (hmdScreen >= 0) { + QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle(); + QScreen* targetScreen = QGuiApplication::screens()[hmdScreen]; + + _previousRect = Application::getInstance()->getWindow()->rect(); + qDebug() << "_previousRect:" << _previousRect; + _previousRect = QRect(mainWindow->mapToGlobal(_previousRect.topLeft()), + mainWindow->mapToGlobal(_previousRect.bottomRight())); + qDebug() << "after mapping... _previousRect:" << _previousRect; + + _previousScreen = mainWindow->screen(); + qDebug() << "_previousScreen:" << _previousScreen; + + QRect rect = QApplication::desktop()->screenGeometry(hmdScreen); + + qDebug() << "about to move to:" << rect.topLeft(); + + mainWindow->setScreen(targetScreen); + mainWindow->setGeometry(rect); + + _wasMoved = true; + } + Application::getInstance()->setFullscreen(true); + Application::getInstance()->setEnableVRMode(true); +} + +void HMDToolsDialog::moveWindowAfterLeaveMode() { + qDebug() << "moveWindowAfterLeaveMode"; + QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle(); + mainWindow->setScreen(_previousScreen); + mainWindow->setGeometry(_previousRect); +} + +void HMDToolsDialog::leaveModeClicked(bool checked) { + qDebug() << "leaveModeClicked"; + + Application::getInstance()->setFullscreen(false); + Application::getInstance()->setEnableVRMode(false); + + if (_wasMoved) { + QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle(); + mainWindow->setScreen(_previousScreen); + mainWindow->setGeometry(_previousRect); + + const int SLIGHT_DELAY = 1500; + QTimer::singleShot(SLIGHT_DELAY, this, SLOT(moveWindowAfterLeaveMode())); + } + _wasMoved = false; +} + +void HMDToolsDialog::reject() { + // Just regularly close upon ESC + this->QDialog::close(); +} + +void HMDToolsDialog::closeEvent(QCloseEvent* event) { + this->QDialog::closeEvent(event); + emit closed(); +} + + diff --git a/interface/src/ui/HMDToolsDialog.h b/interface/src/ui/HMDToolsDialog.h new file mode 100644 index 0000000000..ac6bebc5f4 --- /dev/null +++ b/interface/src/ui/HMDToolsDialog.h @@ -0,0 +1,43 @@ +// +// HMDToolsDialog.h +// interface/src/ui +// +// Created by Brad Hefta-Gaub on 7/19/13. +// Copyright 2013 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_HMDToolsDialog_h +#define hifi_HMDToolsDialog_h + +#include + +class HMDToolsDialog : public QDialog { + Q_OBJECT +public: + // Sets up the UI + HMDToolsDialog(QWidget* parent); + ~HMDToolsDialog(); + +signals: + void closed(); + +public slots: + void reject(); + void enterModeClicked(bool checked); + void leaveModeClicked(bool checked); + void moveWindowAfterLeaveMode(); + +protected: + // Emits a 'closed' signal when this dialog is closed. + void closeEvent(QCloseEvent*); + +private: + bool _wasMoved; + QRect _previousRect; + QScreen* _previousScreen; +}; + +#endif // hifi_HMDToolsDialog_h From 6108f7d9cd1e60c2bfdc465c09e50b030c8808be Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 25 Nov 2014 12:45:20 -0800 Subject: [PATCH 06/57] fix bug in resetSensors moving cursor to center of window on multiple screen systems --- interface/src/Application.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index cd7dc813a6..90b4501662 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3502,7 +3502,6 @@ void Application::deleteVoxelAt(const VoxelDetail& voxel) { } } - void Application::resetSensors() { _mouseX = _glWidget->width() / 2; _mouseY = _glWidget->height() / 2; @@ -3516,7 +3515,11 @@ void Application::resetSensors() { _prioVR.reset(); //_leapmotion.reset(); - QCursor::setPos(_mouseX, _mouseY); + QScreen* currentScreen = _window->windowHandle()->screen(); + QWindow* mainWindow = _window->windowHandle(); + QPoint windowCenter = mainWindow->geometry().center(); + QCursor::setPos(currentScreen, windowCenter); + _myAvatar->reset(); QMetaObject::invokeMethod(&_audio, "reset", Qt::QueuedConnection); From bc376a0a15cec15a5e935f74a32cd2f794d7b226 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 25 Nov 2014 12:46:00 -0800 Subject: [PATCH 07/57] more improvements to HMD Tools --- interface/src/ui/HMDToolsDialog.cpp | 34 ++++++++++++++++++++++------- interface/src/ui/HMDToolsDialog.h | 2 ++ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/interface/src/ui/HMDToolsDialog.cpp b/interface/src/ui/HMDToolsDialog.cpp index 11cc652c37..4f4c624065 100644 --- a/interface/src/ui/HMDToolsDialog.cpp +++ b/interface/src/ui/HMDToolsDialog.cpp @@ -51,8 +51,8 @@ HMDToolsDialog::HMDToolsDialog(QWidget* parent) : _previousRect = Application::getInstance()->getWindow()->rect(); - - // QDesktopWidget::screenCountChanged() SIGNAL + + Application::getInstance()->getWindow()->activateWindow(); } HMDToolsDialog::~HMDToolsDialog() { @@ -70,7 +70,7 @@ void HMDToolsDialog::enterModeClicked(bool checked) { if (hmdScreen >= 0) { QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle(); - QScreen* targetScreen = QGuiApplication::screens()[hmdScreen]; + _hmdScreen = QGuiApplication::screens()[hmdScreen]; _previousRect = Application::getInstance()->getWindow()->rect(); qDebug() << "_previousRect:" << _previousRect; @@ -85,27 +85,36 @@ void HMDToolsDialog::enterModeClicked(bool checked) { qDebug() << "about to move to:" << rect.topLeft(); - mainWindow->setScreen(targetScreen); + mainWindow->setScreen(_hmdScreen); mainWindow->setGeometry(rect); _wasMoved = true; } Application::getInstance()->setFullscreen(true); Application::getInstance()->setEnableVRMode(true); + + const int SLIGHT_DELAY = 500; + QTimer::singleShot(SLIGHT_DELAY, this, SLOT(activateWindowAfterEnterMode())); } -void HMDToolsDialog::moveWindowAfterLeaveMode() { - qDebug() << "moveWindowAfterLeaveMode"; +void HMDToolsDialog::activateWindowAfterEnterMode() { + qDebug() << "activateWindowAfterEnterMode"; + Application::getInstance()->getWindow()->activateWindow(); + QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle(); - mainWindow->setScreen(_previousScreen); - mainWindow->setGeometry(_previousRect); + QPoint windowCenter = mainWindow->geometry().center(); + //QPoint desktopCenter = mainWindow->mapToGlobal(windowCenter); + qDebug() << "windowCenter:" << windowCenter; + QCursor::setPos(_hmdScreen, windowCenter); } + void HMDToolsDialog::leaveModeClicked(bool checked) { qDebug() << "leaveModeClicked"; Application::getInstance()->setFullscreen(false); Application::getInstance()->setEnableVRMode(false); + Application::getInstance()->getWindow()->activateWindow(); if (_wasMoved) { QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle(); @@ -118,6 +127,15 @@ void HMDToolsDialog::leaveModeClicked(bool checked) { _wasMoved = false; } +void HMDToolsDialog::moveWindowAfterLeaveMode() { + qDebug() << "moveWindowAfterLeaveMode"; + QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle(); + mainWindow->setScreen(_previousScreen); + mainWindow->setGeometry(_previousRect); + Application::getInstance()->getWindow()->activateWindow(); +} + + void HMDToolsDialog::reject() { // Just regularly close upon ESC this->QDialog::close(); diff --git a/interface/src/ui/HMDToolsDialog.h b/interface/src/ui/HMDToolsDialog.h index ac6bebc5f4..9620a0529d 100644 --- a/interface/src/ui/HMDToolsDialog.h +++ b/interface/src/ui/HMDToolsDialog.h @@ -28,6 +28,7 @@ public slots: void reject(); void enterModeClicked(bool checked); void leaveModeClicked(bool checked); + void activateWindowAfterEnterMode(); void moveWindowAfterLeaveMode(); protected: @@ -38,6 +39,7 @@ private: bool _wasMoved; QRect _previousRect; QScreen* _previousScreen; + QScreen* _hmdScreen; }; #endif // hifi_HMDToolsDialog_h From aa44906841a7129d8d9cbddc9fa5985f49fd36da Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 25 Nov 2014 13:27:16 -0800 Subject: [PATCH 08/57] make HMD tools a checkable menu --- interface/src/Menu.cpp | 24 +++++++++++++++++------- interface/src/Menu.h | 2 +- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 1c1f9aec23..ac93a71bc0 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -335,7 +335,12 @@ Menu::Menu() : appInstance, SLOT(cameraMenuChanged())); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::UserInterface, Qt::Key_Slash, true); - addActionToQMenuAndActionHash(viewMenu, MenuOption::HMDTools, 0, this, SLOT(hmdTools())); + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::HMDTools, Qt::META | Qt::Key_H, + false, + this, + SLOT(hmdTools(bool))); + + addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::EnableVRMode, 0, false, appInstance, @@ -1596,13 +1601,18 @@ void Menu::lodToolsClosed() { } } -void Menu::hmdTools() { - if (!_hmdToolsDialog) { - _hmdToolsDialog = new HMDToolsDialog(Application::getInstance()->getGLWidget()); - connect(_hmdToolsDialog, SIGNAL(closed()), SLOT(hmdToolsClosed())); - _hmdToolsDialog->show(); +void Menu::hmdTools(bool showTools) { + if (showTools) { + if (!_hmdToolsDialog) { + _hmdToolsDialog = new HMDToolsDialog(Application::getInstance()->getGLWidget()); + connect(_hmdToolsDialog, SIGNAL(closed()), SLOT(hmdToolsClosed())); + _hmdToolsDialog->show(); + } + _hmdToolsDialog->raise(); + } else { + hmdToolsClosed(); } - _hmdToolsDialog->raise(); + Application::getInstance()->getWindow()->activateWindow(); } void Menu::hmdToolsClosed() { diff --git a/interface/src/Menu.h b/interface/src/Menu.h index db836dc690..0d46c4020d 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -185,7 +185,7 @@ public slots: void bandwidthDetails(); void octreeStatsDetails(); void lodTools(); - void hmdTools(); + void hmdTools(bool showTools); void loadSettings(QSettings* settings = NULL); void saveSettings(QSettings* settings = NULL); void importSettings(); From 77077f4e9c71ef66d34fdd30c70e833e8e042315 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 25 Nov 2014 18:17:28 -0800 Subject: [PATCH 09/57] hack a separate emissive information in the g-buffer --- .../resources/shaders/directional_light.frag | 45 ++++++++++++------- .../resources/shaders/model_lightmap.frag | 6 +-- interface/src/renderer/GeometryCache.cpp | 11 ++++- interface/src/renderer/Model.cpp | 8 ++-- libraries/fbx/src/FBXReader.cpp | 24 +++++----- libraries/fbx/src/FBXReader.h | 1 + 6 files changed, 58 insertions(+), 37 deletions(-) diff --git a/interface/resources/shaders/directional_light.frag b/interface/resources/shaders/directional_light.frag index da48149001..d4a6f5a28b 100644 --- a/interface/resources/shaders/directional_light.frag +++ b/interface/resources/shaders/directional_light.frag @@ -36,25 +36,36 @@ uniform vec2 depthTexCoordOffset; uniform vec2 depthTexCoordScale; void main(void) { + float depthVal = texture2D(depthMap, gl_TexCoord[0].st).r; + vec4 normalVal = texture2D(normalMap, gl_TexCoord[0].st); + vec4 diffuseVal = texture2D(diffuseMap, gl_TexCoord[0].st); + vec4 specularVal = texture2D(specularMap, gl_TexCoord[0].st); + // compute the view space position using the depth - float z = near / (texture2D(depthMap, gl_TexCoord[0].st).r * depthScale - 1.0); + float z = near / (depthVal * depthScale - 1.0); vec4 position = vec4((depthTexCoordOffset + gl_TexCoord[0].st * depthTexCoordScale) * z, z, 0.0); // get the normal from the map - vec4 normal = texture2D(normalMap, gl_TexCoord[0].st); - vec4 normalizedNormal = normalize(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0)); - - // compute the base color based on OpenGL lighting model - float diffuse = dot(normalizedNormal, gl_LightSource[0].position); - float facingLight = step(0.0, diffuse); - vec4 baseColor = texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightModelProduct.sceneColor + - gl_FrontLightProduct[0].ambient + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight)); - - // compute the specular multiplier (sans exponent) - float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(position)), - normalizedNormal)); - - // add specular contribution - vec4 specularColor = texture2D(specularMap, gl_TexCoord[0].st); - gl_FragColor = vec4(baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb, normal.a); + vec4 normal = normalVal; + if (normalVal.a == 0.5) { + normal.a = 1.0; + normalVal.a = 0.0; + gl_FragColor = vec4(diffuseVal.rgb * specularColor.rgb, normal.a); + } else { + vec3 normalizedNormal = normalize(normal.xyz * 2.0 - vec3(1.0)); + + // compute the base color based on OpenGL lighting model + float diffuse = dot(normalizedNormal, gl_LightSource[0].position.xyz); + float facingLight = step(0.0, diffuse); + vec3 baseColor = diffuseVal.rgb * (gl_FrontLightModelProduct.sceneColor.rgb + + gl_FrontLightProduct[0].ambient.rgb + gl_FrontLightProduct[0].diffuse.rgb * (diffuse * facingLight)); + + // compute the specular multiplier (sans exponent) + float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position.xyz - normalize(position.xyz)), + normalizedNormal)); + + // add specular contribution + vec4 specularColor = specularVal; + gl_FragColor = vec4(baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb, normal.a); + } } diff --git a/interface/resources/shaders/model_lightmap.frag b/interface/resources/shaders/model_lightmap.frag index b93f0abc6f..7c352b877e 100644 --- a/interface/resources/shaders/model_lightmap.frag +++ b/interface/resources/shaders/model_lightmap.frag @@ -31,7 +31,7 @@ void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); vec4 emissive = texture2D(emissiveMap, interpolatedTexcoord1.st); - gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb * (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb), mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); - gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); - gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 128.0); + gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); + gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 0.5); + gl_FragData[2] = vec4((vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb), gl_FrontMaterial.shininess / 128.0); } diff --git a/interface/src/renderer/GeometryCache.cpp b/interface/src/renderer/GeometryCache.cpp index c7d8b7fc8a..5ef90732ef 100644 --- a/interface/src/renderer/GeometryCache.cpp +++ b/interface/src/renderer/GeometryCache.cpp @@ -829,10 +829,17 @@ void GeometryReader::run() { return; } try { - QMetaObject::invokeMethod(geometry.data(), "setGeometry", Q_ARG(const FBXGeometry&, + std::string urlname = _url.path().toLower().toStdString(); + FBXGeometry fbxgeo; + if (_url.path().toLower().endsWith(".svo")) { + fbxgeo = readSVO(_reply->readAll()); + } else { + fbxgeo = readFBX(_reply->readAll(), _mapping); + } + QMetaObject::invokeMethod(geometry.data(), "setGeometry", Q_ARG(const FBXGeometry&, fbxgeo)); - _url.path().toLower().endsWith(".svo") ? readSVO(_reply->readAll()) : readFBX(_reply->readAll(), _mapping))); + // _url.path().toLower().endsWith(".svo") ? readSVO(_reply->readAll()) : readFBX(_reply->readAll(), _mapping))); } catch (const QString& error) { qDebug() << "Error reading " << _url << ": " << error; diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index e6dc3ce74e..2e17cc2605 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -2382,12 +2382,10 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod } if (locations->emissiveTextureUnit >= 0) { - assert(locations->emissiveParams >= 0); // we should have the emissiveParams defined in the shader - static float emissiveOffset = 0.1f; - static float emissiveScale = 1.0f; - //GLBATCH(glUniform2f)(locations->emissiveParams, 0.1f, 4.0f); + // assert(locations->emissiveParams >= 0); // we should have the emissiveParams defined in the shader + float emissiveOffset = part.emissiveParams.x; + float emissiveScale = part.emissiveParams.y; GLBATCH(glUniform2f)(locations->emissiveParams, emissiveOffset, emissiveScale); - GLBATCH(glActiveTexture)(GL_TEXTURE0 + locations->emissiveTextureUnit); Texture* emissiveMap = networkPart.emissiveTexture.data(); diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index b54abedc33..fd9190f597 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -1216,6 +1216,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) QHash bumpTextures; QHash specularTextures; QHash emissiveTextures; + QHash ambientTextures; QHash localRotations; QHash xComponents; QHash yComponents; @@ -1707,7 +1708,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) emissiveTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1)); } else if (type.contains("ambient")) { - emissiveTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1)); + ambientTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1)); } else { std::string typenam = type.data(); counter++; @@ -1952,19 +1953,20 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) } FBXTexture emissiveTexture; + glm::vec2 emissiveParams(0.f, 1.f); QString emissiveTextureID = emissiveTextures.value(childID); - if (!emissiveTextureID.isNull()) { - emissiveTexture = getTexture(emissiveTextureID, textureNames, textureFilenames, textureContent, textureParams); - - // FBX files generated by 3DSMax have an intermediate texture parent, apparently - foreach (const QString& childTextureID, childMap.values(diffuseTextureID)) { - if (textureFilenames.contains(childTextureID)) { - emissiveTexture = getTexture(emissiveTextureID, textureNames, textureFilenames, textureContent, textureParams); - } + QString ambientTextureID = ambientTextures.value(childID); + if (!emissiveTextureID.isNull() || !ambientTextureID.isNull()) { + + if (!emissiveTextureID.isNull()) { + emissiveTexture = getTexture(emissiveTextureID, textureNames, textureFilenames, textureContent, textureParams); + emissiveParams.y = 4.0f; + } else if (!ambientTextureID.isNull()) { + emissiveTexture = getTexture(ambientTextureID, textureNames, textureFilenames, textureContent, textureParams); } emissiveTexture.texcoordSet = matchTextureUVSetToAttributeChannel(emissiveTexture.texcoordSetName, extracted.texcoordSetMap); - + detectDifferentUVs |= (emissiveTexture.texcoordSet != 0) || (!emissiveTexture.transform.isIdentity()); } @@ -1992,6 +1994,8 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) if (!emissiveTexture.filename.isNull()) { part.emissiveTexture = emissiveTexture; } + part.emissiveParams = emissiveParams; + part.materialID = material.id; } } diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index 60e8ea2448..d92f787050 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -119,6 +119,7 @@ public: glm::vec3 diffuseColor; glm::vec3 specularColor; glm::vec3 emissiveColor; + glm::vec2 emissiveParams; float shininess; float opacity; From ff4d28abebb34dfda671506f5d70ea21025fc867 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 25 Nov 2014 18:27:49 -0800 Subject: [PATCH 10/57] hack a separate emissive information in the g-buffer --- interface/resources/shaders/directional_light.frag | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/shaders/directional_light.frag b/interface/resources/shaders/directional_light.frag index d4a6f5a28b..906a33ea74 100644 --- a/interface/resources/shaders/directional_light.frag +++ b/interface/resources/shaders/directional_light.frag @@ -47,10 +47,10 @@ void main(void) { // get the normal from the map vec4 normal = normalVal; - if (normalVal.a == 0.5) { + if ((normalVal.a >= 0.45) && (normalVal.a <= 0.55)) { normal.a = 1.0; normalVal.a = 0.0; - gl_FragColor = vec4(diffuseVal.rgb * specularColor.rgb, normal.a); + gl_FragColor = vec4(diffuseVal.rgb * specularVal.rgb, 1.0); } else { vec3 normalizedNormal = normalize(normal.xyz * 2.0 - vec3(1.0)); From f111fb2c4b0211a8151356b0ee5d3988dafbaa67 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 25 Nov 2014 20:36:39 -0800 Subject: [PATCH 11/57] added a comment to clarify why getCameraOrientation has an oculus special case --- interface/src/avatar/Head.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index e237d0ae6b..9f59fb38b7 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -273,7 +273,8 @@ void Head::setCorrectedLookAtPosition(glm::vec3 correctedLookAtPosition) { _correctedLookAtPosition = correctedLookAtPosition; } -glm::quat Head::getCameraOrientation () const { +glm::quat Head::getCameraOrientation() const { + // this is used to support driving toward where you're head is looking if (OculusManager::isConnected()) { return getOrientation(); } From e94db7bbc2b12010dfa31e9d0da5b4de603d4d53 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 25 Nov 2014 20:37:13 -0800 Subject: [PATCH 12/57] removed some debug, added a resetSensors() on exit of HMD mode --- interface/src/ui/HMDToolsDialog.cpp | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/interface/src/ui/HMDToolsDialog.cpp b/interface/src/ui/HMDToolsDialog.cpp index 4f4c624065..1e251248c3 100644 --- a/interface/src/ui/HMDToolsDialog.cpp +++ b/interface/src/ui/HMDToolsDialog.cpp @@ -59,32 +59,17 @@ HMDToolsDialog::~HMDToolsDialog() { } void HMDToolsDialog::enterModeClicked(bool checked) { - qDebug() << "enterModeClicked"; - int hmdScreen = OculusManager::getHMDScreen(); - // hack to test... - if (hmdScreen == -1) { - hmdScreen = 0; - } - if (hmdScreen >= 0) { QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle(); _hmdScreen = QGuiApplication::screens()[hmdScreen]; _previousRect = Application::getInstance()->getWindow()->rect(); - qDebug() << "_previousRect:" << _previousRect; _previousRect = QRect(mainWindow->mapToGlobal(_previousRect.topLeft()), mainWindow->mapToGlobal(_previousRect.bottomRight())); - qDebug() << "after mapping... _previousRect:" << _previousRect; - _previousScreen = mainWindow->screen(); - qDebug() << "_previousScreen:" << _previousScreen; - QRect rect = QApplication::desktop()->screenGeometry(hmdScreen); - - qDebug() << "about to move to:" << rect.topLeft(); - mainWindow->setScreen(_hmdScreen); mainWindow->setGeometry(rect); @@ -98,20 +83,14 @@ void HMDToolsDialog::enterModeClicked(bool checked) { } void HMDToolsDialog::activateWindowAfterEnterMode() { - qDebug() << "activateWindowAfterEnterMode"; Application::getInstance()->getWindow()->activateWindow(); - QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle(); QPoint windowCenter = mainWindow->geometry().center(); - //QPoint desktopCenter = mainWindow->mapToGlobal(windowCenter); - qDebug() << "windowCenter:" << windowCenter; QCursor::setPos(_hmdScreen, windowCenter); } void HMDToolsDialog::leaveModeClicked(bool checked) { - qDebug() << "leaveModeClicked"; - Application::getInstance()->setFullscreen(false); Application::getInstance()->setEnableVRMode(false); Application::getInstance()->getWindow()->activateWindow(); @@ -128,11 +107,11 @@ void HMDToolsDialog::leaveModeClicked(bool checked) { } void HMDToolsDialog::moveWindowAfterLeaveMode() { - qDebug() << "moveWindowAfterLeaveMode"; QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle(); mainWindow->setScreen(_previousScreen); mainWindow->setGeometry(_previousRect); Application::getInstance()->getWindow()->activateWindow(); + Application::getInstance()->resetSensors(); } From 53ecf97df2d25a58c502b78c856f5eb849941c64 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 25 Nov 2014 21:58:26 -0800 Subject: [PATCH 13/57] fix broken camera after leaving oculus/hmd mode --- interface/src/Application.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 31b1dd66f6..1a7ccf21ee 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -668,6 +668,8 @@ void Application::paintGL() { // Update camera position if (!OculusManager::isConnected()) { + _myCamera.setHmdPosition(glm::vec3()); + _myCamera.setHmdRotation(glm::quat()); _myCamera.update(1.0f / _fps); } From ee46c781c46ed56313656e7fc8a328a1935d2997 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Nov 2014 08:40:11 -0800 Subject: [PATCH 14/57] expand comment --- interface/src/avatar/Head.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index 9f59fb38b7..660ebfcbb3 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -274,7 +274,11 @@ void Head::setCorrectedLookAtPosition(glm::vec3 correctedLookAtPosition) { } glm::quat Head::getCameraOrientation() const { - // this is used to support driving toward where you're head is looking + // NOTE: Head::getCameraOrientation() is not used for orienting the camera "view" while in Oculus mode, so + // you may wonder why this code is here. This method will be called while in Oculus mode to determine how + // to change the driving direction while in Oculus mode. It is used to support driving toward where you're + // head is looking. Note that in oculus mode, your actual camera view and where your head is looking is not + // always the same. if (OculusManager::isConnected()) { return getOrientation(); } From 821cf46ee99b11545d56a0f83560f0e6d057c1f5 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Nov 2014 09:11:26 -0800 Subject: [PATCH 15/57] don't delete the HMDToolsDialog on hide, keep it around till app exit. --- interface/src/Menu.cpp | 12 +++++++----- interface/src/ui/HMDToolsDialog.cpp | 3 +++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index ac93a71bc0..2c7b4a9efd 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -659,6 +659,10 @@ Menu::Menu() : Menu::~Menu() { bandwidthDetailsClosed(); octreeStatsDetailsClosed(); + if (_hmdToolsDialog) { + delete _hmdToolsDialog; + _hmdToolsDialog = NULL; + } } void Menu::loadSettings(QSettings* settings) { @@ -1606,8 +1610,8 @@ void Menu::hmdTools(bool showTools) { if (!_hmdToolsDialog) { _hmdToolsDialog = new HMDToolsDialog(Application::getInstance()->getGLWidget()); connect(_hmdToolsDialog, SIGNAL(closed()), SLOT(hmdToolsClosed())); - _hmdToolsDialog->show(); } + _hmdToolsDialog->show(); _hmdToolsDialog->raise(); } else { hmdToolsClosed(); @@ -1616,10 +1620,8 @@ void Menu::hmdTools(bool showTools) { } void Menu::hmdToolsClosed() { - if (_hmdToolsDialog) { - delete _hmdToolsDialog; - _hmdToolsDialog = NULL; - } + Menu::getInstance()->getActionForOption(MenuOption::HMDTools)->setChecked(false); + _hmdToolsDialog->hide(); } void Menu::cycleFrustumRenderMode() { diff --git a/interface/src/ui/HMDToolsDialog.cpp b/interface/src/ui/HMDToolsDialog.cpp index 1e251248c3..3cbbb5daf2 100644 --- a/interface/src/ui/HMDToolsDialog.cpp +++ b/interface/src/ui/HMDToolsDialog.cpp @@ -123,6 +123,9 @@ void HMDToolsDialog::reject() { void HMDToolsDialog::closeEvent(QCloseEvent* event) { this->QDialog::closeEvent(event); emit closed(); + + // TODO: consider if we want to prevent closing of this window + //event->ignore(); } From 59eeeb90067462a0fbd94976de15fab2f4034c51 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Nov 2014 10:11:29 -0800 Subject: [PATCH 16/57] add debug details to HMDTools --- interface/src/ui/HMDToolsDialog.cpp | 43 ++++++++++++++++++++++++++--- interface/src/ui/HMDToolsDialog.h | 4 +++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/interface/src/ui/HMDToolsDialog.cpp b/interface/src/ui/HMDToolsDialog.cpp index 3cbbb5daf2..80fb6a93d6 100644 --- a/interface/src/ui/HMDToolsDialog.cpp +++ b/interface/src/ui/HMDToolsDialog.cpp @@ -44,20 +44,52 @@ HMDToolsDialog::HMDToolsDialog(QWidget* parent) : form->addRow("", leaveModeButton); connect(leaveModeButton,SIGNAL(clicked(bool)),this,SLOT(leaveModeClicked(bool))); + // Create a label with debug details... + _debugDetails = new QLabel(); + _debugDetails->setText(getDebugDetails()); + const int WIDTH = 350; + const int HEIGHT = 100; + _debugDetails->setFixedSize(WIDTH, HEIGHT); + form->addRow("", _debugDetails); + this->QDialog::setLayout(form); - _wasMoved = false; - _previousRect = Application::getInstance()->getWindow()->rect(); - - Application::getInstance()->getWindow()->activateWindow(); + + QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle(); + connect(mainWindow, &QWindow::screenChanged, this, &HMDToolsDialog::applicationWindowScreenChanged); } HMDToolsDialog::~HMDToolsDialog() { } +void HMDToolsDialog::applicationWindowScreenChanged(QScreen* screen) { + _debugDetails->setText(getDebugDetails()); +} + +QString HMDToolsDialog::getDebugDetails() const { + QString results; + + int hmdScreenNumber = OculusManager::getHMDScreen(); + if (hmdScreenNumber > 0) { + results += "HMD Screen: " + QGuiApplication::screens()[hmdScreenNumber]->name() + "\n"; + } else { + results += "HMD Screen Name: Unknown\n"; + } + + int desktopPrimaryScreenNumber = QApplication::desktop()->primaryScreen(); + QScreen* desktopPrimaryScreen = QGuiApplication::screens()[desktopPrimaryScreenNumber]; + results += "Desktop's Primary Screen: " + desktopPrimaryScreen->name() + "\n"; + + results += "Application Primary Screen: " + QGuiApplication::primaryScreen()->name() + "\n"; + QScreen* mainWindowScreen = Application::getInstance()->getWindow()->windowHandle()->screen(); + results += "Application Main Window Screen: " + mainWindowScreen->name() + "\n"; + + return results; +} + void HMDToolsDialog::enterModeClicked(bool checked) { int hmdScreen = OculusManager::getHMDScreen(); @@ -74,6 +106,9 @@ void HMDToolsDialog::enterModeClicked(bool checked) { mainWindow->setGeometry(rect); _wasMoved = true; + } else { + // if we're on a single screen setup, then hide our tools window when entering HMD mode + hide(); } Application::getInstance()->setFullscreen(true); Application::getInstance()->setEnableVRMode(true); diff --git a/interface/src/ui/HMDToolsDialog.h b/interface/src/ui/HMDToolsDialog.h index 9620a0529d..c2a36f5a30 100644 --- a/interface/src/ui/HMDToolsDialog.h +++ b/interface/src/ui/HMDToolsDialog.h @@ -20,6 +20,8 @@ public: // Sets up the UI HMDToolsDialog(QWidget* parent); ~HMDToolsDialog(); + + QString getDebugDetails() const; signals: void closed(); @@ -30,6 +32,7 @@ public slots: void leaveModeClicked(bool checked); void activateWindowAfterEnterMode(); void moveWindowAfterLeaveMode(); + void applicationWindowScreenChanged(QScreen* screen); protected: // Emits a 'closed' signal when this dialog is closed. @@ -40,6 +43,7 @@ private: QRect _previousRect; QScreen* _previousScreen; QScreen* _hmdScreen; + QLabel* _debugDetails; }; #endif // hifi_HMDToolsDialog_h From c58061792198f2693578edb456ba2e45b9b38776 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Nov 2014 10:23:44 -0800 Subject: [PATCH 17/57] better mirrored monitor support --- interface/src/ui/HMDToolsDialog.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/interface/src/ui/HMDToolsDialog.cpp b/interface/src/ui/HMDToolsDialog.cpp index 80fb6a93d6..70d5d836fc 100644 --- a/interface/src/ui/HMDToolsDialog.cpp +++ b/interface/src/ui/HMDToolsDialog.cpp @@ -73,7 +73,7 @@ QString HMDToolsDialog::getDebugDetails() const { QString results; int hmdScreenNumber = OculusManager::getHMDScreen(); - if (hmdScreenNumber > 0) { + if (hmdScreenNumber >= 0) { results += "HMD Screen: " + QGuiApplication::screens()[hmdScreenNumber]->name() + "\n"; } else { results += "HMD Screen Name: Unknown\n"; @@ -91,7 +91,10 @@ QString HMDToolsDialog::getDebugDetails() const { } void HMDToolsDialog::enterModeClicked(bool checked) { + _debugDetails->setText(getDebugDetails()); + int hmdScreen = OculusManager::getHMDScreen(); + qDebug() << "enterModeClicked().... hmdScreen:" << hmdScreen; if (hmdScreen >= 0) { QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle(); @@ -106,10 +109,14 @@ void HMDToolsDialog::enterModeClicked(bool checked) { mainWindow->setGeometry(rect); _wasMoved = true; - } else { - // if we're on a single screen setup, then hide our tools window when entering HMD mode - hide(); } + + + // if we're on a single screen setup, then hide our tools window when entering HMD mode + if (QApplication::desktop()->screenCount() == 1) { + close(); + } + Application::getInstance()->setFullscreen(true); Application::getInstance()->setEnableVRMode(true); @@ -126,6 +133,8 @@ void HMDToolsDialog::activateWindowAfterEnterMode() { void HMDToolsDialog::leaveModeClicked(bool checked) { + _debugDetails->setText(getDebugDetails()); + Application::getInstance()->setFullscreen(false); Application::getInstance()->setEnableVRMode(false); Application::getInstance()->getWindow()->activateWindow(); @@ -152,15 +161,13 @@ void HMDToolsDialog::moveWindowAfterLeaveMode() { void HMDToolsDialog::reject() { // Just regularly close upon ESC - this->QDialog::close(); + close(); } void HMDToolsDialog::closeEvent(QCloseEvent* event) { + // TODO: consider if we want to prevent closing of this window with event->ignore(); this->QDialog::closeEvent(event); emit closed(); - - // TODO: consider if we want to prevent closing of this window - //event->ignore(); } From ad6680553c643bbb9f7d2b9d3c53127e09667e9a Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Nov 2014 10:46:47 -0800 Subject: [PATCH 18/57] snap cursor to center of HMD tools dialog when shown, or app when the dialog is hidden --- interface/src/ui/HMDToolsDialog.cpp | 15 +++++++++++++++ interface/src/ui/HMDToolsDialog.h | 7 +++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/HMDToolsDialog.cpp b/interface/src/ui/HMDToolsDialog.cpp index 70d5d836fc..141b0d61ad 100644 --- a/interface/src/ui/HMDToolsDialog.cpp +++ b/interface/src/ui/HMDToolsDialog.cpp @@ -170,4 +170,19 @@ void HMDToolsDialog::closeEvent(QCloseEvent* event) { emit closed(); } +void HMDToolsDialog::centerCursorOnWidget(QWidget* widget) { + QWindow* window = widget->windowHandle(); + QScreen* screen = window->screen(); + QPoint windowCenter = window->geometry().center(); + QCursor::setPos(screen, windowCenter); +} + +void HMDToolsDialog::showEvent(QShowEvent* event) { + centerCursorOnWidget(this); +} + +void HMDToolsDialog::hideEvent(QHideEvent* event) { + centerCursorOnWidget(Application::getInstance()->getWindow()); +} + diff --git a/interface/src/ui/HMDToolsDialog.h b/interface/src/ui/HMDToolsDialog.h index c2a36f5a30..f1a5f582cd 100644 --- a/interface/src/ui/HMDToolsDialog.h +++ b/interface/src/ui/HMDToolsDialog.h @@ -35,10 +35,13 @@ public slots: void applicationWindowScreenChanged(QScreen* screen); protected: - // Emits a 'closed' signal when this dialog is closed. - void closeEvent(QCloseEvent*); + virtual void closeEvent(QCloseEvent*); // Emits a 'closed' signal when this dialog is closed. + virtual void showEvent(QShowEvent* event); + virtual void hideEvent(QHideEvent* event); private: + void centerCursorOnWidget(QWidget* widget); + bool _wasMoved; QRect _previousRect; QScreen* _previousScreen; From 0c5a97841185dd5db6728116db07f86c96a84a89 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Nov 2014 10:53:38 -0800 Subject: [PATCH 19/57] fix crash in activateWindowAfterEnterMode in no oculus case --- interface/src/ui/HMDToolsDialog.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/interface/src/ui/HMDToolsDialog.cpp b/interface/src/ui/HMDToolsDialog.cpp index 141b0d61ad..9a409b17f1 100644 --- a/interface/src/ui/HMDToolsDialog.cpp +++ b/interface/src/ui/HMDToolsDialog.cpp @@ -126,9 +126,9 @@ void HMDToolsDialog::enterModeClicked(bool checked) { void HMDToolsDialog::activateWindowAfterEnterMode() { Application::getInstance()->getWindow()->activateWindow(); - QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle(); - QPoint windowCenter = mainWindow->geometry().center(); - QCursor::setPos(_hmdScreen, windowCenter); + + // center the cursor on the main application window + centerCursorOnWidget(Application::getInstance()->getWindow()); } @@ -178,10 +178,12 @@ void HMDToolsDialog::centerCursorOnWidget(QWidget* widget) { } void HMDToolsDialog::showEvent(QShowEvent* event) { + // center the cursor on the hmd tools dialog centerCursorOnWidget(this); } void HMDToolsDialog::hideEvent(QHideEvent* event) { + // center the cursor on the main application window centerCursorOnWidget(Application::getInstance()->getWindow()); } From 5f58c76842879b8b15e6f8c3a317a45b82c82df1 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 26 Nov 2014 12:03:10 -0800 Subject: [PATCH 20/57] Fix hands being put in face if Leap on HMD is set but Leap not connected The joints were reporting themselves as "active" even though the Leap wasn't connected, both at startup if not connected and after unplugging. --- interface/src/devices/Leapmotion.cpp | 18 +++++++++++------- interface/src/devices/MotionTracker.cpp | 4 ++-- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/interface/src/devices/Leapmotion.cpp b/interface/src/devices/Leapmotion.cpp index 62037ae7f6..6a47eadb96 100644 --- a/interface/src/devices/Leapmotion.cpp +++ b/interface/src/devices/Leapmotion.cpp @@ -135,16 +135,20 @@ glm::vec3 vec3FromLeapVector(const Leap::Vector& vec) { void Leapmotion::update() { #ifdef HAVE_LEAPMOTION - // Check that the controller is actually active + bool wasActive = _active; _active = _controller.isConnected(); - if (!_active) { - return; + + if (_active || wasActive) { + // Go through all the joints and increment their counter since last update. + // Increment all counters once after controller first becomes inactive so that each joint reports itself as inactive. + // TODO C++11 for (auto jointIt = _jointsArray.begin(); jointIt != _jointsArray.end(); jointIt++) { + for (JointTracker::Vector::iterator jointIt = _jointsArray.begin(); jointIt != _jointsArray.end(); jointIt++) { + (*jointIt).tickNewFrame(); + } } - // go through all the joints and increment their counter since last update - // TODO C++11 for (auto jointIt = _jointsArray.begin(); jointIt != _jointsArray.end(); jointIt++) { - for (JointTracker::Vector::iterator jointIt = _jointsArray.begin(); jointIt != _jointsArray.end(); jointIt++) { - (*jointIt).tickNewFrame(); + if (!_active) { + return; } // Get the most recent frame and report some basic information diff --git a/interface/src/devices/MotionTracker.cpp b/interface/src/devices/MotionTracker.cpp index 6b81c94f82..d5272888e7 100644 --- a/interface/src/devices/MotionTracker.cpp +++ b/interface/src/devices/MotionTracker.cpp @@ -119,14 +119,14 @@ MotionTracker::JointTracker::JointTracker() : _absFrame(), _semantic(""), _parent(INVALID_PARENT), - _lastUpdate(0) + _lastUpdate(1) // Joint inactive { } MotionTracker::JointTracker::JointTracker(const Semantic& semantic, Index parent) : _semantic(semantic), _parent(parent), - _lastUpdate(0) + _lastUpdate(1) // Joint inactive { } From 5871ecd85cc72997d17f16a08aab9ea600af2b12 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 26 Nov 2014 12:03:27 -0800 Subject: [PATCH 21/57] Stop incrementing counter after limit reached --- examples/leapHands.js | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/examples/leapHands.js b/examples/leapHands.js index 04253c8ab6..6bdca051be 100644 --- a/examples/leapHands.js +++ b/examples/leapHands.js @@ -471,17 +471,20 @@ var leapHands = (function () { } else { - hands[h].inactiveCount += 1; + if (hands[h].inactiveCount < MAX_HAND_INACTIVE_COUNT) { - if (hands[h].inactiveCount === MAX_HAND_INACTIVE_COUNT) { - if (h === 0) { - MyAvatar.clearJointData("LeftHand"); - MyAvatar.clearJointData("LeftForeArm"); - MyAvatar.clearJointData("LeftArm"); - } else { - MyAvatar.clearJointData("RightHand"); - MyAvatar.clearJointData("RightForeArm"); - MyAvatar.clearJointData("RightArm"); + hands[h].inactiveCount += 1; + + if (hands[h].inactiveCount === MAX_HAND_INACTIVE_COUNT) { + if (h === 0) { + MyAvatar.clearJointData("LeftHand"); + MyAvatar.clearJointData("LeftForeArm"); + MyAvatar.clearJointData("LeftArm"); + } else { + MyAvatar.clearJointData("RightHand"); + MyAvatar.clearJointData("RightForeArm"); + MyAvatar.clearJointData("RightArm"); + } } } } From 208eb663bddb8a8bda402263a72a24fd7dba6202 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Nov 2014 12:07:39 -0800 Subject: [PATCH 22/57] prevent HMD tools from being moved to HMD screen --- interface/src/ui/HMDToolsDialog.cpp | 70 ++++++++++++++++++++++++++++- interface/src/ui/HMDToolsDialog.h | 5 +++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/HMDToolsDialog.cpp b/interface/src/ui/HMDToolsDialog.cpp index 9a409b17f1..a5e54fa546 100644 --- a/interface/src/ui/HMDToolsDialog.cpp +++ b/interface/src/ui/HMDToolsDialog.cpp @@ -27,7 +27,10 @@ HMDToolsDialog::HMDToolsDialog(QWidget* parent) : - QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint) + QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint) , + _previousScreen(NULL), + _hmdScreen(NULL), + _previousDialogScreen(NULL) { this->setWindowTitle("HMD Tools"); @@ -58,8 +61,18 @@ HMDToolsDialog::HMDToolsDialog(QWidget* parent) : _previousRect = Application::getInstance()->getWindow()->rect(); Application::getInstance()->getWindow()->activateWindow(); + // watch for our application window moving screens. If it does we want to update our screen details QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle(); connect(mainWindow, &QWindow::screenChanged, this, &HMDToolsDialog::applicationWindowScreenChanged); + + // watch for our dialog window moving screens. If it does we want to enforce our rules about what screens we're + // allowed on + QWindow* dialogWindow = windowHandle(); + connect(dialogWindow, &QWindow::screenChanged, this, &HMDToolsDialog::dialogWindowScreenChanged); + connect(dialogWindow, &QWindow::xChanged, this, &HMDToolsDialog::dialogWindowGeometryChanged); + connect(dialogWindow, &QWindow::yChanged, this, &HMDToolsDialog::dialogWindowGeometryChanged); + connect(dialogWindow, &QWindow::widthChanged, this, &HMDToolsDialog::dialogWindowGeometryChanged); + connect(dialogWindow, &QWindow::heightChanged, this, &HMDToolsDialog::dialogWindowGeometryChanged); } HMDToolsDialog::~HMDToolsDialog() { @@ -69,6 +82,61 @@ void HMDToolsDialog::applicationWindowScreenChanged(QScreen* screen) { _debugDetails->setText(getDebugDetails()); } +void HMDToolsDialog::dialogWindowGeometryChanged(int arg) { + QWindow* dialogWindow = windowHandle(); + _previousDialogRect = rect(); + _previousDialogRect = QRect(dialogWindow->mapToGlobal(_previousDialogRect.topLeft()), + dialogWindow->mapToGlobal(_previousDialogRect.bottomRight())); + _previousDialogScreen = dialogWindow->screen(); +} + +void HMDToolsDialog::dialogWindowScreenChanged(QScreen* screen) { + _debugDetails->setText(getDebugDetails()); + + // if we have more than one screen, and a known hmdScreen then try to + // keep our dialog off of the hmdScreen + if (QApplication::desktop()->screenCount() > 1) { + int hmdScreenNumber = OculusManager::getHMDScreen(); + + if (hmdScreenNumber >= 0) { + QScreen* hmdScreen = QGuiApplication::screens()[hmdScreenNumber]; + + if (screen == hmdScreen) { + qDebug() << "HMD Tools: Whoa! What are you doing? You don't want to move me to the HMD Screen!"; + QWindow* dialogWindow = windowHandle(); + + // try to pick a better screen + QScreen* betterScreen = NULL; + + QWindow* appWindow = Application::getInstance()->getWindow()->windowHandle(); + QScreen* appScreen = appWindow->screen(); + + if (_previousDialogScreen && _previousDialogScreen != hmdScreen) { + // first, if the previous dialog screen is not the HMD screen, then move it there. + betterScreen = appScreen; + } else if (appScreen != hmdScreen) { + // second, if the application screen is not the HMD screen, then move it there. + betterScreen = appScreen; + } else if (_previousScreen && _previousScreen != hmdScreen) { + // third, if the application screen is the HMD screen, we want to move it to + // the previous screen + betterScreen = _previousScreen; + } else { + // last, if we can't use the previous screen the use the primary desktop screen + int desktopPrimaryScreenNumber = QApplication::desktop()->primaryScreen(); + QScreen* desktopPrimaryScreen = QGuiApplication::screens()[desktopPrimaryScreenNumber]; + betterScreen = desktopPrimaryScreen; + } + + if (betterScreen) { + dialogWindow->setScreen(betterScreen); + dialogWindow->setGeometry(_previousDialogRect); + } + } + } + } +} + QString HMDToolsDialog::getDebugDetails() const { QString results; diff --git a/interface/src/ui/HMDToolsDialog.h b/interface/src/ui/HMDToolsDialog.h index f1a5f582cd..4fe0dd626f 100644 --- a/interface/src/ui/HMDToolsDialog.h +++ b/interface/src/ui/HMDToolsDialog.h @@ -33,6 +33,8 @@ public slots: void activateWindowAfterEnterMode(); void moveWindowAfterLeaveMode(); void applicationWindowScreenChanged(QScreen* screen); + void dialogWindowScreenChanged(QScreen* screen); + void dialogWindowGeometryChanged(int arg); protected: virtual void closeEvent(QCloseEvent*); // Emits a 'closed' signal when this dialog is closed. @@ -47,6 +49,9 @@ private: QScreen* _previousScreen; QScreen* _hmdScreen; QLabel* _debugDetails; + + QRect _previousDialogRect; + QScreen* _previousDialogScreen; }; #endif // hifi_HMDToolsDialog_h From 2fc3fdc7e6c717f36c8ff6e7426fd6f2f1b65702 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Nov 2014 12:26:02 -0800 Subject: [PATCH 23/57] improve how cameras are reset when leaving vr mode --- interface/src/Application.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1a7ccf21ee..397f883b3e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -668,8 +668,6 @@ void Application::paintGL() { // Update camera position if (!OculusManager::isConnected()) { - _myCamera.setHmdPosition(glm::vec3()); - _myCamera.setHmdRotation(glm::quat()); _myCamera.update(1.0f / _fps); } @@ -1606,6 +1604,11 @@ void Application::setEnableVRMode(bool enableVRMode) { OculusManager::recalibrate(); } else { OculusManager::abandonCalibration(); + + _mirrorCamera.setHmdPosition(glm::vec3()); + _mirrorCamera.setHmdRotation(glm::quat()); + _myCamera.setHmdPosition(glm::vec3()); + _myCamera.setHmdRotation(glm::quat()); } resizeGL(_glWidget->getDeviceWidth(), _glWidget->getDeviceHeight()); From 711f9f69058ca26e1a47602c959c9a72a49e60df Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Nov 2014 12:34:47 -0800 Subject: [PATCH 24/57] fix bug where audio meter is incorrectly offset when in oculus mode --- interface/src/ui/ApplicationOverlay.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 55d4cf7c8b..1307672ad1 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -984,7 +984,8 @@ void ApplicationOverlay::renderAudioMeter() { const int AUDIO_METER_X = MIRROR_VIEW_LEFT_PADDING + MUTE_ICON_SIZE + AUDIO_METER_INSET + AUDIO_METER_GAP; int audioMeterY; - bool boxed = Menu::getInstance()->isOptionChecked(MenuOption::Mirror) && + bool smallMirrorVisible = Menu::getInstance()->isOptionChecked(MenuOption::Mirror) && !OculusManager::isConnected(); + bool boxed = smallMirrorVisible && !Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror); if (boxed) { audioMeterY = MIRROR_VIEW_HEIGHT + AUDIO_METER_GAP + MUTE_ICON_PADDING; From fe9fab68bfd6ea1c94d48a16bb5c29d09af4ff78 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Nov 2014 17:30:59 -0800 Subject: [PATCH 25/57] don't exit app in full screen or hdm mode --- interface/src/Application.cpp | 1 + interface/src/ui/HMDToolsDialog.cpp | 103 ++++++++++++++++++---------- interface/src/ui/HMDToolsDialog.h | 4 ++ 3 files changed, 70 insertions(+), 38 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 397f883b3e..6791ae3d62 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -438,6 +438,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : void Application::aboutToQuit() { _aboutToQuit = true; + setFullscreen(false); // if you exit while in full screen, you'll get bad behavior when you restart. } Application::~Application() { diff --git a/interface/src/ui/HMDToolsDialog.cpp b/interface/src/ui/HMDToolsDialog.cpp index a5e54fa546..f2be62a026 100644 --- a/interface/src/ui/HMDToolsDialog.cpp +++ b/interface/src/ui/HMDToolsDialog.cpp @@ -30,7 +30,8 @@ HMDToolsDialog::HMDToolsDialog(QWidget* parent) : QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint) , _previousScreen(NULL), _hmdScreen(NULL), - _previousDialogScreen(NULL) + _previousDialogScreen(NULL), + _inHDMMode(false) { this->setWindowTitle("HMD Tools"); @@ -65,14 +66,18 @@ HMDToolsDialog::HMDToolsDialog(QWidget* parent) : QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle(); connect(mainWindow, &QWindow::screenChanged, this, &HMDToolsDialog::applicationWindowScreenChanged); - // watch for our dialog window moving screens. If it does we want to enforce our rules about what screens we're - // allowed on + // watch for our dialog window moving screens. If it does we want to enforce our rules about + // what screens we're allowed on QWindow* dialogWindow = windowHandle(); connect(dialogWindow, &QWindow::screenChanged, this, &HMDToolsDialog::dialogWindowScreenChanged); connect(dialogWindow, &QWindow::xChanged, this, &HMDToolsDialog::dialogWindowGeometryChanged); connect(dialogWindow, &QWindow::yChanged, this, &HMDToolsDialog::dialogWindowGeometryChanged); connect(dialogWindow, &QWindow::widthChanged, this, &HMDToolsDialog::dialogWindowGeometryChanged); connect(dialogWindow, &QWindow::heightChanged, this, &HMDToolsDialog::dialogWindowGeometryChanged); + + // when the application is about to quit, leave HDM mode + connect(Application::getInstance(), SIGNAL(aboutToQuit()), this, SLOT(aboutToQuit())); + } HMDToolsDialog::~HMDToolsDialog() { @@ -159,37 +164,45 @@ QString HMDToolsDialog::getDebugDetails() const { } void HMDToolsDialog::enterModeClicked(bool checked) { - _debugDetails->setText(getDebugDetails()); + enterHDMMode(); +} - int hmdScreen = OculusManager::getHMDScreen(); - qDebug() << "enterModeClicked().... hmdScreen:" << hmdScreen; +void HMDToolsDialog::enterHDMMode() { + if (!_inHDMMode) { + _debugDetails->setText(getDebugDetails()); + + int hmdScreen = OculusManager::getHMDScreen(); + qDebug() << "enterModeClicked().... hmdScreen:" << hmdScreen; - if (hmdScreen >= 0) { - QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle(); - _hmdScreen = QGuiApplication::screens()[hmdScreen]; + if (hmdScreen >= 0) { + QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle(); + _hmdScreen = QGuiApplication::screens()[hmdScreen]; - _previousRect = Application::getInstance()->getWindow()->rect(); - _previousRect = QRect(mainWindow->mapToGlobal(_previousRect.topLeft()), - mainWindow->mapToGlobal(_previousRect.bottomRight())); - _previousScreen = mainWindow->screen(); - QRect rect = QApplication::desktop()->screenGeometry(hmdScreen); - mainWindow->setScreen(_hmdScreen); - mainWindow->setGeometry(rect); + _previousRect = Application::getInstance()->getWindow()->rect(); + _previousRect = QRect(mainWindow->mapToGlobal(_previousRect.topLeft()), + mainWindow->mapToGlobal(_previousRect.bottomRight())); + _previousScreen = mainWindow->screen(); + QRect rect = QApplication::desktop()->screenGeometry(hmdScreen); + mainWindow->setScreen(_hmdScreen); + mainWindow->setGeometry(rect); - _wasMoved = true; - } + _wasMoved = true; + } - // if we're on a single screen setup, then hide our tools window when entering HMD mode - if (QApplication::desktop()->screenCount() == 1) { - close(); - } + // if we're on a single screen setup, then hide our tools window when entering HMD mode + if (QApplication::desktop()->screenCount() == 1) { + close(); + } - Application::getInstance()->setFullscreen(true); - Application::getInstance()->setEnableVRMode(true); + Application::getInstance()->setFullscreen(true); + Application::getInstance()->setEnableVRMode(true); - const int SLIGHT_DELAY = 500; - QTimer::singleShot(SLIGHT_DELAY, this, SLOT(activateWindowAfterEnterMode())); + const int SLIGHT_DELAY = 500; + QTimer::singleShot(SLIGHT_DELAY, this, SLOT(activateWindowAfterEnterMode())); + + _inHDMMode = true; + } } void HMDToolsDialog::activateWindowAfterEnterMode() { @@ -199,23 +212,30 @@ void HMDToolsDialog::activateWindowAfterEnterMode() { centerCursorOnWidget(Application::getInstance()->getWindow()); } - void HMDToolsDialog::leaveModeClicked(bool checked) { - _debugDetails->setText(getDebugDetails()); + leaveHDMMode(); +} - Application::getInstance()->setFullscreen(false); - Application::getInstance()->setEnableVRMode(false); - Application::getInstance()->getWindow()->activateWindow(); - if (_wasMoved) { - QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle(); - mainWindow->setScreen(_previousScreen); - mainWindow->setGeometry(_previousRect); +void HMDToolsDialog::leaveHDMMode() { + if (_inHDMMode) { + _debugDetails->setText(getDebugDetails()); + + Application::getInstance()->setFullscreen(false); + Application::getInstance()->setEnableVRMode(false); + Application::getInstance()->getWindow()->activateWindow(); + + if (_wasMoved) { + QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle(); + mainWindow->setScreen(_previousScreen); + mainWindow->setGeometry(_previousRect); - const int SLIGHT_DELAY = 1500; - QTimer::singleShot(SLIGHT_DELAY, this, SLOT(moveWindowAfterLeaveMode())); + const int SLIGHT_DELAY = 1500; + QTimer::singleShot(SLIGHT_DELAY, this, SLOT(moveWindowAfterLeaveMode())); + } + _wasMoved = false; + _inHDMMode = false; } - _wasMoved = false; } void HMDToolsDialog::moveWindowAfterLeaveMode() { @@ -256,3 +276,10 @@ void HMDToolsDialog::hideEvent(QHideEvent* event) { } +void HMDToolsDialog::aboutToQuit() { + if (_inHDMMode) { + leaveHDMMode(); + } +} + + diff --git a/interface/src/ui/HMDToolsDialog.h b/interface/src/ui/HMDToolsDialog.h index 4fe0dd626f..d2068d9e82 100644 --- a/interface/src/ui/HMDToolsDialog.h +++ b/interface/src/ui/HMDToolsDialog.h @@ -35,6 +35,7 @@ public slots: void applicationWindowScreenChanged(QScreen* screen); void dialogWindowScreenChanged(QScreen* screen); void dialogWindowGeometryChanged(int arg); + void aboutToQuit(); protected: virtual void closeEvent(QCloseEvent*); // Emits a 'closed' signal when this dialog is closed. @@ -43,6 +44,8 @@ protected: private: void centerCursorOnWidget(QWidget* widget); + void enterHDMMode(); + void leaveHDMMode(); bool _wasMoved; QRect _previousRect; @@ -52,6 +55,7 @@ private: QRect _previousDialogRect; QScreen* _previousDialogScreen; + bool _inHDMMode; }; #endif // hifi_HMDToolsDialog_h From 85ca03199ebafcd8f26091d8c87eb8c107d0413b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Nov 2014 17:53:41 -0800 Subject: [PATCH 26/57] remove Entities developer menu items from C++ menu, make them available through script --- examples/developerMenuItems.js | 37 ++++++++++++++++++++++++++++++++++ interface/src/Menu.cpp | 16 --------------- 2 files changed, 37 insertions(+), 16 deletions(-) create mode 100644 examples/developerMenuItems.js diff --git a/examples/developerMenuItems.js b/examples/developerMenuItems.js new file mode 100644 index 0000000000..221975c9c8 --- /dev/null +++ b/examples/developerMenuItems.js @@ -0,0 +1,37 @@ +// +// developerMenuItems.js +// examples +// +// Created by Brad Hefta-Gaub on 2/24/14 +// Copyright 2013 High Fidelity, Inc. +// +// Adds a bunch of developer and debugging menu items +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + + +function setupMenus() { + if (!Menu.menuExists("Developer")) { + Menu.addMenu("Developer"); + } + if (!Menu.menuExists("Developer > Entities")) { + Menu.addMenu("Developer > Entities"); + Menu.addMenuItem({ menuName: "Developer > Entities", menuItemName: "Display Model Bounds", isCheckable: true, isChecked: false }); + Menu.addMenuItem({ menuName: "Developer > Entities", menuItemName: "Display Model Element Bounds", isCheckable: true, isChecked: false }); + Menu.addMenuItem({ menuName: "Developer > Entities", menuItemName: "Display Model Element Children", isCheckable: true, isChecked: false }); + Menu.addMenuItem({ menuName: "Developer > Entities", menuItemName: "Disable Light Entities", isCheckable: true, isChecked: false }); + Menu.addMenuItem({ menuName: "Developer > Entities", menuItemName: "Don't Attempt to Reduce Material Switches", isCheckable: true, isChecked: false }); + Menu.addMenuItem({ menuName: "Developer > Entities", menuItemName: "Don't Attempt Render Entities as Scene", isCheckable: true, isChecked: false }); + Menu.addMenu("Developer > Entities > Culling"); + Menu.addMenuItem({ menuName: "Developer > Entities > Culling", menuItemName: "Don't Cull Out Of View Mesh Parts", isCheckable: true, isChecked: false }); + Menu.addMenuItem({ menuName: "Developer > Entities > Culling", menuItemName: "Don't Cull Too Small Mesh Parts", isCheckable: true, isChecked: false }); + } +} + +function scriptEnding() { + Menu.removeMenu("Developer > Entities"); +} +setupMenus(); +Script.scriptEnding.connect(scriptEnding); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 2c7b4a9efd..6cfb3db35a 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -445,23 +445,7 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderBoundingCollisionShapes); addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderLookAtVectors, 0, false); addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderFocusIndicator, 0, false); - - QMenu* entitiesDebugMenu = developerMenu->addMenu("Entities"); - addCheckableActionToQMenuAndActionHash(entitiesDebugMenu, MenuOption::DisplayModelBounds, 0, false); - addCheckableActionToQMenuAndActionHash(entitiesDebugMenu, MenuOption::DisplayModelElementProxy, 0, false); - addCheckableActionToQMenuAndActionHash(entitiesDebugMenu, MenuOption::DisplayModelElementChildProxies, 0, false); - addCheckableActionToQMenuAndActionHash(entitiesDebugMenu, MenuOption::DisableLightEntities, 0, false); - addCheckableActionToQMenuAndActionHash(entitiesDebugMenu, MenuOption::DontReduceMaterialSwitches, 0, false); - addCheckableActionToQMenuAndActionHash(entitiesDebugMenu, MenuOption::DontRenderEntitiesAsScene, 0, false); - - QMenu* entityCullingMenu = entitiesDebugMenu->addMenu("Culling"); - addCheckableActionToQMenuAndActionHash(entityCullingMenu, MenuOption::DontCullOutOfViewMeshParts, 0, false); - addCheckableActionToQMenuAndActionHash(entityCullingMenu, MenuOption::DontCullTooSmallMeshParts, 0, false); - - - - QMenu* voxelOptionsMenu = developerMenu->addMenu("Voxels"); addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelTextures); addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::AmbientOcclusion); From 184acaedefa7e5ff8b7aecb520529ec8f982dc7e Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Nov 2014 19:43:01 -0800 Subject: [PATCH 27/57] switch to single button for mode switching --- interface/src/ui/HMDToolsDialog.cpp | 31 ++++++++++++++--------------- interface/src/ui/HMDToolsDialog.h | 4 ++-- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/interface/src/ui/HMDToolsDialog.cpp b/interface/src/ui/HMDToolsDialog.cpp index f2be62a026..d7cb5b4756 100644 --- a/interface/src/ui/HMDToolsDialog.cpp +++ b/interface/src/ui/HMDToolsDialog.cpp @@ -28,6 +28,8 @@ HMDToolsDialog::HMDToolsDialog(QWidget* parent) : QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint) , + _switchModeButton(NULL), + _debugDetails(NULL), _previousScreen(NULL), _hmdScreen(NULL), _previousDialogScreen(NULL), @@ -37,21 +39,17 @@ HMDToolsDialog::HMDToolsDialog(QWidget* parent) : // Create layouter QFormLayout* form = new QFormLayout(); + const int WIDTH = 350; // Add a button to enter - QPushButton* enterModeButton = new QPushButton("Enter HMD Mode"); - form->addRow("", enterModeButton); - connect(enterModeButton,SIGNAL(clicked(bool)),this,SLOT(enterModeClicked(bool))); - - // Add a button to leave - QPushButton* leaveModeButton = new QPushButton("Leave HMD Mode"); - form->addRow("", leaveModeButton); - connect(leaveModeButton,SIGNAL(clicked(bool)),this,SLOT(leaveModeClicked(bool))); + _switchModeButton = new QPushButton("Enter HMD Mode"); + _switchModeButton->setFixedWidth(WIDTH); + form->addRow("", _switchModeButton); + connect(_switchModeButton,SIGNAL(clicked(bool)),this,SLOT(switchModeClicked(bool))); // Create a label with debug details... _debugDetails = new QLabel(); _debugDetails->setText(getDebugDetails()); - const int WIDTH = 350; const int HEIGHT = 100; _debugDetails->setFixedSize(WIDTH, HEIGHT); form->addRow("", _debugDetails); @@ -163,12 +161,17 @@ QString HMDToolsDialog::getDebugDetails() const { return results; } -void HMDToolsDialog::enterModeClicked(bool checked) { - enterHDMMode(); +void HMDToolsDialog::switchModeClicked(bool checked) { + if (!_inHDMMode) { + enterHDMMode(); + } else { + leaveHDMMode(); + } } void HMDToolsDialog::enterHDMMode() { if (!_inHDMMode) { + _switchModeButton->setText("Leave HMD Mode"); _debugDetails->setText(getDebugDetails()); int hmdScreen = OculusManager::getHMDScreen(); @@ -212,13 +215,9 @@ void HMDToolsDialog::activateWindowAfterEnterMode() { centerCursorOnWidget(Application::getInstance()->getWindow()); } -void HMDToolsDialog::leaveModeClicked(bool checked) { - leaveHDMMode(); -} - - void HMDToolsDialog::leaveHDMMode() { if (_inHDMMode) { + _switchModeButton->setText("Enter HMD Mode"); _debugDetails->setText(getDebugDetails()); Application::getInstance()->setFullscreen(false); diff --git a/interface/src/ui/HMDToolsDialog.h b/interface/src/ui/HMDToolsDialog.h index d2068d9e82..91db300224 100644 --- a/interface/src/ui/HMDToolsDialog.h +++ b/interface/src/ui/HMDToolsDialog.h @@ -28,8 +28,7 @@ signals: public slots: void reject(); - void enterModeClicked(bool checked); - void leaveModeClicked(bool checked); + void switchModeClicked(bool checked); void activateWindowAfterEnterMode(); void moveWindowAfterLeaveMode(); void applicationWindowScreenChanged(QScreen* screen); @@ -51,6 +50,7 @@ private: QRect _previousRect; QScreen* _previousScreen; QScreen* _hmdScreen; + QPushButton* _switchModeButton; QLabel* _debugDetails; QRect _previousDialogRect; From 39042f61cd8a535d0afb7e87e2110230d8824508 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 26 Nov 2014 19:57:18 -0800 Subject: [PATCH 28/57] 1P mirror can lean fwd/back --- interface/src/Application.cpp | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 58b28fcef9..a1f374c3c6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -650,20 +650,11 @@ void Application::paintGL() { } } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { - //Only behave like a true mirror when in the OR - if (OculusManager::isConnected()) { - _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); - _myCamera.setPosition(_myAvatar->getHead()->getEyePosition() + - glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) + - (_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * - glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); - } else { - _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); - _myCamera.setPosition(_myAvatar->getHead()->getEyePosition() + - glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) + - (_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * - glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); - } + _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); + _myCamera.setPosition(_myAvatar->getDefaultEyePosition() + + glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) + + (_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * + glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); } // Update camera position From fe010b685a6a9ccf71348986ce85e5605ba145c5 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 26 Nov 2014 20:19:23 -0800 Subject: [PATCH 29/57] more HMD Tools improvements, better support for detecting adding/removing screens --- interface/src/ui/HMDToolsDialog.cpp | 47 ++++++++++++++++++++++------- interface/src/ui/HMDToolsDialog.h | 6 ++-- 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/interface/src/ui/HMDToolsDialog.cpp b/interface/src/ui/HMDToolsDialog.cpp index d7cb5b4756..88924f68d1 100644 --- a/interface/src/ui/HMDToolsDialog.cpp +++ b/interface/src/ui/HMDToolsDialog.cpp @@ -28,10 +28,11 @@ HMDToolsDialog::HMDToolsDialog(QWidget* parent) : QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint) , - _switchModeButton(NULL), - _debugDetails(NULL), _previousScreen(NULL), _hmdScreen(NULL), + _hmdScreenNumber(-1), + _switchModeButton(NULL), + _debugDetails(NULL), _previousDialogScreen(NULL), _inHDMMode(false) { @@ -75,6 +76,9 @@ HMDToolsDialog::HMDToolsDialog(QWidget* parent) : // when the application is about to quit, leave HDM mode connect(Application::getInstance(), SIGNAL(aboutToQuit()), this, SLOT(aboutToQuit())); + + // keep track of changes to the number of screens + connect(QApplication::desktop(), &QDesktopWidget::screenCountChanged, this, &HMDToolsDialog::screenCountChanged); } @@ -99,11 +103,11 @@ void HMDToolsDialog::dialogWindowScreenChanged(QScreen* screen) { // if we have more than one screen, and a known hmdScreen then try to // keep our dialog off of the hmdScreen if (QApplication::desktop()->screenCount() > 1) { - int hmdScreenNumber = OculusManager::getHMDScreen(); - - if (hmdScreenNumber >= 0) { - QScreen* hmdScreen = QGuiApplication::screens()[hmdScreenNumber]; + // we want to use a local variable here because we are not necesarily in HMD mode + int hmdScreenNumber = OculusManager::getHMDScreen(); + if (_hmdScreenNumber >= 0) { + QScreen* hmdScreen = QGuiApplication::screens()[hmdScreenNumber]; if (screen == hmdScreen) { qDebug() << "HMD Tools: Whoa! What are you doing? You don't want to move me to the HMD Screen!"; QWindow* dialogWindow = windowHandle(); @@ -157,6 +161,7 @@ QString HMDToolsDialog::getDebugDetails() const { results += "Application Primary Screen: " + QGuiApplication::primaryScreen()->name() + "\n"; QScreen* mainWindowScreen = Application::getInstance()->getWindow()->windowHandle()->screen(); results += "Application Main Window Screen: " + mainWindowScreen->name() + "\n"; + results += "Total Screens: " + QString::number(QApplication::desktop()->screenCount()) + "\n"; return results; } @@ -174,18 +179,17 @@ void HMDToolsDialog::enterHDMMode() { _switchModeButton->setText("Leave HMD Mode"); _debugDetails->setText(getDebugDetails()); - int hmdScreen = OculusManager::getHMDScreen(); - qDebug() << "enterModeClicked().... hmdScreen:" << hmdScreen; + _hmdScreenNumber = OculusManager::getHMDScreen(); - if (hmdScreen >= 0) { + if (_hmdScreenNumber >= 0) { QWindow* mainWindow = Application::getInstance()->getWindow()->windowHandle(); - _hmdScreen = QGuiApplication::screens()[hmdScreen]; + _hmdScreen = QGuiApplication::screens()[_hmdScreenNumber]; _previousRect = Application::getInstance()->getWindow()->rect(); _previousRect = QRect(mainWindow->mapToGlobal(_previousRect.topLeft()), mainWindow->mapToGlobal(_previousRect.bottomRight())); _previousScreen = mainWindow->screen(); - QRect rect = QApplication::desktop()->screenGeometry(hmdScreen); + QRect rect = QApplication::desktop()->screenGeometry(_hmdScreenNumber); mainWindow->setScreen(_hmdScreen); mainWindow->setGeometry(rect); @@ -281,4 +285,25 @@ void HMDToolsDialog::aboutToQuit() { } } +void HMDToolsDialog::screenCountChanged(int newCount) { + if (!OculusManager::isConnected()) { + OculusManager::connect(); + } + int hmdScreenNumber = OculusManager::getHMDScreen(); + + if (_inHDMMode && _hmdScreenNumber != hmdScreenNumber) { + qDebug() << "HMD Display changed WHILE IN HMD MODE"; + leaveHDMMode(); + + // if there is a new best HDM screen then go back into HDM mode after done leaving + if (hmdScreenNumber >= 0) { + qDebug() << "Trying to go back into HDM Mode"; + const int SLIGHT_DELAY = 2000; + QTimer::singleShot(SLIGHT_DELAY, this, SLOT(enterHDMMode())); + } + } + _debugDetails->setText(getDebugDetails()); +} + + diff --git a/interface/src/ui/HMDToolsDialog.h b/interface/src/ui/HMDToolsDialog.h index 91db300224..e3e5573533 100644 --- a/interface/src/ui/HMDToolsDialog.h +++ b/interface/src/ui/HMDToolsDialog.h @@ -34,8 +34,9 @@ public slots: void applicationWindowScreenChanged(QScreen* screen); void dialogWindowScreenChanged(QScreen* screen); void dialogWindowGeometryChanged(int arg); - void aboutToQuit(); - + void aboutToQuit(); + void screenCountChanged(int newCount); + protected: virtual void closeEvent(QCloseEvent*); // Emits a 'closed' signal when this dialog is closed. virtual void showEvent(QShowEvent* event); @@ -50,6 +51,7 @@ private: QRect _previousRect; QScreen* _previousScreen; QScreen* _hmdScreen; + int _hmdScreenNumber; QPushButton* _switchModeButton; QLabel* _debugDetails; From c78af1c982f3f891ca413b7c9f2058ee4e1f8740 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 27 Nov 2014 10:48:36 -0800 Subject: [PATCH 30/57] fixing the bug when lighmaps are diasppearing in the , i don;t understand why --- interface/src/renderer/Model.cpp | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 2e17cc2605..b2570b7c28 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -2381,24 +2381,27 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod GLBATCH(glActiveTexture)(GL_TEXTURE0); } - if (locations->emissiveTextureUnit >= 0) { - // assert(locations->emissiveParams >= 0); // we should have the emissiveParams defined in the shader - float emissiveOffset = part.emissiveParams.x; - float emissiveScale = part.emissiveParams.y; - GLBATCH(glUniform2f)(locations->emissiveParams, emissiveOffset, emissiveScale); - - GLBATCH(glActiveTexture)(GL_TEXTURE0 + locations->emissiveTextureUnit); - Texture* emissiveMap = networkPart.emissiveTexture.data(); - GLBATCH(glBindTexture)(GL_TEXTURE_2D, !emissiveMap ? - Application::getInstance()->getTextureCache()->getWhiteTextureID() : emissiveMap->getID()); - GLBATCH(glActiveTexture)(GL_TEXTURE0); - } - if (args) { args->_materialSwitches++; } } + + // HACK: For unkwon reason (yet!) this code that should be assigned only if the material changes need to be called for every + // drawcall with an emissive, so let's do it for now. + if (locations->emissiveTextureUnit >= 0) { + // assert(locations->emissiveParams >= 0); // we should have the emissiveParams defined in the shader + float emissiveOffset = part.emissiveParams.x; + float emissiveScale = part.emissiveParams.y; + GLBATCH(glUniform2f)(locations->emissiveParams, emissiveOffset, emissiveScale); + + GLBATCH(glActiveTexture)(GL_TEXTURE0 + locations->emissiveTextureUnit); + Texture* emissiveMap = networkPart.emissiveTexture.data(); + GLBATCH(glBindTexture)(GL_TEXTURE_2D, !emissiveMap ? + Application::getInstance()->getTextureCache()->getWhiteTextureID() : emissiveMap->getID()); + GLBATCH(glActiveTexture)(GL_TEXTURE0); + } + lastMaterialID = part.materialID; } From 583e079d3a1f3650e7fb063f308f86848adaa97e Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 28 Nov 2014 10:01:15 -0800 Subject: [PATCH 31/57] Fix Hydra cursors in VR display They weren't being drawn at the correct location an so weren't matching up with location of voxel being added or deleted, for example. --- interface/src/devices/SixenseManager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index d636f8929c..6d227027ed 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -477,7 +477,8 @@ void SixenseManager::emulateMouse(PalmData* palm, int index) { triggerButton = Qt::LeftButton; } - if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers)) { + if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers) + || Menu::getInstance()->isOptionChecked(MenuOption::EnableVRMode)) { pos = application->getApplicationOverlay().getPalmClickLocation(palm); } else { // Get directon relative to avatar orientation From 5c2cc20313e14757e14399051dd814846b543b7f Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 28 Nov 2014 17:36:55 -0800 Subject: [PATCH 32/57] fixes the stutter in animation when observer moves --- interface/src/renderer/AnimationHandle.cpp | 8 +++----- libraries/animation/src/AnimationLoop.cpp | 5 +++-- libraries/animation/src/AnimationLoop.h | 4 ++++ libraries/entities/src/ModelEntityItem.cpp | 4 +++- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/interface/src/renderer/AnimationHandle.cpp b/interface/src/renderer/AnimationHandle.cpp index 767f941049..89c265875b 100644 --- a/interface/src/renderer/AnimationHandle.cpp +++ b/interface/src/renderer/AnimationHandle.cpp @@ -138,11 +138,9 @@ void AnimationHandle::simulate(float deltaTime) { return; } - // TODO: When moving the loop/frame calculations to AnimationLoop class, we changed this behavior - // see AnimationLoop class for more details. Do we need to support clamping the endFrameIndex to - // the max number of frames in the geometry??? - // - // float endFrameIndex = qMin(_lastFrame, animationGeometry.animationFrames.size() - (_loop ? 0.0f : 1.0f)); + if (_animationLoop.getMaxFrameIndexHint() != animationGeometry.animationFrames.size()) { + _animationLoop.setMaxFrameIndexHint(animationGeometry.animationFrames.size()); + } // blend between the closest two frames applyFrame(getFrameIndex()); diff --git a/libraries/animation/src/AnimationLoop.cpp b/libraries/animation/src/AnimationLoop.cpp index f81904990f..75a3cdd338 100644 --- a/libraries/animation/src/AnimationLoop.cpp +++ b/libraries/animation/src/AnimationLoop.cpp @@ -20,7 +20,8 @@ AnimationLoop::AnimationLoop() : _firstFrame(0.0f), _lastFrame(FLT_MAX), _running(false), - _frameIndex(0.0f) + _frameIndex(0.0f), + _maxFrameIndexHint(FLT_MAX) { } @@ -55,7 +56,7 @@ void AnimationLoop::simulate(float deltaTime) { // If we knew the number of frames from the animation, we'd consider using it here // animationGeometry.animationFrames.size() - float maxFrame = _lastFrame; + float maxFrame = _maxFrameIndexHint; float endFrameIndex = qMin(_lastFrame, maxFrame - (_loop ? 0.0f : 1.0f)); float startFrameIndex = qMin(_firstFrame, endFrameIndex); if ((!_loop && (_frameIndex < startFrameIndex || _frameIndex > endFrameIndex)) || startFrameIndex == endFrameIndex) { diff --git a/libraries/animation/src/AnimationLoop.h b/libraries/animation/src/AnimationLoop.h index b56f68f23b..aff2cd86ee 100644 --- a/libraries/animation/src/AnimationLoop.h +++ b/libraries/animation/src/AnimationLoop.h @@ -44,6 +44,9 @@ public: void setFrameIndex(float frameIndex) { _frameIndex = glm::clamp(frameIndex, _firstFrame, _lastFrame); } float getFrameIndex() const { return _frameIndex; } + + void setMaxFrameIndexHint(float value) { _maxFrameIndexHint = value; } + float getMaxFrameIndexHint() const { return _maxFrameIndexHint; } void start() { setRunning(true); } void stop() { setRunning(false); } @@ -58,6 +61,7 @@ private: float _lastFrame; bool _running; float _frameIndex; + float _maxFrameIndexHint; }; #endif // hifi_AnimationLoop_h diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 31a0c57f5b..63fe3daa03 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -344,7 +344,9 @@ QVector ModelEntityItem::getAnimationFrame() { Animation* myAnimation = getAnimation(_animationURL); QVector frames = myAnimation->getFrames(); int frameCount = frames.size(); - + if (_animationLoop.getMaxFrameIndexHint() != frameCount) { + _animationLoop.setMaxFrameIndexHint(frameCount); + } if (frameCount > 0) { int animationFrameIndex = (int)(glm::floor(getAnimationFrameIndex())) % frameCount; if (animationFrameIndex < 0 || animationFrameIndex > frameCount) { From 709a40516d5ffcc2e3fc5b25c152f8ba3e91c970 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Sat, 29 Nov 2014 12:17:38 -0800 Subject: [PATCH 33/57] Add auto-turn of body when head is beyond 45 degrees --- examples/headMove.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/examples/headMove.js b/examples/headMove.js index df5c858b46..4d2e4ded07 100644 --- a/examples/headMove.js +++ b/examples/headMove.js @@ -19,6 +19,7 @@ var warpPosition = { x: 0, y: 0, z: 0 }; var hipsToEyes; var restoreCountdownTimer; +var headTurningTimer = 0.0; // Overlays to show target location @@ -168,6 +169,20 @@ function update(deltaTime) { restoreCountDownTimer = 0.0; } } + var HEAD_TURN_TIME = 0.10; + var HEAD_TURN_DEGREES = 4.0; + var HEAD_TURN_START_ANGLE = 45.0; + var currentYaw = MyAvatar.getHeadFinalYaw(); + if (Math.abs(currentYaw) > HEAD_TURN_START_ANGLE) { + headTurningTimer += deltaTime; + if (headTurningTimer > HEAD_TURN_TIME) { + headTurningTimer = 0.0; + MyAvatar.orientation = Quat.multiply(Quat.fromPitchYawRollDegrees(0, (currentYaw > 0) ? HEAD_TURN_DEGREES: -HEAD_TURN_DEGREES, 0), + MyAvatar.orientation); + } + } else { + headTurningTimer = 0.0; + } } Controller.keyPressEvent.connect(function(event) { From 321d651d77fe0c8927e003c08715020de8928765 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Sun, 30 Nov 2014 12:54:43 -0800 Subject: [PATCH 34/57] Hack for avoiding lightmaps loading in starchamber --- interface/src/renderer/GeometryCache.cpp | 7 ++++++- libraries/fbx/src/FBXReader.cpp | 10 +++++----- libraries/fbx/src/FBXReader.h | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/interface/src/renderer/GeometryCache.cpp b/interface/src/renderer/GeometryCache.cpp index 5ef90732ef..04b59e7ea1 100644 --- a/interface/src/renderer/GeometryCache.cpp +++ b/interface/src/renderer/GeometryCache.cpp @@ -834,7 +834,12 @@ void GeometryReader::run() { if (_url.path().toLower().endsWith(".svo")) { fbxgeo = readSVO(_reply->readAll()); } else { - fbxgeo = readFBX(_reply->readAll(), _mapping); + bool grabLightmaps = true; + // HACK: For monday 12/01/2014 we need to kill lighmaps loading in starchamber... + if (_url.path().toLower().endsWith("loungev4_11-18.fbx")) { + grabLightmaps = false; + } + fbxgeo = readFBX(_reply->readAll(), _mapping, grabLightmaps); } QMetaObject::invokeMethod(geometry.data(), "setGeometry", Q_ARG(const FBXGeometry&, fbxgeo)); diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index fd9190f597..d77cbbd0a1 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -1194,7 +1194,7 @@ int matchTextureUVSetToAttributeChannel(const std::string& texUVSetName, const Q } } -FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) { +FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping, bool loadLightmaps) { QHash meshes; QHash modelIDsToNames; QHash meshIDsToMeshIndices; @@ -1704,10 +1704,10 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) } else if (type.contains("shininess")) { counter++; - } else if (type.contains("emissive")) { + } else if (loadLightmaps && type.contains("emissive")) { emissiveTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1)); - } else if (type.contains("ambient")) { + } else if (loadLightmaps && type.contains("ambient")) { ambientTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1)); } else { std::string typenam = type.data(); @@ -2372,10 +2372,10 @@ QByteArray writeMapping(const QVariantHash& mapping) { return buffer.data(); } -FBXGeometry readFBX(const QByteArray& model, const QVariantHash& mapping) { +FBXGeometry readFBX(const QByteArray& model, const QVariantHash& mapping, bool loadLightmaps) { QBuffer buffer(const_cast(&model)); buffer.open(QIODevice::ReadOnly); - return extractFBXGeometry(parseFBX(&buffer), mapping); + return extractFBXGeometry(parseFBX(&buffer), mapping, loadLightmaps); } bool addMeshVoxelsOperation(OctreeElement* element, void* extraData) { diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index d92f787050..3adf5b5ffb 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -253,7 +253,7 @@ QByteArray writeMapping(const QVariantHash& mapping); /// Reads FBX geometry from the supplied model and mapping data. /// \exception QString if an error occurs in parsing -FBXGeometry readFBX(const QByteArray& model, const QVariantHash& mapping); +FBXGeometry readFBX(const QByteArray& model, const QVariantHash& mapping, bool loadLightmaps = true); /// Reads SVO geometry from the supplied model data. FBXGeometry readSVO(const QByteArray& model); From fed7d789f6023eef1670974eb75b558691b16a8d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Sun, 30 Nov 2014 17:29:18 -0800 Subject: [PATCH 35/57] have the domain-server write its local port into shared memory --- domain-server/src/DomainServer.cpp | 13 +++++++++++++ libraries/networking/src/LimitedNodeList.h | 2 ++ 2 files changed, 15 insertions(+) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 02f17bc502..84948e2406 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -228,6 +229,18 @@ void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) { LimitedNodeList* nodeList = LimitedNodeList::createInstance(domainServerPort, domainServerDTLSPort); + // no matter the local port, save it to shared mem so that local assignment clients can ask what it is + QSharedMemory* sharedPortMem = new QSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, this); + quint16 localPort = nodeList->getNodeSocket().localPort(); + + // attempt to create the shared memory segment + if (sharedPortMem->create(sizeof(localPort)) || sharedPortMem->attach()) { + memcpy(sharedPortMem->data(), &localPort, sizeof(localPort)); + qDebug() << "Wrote local listening port to shared memory at key" << DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY; + } else { + qWarning() << "Failed to create and attach to shared memory to share local port with assignment-client children."; + } + // set our LimitedNodeList UUID to match the UUID from our config // nodes will currently use this to add resources to data-web that relate to our domain const QString METAVERSE_DOMAIN_ID_KEY_PATH = "metaverse.id"; diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 64495fbd34..ad8c1688bb 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -44,6 +44,8 @@ const char DEFAULT_ASSIGNMENT_SERVER_HOSTNAME[] = "localhost"; const char STUN_SERVER_HOSTNAME[] = "stun.highfidelity.io"; const unsigned short STUN_SERVER_PORT = 3478; +const QString DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY = "domain-server.local-port"; + class HifiSockAddr; typedef QSet NodeSet; From 59432e8d2935f2b1937a26b784fc64fdc29640e4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Sun, 30 Nov 2014 17:54:10 -0800 Subject: [PATCH 36/57] complete sharing of local domain-server port to local AC --- assignment-client/src/AssignmentClient.cpp | 59 +++++++++++++++++----- assignment-client/src/AssignmentClient.h | 4 ++ domain-server/src/DomainServer.cpp | 5 +- 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index ae235eb1ff..9972adfda2 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -10,6 +10,7 @@ // #include +#include #include #include @@ -38,7 +39,8 @@ int hifiSockAddrMeta = qRegisterMetaType("HifiSockAddr"); AssignmentClient::AssignmentClient(int &argc, char **argv) : QCoreApplication(argc, argv), _shutdownEventListener(this), - _assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME) + _assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME), + _localASPortSharedMem(NULL) { LogUtils::init(); @@ -89,13 +91,7 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : // create a NodeList as an unassigned client NodeList* nodeList = NodeList::createInstance(NodeType::Unassigned); - unsigned short assignmentServerPort = DEFAULT_DOMAIN_SERVER_PORT; - - // check for an overriden assignment server port - if (argumentVariantMap.contains(CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION)) { - assignmentServerPort = - argumentVariantMap.value(CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION).toString().toUInt(); - } + quint16 assignmentServerPort = DEFAULT_DOMAIN_SERVER_PORT; // check for an overriden assignment server hostname if (argumentVariantMap.contains(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION)) { @@ -103,10 +99,16 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : _assignmentServerHostname = argumentVariantMap.value(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION).toString(); } - HifiSockAddr assignmentServerSocket(_assignmentServerHostname, assignmentServerPort, true); - nodeList->setAssignmentServerSocket(assignmentServerSocket); + // check for an overriden assignment server port + if (argumentVariantMap.contains(CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION)) { + assignmentServerPort = + argumentVariantMap.value(CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION).toString().toUInt(); + } + + _assignmentServerSocket = HifiSockAddr(_assignmentServerHostname, assignmentServerPort, true); + nodeList->setAssignmentServerSocket(_assignmentServerSocket); - qDebug() << "Assignment server socket is" << assignmentServerSocket; + qDebug() << "Assignment server socket is" << _assignmentServerSocket; // call a timer function every ASSIGNMENT_REQUEST_INTERVAL_MSECS to ask for assignment, if required qDebug() << "Waiting for assignment -" << _requestAssignment; @@ -129,7 +131,40 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : void AssignmentClient::sendAssignmentRequest() { if (!_currentAssignment) { - NodeList::getInstance()->sendAssignment(_requestAssignment); + + NodeList* nodeList = NodeList::getInstance(); + + if (_assignmentServerHostname == "localhost") { + // we want to check again for the local domain-server port in case the DS has restarted + if (!_localASPortSharedMem) { + _localASPortSharedMem = new QSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, this); + + if (!_localASPortSharedMem->attach(QSharedMemory::ReadOnly)) { + qWarning() << "Could not attach to shared memory at key" << DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY + << "- will attempt to connect to domain-server on" << _assignmentServerSocket.getPort(); + } + } + + if (_localASPortSharedMem->isAttached()) { + _localASPortSharedMem->lock(); + + quint16 localAssignmentServerPort; + memcpy(&localAssignmentServerPort, _localASPortSharedMem->data(), sizeof(localAssignmentServerPort)); + + _localASPortSharedMem->unlock(); + + if (localAssignmentServerPort != _assignmentServerSocket.getPort()) { + qDebug() << "Port for local assignment server read from shared memory is" + << localAssignmentServerPort; + + _assignmentServerSocket.setPort(localAssignmentServerPort); + nodeList->setAssignmentServerSocket(_assignmentServerSocket); + } + } + + } + + nodeList->sendAssignment(_requestAssignment); } } diff --git a/assignment-client/src/AssignmentClient.h b/assignment-client/src/AssignmentClient.h index 7628aa0a3b..566805d67f 100644 --- a/assignment-client/src/AssignmentClient.h +++ b/assignment-client/src/AssignmentClient.h @@ -17,6 +17,8 @@ #include "ShutdownEventListener.h" #include "ThreadedAssignment.h" +class QSharedMemory; + class AssignmentClient : public QCoreApplication { Q_OBJECT public: @@ -34,6 +36,8 @@ private: static SharedAssignmentPointer _currentAssignment; ShutdownEventListener _shutdownEventListener; QString _assignmentServerHostname; + HifiSockAddr _assignmentServerSocket; + QSharedMemory* _localASPortSharedMem; }; #endif // hifi_AssignmentClient_h diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 84948e2406..ddc06c8015 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -235,8 +235,11 @@ void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) { // attempt to create the shared memory segment if (sharedPortMem->create(sizeof(localPort)) || sharedPortMem->attach()) { + sharedPortMem->lock(); memcpy(sharedPortMem->data(), &localPort, sizeof(localPort)); - qDebug() << "Wrote local listening port to shared memory at key" << DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY; + sharedPortMem->unlock(); + + qDebug() << "Wrote local listening port" << localPort << "to shared memory at key" << DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY; } else { qWarning() << "Failed to create and attach to shared memory to share local port with assignment-client children."; } From 8449575fa231cfe504cbfcecc395d2f447f59f16 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 1 Dec 2014 09:25:21 -0800 Subject: [PATCH 37/57] fix for ice-server heartbeat without an access token --- domain-server/src/DomainServer.cpp | 45 ++++++++++++++++-------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index ddc06c8015..80777ce529 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -337,9 +337,31 @@ bool DomainServer::optionallySetupAssignmentPayment() { void DomainServer::setupAutomaticNetworking() { + LimitedNodeList* nodeList = LimitedNodeList::getInstance(); + + const int STUN_REFLEXIVE_KEEPALIVE_INTERVAL_MSECS = 10 * 1000; + const int STUN_IP_ADDRESS_CHECK_INTERVAL_MSECS = 30 * 1000; + + // setup our timer to check our IP via stun every X seconds + QTimer* dynamicIPTimer = new QTimer(this); + connect(dynamicIPTimer, &QTimer::timeout, this, &DomainServer::requestCurrentPublicSocketViaSTUN); + + if (_automaticNetworkingSetting == FULL_AUTOMATIC_NETWORKING_VALUE) { + dynamicIPTimer->start(STUN_REFLEXIVE_KEEPALIVE_INTERVAL_MSECS); + + // setup a timer to heartbeat with the ice-server every so often + QTimer* iceHeartbeatTimer = new QTimer(this); + connect(iceHeartbeatTimer, &QTimer::timeout, this, &DomainServer::performICEUpdates); + iceHeartbeatTimer->start(ICE_HEARBEAT_INTERVAL_MSECS); + + // call our sendHeartbeaToIceServer immediately anytime a local or public socket changes + connect(nodeList, &LimitedNodeList::localSockAddrChanged, this, &DomainServer::sendHeartbeatToIceServer); + connect(nodeList, &LimitedNodeList::publicSockAddrChanged, this, &DomainServer::sendHeartbeatToIceServer); + } + if (!didSetupAccountManagerWithAccessToken()) { - qDebug() << "Cannot setup domain-server automatic networking without an access token."; - qDebug() << "Please add an access token to your config file or via the web interface."; + qDebug() << "Cannot send heartbeat to data server without an access token."; + qDebug() << "Add an access token to your config file or via the web interface."; return; } @@ -350,37 +372,18 @@ void DomainServer::setupAutomaticNetworking() { if (_automaticNetworkingSetting == IP_ONLY_AUTOMATIC_NETWORKING_VALUE || _automaticNetworkingSetting == FULL_AUTOMATIC_NETWORKING_VALUE) { - LimitedNodeList* nodeList = LimitedNodeList::getInstance(); const QUuid& domainID = nodeList->getSessionUUID(); if (!domainID.isNull()) { qDebug() << "domain-server" << _automaticNetworkingSetting << "automatic networking enabled for ID" << uuidStringWithoutCurlyBraces(domainID) << "via" << _oauthProviderURL.toString(); - const int STUN_IP_ADDRESS_CHECK_INTERVAL_MSECS = 30 * 1000; - const int STUN_REFLEXIVE_KEEPALIVE_INTERVAL_MSECS = 10 * 1000; - - // setup our timer to check our IP via stun every X seconds - QTimer* dynamicIPTimer = new QTimer(this); - connect(dynamicIPTimer, &QTimer::timeout, this, &DomainServer::requestCurrentPublicSocketViaSTUN); - if (_automaticNetworkingSetting == IP_ONLY_AUTOMATIC_NETWORKING_VALUE) { dynamicIPTimer->start(STUN_IP_ADDRESS_CHECK_INTERVAL_MSECS); // send public socket changes to the data server so nodes can find us at our new IP connect(nodeList, &LimitedNodeList::publicSockAddrChanged, this, &DomainServer::performIPAddressUpdate); } else { - dynamicIPTimer->start(STUN_REFLEXIVE_KEEPALIVE_INTERVAL_MSECS); - - // setup a timer to heartbeat with the ice-server every so often - QTimer* iceHeartbeatTimer = new QTimer(this); - connect(iceHeartbeatTimer, &QTimer::timeout, this, &DomainServer::performICEUpdates); - iceHeartbeatTimer->start(ICE_HEARBEAT_INTERVAL_MSECS); - - // call our sendHeartbeaToIceServer immediately anytime a local or public socket changes - connect(nodeList, &LimitedNodeList::localSockAddrChanged, this, &DomainServer::sendHeartbeatToIceServer); - connect(nodeList, &LimitedNodeList::publicSockAddrChanged, this, &DomainServer::sendHeartbeatToIceServer); - // send our heartbeat to data server so it knows what our network settings are sendHeartbeatToDataServer(); } From 40db44e4bd708831694cc283cccb03e5174c23e3 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 1 Dec 2014 09:59:51 -0800 Subject: [PATCH 38/57] fix for custom hifi URL lookup --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 20ae07b0c9..31b73274fc 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -842,7 +842,7 @@ bool Application::event(QEvent* event) { QFileOpenEvent* fileEvent = static_cast(event); if (!fileEvent->url().isEmpty()) { - AddressManager::getInstance().handleLookupString(fileEvent->url().toLocalFile()); + AddressManager::getInstance().handleLookupString(fileEvent->url().toString()); } return false; From 6d7f799dbe072a857d9ffdf1a9be66c6578f764f Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 1 Dec 2014 10:32:35 -0800 Subject: [PATCH 39/57] oculus mirror lean hack --- interface/src/avatar/MyAvatar.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 3cbe2ac8ae..3301cf0347 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -367,6 +367,15 @@ void MyAvatar::updateFromTrackers(float deltaTime) { const float TORSO_LENGTH = 0.5f; glm::vec3 relativePosition = estimatedPosition - glm::vec3(0.0f, -TORSO_LENGTH, 0.0f); const float MAX_LEAN = 45.0f; + + // Invert left/right lean when in mirror mode + // NOTE: this is kinda a hack, it's the same hack we use to make the head tilt. But it's not really a mirror + // it just makes you feel like you're looking in a mirror because the body movements of the avatar appear to + // match your body movements. + if (OculusManager::isConnected() && Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_MIRROR) { + relativePosition.x = -relativePosition.x; + } + head->setLeanSideways(glm::clamp(glm::degrees(atanf(relativePosition.x * _leanScale / TORSO_LENGTH)), -MAX_LEAN, MAX_LEAN)); head->setLeanForward(glm::clamp(glm::degrees(atanf(relativePosition.z * _leanScale / TORSO_LENGTH)), From 7f36a11f3539ec07ca807ea097d813d48acd2627 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Mon, 1 Dec 2014 10:40:37 -0800 Subject: [PATCH 40/57] Find Oculus libraries when using Visual Studio 2013 --- cmake/modules/FindLibOVR.cmake | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cmake/modules/FindLibOVR.cmake b/cmake/modules/FindLibOVR.cmake index a1d75add3f..6ffb3ed309 100644 --- a/cmake/modules/FindLibOVR.cmake +++ b/cmake/modules/FindLibOVR.cmake @@ -48,8 +48,13 @@ elseif (UNIX) select_library_configurations(XINERAMA) elseif (WIN32) - find_library(LIBOVR_LIBRARY_DEBUG NAMES libovrd PATH_SUFFIXES Lib/Win32/VS2010 HINTS ${LIBOVR_SEARCH_DIRS}) - find_library(LIBOVR_LIBRARY_RELEASE NAMES libovr PATH_SUFFIXES Lib/Win32/VS2010 HINTS ${LIBOVR_SEARCH_DIRS}) + if (MSVC10) + find_library(LIBOVR_LIBRARY_DEBUG NAMES libovrd PATH_SUFFIXES Lib/Win32/VS2010 HINTS ${LIBOVR_SEARCH_DIRS}) + find_library(LIBOVR_LIBRARY_RELEASE NAMES libovr PATH_SUFFIXES Lib/Win32/VS2010 HINTS ${LIBOVR_SEARCH_DIRS}) + elseif (MSVC12) + find_library(LIBOVR_LIBRARY_DEBUG NAMES libovrd PATH_SUFFIXES Lib/Win32/VS2013 HINTS ${LIBOVR_SEARCH_DIRS}) + find_library(LIBOVR_LIBRARY_RELEASE NAMES libovr PATH_SUFFIXES Lib/Win32/VS2013 HINTS ${LIBOVR_SEARCH_DIRS}) + endif () find_package(ATL) endif () From 09eb150edc9adb0e06ac9931633ce00115e99240 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Mon, 1 Dec 2014 11:40:35 -0800 Subject: [PATCH 41/57] Update build instructions for VS2013 Community and Professional --- BUILD.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/BUILD.md b/BUILD.md index d6e1603f37..e1d920b8df 100644 --- a/BUILD.md +++ b/BUILD.md @@ -96,12 +96,13 @@ Currently building on Windows has been tested using the following compilers: #####Windows SDK 7.1 -Whichever version of Visual Studio you use, you will need [Microsoft Windows SDK for Windows 7 and .NET Framework 4](http://www.microsoft.com/en-us/download/details.aspx?id=8279). +If using Visual Studio 2010, or using Visual Studio 2013 but building as a Visual Studio 2010 project, you need [Microsoft Windows SDK for Windows 7 and .NET Framework 4](http://www.microsoft.com/en-us/download/details.aspx?id=8279). NOTE: If using Visual Studio C++ 2010 Express, you need to follow a specific install order. See below before installing the Windows SDK. -######Windows 8.1 -You may have already downloaded the Windows 8 SDK (e.g. if you have previously installed Visual Studio 2013). If so, change CMAKE_PREFIX_PATH in %HIFI_DIR%\CMakeLists.txt to point to the Windows 8 SDK binaries. The default path is `C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x86` +######Windows SDK 8.1 + +If using Visual Studio 2013 and building as a Visual Studio 2013 project you need the Windows 8 SDK which you should already have as part of installing Visual Studio 2013. You should be able to see it at `C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x86`. #####Visual Studio C++ 2010 Express @@ -123,9 +124,11 @@ Some of the build instructions will ask you to start a Visual Studio Command Pro #####Visual Studio 2013 -This product must be purchased separately. +You can use the Community or Professional editions of Visual Studio 2013. -Visual Studio 2013 doesn't have a shortcut to start a Visual Studio Command Prompt. Instead, start a regular command prompt and then run: +You can start a Visual Studio 2013 command prompt using the shortcut provided in the Visual Studio Tools folder installed as part of Visual Studio 2013. + +Or you can start a regular command prompt and then run: "%VS120COMNTOOLS%\vsvars32.bat" @@ -146,6 +149,8 @@ Once Qt is installed, you need to manually configure the following: * Make sure the Qt runtime DLLs are loadable. You must do this before you attempt to build because some tools for the build depend on Qt. E.g., add to the PATH: `Qt\5.2.0\msvc2010_opengl\bin\`. * Set the QT_CMAKE_PREFIX_PATH environment variable to your `Qt\5.2.0\msvc2010_opengl` directory. +If building as a Visual Studio 2013 project, download and configure the msvc2013 version of Qt instead. + ####External Libraries CMake will need to know where the headers and libraries for required external dependencies are. From 845e687fc579add8016dd593d41f94f9a956dad2 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 1 Dec 2014 11:45:07 -0800 Subject: [PATCH 42/57] Adding a Hack for the apaartment model to boost the lightmaps --- interface/src/renderer/GeometryCache.cpp | 5 ++++- libraries/fbx/src/FBXReader.cpp | 7 ++++--- libraries/fbx/src/FBXReader.h | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/interface/src/renderer/GeometryCache.cpp b/interface/src/renderer/GeometryCache.cpp index 04b59e7ea1..e2517613df 100644 --- a/interface/src/renderer/GeometryCache.cpp +++ b/interface/src/renderer/GeometryCache.cpp @@ -835,11 +835,14 @@ void GeometryReader::run() { fbxgeo = readSVO(_reply->readAll()); } else { bool grabLightmaps = true; + float lightmapLevel = 1.0f; // HACK: For monday 12/01/2014 we need to kill lighmaps loading in starchamber... if (_url.path().toLower().endsWith("loungev4_11-18.fbx")) { grabLightmaps = false; + } else if (_url.path().toLower().endsWith("apt8_reboot.fbx")) { + lightmapLevel = 4.0f; } - fbxgeo = readFBX(_reply->readAll(), _mapping, grabLightmaps); + fbxgeo = readFBX(_reply->readAll(), _mapping, grabLightmaps, lightmapLevel); } QMetaObject::invokeMethod(geometry.data(), "setGeometry", Q_ARG(const FBXGeometry&, fbxgeo)); diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index d77cbbd0a1..5f215ac4d0 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -1194,7 +1194,7 @@ int matchTextureUVSetToAttributeChannel(const std::string& texUVSetName, const Q } } -FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping, bool loadLightmaps) { +FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping, bool loadLightmaps, float lightmapLevel) { QHash meshes; QHash modelIDsToNames; QHash meshIDsToMeshIndices; @@ -1954,6 +1954,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping, FBXTexture emissiveTexture; glm::vec2 emissiveParams(0.f, 1.f); + emissiveParams.y = lightmapLevel; QString emissiveTextureID = emissiveTextures.value(childID); QString ambientTextureID = ambientTextures.value(childID); if (!emissiveTextureID.isNull() || !ambientTextureID.isNull()) { @@ -2372,10 +2373,10 @@ QByteArray writeMapping(const QVariantHash& mapping) { return buffer.data(); } -FBXGeometry readFBX(const QByteArray& model, const QVariantHash& mapping, bool loadLightmaps) { +FBXGeometry readFBX(const QByteArray& model, const QVariantHash& mapping, bool loadLightmaps, float lightmapLevel) { QBuffer buffer(const_cast(&model)); buffer.open(QIODevice::ReadOnly); - return extractFBXGeometry(parseFBX(&buffer), mapping, loadLightmaps); + return extractFBXGeometry(parseFBX(&buffer), mapping, loadLightmaps, lightmapLevel); } bool addMeshVoxelsOperation(OctreeElement* element, void* extraData) { diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index 3adf5b5ffb..a5df7ccc0c 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -253,7 +253,7 @@ QByteArray writeMapping(const QVariantHash& mapping); /// Reads FBX geometry from the supplied model and mapping data. /// \exception QString if an error occurs in parsing -FBXGeometry readFBX(const QByteArray& model, const QVariantHash& mapping, bool loadLightmaps = true); +FBXGeometry readFBX(const QByteArray& model, const QVariantHash& mapping, bool loadLightmaps = true, float lightmapLevel = 1.0f); /// Reads SVO geometry from the supplied model data. FBXGeometry readSVO(const QByteArray& model); From 1950ce5a4b9d1d9d023205300a8a51e3a820d497 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 25 Nov 2014 14:09:32 -0800 Subject: [PATCH 43/57] Add option for white grid color --- examples/html/gridControls.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/html/gridControls.html b/examples/html/gridControls.html index 241fa2406c..d95c9545e4 100644 --- a/examples/html/gridControls.html +++ b/examples/html/gridControls.html @@ -6,7 +6,7 @@ var gridColor = { red: 0, green: 0, blue: 0 }; var gridColors = [ { red: 0, green: 0, blue: 0 }, - { red: 128, green: 128, blue: 128 }, + { red: 255, green: 255, blue: 255 }, { red: 255, green: 0, blue: 0 }, { red: 0, green: 255, blue: 0}, { red: 0, green: 0, blue: 255 }, From 2c524cd70ce3835982092e9b4a40d7563d70b77d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 25 Nov 2014 14:10:39 -0800 Subject: [PATCH 44/57] Darken colors of selection/highlight boxes --- examples/libraries/entitySelectionTool.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index 813bf015d1..f1e311246e 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -306,7 +306,7 @@ SelectionDisplay = (function () { var highlightBox = Overlays.addOverlay("cube", { position: { x:0, y: 0, z: 0}, size: 1, - color: { red: 180, green: 180, blue: 180}, + color: { red: 90, green: 90, blue: 90}, alpha: 1, solid: false, visible: false, @@ -318,7 +318,7 @@ SelectionDisplay = (function () { var selectionBox = Overlays.addOverlay("cube", { position: { x:0, y: 0, z: 0}, size: 1, - color: { red: 180, green: 180, blue: 180}, + color: { red: 60, green: 60, blue: 60}, alpha: 1, solid: false, visible: false, From fc5adef501a326300fb3ef42cf29a14188ea3a08 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 25 Nov 2014 14:11:04 -0800 Subject: [PATCH 45/57] Update the tool window to use tabbed windows --- interface/src/ui/ToolWindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/ui/ToolWindow.cpp b/interface/src/ui/ToolWindow.cpp index de88d75b3d..799402a486 100644 --- a/interface/src/ui/ToolWindow.cpp +++ b/interface/src/ui/ToolWindow.cpp @@ -21,6 +21,7 @@ ToolWindow::ToolWindow(QWidget* parent) : _hasShown(false), _lastGeometry() { + setDockOptions(QMainWindow::ForceTabbedDocks); Application::getInstance()->installEventFilter(this); } From da568c96cea7d7a5bacb43b5f0f1de63f5c70b30 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 1 Dec 2014 12:04:00 -0800 Subject: [PATCH 46/57] Add rotation degrees overlay --- examples/libraries/entitySelectionTool.js | 131 +++++++++++++++++++--- 1 file changed, 113 insertions(+), 18 deletions(-) diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index f1e311246e..2b3819aff1 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -200,6 +200,12 @@ SelectionManager = (function() { return that; })(); +function normalizeDegrees(degrees) { + while (degrees > 180) degrees -= 360; + while (degrees < -180) degrees += 360; + return degrees; +} + SelectionDisplay = (function () { var that = {}; @@ -207,6 +213,8 @@ SelectionDisplay = (function () { var GRABBER_DISTANCE_TO_SIZE_RATIO = 0.0075; + var ROTATION_DISPLAY_DISTANCE_MULTIPLIER = 1.2; + var showExtendedStretchHandles = false; var spaceMode = SPACE_LOCAL; @@ -223,6 +231,9 @@ SelectionDisplay = (function () { var innerSnapAngle = 22.5; // the angle which we snap to on the inner rotation tool var innerRadius; var outerRadius; + var yawOffset = 0; + var pitchOffset = 0; + var rollOffset = 0; var yawHandleRotation; var pitchHandleRotation; var rollHandleRotation; @@ -326,6 +337,23 @@ SelectionDisplay = (function () { lineWidth: 1.0, }); + var rotationDegreesDisplay = Overlays.addOverlay("text3d", { + position: { x:0, y: 0, z: 0}, + text: "", + color: { red: 0, green: 0, blue: 0}, + backgroundColor: { red: 255, green: 255, blue: 255 }, + alpha: 0.7, + visible: false, + isFacingAvatar: true, + drawInFront: true, + dimensions: { x: 0, y: 0 }, + lineHeight: 0.0, + topMargin: 0, + rightMargin: 0, + bottomMargin: 0, + leftMargin: 0, + }); + var grabberMoveUp = Overlays.addOverlay("billboard", { url: HIFI_PUBLIC_BUCKET + "images/up-arrow.png", position: { x:0, y: 0, z: 0}, @@ -585,6 +613,7 @@ SelectionDisplay = (function () { rotateOverlayCurrent, rotateZeroOverlay, rotateCurrentOverlay, + rotationDegreesDisplay, xRailOverlay, yRailOverlay, zRailOverlay, @@ -757,6 +786,10 @@ SelectionDisplay = (function () { pitchHandleRotation = Quat.fromVec3Degrees({ x: 0, y: 90, z: 0 }); rollHandleRotation = Quat.fromVec3Degrees({ x: 0, y: 0, z: 0 }); + yawOffset = 90; + pitchOffset = 0; + rollOffset = 0; + yawNormal = { x: 0, y: 1, z: 0 }; pitchNormal = { x: 1, y: 0, z: 0 }; rollNormal = { x: 0, y: 0, z: 1 }; @@ -788,6 +821,10 @@ SelectionDisplay = (function () { pitchHandleRotation = Quat.fromVec3Degrees({ x: 180, y: 270, z: 0 }); rollHandleRotation = Quat.fromVec3Degrees({ x: 0, y: 0, z: 90 }); + yawOffset = 0; + pitchOffset = 180; + rollOffset = 90; + yawNormal = { x: 0, y: 1, z: 0 }; pitchNormal = { x: 1, y: 0, z: 0 }; rollNormal = { x: 0, y: 0, z: 1 }; @@ -822,6 +859,10 @@ SelectionDisplay = (function () { pitchHandleRotation = Quat.fromVec3Degrees({ x: 90, y: 0, z: 90 }); rollHandleRotation = Quat.fromVec3Degrees({ x: 0, y: 0, z: 180 }); + yawOffset = 180; + pitchOffset = 90; + rollOffset = 180; + yawNormal = { x: 0, y: 1, z: 0 }; pitchNormal = { x: 1, y: 0, z: 0 }; rollNormal = { x: 0, y: 0, z: 1 }; @@ -848,8 +889,12 @@ SelectionDisplay = (function () { } else { yawHandleRotation = Quat.fromVec3Degrees({ x: 270, y: 270, z: 0 }); - rollHandleRotation = Quat.fromVec3Degrees({ x: 0, y: 0, z: 180 }); pitchHandleRotation = Quat.fromVec3Degrees({ x: 180, y: 270, z: 0 }); + rollHandleRotation = Quat.fromVec3Degrees({ x: 0, y: 0, z: 180 }); + + yawOffset = 270; + pitchOffset = 180; + rollOffset = 180; yawNormal = { x: 0, y: 1, z: 0 }; rollNormal = { x: 0, y: 0, z: 1 }; @@ -1570,11 +1615,17 @@ SelectionDisplay = (function () { endAt: 0, innerRadius: 0.9, }); + + Overlays.editOverlay(rotationDegreesDisplay, { + visible: true, + ignoreRayIntersection: true, + }); }, onEnd: function(event, reason) { Overlays.editOverlay(rotateOverlayInner, { visible: false }); Overlays.editOverlay(rotateOverlayOuter, { visible: false }); Overlays.editOverlay(rotateOverlayCurrent, { visible: false }); + Overlays.editOverlay(rotationDegreesDisplay, { visible: false }); pushCommandForSelections(); }, @@ -1605,12 +1656,9 @@ SelectionDisplay = (function () { var angleFromZero = Vec3.orientedAngle(centerToZero, centerToIntersect, rotationNormal); var distanceFromCenter = Vec3.distance(center, result.intersection); - var snapToInner = false; - // var innerRadius = (Vec3.length(selectionManager.worldDimensions) / 2) * 1.1; - if (distanceFromCenter < innerRadius) { - angleFromZero = Math.floor(angleFromZero/innerSnapAngle) * innerSnapAngle; - snapToInner = true; - } + var snapToInner = distanceFromCenter < innerRadius; + var snapAngle = snapToInner ? innerSnapAngle : 1.0; + angleFromZero = Math.floor(angleFromZero / snapAngle) * snapAngle; // for debugging if (debug) { @@ -1632,7 +1680,20 @@ SelectionDisplay = (function () { rotation: Quat.multiply(yawChange, initialProperties.rotation), }); } - + + var angle = (yawOffset + angleFromZero + 180) * (Math.PI / 180); + var position = Vec3.sum( selectionManager.worldPosition, { + x: -Math.cos(angle) * outerRadius * ROTATION_DISPLAY_DISTANCE_MULTIPLIER, + y: -selectionManager.worldDimensions.y / 2, + z: Math.sin(angle) * outerRadius * ROTATION_DISPLAY_DISTANCE_MULTIPLIER, + }); + Overlays.editOverlay(rotationDegreesDisplay, { + position: position, + dimensions: { x: innerRadius / 2, y: innerRadius / 5.6 }, + lineHeight: innerRadius / 6, + text: normalizeDegrees(angleFromZero), + }); + // update the rotation display accordingly... var startAtCurrent = 0; var endAtCurrent = angleFromZero; @@ -1701,11 +1762,17 @@ SelectionDisplay = (function () { endAt: 0, innerRadius: 0.9, }); + + Overlays.editOverlay(rotationDegreesDisplay, { + visible: true, + ignoreRayIntersection: true, + }); }, onEnd: function(event, reason) { Overlays.editOverlay(rotateOverlayInner, { visible: false }); Overlays.editOverlay(rotateOverlayOuter, { visible: false }); Overlays.editOverlay(rotateOverlayCurrent, { visible: false }); + Overlays.editOverlay(rotationDegreesDisplay, { visible: false }); pushCommandForSelections(); }, @@ -1736,11 +1803,9 @@ SelectionDisplay = (function () { var angleFromZero = Vec3.orientedAngle(centerToZero, centerToIntersect, rotationNormal); var distanceFromCenter = Vec3.distance(center, result.intersection); - var snapToInner = false; - if (distanceFromCenter < innerRadius) { - angleFromZero = Math.floor(angleFromZero/innerSnapAngle) * innerSnapAngle; - snapToInner = true; - } + var snapToInner = distanceFromCenter < innerRadius; + var snapAngle = snapToInner ? innerSnapAngle : 1.0; + angleFromZero = Math.floor(angleFromZero / snapAngle) * snapAngle; // for debugging if (debug) { @@ -1764,6 +1829,19 @@ SelectionDisplay = (function () { }); } + var angle = (rollOffset + angleFromZero - 90) * (Math.PI / 180); + var position = Vec3.sum( selectionManager.worldPosition, { + x: selectionManager.worldDimensions.x / 2, + y: Math.cos(angle) * outerRadius * ROTATION_DISPLAY_DISTANCE_MULTIPLIER, + z: Math.sin(angle) * outerRadius * ROTATION_DISPLAY_DISTANCE_MULTIPLIER, + }); + Overlays.editOverlay(rotationDegreesDisplay, { + position: position, + dimensions: { x: innerRadius / 2, y: innerRadius / 5.6 }, + lineHeight: innerRadius / 6, + text: normalizeDegrees(angleFromZero), + }); + // update the rotation display accordingly... var startAtCurrent = 0; var endAtCurrent = angleFromZero; @@ -1831,11 +1909,17 @@ SelectionDisplay = (function () { endAt: 0, innerRadius: 0.9, }); + + Overlays.editOverlay(rotationDegreesDisplay, { + visible: true, + ignoreRayIntersection: true, + }); }, onEnd: function(event, reason) { Overlays.editOverlay(rotateOverlayInner, { visible: false }); Overlays.editOverlay(rotateOverlayOuter, { visible: false }); Overlays.editOverlay(rotateOverlayCurrent, { visible: false }); + Overlays.editOverlay(rotationDegreesDisplay, { visible: false }); pushCommandForSelections(); }, @@ -1866,11 +1950,9 @@ SelectionDisplay = (function () { var angleFromZero = Vec3.orientedAngle(centerToZero, centerToIntersect, rotationNormal); var distanceFromCenter = Vec3.distance(center, result.intersection); - var snapToInner = false; - if (distanceFromCenter < innerRadius) { - angleFromZero = Math.floor(angleFromZero/innerSnapAngle) * innerSnapAngle; - snapToInner = true; - } + var snapToInner = distanceFromCenter < innerRadius; + var snapAngle = snapToInner ? innerSnapAngle : 1.0; + angleFromZero = Math.floor(angleFromZero / snapAngle) * snapAngle; // for debugging if (debug) { @@ -1893,6 +1975,19 @@ SelectionDisplay = (function () { }); } + var angle = (rollOffset + angleFromZero + 90) * (Math.PI / 180); + var position = Vec3.sum( selectionManager.worldPosition, { + x: Math.sin(angle) * outerRadius * ROTATION_DISPLAY_DISTANCE_MULTIPLIER, + y: -Math.cos(angle) * outerRadius * ROTATION_DISPLAY_DISTANCE_MULTIPLIER, + z: -selectionManager.worldDimensions.z / 2, + }); + Overlays.editOverlay(rotationDegreesDisplay, { + position: position, + dimensions: { x: innerRadius / 2, y: innerRadius / 5.6 }, + lineHeight: innerRadius / 6, + text: normalizeDegrees(angleFromZero), + }); + // update the rotation display accordingly... var startAtCurrent = 0; var endAtCurrent = angleFromZero; From 4f0683dc5ee9f45d02275e52c0540b19462e511c Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 1 Dec 2014 15:07:03 -0800 Subject: [PATCH 47/57] Fix stretch tools not following mouse correctly --- examples/libraries/entitySelectionTool.js | 76 ++++++++++++++--------- 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index 2b3819aff1..ead424522a 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -1337,7 +1337,11 @@ SelectionDisplay = (function () { var vec3Mult = function(v1, v2) { return { x: v1.x * v2.x, y: v1.y * v2.y, z: v1.z * v2.z }; } - var makeStretchTool = function(stretchMode, direction, pivot) { + // stretchMode - name of mode + // direction - direction to stretch in + // pivot - point to use as a pivot + // offset - the position of the overlay tool relative to the selections center position + var makeStretchTool = function(stretchMode, direction, pivot, offset) { var signs = { x: direction.x < 0 ? -1 : (direction.x > 0 ? 1 : 0), y: direction.y < 0 ? -1 : (direction.y > 0 ? 1 : 0), @@ -1358,6 +1362,7 @@ SelectionDisplay = (function () { var initialDimensions = null; var initialIntersection = null; var initialProperties = null; + var pickRayPosition = null; var rotation = null; var onBegin = function(event) { @@ -1366,13 +1371,22 @@ SelectionDisplay = (function () { rotation = spaceMode == SPACE_LOCAL ? properties.rotation : Quat.fromPitchYawRollDegrees(0, 0, 0); if (spaceMode == SPACE_LOCAL) { + rotation = SelectionManager.localRotation; initialPosition = SelectionManager.localPosition; initialDimensions = SelectionManager.localDimensions; } else { + rotation = SelectionManager.worldRotation; initialPosition = SelectionManager.worldPosition; initialDimensions = SelectionManager.worldDimensions; } + var scaledOffset = { + x: initialDimensions.x * offset.x * 0.5, + y: initialDimensions.y * offset.y * 0.5, + z: initialDimensions.z * offset.z * 0.5, + }; + pickRayPosition = Vec3.sum(initialPosition, Vec3.multiplyQbyV(rotation, scaledOffset)); + if (numDimensions == 1 && mask.x) { var start = Vec3.multiplyQbyV(rotation, { x: -10000, y: 0, z: 0 }); start = Vec3.sum(start, properties.position); @@ -1426,7 +1440,7 @@ SelectionDisplay = (function () { planeNormal = Vec3.multiplyQbyV(rotation, planeNormal); var pickRay = Camera.computePickRay(event.x, event.y); lastPick = rayPlaneIntersection(pickRay, - initialPosition, + pickRayPosition, planeNormal); // Overlays.editOverlay(normalLine, { @@ -1461,7 +1475,7 @@ SelectionDisplay = (function () { var pickRay = Camera.computePickRay(event.x, event.y); newPick = rayPlaneIntersection(pickRay, - initialPosition, + pickRayPosition, planeNormal); var vector = Vec3.subtract(newPick, lastPick); @@ -1536,44 +1550,44 @@ SelectionDisplay = (function () { }; }; - function addStretchTool(overlay, mode, pivot, direction) { + function addStretchTool(overlay, mode, pivot, direction, offset) { if (!pivot) { pivot = Vec3.multiply(-1, direction); pivot.y = direction.y; } - var tool = makeStretchTool(mode, direction, pivot); + var tool = makeStretchTool(mode, direction, pivot, offset); addGrabberTool(overlay, tool); } - addStretchTool(grabberNEAR, "STRETCH_NEAR", { x: 0, y: 0, z: -1 }, { x: 0, y: 0, z: 1 }); - addStretchTool(grabberFAR, "STRETCH_FAR", { x: 0, y: 0, z: 1 }, { x: 0, y: 0, z: -1 }); - addStretchTool(grabberTOP, "STRETCH_TOP", { x: 0, y: 1, z: 0 }, { x: 0, y: -1, z: 0 }); - addStretchTool(grabberBOTTOM, "STRETCH_BOTTOM", { x: 0, y: -1, z: 0 }, { x: 0, y: 1, z: 0 }); - addStretchTool(grabberRIGHT, "STRETCH_RIGHT", { x: 1, y: 0, z: 0 }, { x: -1, y: 0, z: 0 }); - addStretchTool(grabberLEFT, "STRETCH_LEFT", { x: -1, y: 0, z: 0 }, { x: 1, y: 0, z: 0 }); + addStretchTool(grabberNEAR, "STRETCH_NEAR", { x: 0, y: 0, z: -1 }, { x: 0, y: 0, z: 1 }, { x: 0, y: 0, z: -1 }); + addStretchTool(grabberFAR, "STRETCH_FAR", { x: 0, y: 0, z: 1 }, { x: 0, y: 0, z: -1 }, { x: 0, y: 0, z: 1 }); + addStretchTool(grabberTOP, "STRETCH_TOP", { x: 0, y: 1, z: 0 }, { x: 0, y: -1, z: 0 }, { x: 0, y: 1, z: 0 }); + addStretchTool(grabberBOTTOM, "STRETCH_BOTTOM", { x: 0, y: -1, z: 0 }, { x: 0, y: 1, z: 0 }, { x: 0, y: -1, z: 0 }); + addStretchTool(grabberRIGHT, "STRETCH_RIGHT", { x: 1, y: 0, z: 0 }, { x: -1, y: 0, z: 0 }, { x: 1, y: 0, z: 0 }); + addStretchTool(grabberLEFT, "STRETCH_LEFT", { x: -1, y: 0, z: 0 }, { x: 1, y: 0, z: 0 }, { x: -1, y: 0, z: 0 }); - addStretchTool(grabberLBN, "STRETCH_LBN", null, {x: 1, y: 0, z: 1}); - addStretchTool(grabberRBN, "STRETCH_RBN", null, {x: -1, y: 0, z: 1}); - addStretchTool(grabberLBF, "STRETCH_LBF", null, {x: 1, y: 0, z: -1}); - addStretchTool(grabberRBF, "STRETCH_RBF", null, {x: -1, y: 0, z: -1}); - addStretchTool(grabberLTN, "STRETCH_LTN", null, {x: 1, y: 0, z: 1}); - addStretchTool(grabberRTN, "STRETCH_RTN", null, {x: -1, y: 0, z: 1}); - addStretchTool(grabberLTF, "STRETCH_LTF", null, {x: 1, y: 0, z: -1}); - addStretchTool(grabberRTF, "STRETCH_RTF", null, {x: -1, y: 0, z: -1}); + addStretchTool(grabberLBN, "STRETCH_LBN", null, {x: 1, y: 0, z: 1}, { x: -1, y: -1, z: -1 }); + addStretchTool(grabberRBN, "STRETCH_RBN", null, {x: -1, y: 0, z: 1}, { x: 1, y: -1, z: -1 }); + addStretchTool(grabberLBF, "STRETCH_LBF", null, {x: 1, y: 0, z: -1}, { x: -1, y: -1, z: 1 }); + addStretchTool(grabberRBF, "STRETCH_RBF", null, {x: -1, y: 0, z: -1}, { x: 1, y: -1, z: 1 }); + addStretchTool(grabberLTN, "STRETCH_LTN", null, {x: 1, y: 0, z: 1}, { x: -1, y: 1, z: -1 }); + addStretchTool(grabberRTN, "STRETCH_RTN", null, {x: -1, y: 0, z: 1}, { x: 1, y: 1, z: -1 }); + addStretchTool(grabberLTF, "STRETCH_LTF", null, {x: 1, y: 0, z: -1}, { x: -1, y: 1, z: 1 }); + addStretchTool(grabberRTF, "STRETCH_RTF", null, {x: -1, y: 0, z: -1}, { x: 1, y: 1, z: 1 }); - addStretchTool(grabberEdgeTR, "STRETCH_EdgeTR", null, {x: 1, y: 1, z: 0}); - addStretchTool(grabberEdgeTL, "STRETCH_EdgeTL", null, {x: -1, y: 1, z: 0}); - addStretchTool(grabberEdgeTF, "STRETCH_EdgeTF", null, {x: 0, y: 1, z: -1}); - addStretchTool(grabberEdgeTN, "STRETCH_EdgeTN", null, {x: 0, y: 1, z: 1}); - addStretchTool(grabberEdgeBR, "STRETCH_EdgeBR", null, {x: -1, y: 0, z: 0}); - addStretchTool(grabberEdgeBL, "STRETCH_EdgeBL", null, {x: 1, y: 0, z: 0}); - addStretchTool(grabberEdgeBF, "STRETCH_EdgeBF", null, {x: 0, y: 0, z: -1}); - addStretchTool(grabberEdgeBN, "STRETCH_EdgeBN", null, {x: 0, y: 0, z: 1}); - addStretchTool(grabberEdgeNR, "STRETCH_EdgeNR", null, {x: -1, y: 0, z: 1}); - addStretchTool(grabberEdgeNL, "STRETCH_EdgeNL", null, {x: 1, y: 0, z: 1}); - addStretchTool(grabberEdgeFR, "STRETCH_EdgeFR", null, {x: -1, y: 0, z: -1}); - addStretchTool(grabberEdgeFL, "STRETCH_EdgeFL", null, {x: 1, y: 0, z: -1}); + addStretchTool(grabberEdgeTR, "STRETCH_EdgeTR", null, {x: 1, y: 1, z: 0}, { x: 1, y: 1, z: 0 }); + addStretchTool(grabberEdgeTL, "STRETCH_EdgeTL", null, {x: -1, y: 1, z: 0}, { x: -1, y: 1, z: 0 }); + addStretchTool(grabberEdgeTF, "STRETCH_EdgeTF", null, {x: 0, y: 1, z: -1}, { x: 0, y: 1, z: -1 }); + addStretchTool(grabberEdgeTN, "STRETCH_EdgeTN", null, {x: 0, y: 1, z: 1}, { x: 0, y: 1, z: 1 }); + addStretchTool(grabberEdgeBR, "STRETCH_EdgeBR", null, {x: -1, y: 0, z: 0}, { x: 1, y: -1, z: 0 }); + addStretchTool(grabberEdgeBL, "STRETCH_EdgeBL", null, {x: 1, y: 0, z: 0}, { x: -1, y: -1, z: 0 }); + addStretchTool(grabberEdgeBF, "STRETCH_EdgeBF", null, {x: 0, y: 0, z: -1}, { x: 0, y: -1, z: -1 }); + addStretchTool(grabberEdgeBN, "STRETCH_EdgeBN", null, {x: 0, y: 0, z: 1}, { x: 0, y: -1, z: 1 }); + addStretchTool(grabberEdgeNR, "STRETCH_EdgeNR", null, {x: -1, y: 0, z: 1}, { x: 1, y: 0, z: -1 }); + addStretchTool(grabberEdgeNL, "STRETCH_EdgeNL", null, {x: 1, y: 0, z: 1}, { x: -1, y: 0, z: -1 }); + addStretchTool(grabberEdgeFR, "STRETCH_EdgeFR", null, {x: -1, y: 0, z: -1}, { x: 1, y: 0, z: 1 }); + addStretchTool(grabberEdgeFL, "STRETCH_EdgeFL", null, {x: 1, y: 0, z: -1}, { x: -1, y: 0, z: 1 }); var initialPosition = SelectionManager.worldPosition; addGrabberTool(yawHandle, { From 06ab17987bbd12e58c8457a8a5e4aedd8a12d33f Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 1 Dec 2014 16:08:50 -0800 Subject: [PATCH 48/57] Fix position of rotation degrees display The position of the display was not always correct depending on the camera orientation relative to the selection. --- examples/libraries/entitySelectionTool.js | 69 +++++++++++------------ 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index ead424522a..e37171c92a 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -213,7 +213,11 @@ SelectionDisplay = (function () { var GRABBER_DISTANCE_TO_SIZE_RATIO = 0.0075; + // These are multipliers for sizing the rotation degrees display while rotating an entity var ROTATION_DISPLAY_DISTANCE_MULTIPLIER = 1.2; + var ROTATION_DISPLAY_SIZE_X_MULTIPLIER = 0.5; + var ROTATION_DISPLAY_SIZE_Y_MULTIPLIER = 0.18; + var ROTATION_DISPLAY_LINE_HEIGHT_MULTIPLIER = 0.17; var showExtendedStretchHandles = false; @@ -1589,6 +1593,26 @@ SelectionDisplay = (function () { addStretchTool(grabberEdgeFR, "STRETCH_EdgeFR", null, {x: -1, y: 0, z: -1}, { x: 1, y: 0, z: 1 }); addStretchTool(grabberEdgeFL, "STRETCH_EdgeFL", null, {x: 1, y: 0, z: -1}, { x: -1, y: 0, z: 1 }); + function updateRotationDegreesOverlay(angleFromZero, handleRotation, centerPosition) { + var angle = angleFromZero * (Math.PI / 180); + var position = { + x: Math.cos(angle) * outerRadius * ROTATION_DISPLAY_DISTANCE_MULTIPLIER, + y: Math.sin(angle) * outerRadius * ROTATION_DISPLAY_DISTANCE_MULTIPLIER, + z: 0, + }; + position = Vec3.multiplyQbyV(handleRotation, position); + position = Vec3.sum(centerPosition, position); + Overlays.editOverlay(rotationDegreesDisplay, { + position: position, + dimensions: { + x: innerRadius * ROTATION_DISPLAY_SIZE_X_MULTIPLIER, + y: innerRadius * ROTATION_DISPLAY_SIZE_Y_MULTIPLIER + }, + lineHeight: innerRadius * ROTATION_DISPLAY_LINE_HEIGHT_MULTIPLIER, + text: normalizeDegrees(angleFromZero), + }); + } + var initialPosition = SelectionManager.worldPosition; addGrabberTool(yawHandle, { mode: "ROTATE_YAW", @@ -1634,6 +1658,8 @@ SelectionDisplay = (function () { visible: true, ignoreRayIntersection: true, }); + + updateRotationDegreesOverlay(0, yawHandleRotation, yawCenter); }, onEnd: function(event, reason) { Overlays.editOverlay(rotateOverlayInner, { visible: false }); @@ -1695,18 +1721,7 @@ SelectionDisplay = (function () { }); } - var angle = (yawOffset + angleFromZero + 180) * (Math.PI / 180); - var position = Vec3.sum( selectionManager.worldPosition, { - x: -Math.cos(angle) * outerRadius * ROTATION_DISPLAY_DISTANCE_MULTIPLIER, - y: -selectionManager.worldDimensions.y / 2, - z: Math.sin(angle) * outerRadius * ROTATION_DISPLAY_DISTANCE_MULTIPLIER, - }); - Overlays.editOverlay(rotationDegreesDisplay, { - position: position, - dimensions: { x: innerRadius / 2, y: innerRadius / 5.6 }, - lineHeight: innerRadius / 6, - text: normalizeDegrees(angleFromZero), - }); + updateRotationDegreesOverlay(angleFromZero, yawHandleRotation, yawCenter); // update the rotation display accordingly... var startAtCurrent = 0; @@ -1781,6 +1796,8 @@ SelectionDisplay = (function () { visible: true, ignoreRayIntersection: true, }); + + updateRotationDegreesOverlay(0, pitchHandleRotation, pitchCenter); }, onEnd: function(event, reason) { Overlays.editOverlay(rotateOverlayInner, { visible: false }); @@ -1843,18 +1860,7 @@ SelectionDisplay = (function () { }); } - var angle = (rollOffset + angleFromZero - 90) * (Math.PI / 180); - var position = Vec3.sum( selectionManager.worldPosition, { - x: selectionManager.worldDimensions.x / 2, - y: Math.cos(angle) * outerRadius * ROTATION_DISPLAY_DISTANCE_MULTIPLIER, - z: Math.sin(angle) * outerRadius * ROTATION_DISPLAY_DISTANCE_MULTIPLIER, - }); - Overlays.editOverlay(rotationDegreesDisplay, { - position: position, - dimensions: { x: innerRadius / 2, y: innerRadius / 5.6 }, - lineHeight: innerRadius / 6, - text: normalizeDegrees(angleFromZero), - }); + updateRotationDegreesOverlay(angleFromZero, pitchHandleRotation, pitchCenter); // update the rotation display accordingly... var startAtCurrent = 0; @@ -1928,6 +1934,8 @@ SelectionDisplay = (function () { visible: true, ignoreRayIntersection: true, }); + + updateRotationDegreesOverlay(0, rollHandleRotation, rollCenter); }, onEnd: function(event, reason) { Overlays.editOverlay(rotateOverlayInner, { visible: false }); @@ -1989,18 +1997,7 @@ SelectionDisplay = (function () { }); } - var angle = (rollOffset + angleFromZero + 90) * (Math.PI / 180); - var position = Vec3.sum( selectionManager.worldPosition, { - x: Math.sin(angle) * outerRadius * ROTATION_DISPLAY_DISTANCE_MULTIPLIER, - y: -Math.cos(angle) * outerRadius * ROTATION_DISPLAY_DISTANCE_MULTIPLIER, - z: -selectionManager.worldDimensions.z / 2, - }); - Overlays.editOverlay(rotationDegreesDisplay, { - position: position, - dimensions: { x: innerRadius / 2, y: innerRadius / 5.6 }, - lineHeight: innerRadius / 6, - text: normalizeDegrees(angleFromZero), - }); + updateRotationDegreesOverlay(angleFromZero, rollHandleRotation, rollCenter); // update the rotation display accordingly... var startAtCurrent = 0; From ce4d4073789da913e19eefe32f4e1d3ea2b2e027 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 1 Dec 2014 16:12:18 -0800 Subject: [PATCH 49/57] Update normalizeDegrees to be exclusive on the -180 end --- examples/libraries/entitySelectionTool.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index e37171c92a..478782c6ec 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -200,9 +200,10 @@ SelectionManager = (function() { return that; })(); +// Normalize degrees to be in the range (-180, 180] function normalizeDegrees(degrees) { while (degrees > 180) degrees -= 360; - while (degrees < -180) degrees += 360; + while (degrees <= -180) degrees += 360; return degrees; } From 0b7ddb009dca37a3433def60898fbb9347cbc73a Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 1 Dec 2014 16:33:51 -0800 Subject: [PATCH 50/57] Fix tabification of tool windows --- interface/src/ui/ToolWindow.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/interface/src/ui/ToolWindow.cpp b/interface/src/ui/ToolWindow.cpp index 799402a486..da1d2c68f4 100644 --- a/interface/src/ui/ToolWindow.cpp +++ b/interface/src/ui/ToolWindow.cpp @@ -100,8 +100,17 @@ void ToolWindow::onChildVisibilityUpdated(bool visible) { } void ToolWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget* dockWidget) { + QList dockWidgets = findChildren(); + QMainWindow::addDockWidget(area, dockWidget); + // We want to force tabbing, so retabify all of our widgets. + QDockWidget* lastDockWidget = dockWidget; + foreach (QDockWidget* nextDockWidget, dockWidgets) { + tabifyDockWidget(lastDockWidget, nextDockWidget); + lastDockWidget = nextDockWidget; + } + connect(dockWidget, &QDockWidget::visibilityChanged, this, &ToolWindow::onChildVisibilityUpdated); } From a8eb49a8226c5ae6a4acf550a5fe37818620369d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 1 Dec 2014 16:38:40 -0800 Subject: [PATCH 51/57] Remove now-unused *Offset variables --- examples/libraries/entitySelectionTool.js | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index 478782c6ec..5544fec84d 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -236,9 +236,6 @@ SelectionDisplay = (function () { var innerSnapAngle = 22.5; // the angle which we snap to on the inner rotation tool var innerRadius; var outerRadius; - var yawOffset = 0; - var pitchOffset = 0; - var rollOffset = 0; var yawHandleRotation; var pitchHandleRotation; var rollHandleRotation; @@ -791,10 +788,6 @@ SelectionDisplay = (function () { pitchHandleRotation = Quat.fromVec3Degrees({ x: 0, y: 90, z: 0 }); rollHandleRotation = Quat.fromVec3Degrees({ x: 0, y: 0, z: 0 }); - yawOffset = 90; - pitchOffset = 0; - rollOffset = 0; - yawNormal = { x: 0, y: 1, z: 0 }; pitchNormal = { x: 1, y: 0, z: 0 }; rollNormal = { x: 0, y: 0, z: 1 }; @@ -826,10 +819,6 @@ SelectionDisplay = (function () { pitchHandleRotation = Quat.fromVec3Degrees({ x: 180, y: 270, z: 0 }); rollHandleRotation = Quat.fromVec3Degrees({ x: 0, y: 0, z: 90 }); - yawOffset = 0; - pitchOffset = 180; - rollOffset = 90; - yawNormal = { x: 0, y: 1, z: 0 }; pitchNormal = { x: 1, y: 0, z: 0 }; rollNormal = { x: 0, y: 0, z: 1 }; @@ -864,10 +853,6 @@ SelectionDisplay = (function () { pitchHandleRotation = Quat.fromVec3Degrees({ x: 90, y: 0, z: 90 }); rollHandleRotation = Quat.fromVec3Degrees({ x: 0, y: 0, z: 180 }); - yawOffset = 180; - pitchOffset = 90; - rollOffset = 180; - yawNormal = { x: 0, y: 1, z: 0 }; pitchNormal = { x: 1, y: 0, z: 0 }; rollNormal = { x: 0, y: 0, z: 1 }; @@ -897,10 +882,6 @@ SelectionDisplay = (function () { pitchHandleRotation = Quat.fromVec3Degrees({ x: 180, y: 270, z: 0 }); rollHandleRotation = Quat.fromVec3Degrees({ x: 0, y: 0, z: 180 }); - yawOffset = 270; - pitchOffset = 180; - rollOffset = 180; - yawNormal = { x: 0, y: 1, z: 0 }; rollNormal = { x: 0, y: 0, z: 1 }; pitchNormal = { x: 1, y: 0, z: 0 }; From 9d9a7ead5b8f73dcfe6e306aac220bbb7bfb2a6a Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 1 Dec 2014 16:39:36 -0800 Subject: [PATCH 52/57] Remove unnecessary overlay property updates --- examples/libraries/entitySelectionTool.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index 5544fec84d..1a43231f6f 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -348,6 +348,7 @@ SelectionDisplay = (function () { visible: false, isFacingAvatar: true, drawInFront: true, + ignoreRayIntersection: true, dimensions: { x: 0, y: 0 }, lineHeight: 0.0, topMargin: 0, @@ -1638,7 +1639,6 @@ SelectionDisplay = (function () { Overlays.editOverlay(rotationDegreesDisplay, { visible: true, - ignoreRayIntersection: true, }); updateRotationDegreesOverlay(0, yawHandleRotation, yawCenter); @@ -1776,7 +1776,6 @@ SelectionDisplay = (function () { Overlays.editOverlay(rotationDegreesDisplay, { visible: true, - ignoreRayIntersection: true, }); updateRotationDegreesOverlay(0, pitchHandleRotation, pitchCenter); @@ -1914,7 +1913,6 @@ SelectionDisplay = (function () { Overlays.editOverlay(rotationDegreesDisplay, { visible: true, - ignoreRayIntersection: true, }); updateRotationDegreesOverlay(0, rollHandleRotation, rollCenter); From 36f716cd6165e846a4bb475a08c217de20a37001 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 2 Dec 2014 10:13:43 -0800 Subject: [PATCH 53/57] have script loading be separate from ScriptEngine constructor --- libraries/script-engine/src/ScriptEngine.cpp | 114 ++++++++----------- libraries/script-engine/src/ScriptEngine.h | 8 +- 2 files changed, 54 insertions(+), 68 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index e6002d7c10..fefe8e2103 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -100,71 +100,6 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam { } -ScriptEngine::ScriptEngine(const QUrl& scriptURL, - AbstractControllerScriptingInterface* controllerScriptingInterface) : - _scriptContents(), - _isFinished(false), - _isRunning(false), - _isInitialized(false), - _isAvatar(false), - _avatarIdentityTimer(NULL), - _avatarBillboardTimer(NULL), - _timerFunctionMap(), - _isListeningToAudioStream(false), - _avatarSound(NULL), - _numAvatarSoundSentBytes(0), - _controllerScriptingInterface(controllerScriptingInterface), - _avatarData(NULL), - _scriptName(), - _fileNameString(), - _quatLibrary(), - _vec3Library(), - _uuidLibrary(), - _animationCache(this), - _isUserLoaded(false), - _arrayBufferClass(new ArrayBufferClass(this)) -{ - QString scriptURLString = scriptURL.toString(); - _fileNameString = scriptURLString; - - QUrl url(scriptURL); - - // if the scheme length is one or lower, maybe they typed in a file, let's try - const int WINDOWS_DRIVE_LETTER_SIZE = 1; - if (url.scheme().size() <= WINDOWS_DRIVE_LETTER_SIZE) { - url = QUrl::fromLocalFile(scriptURLString); - } - - // ok, let's see if it's valid... and if so, load it - if (url.isValid()) { - if (url.scheme() == "file") { - QString fileName = url.toLocalFile(); - QFile scriptFile(fileName); - if (scriptFile.open(QFile::ReadOnly | QFile::Text)) { - qDebug() << "Loading file:" << fileName; - QTextStream in(&scriptFile); - _scriptContents = in.readAll(); - } else { - qDebug() << "ERROR Loading file:" << fileName; - emit errorMessage("ERROR Loading file:" + fileName); - } - } else { - QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); - QNetworkReply* reply = networkAccessManager.get(QNetworkRequest(url)); - qDebug() << "Downloading script at" << url; - QEventLoop loop; - QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); - loop.exec(); - if (reply->error() == QNetworkReply::NoError && reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) == 200) { - _scriptContents = reply->readAll(); - } else { - qDebug() << "ERROR Loading file:" << url.toString(); - emit errorMessage("ERROR Loading file:" + url.toString()); - } - } - } -} - void ScriptEngine::setIsAvatar(bool isAvatar) { _isAvatar = isAvatar; @@ -217,6 +152,55 @@ bool ScriptEngine::setScriptContents(const QString& scriptContents, const QStrin return true; } +void ScriptEngine::loadURL(const QUrl& scriptURL) { + if (_isRunning) { + return; + } + + QString scriptURLString = scriptURL.toString(); + _fileNameString = scriptURLString; + + QUrl url(scriptURL); + + // if the scheme length is one or lower, maybe they typed in a file, let's try + const int WINDOWS_DRIVE_LETTER_SIZE = 1; + if (url.scheme().size() <= WINDOWS_DRIVE_LETTER_SIZE) { + url = QUrl::fromLocalFile(scriptURLString); + } + + // ok, let's see if it's valid... and if so, load it + if (url.isValid()) { + if (url.scheme() == "file") { + QString fileName = url.toLocalFile(); + QFile scriptFile(fileName); + if (scriptFile.open(QFile::ReadOnly | QFile::Text)) { + qDebug() << "Loading file:" << fileName; + QTextStream in(&scriptFile); + _scriptContents = in.readAll(); + emit scriptLoaded(); + } else { + qDebug() << "ERROR Loading file:" << fileName; + emit errorLoadingScript(); + } + } else { + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkReply* reply = networkAccessManager.get(QNetworkRequest(url)); + connect(reply, &QNetworkReply::finished, this, &ScriptEngine::handleScriptDownload); + } + } +} + +void ScriptEngine::handleScriptDownload() { + QNetworkReply* reply = qobject_cast(sender()); + + if (reply->error() == QNetworkReply::NoError && reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) == 200) { + _scriptContents = reply->readAll(); + } else { + qDebug() << "ERROR Loading file:" << reply->url().toString(); + emit errorLoadingScript(); + } +} + Q_SCRIPT_DECLARE_QMETAOBJECT(LocalVoxels, QString) void ScriptEngine::init() { diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index bb279b8887..ee952d9d35 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -40,9 +40,6 @@ const unsigned int SCRIPT_DATA_CALLBACK_USECS = floor(((1.0 / 60.0f) * 1000 * 10 class ScriptEngine : public QScriptEngine { Q_OBJECT public: - ScriptEngine(const QUrl& scriptURL, - AbstractControllerScriptingInterface* controllerScriptingInterface = NULL); - ScriptEngine(const QString& scriptContents = NO_SCRIPT, const QString& fileNameString = QString(""), AbstractControllerScriptingInterface* controllerScriptingInterface = NULL); @@ -94,6 +91,7 @@ public: bool isUserLoaded() const { return _isUserLoaded; } public slots: + void loadURL(const QUrl& scriptURL); void stop(); QScriptValue evaluate(const QString& program, const QString& fileName = QString(), int lineNumber = 1); @@ -109,6 +107,8 @@ public slots: void nodeKilled(SharedNodePointer node); signals: + void scriptLoaded(); + void errorLoadingScript(); void update(float deltaTime); void scriptEnding(); void finished(const QString& fileNameString); @@ -155,6 +155,8 @@ private: ArrayBufferClass* _arrayBufferClass; QHash _outgoingScriptAudioSequenceNumbers; +private slots: + void handleScriptDownload(); }; #endif // hifi_ScriptEngine_h From d7f168999d1de69951942d02fa4fa6a39a3d65b1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 2 Dec 2014 10:30:23 -0800 Subject: [PATCH 54/57] don't block main thread for a script load --- interface/src/Application.cpp | 49 +++++++++++++------- interface/src/Application.h | 3 ++ libraries/script-engine/src/ScriptEngine.cpp | 7 +-- libraries/script-engine/src/ScriptEngine.h | 4 +- 4 files changed, 40 insertions(+), 23 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 20ae07b0c9..35b13cbec7 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4013,26 +4013,23 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser return _scriptEnginesHash[scriptURLString]; } - ScriptEngine* scriptEngine; - if (scriptFilename.isNull()) { - scriptEngine = new ScriptEngine(NO_SCRIPT, "", &_controllerScriptingInterface); - } else { - // start the script on a new thread... - scriptEngine = new ScriptEngine(scriptUrl, &_controllerScriptingInterface); - - if (!scriptEngine->hasScript()) { - qDebug() << "Application::loadScript(), script failed to load..."; - QMessageBox::warning(getWindow(), "Error Loading Script", scriptURLString + " failed to load."); - return NULL; - } - - _scriptEnginesHash.insertMulti(scriptURLString, scriptEngine); - _runningScriptsWidget->setRunningScripts(getRunningScripts()); - UserActivityLogger::getInstance().loadedScript(scriptURLString); - } + ScriptEngine* scriptEngine = new ScriptEngine(NO_SCRIPT, "", &_controllerScriptingInterface); scriptEngine->setUserLoaded(isUserLoaded); - registerScriptEngineWithApplicationServices(scriptEngine); + if (scriptFilename.isNull()) { + // this had better be the script editor (we should de-couple so somebody who thinks they are loading a script + // doesn't just get an empty script engine) + + // we can complete setup now since there isn't a script we have to load + registerScriptEngineWithApplicationServices(scriptEngine); + } else { + // connect to the appropriate signals of this script engine + connect(scriptEngine, &ScriptEngine::scriptLoaded, this, &Application::handleScriptEngineLoaded); + connect(scriptEngine, &ScriptEngine::scriptLoaded, this, &Application::handleScriptLoadError); + + // get the script engine object to load the script at the designated script URL + scriptEngine->loadURL(scriptUrl); + } // restore the main window's active state if (activateMainWindow && !loadScriptFromEditor) { @@ -4043,6 +4040,22 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser return scriptEngine; } +void Application::handleScriptEngineLoaded(const QUrl& scriptURL) { + ScriptEngine* scriptEngine = qobject_cast(sender()); + + _scriptEnginesHash.insertMulti(scriptURL.toString(), scriptEngine); + _runningScriptsWidget->setRunningScripts(getRunningScripts()); + UserActivityLogger::getInstance().loadedScript(scriptURL.toString()); + + // register our application services and set it off on its own thread + registerScriptEngineWithApplicationServices(scriptEngine); +} + +void Application::handleScriptLoadError(const QUrl& scriptURL) { + qDebug() << "Application::loadScript(), script failed to load..."; + QMessageBox::warning(getWindow(), "Error Loading Script", scriptURL.toString() + " failed to load."); +} + void Application::scriptFinished(const QString& scriptName) { const QString& scriptURLString = QUrl(scriptName).toString(); QHash::iterator it = _scriptEnginesHash.find(scriptURLString); diff --git a/interface/src/Application.h b/interface/src/Application.h index 9f2cdbd520..caaebea876 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -393,6 +393,9 @@ private slots: void timer(); void idle(); void aboutToQuit(); + + void handleScriptEngineLoaded(const QUrl& scriptURL); + void handleScriptLoadError(const QUrl& scriptURL); void connectedToDomain(const QString& hostname); diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index fefe8e2103..6cef69d23f 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -177,10 +177,10 @@ void ScriptEngine::loadURL(const QUrl& scriptURL) { qDebug() << "Loading file:" << fileName; QTextStream in(&scriptFile); _scriptContents = in.readAll(); - emit scriptLoaded(); + emit scriptLoaded(url); } else { qDebug() << "ERROR Loading file:" << fileName; - emit errorLoadingScript(); + emit errorLoadingScript(url); } } else { QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); @@ -195,9 +195,10 @@ void ScriptEngine::handleScriptDownload() { if (reply->error() == QNetworkReply::NoError && reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) == 200) { _scriptContents = reply->readAll(); + emit scriptLoaded(reply->url()); } else { qDebug() << "ERROR Loading file:" << reply->url().toString(); - emit errorLoadingScript(); + emit errorLoadingScript(reply->url()); } } diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index ee952d9d35..4b6b3e48ab 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -107,8 +107,8 @@ public slots: void nodeKilled(SharedNodePointer node); signals: - void scriptLoaded(); - void errorLoadingScript(); + void scriptLoaded(const QUrl& scriptURL); + void errorLoadingScript(const QUrl& scriptURL); void update(float deltaTime); void scriptEnding(); void finished(const QString& fileNameString); From 0a92374ca6df9172e031999f2f58600ed5d1aec9 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 2 Dec 2014 10:39:20 -0800 Subject: [PATCH 55/57] fix an incorrect connection to script load error --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 35b13cbec7..f499d04cfa 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4025,7 +4025,7 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser } else { // connect to the appropriate signals of this script engine connect(scriptEngine, &ScriptEngine::scriptLoaded, this, &Application::handleScriptEngineLoaded); - connect(scriptEngine, &ScriptEngine::scriptLoaded, this, &Application::handleScriptLoadError); + connect(scriptEngine, &ScriptEngine::errorLoadingScript, this, &Application::handleScriptLoadError); // get the script engine object to load the script at the designated script URL scriptEngine->loadURL(scriptUrl); From 0814949e4cd9ec65c43657fa3daad7dc8325370f Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 2 Dec 2014 11:05:17 -0800 Subject: [PATCH 56/57] moving EntityCollisionSystem back to entities lib --- interface/src/Application.h | 2 +- .../entities/src}/EntityCollisionSystem.cpp | 9 ++++----- .../entities/src}/EntityCollisionSystem.h | 5 +++-- 3 files changed, 8 insertions(+), 8 deletions(-) rename {interface/src/entities => libraries/entities/src}/EntityCollisionSystem.cpp (99%) rename {interface/src/entities => libraries/entities/src}/EntityCollisionSystem.h (97%) diff --git a/interface/src/Application.h b/interface/src/Application.h index 1c49e871e7..6980ac7a48 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -59,7 +60,6 @@ #include "devices/SixenseManager.h" #include "devices/Visage.h" #include "devices/DdeFaceTracker.h" -#include "entities/EntityCollisionSystem.h" #include "entities/EntityTreeRenderer.h" #include "renderer/AmbientOcclusionEffect.h" #include "renderer/DeferredLightingEffect.h" diff --git a/interface/src/entities/EntityCollisionSystem.cpp b/libraries/entities/src/EntityCollisionSystem.cpp similarity index 99% rename from interface/src/entities/EntityCollisionSystem.cpp rename to libraries/entities/src/EntityCollisionSystem.cpp index 1760d63157..2ac8ea596d 100644 --- a/interface/src/entities/EntityCollisionSystem.cpp +++ b/libraries/entities/src/EntityCollisionSystem.cpp @@ -19,12 +19,11 @@ #include #include -#include -#include -#include -#include - #include "EntityCollisionSystem.h" +#include "EntityEditPacketSender.h" +#include "EntityItem.h" +#include "EntityTreeElement.h" +#include "EntityTree.h" const int MAX_COLLISIONS_PER_Entity = 16; diff --git a/interface/src/entities/EntityCollisionSystem.h b/libraries/entities/src/EntityCollisionSystem.h similarity index 97% rename from interface/src/entities/EntityCollisionSystem.h rename to libraries/entities/src/EntityCollisionSystem.h index a1eb174756..b4421ffc72 100644 --- a/interface/src/entities/EntityCollisionSystem.h +++ b/libraries/entities/src/EntityCollisionSystem.h @@ -20,12 +20,13 @@ #include #include -#include #include #include -#include #include +#include "EntityItem.h" +#include "SimpleEntitySimulation.h" + class AbstractAudioInterface; class AvatarData; class EntityEditPacketSender; From b9944edf66d33a08f857325737d342684fd7550b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 2 Dec 2014 11:13:37 -0800 Subject: [PATCH 57/57] OctreeServer::createTree() is now protected --- assignment-client/src/entities/EntityServer.h | 4 +++- assignment-client/src/octree/OctreeServer.h | 2 +- assignment-client/src/voxels/VoxelServer.h | 2 +- interface/src/entities/EntityTreeRenderer.h | 4 +++- libraries/entities/src/EntityTreeHeadlessViewer.h | 4 +++- libraries/octree/src/OctreeRenderer.h | 3 ++- libraries/voxels/src/VoxelTreeHeadlessViewer.h | 4 +++- 7 files changed, 16 insertions(+), 7 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.h b/assignment-client/src/entities/EntityServer.h index 14fd26b775..d072d18cdf 100644 --- a/assignment-client/src/entities/EntityServer.h +++ b/assignment-client/src/entities/EntityServer.h @@ -27,7 +27,6 @@ public: // Subclasses must implement these methods virtual OctreeQueryNode* createOctreeQueryNode(); - virtual Octree* createTree(); virtual char getMyNodeType() const { return NodeType::EntityServer; } virtual PacketType getMyQueryMessageType() const { return PacketTypeEntityQuery; } virtual const char* getMyServerName() const { return MODEL_SERVER_NAME; } @@ -46,6 +45,9 @@ public: public slots: void pruneDeletedEntities(); +protected: + virtual Octree* createTree(); + private: EntitySimulation* _entitySimulation; }; diff --git a/assignment-client/src/octree/OctreeServer.h b/assignment-client/src/octree/OctreeServer.h index 27365c1e9d..4999594a98 100644 --- a/assignment-client/src/octree/OctreeServer.h +++ b/assignment-client/src/octree/OctreeServer.h @@ -62,7 +62,6 @@ public: // Subclasses must implement these methods virtual OctreeQueryNode* createOctreeQueryNode() = 0; - virtual Octree* createTree() = 0; virtual char getMyNodeType() const = 0; virtual PacketType getMyQueryMessageType() const = 0; virtual const char* getMyServerName() const = 0; @@ -132,6 +131,7 @@ public slots: void readPendingDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr); protected: + virtual Octree* createTree() = 0; bool readOptionBool(const QString& optionName, const QJsonObject& settingsSectionObject, bool& result); bool readOptionInt(const QString& optionName, const QJsonObject& settingsSectionObject, int& result); bool readOptionString(const QString& optionName, const QJsonObject& settingsSectionObject, QString& result); diff --git a/assignment-client/src/voxels/VoxelServer.h b/assignment-client/src/voxels/VoxelServer.h index f4b6bd3a42..4d21695f33 100644 --- a/assignment-client/src/voxels/VoxelServer.h +++ b/assignment-client/src/voxels/VoxelServer.h @@ -36,7 +36,6 @@ public: // Subclasses must implement these methods virtual OctreeQueryNode* createOctreeQueryNode(); - virtual Octree* createTree(); virtual char getMyNodeType() const { return NodeType::VoxelServer; } virtual PacketType getMyQueryMessageType() const { return PacketTypeVoxelQuery; } virtual const char* getMyServerName() const { return VOXEL_SERVER_NAME; } @@ -50,6 +49,7 @@ public: virtual int sendSpecialPacket(const SharedNodePointer& node, OctreeQueryNode* queryNode, int& packetsSent); protected: + virtual Octree* createTree(); virtual void readAdditionalConfiguration(const QJsonObject& settingsSectionObject); private: diff --git a/interface/src/entities/EntityTreeRenderer.h b/interface/src/entities/EntityTreeRenderer.h index 9f06011d30..0042dd495f 100644 --- a/interface/src/entities/EntityTreeRenderer.h +++ b/interface/src/entities/EntityTreeRenderer.h @@ -40,7 +40,6 @@ public: EntityTreeRenderer(bool wantScripts); virtual ~EntityTreeRenderer(); - virtual Octree* createTree() { return new EntityTree(true); } virtual char getMyNodeType() const { return NodeType::EntityServer; } virtual PacketType getMyQueryMessageType() const { return PacketTypeEntityQuery; } virtual PacketType getExpectedPacketType() const { return PacketTypeEntityData; } @@ -108,6 +107,9 @@ public slots: void changingEntityID(const EntityItemID& oldEntityID, const EntityItemID& newEntityID); void entitySciptChanging(const EntityItemID& entityID); +protected: + virtual Octree* createTree() { return new EntityTree(true); } + private: void checkAndCallPreload(const EntityItemID& entityID); void checkAndCallUnload(const EntityItemID& entityID); diff --git a/libraries/entities/src/EntityTreeHeadlessViewer.h b/libraries/entities/src/EntityTreeHeadlessViewer.h index 16839f9951..3989582c2b 100644 --- a/libraries/entities/src/EntityTreeHeadlessViewer.h +++ b/libraries/entities/src/EntityTreeHeadlessViewer.h @@ -30,7 +30,6 @@ public: EntityTreeHeadlessViewer(); virtual ~EntityTreeHeadlessViewer(); - virtual Octree* createTree() { return new EntityTree(true); } virtual char getMyNodeType() const { return NodeType::EntityServer; } virtual PacketType getMyQueryMessageType() const { return PacketTypeEntityQuery; } virtual PacketType getExpectedPacketType() const { return PacketTypeEntityData; } @@ -42,7 +41,10 @@ public: void processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode); virtual void init(); + protected: + virtual Octree* createTree() { return new EntityTree(true); } + EntitySimulation* _simulation; }; diff --git a/libraries/octree/src/OctreeRenderer.h b/libraries/octree/src/OctreeRenderer.h index 2999f34fb6..4ee0865243 100644 --- a/libraries/octree/src/OctreeRenderer.h +++ b/libraries/octree/src/OctreeRenderer.h @@ -35,7 +35,6 @@ public: OctreeRenderer(); virtual ~OctreeRenderer(); - virtual Octree* createTree() = 0; virtual char getMyNodeType() const = 0; virtual PacketType getMyQueryMessageType() const = 0; virtual PacketType getExpectedPacketType() const = 0; @@ -81,6 +80,8 @@ public: int getOpaqueMeshPartsRendered() const { return _opaqueMeshPartsRendered; } protected: + virtual Octree* createTree() = 0; + Octree* _tree; bool _managedTree; ViewFrustum* _viewFrustum; diff --git a/libraries/voxels/src/VoxelTreeHeadlessViewer.h b/libraries/voxels/src/VoxelTreeHeadlessViewer.h index 4acd5aa52d..291ad7f813 100644 --- a/libraries/voxels/src/VoxelTreeHeadlessViewer.h +++ b/libraries/voxels/src/VoxelTreeHeadlessViewer.h @@ -27,7 +27,6 @@ public: VoxelTreeHeadlessViewer(); virtual ~VoxelTreeHeadlessViewer(); - virtual Octree* createTree() { return new VoxelTree(true); } virtual char getMyNodeType() const { return NodeType::VoxelServer; } virtual PacketType getMyQueryMessageType() const { return PacketTypeVoxelQuery; } virtual PacketType getExpectedPacketType() const { return PacketTypeVoxelData; } @@ -35,6 +34,9 @@ public: VoxelTree* getTree() { return (VoxelTree*)_tree; } virtual void init(); + +protected: + virtual Octree* createTree() { return new VoxelTree(true); } }; #endif // hifi_VoxelTreeHeadlessViewer_h