diff --git a/interface/resources/qml/AssetServer.qml b/interface/resources/qml/AssetServer.qml index c85fd5b379..bf46ba121c 100644 --- a/interface/resources/qml/AssetServer.qml +++ b/interface/resources/qml/AssetServer.qml @@ -542,7 +542,7 @@ ScrollingWindow { Item { height: parent.height width: parent.width - HifiControls.Button { + HifiControls.QueuedButton { id: uploadButton anchors.right: parent.right @@ -552,22 +552,7 @@ ScrollingWindow { height: 30 width: 155 - onClicked: uploadClickedTimer.running = true - - // For some reason trigginer an API that enters - // an internal event loop directly from the button clicked - // trigger below causes the appliction to behave oddly. - // Most likely because the button onClicked handling is never - // completed until the function returns. - // FIXME find a better way of handling the input dialogs that - // doesn't trigger this. - Timer { - id: uploadClickedTimer - interval: 5 - repeat: false - running: false - onTriggered: uploadClicked(); - } + onClickedQueued: uploadClicked() } Item { diff --git a/interface/resources/qml/controls-uit/QueuedButton.qml b/interface/resources/qml/controls-uit/QueuedButton.qml new file mode 100644 index 0000000000..36ffbe582f --- /dev/null +++ b/interface/resources/qml/controls-uit/QueuedButton.qml @@ -0,0 +1,43 @@ +// +// QueuedButton.qml +// -- original Button.qml + signal timer workaround --ht +// Created by David Rowe on 16 Feb 2016 +// Copyright 2016 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 +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 as Original +import QtQuick.Controls.Styles 1.4 + +import "../styles-uit" +import "." as HifiControls + +HifiControls.Button { + // FIXME: THIS WORKAROUND MIGRATED/CONSOLIDATED FROM RUNNINGSCRIPTS.QML + + // For some reason trigginer an API that enters + // an internal event loop directly from the button clicked + // trigger below causes the appliction to behave oddly. + // Most likely because the button onClicked handling is never + // completed until the function returns. + // FIXME find a better way of handling the input dialogs that + // doesn't trigger this. + + // NOTE: dialogs that need to use this workaround can connect via + // onQueuedClicked: ... + // instead of: + // onClicked: ... + + signal clickedQueued() + Timer { + id: fromTimer + interval: 5 + repeat: false + running: false + onTriggered: clickedQueued() + } + onClicked: fromTimer.running = true +} diff --git a/interface/resources/qml/dialogs/preferences/AvatarPreference.qml b/interface/resources/qml/dialogs/preferences/AvatarPreference.qml index 7ae4fe6761..bcc5a1d9e6 100644 --- a/interface/resources/qml/dialogs/preferences/AvatarPreference.qml +++ b/interface/resources/qml/dialogs/preferences/AvatarPreference.qml @@ -16,7 +16,6 @@ import "../../hifi/tablet/tabletWindows/preferences" Preference { id: root property alias text: dataTextField.text - property alias buttonText: button.text property alias placeholderText: dataTextField.placeholderText property var browser; height: control.height + hifi.dimensions.controlInterlineHeight @@ -58,28 +57,46 @@ Preference { right: parent.right bottom: parent.bottom } - height: Math.max(dataTextField.controlHeight, button.height) + height: dataTextField.controlHeight + bookmarkAvatarButton.height + hifi.dimensions.contentSpacing.y TextField { id: dataTextField + label: root.label placeholderText: root.placeholderText text: preference.value - label: root.label + colorScheme: dataTextField.acceptableInput ? hifi.colorSchemes.dark : hifi.colorSchemes.light + validator: RegExpValidator { + regExp: /.*\.(?:fst).*\?*/ig + } anchors { left: parent.left - right: button.left - rightMargin: hifi.dimensions.contentSpacing.x - bottom: parent.bottom + right: parent.right + bottom: bookmarkAvatarButton.top + bottomMargin: hifi.dimensions.contentSpacing.y } - colorScheme: hifi.colorSchemes.dark + } + + QueuedButton { + id: bookmarkAvatarButton + text: "Bookmark Avatar" + width: 140 + visible: dataTextField.acceptableInput + anchors { + left: parent.left + bottom: parent.bottom + rightMargin: hifi.dimensions.contentSpacing.x + } + onClickedQueued: ApplicationInterface.loadAddAvatarBookmarkDialog() } Button { - id: button - text: "Browse" + id: browseAvatarsButton + text: "Browse Avatars" + width: 140 anchors { - right: parent.right - verticalCenter: dataTextField.verticalCenter + left: dataTextField.acceptableInput ? bookmarkAvatarButton.right : parent.left + bottom: parent.bottom + leftMargin: dataTextField.acceptableInput ? hifi.dimensions.contentSpacing.x : 0 } onClicked: { if (typeof desktop !== "undefined") { @@ -103,5 +120,6 @@ Preference { eventBridge: tabletRoot.eventBridge } } + } } diff --git a/interface/resources/qml/hifi/dialogs/RunningScripts.qml b/interface/resources/qml/hifi/dialogs/RunningScripts.qml index 29807d9646..d95dbc2e55 100644 --- a/interface/resources/qml/hifi/dialogs/RunningScripts.qml +++ b/interface/resources/qml/hifi/dialogs/RunningScripts.qml @@ -219,41 +219,18 @@ ScrollingWindow { Row { spacing: hifi.dimensions.contentSpacing.x - HifiControls.Button { + HifiControls.QueuedButton { text: "from URL" color: hifi.buttons.black height: 26 - onClicked: fromUrlTimer.running = true - - // For some reason trigginer an API that enters - // an internal event loop directly from the button clicked - // trigger below causes the appliction to behave oddly. - // Most likely because the button onClicked handling is never - // completed until the function returns. - // FIXME find a better way of handling the input dialogs that - // doesn't trigger this. - Timer { - id: fromUrlTimer - interval: 5 - repeat: false - running: false - onTriggered: ApplicationInterface.loadScriptURLDialog(); - } + onClickedQueued: ApplicationInterface.loadScriptURLDialog() } - HifiControls.Button { + HifiControls.QueuedButton { text: "from Disk" color: hifi.buttons.black height: 26 - onClicked: fromDiskTimer.running = true - - Timer { - id: fromDiskTimer - interval: 5 - repeat: false - running: false - onTriggered: ApplicationInterface.loadDialog(); - } + onClickedQueued: ApplicationInterface.loadDialog() } HifiControls.Button { diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 88278034d0..7763c3fb0b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -81,6 +82,7 @@ #include #include #include +#include "LocationBookmarks.h" #include #include #include @@ -530,6 +532,8 @@ bool setupEssentials(int& argc, char** argv) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(nullptr, qApp->getOcteeSceneStats()); + DependencyManager::set(); + DependencyManager::set(); return previousSessionCrashed; } @@ -703,8 +707,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo usleep(USECS_PER_MSEC * 50); // 20hz } - _bookmarks = new Bookmarks(); // Before setting up the menu - // start the nodeThread so its event loop is running QThread* nodeThread = new QThread(this); nodeThread->setObjectName("NodeList Thread"); @@ -1122,19 +1124,19 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo return qApp->isHMDMode() ? 1 : 0; }); _applicationStateDevice->setInputVariant(STATE_CAMERA_FULL_SCREEN_MIRROR, []() -> float { - return qApp->getCamera()->getMode() == CAMERA_MODE_MIRROR ? 1 : 0; + return qApp->getCamera().getMode() == CAMERA_MODE_MIRROR ? 1 : 0; }); _applicationStateDevice->setInputVariant(STATE_CAMERA_FIRST_PERSON, []() -> float { - return qApp->getCamera()->getMode() == CAMERA_MODE_FIRST_PERSON ? 1 : 0; + return qApp->getCamera().getMode() == CAMERA_MODE_FIRST_PERSON ? 1 : 0; }); _applicationStateDevice->setInputVariant(STATE_CAMERA_THIRD_PERSON, []() -> float { - return qApp->getCamera()->getMode() == CAMERA_MODE_THIRD_PERSON ? 1 : 0; + return qApp->getCamera().getMode() == CAMERA_MODE_THIRD_PERSON ? 1 : 0; }); _applicationStateDevice->setInputVariant(STATE_CAMERA_ENTITY, []() -> float { - return qApp->getCamera()->getMode() == CAMERA_MODE_ENTITY ? 1 : 0; + return qApp->getCamera().getMode() == CAMERA_MODE_ENTITY ? 1 : 0; }); _applicationStateDevice->setInputVariant(STATE_CAMERA_INDEPENDENT, []() -> float { - return qApp->getCamera()->getMode() == CAMERA_MODE_INDEPENDENT ? 1 : 0; + return qApp->getCamera().getMode() == CAMERA_MODE_INDEPENDENT ? 1 : 0; }); _applicationStateDevice->setInputVariant(STATE_SNAP_TURN, []() -> float { return qApp->getMyAvatar()->getSnapTurn() ? 1 : 0; @@ -1783,14 +1785,23 @@ void Application::cleanupBeforeQuit() { DependencyManager::destroy(); DependencyManager::destroy(); - // shutdown render engine - _main3DScene = nullptr; - _renderEngine = nullptr; - qCDebug(interfaceapp) << "Application::cleanupBeforeQuit() complete"; } Application::~Application() { + // remove avatars from physics engine + DependencyManager::get()->clearOtherAvatars(); + VectorOfMotionStates motionStates; + DependencyManager::get()->getObjectsToRemoveFromPhysics(motionStates); + _physicsEngine->removeObjects(motionStates); + DependencyManager::get()->deleteAllAvatars(); + + _physicsEngine->setCharacterController(nullptr); + + // shutdown render engine + _main3DScene = nullptr; + _renderEngine = nullptr; + DependencyManager::destroy(); _entityClipboard->eraseAllOctreeElements(); @@ -1802,14 +1813,6 @@ Application::~Application() { _octreeProcessor.terminate(); _entityEditSender.terminate(); - _physicsEngine->setCharacterController(nullptr); - - // remove avatars from physics engine - DependencyManager::get()->clearOtherAvatars(); - VectorOfMotionStates motionStates; - DependencyManager::get()->getObjectsToRemoveFromPhysics(motionStates); - _physicsEngine->removeObjects(motionStates); - DependencyManager::get()->deleteAllAvatars(); DependencyManager::destroy(); DependencyManager::destroy(); @@ -2009,6 +2012,8 @@ void Application::initializeUi() { rootContext->setContextProperty("Settings", SettingsScriptingInterface::getInstance()); rootContext->setContextProperty("ScriptDiscoveryService", DependencyManager::get().data()); rootContext->setContextProperty("AudioDevice", AudioDeviceScriptingInterface::getInstance()); + rootContext->setContextProperty("AvatarBookmarks", DependencyManager::get().data()); + rootContext->setContextProperty("LocationBookmarks", DependencyManager::get().data()); // Caches rootContext->setContextProperty("AnimationCache", DependencyManager::get().data()); @@ -2436,7 +2441,7 @@ void Application::resizeGL() { // Possible change in aspect ratio { QMutexLocker viewLocker(&_viewMutex); - loadViewFrustum(_myCamera, _viewFrustum); + _myCamera.loadViewFrustum(_viewFrustum); } auto offscreenUi = DependencyManager::get(); @@ -4521,7 +4526,7 @@ void Application::update(float deltaTime) { // to the server. { QMutexLocker viewLocker(&_viewMutex); - loadViewFrustum(_myCamera, _viewFrustum); + _myCamera.loadViewFrustum(_viewFrustum); } quint64 now = usecTimestampNow(); @@ -4849,24 +4854,6 @@ QRect Application::getDesirableApplicationGeometry() const { return applicationGeometry; } -///////////////////////////////////////////////////////////////////////////////////// -// loadViewFrustum() -// -// Description: this will load the view frustum bounds for EITHER the head -// or the "myCamera". -// -void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) { - // We will use these below, from either the camera or head vectors calculated above - viewFrustum.setProjection(camera.getProjection()); - - // Set the viewFrustum up with the correct position and orientation of the camera - viewFrustum.setPosition(camera.getPosition()); - viewFrustum.setOrientation(camera.getOrientation()); - - // Ask the ViewFrustum class to calculate our corners - viewFrustum.calculate(); -} - glm::vec3 Application::getSunDirection() const { // Sun direction is in fact just the location of the sun relative to the origin auto skyStage = DependencyManager::get()->getSkyStage(); @@ -5038,7 +5025,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se // load the view frustum { QMutexLocker viewLocker(&_viewMutex); - loadViewFrustum(theCamera, _displayViewFrustum); + theCamera.loadViewFrustum(_displayViewFrustum); } // TODO fix shadows and make them use the GPU library @@ -5055,7 +5042,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se transaction.resetItem(BackgroundRenderData::_item, backgroundRenderPayload); } - // Assuming nothing get's rendered through that + // Assuming nothing gets rendered through that if (!selfAvatarOnly) { if (DependencyManager::get()->shouldRenderEntities()) { // render models... @@ -5111,6 +5098,8 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se QMutexLocker viewLocker(&_viewMutex); renderArgs->setViewFrustum(_displayViewFrustum); } + renderArgs->_cameraMode = (int8_t)theCamera.getMode(); // HACK + renderArgs->_scene = getMain3DScene(); _renderEngine->getRenderContext()->args = renderArgs; // Before the deferred pass, let's try to use the render engine @@ -5494,6 +5483,8 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri scriptEngine->registerGlobalObject("AudioDevice", AudioDeviceScriptingInterface::getInstance()); scriptEngine->registerGlobalObject("AudioStats", DependencyManager::get()->getStats().data()); scriptEngine->registerGlobalObject("AudioScope", DependencyManager::get().data()); + scriptEngine->registerGlobalObject("AvatarBookmarks", DependencyManager::get().data()); + scriptEngine->registerGlobalObject("LocationBookmarks", DependencyManager::get().data()); // Caches scriptEngine->registerGlobalObject("AnimationCache", DependencyManager::get().data()); @@ -6359,7 +6350,6 @@ void Application::loadLODToolsDialog() { } else { tablet->pushOntoStack("../../hifi/dialogs/TabletLODTools.qml"); } - } @@ -6409,6 +6399,11 @@ void Application::toggleEntityScriptServerLogDialog() { } } +void Application::loadAddAvatarBookmarkDialog() const { + auto avatarBookmarks = DependencyManager::get(); + avatarBookmarks->addBookmark(); +} + void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRatio) { postLambdaEvent([notify, includeAnimated, aspectRatio, this] { QMediaPlayer* player = new QMediaPlayer(); diff --git a/interface/src/Application.h b/interface/src/Application.h index 44c0f127c2..9f429b0433 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -52,8 +52,7 @@ #include "avatar/MyAvatar.h" #include "BandwidthRecorder.h" -#include "Bookmarks.h" -#include "Camera.h" +#include "FancyCamera.h" #include "ConnectionMonitor.h" #include "gpu/Context.h" #include "Menu.h" @@ -175,8 +174,8 @@ public: bool isThrottleRendering() const; - Camera* getCamera() { return &_myCamera; } - const Camera* getCamera() const { return &_myCamera; } + Camera& getCamera() { return _myCamera; } + const Camera& getCamera() const { return _myCamera; } // Represents the current view frustum of the avatar. void copyViewFrustum(ViewFrustum& viewOut) const; // Represents the view frustum of the current rendering pass, @@ -261,7 +260,6 @@ public: glm::mat4 getEyeProjection(int eye) const; QRect getDesirableApplicationGeometry() const; - Bookmarks* getBookmarks() const { return _bookmarks; } virtual bool canAcceptURL(const QString& url) const override; virtual bool acceptURL(const QString& url, bool defaultUpload = false) override; @@ -270,7 +268,7 @@ public: int getMaxOctreePacketsPerSecond() const; render::ScenePointer getMain3DScene() override { return _main3DScene; } - render::ScenePointer getMain3DScene() const { return _main3DScene; } + const render::ScenePointer& getMain3DScene() const { return _main3DScene; } render::EnginePointer getRenderEngine() override { return _renderEngine; } gpu::ContextPointer getGPUContext() const { return _gpuContext; } @@ -280,7 +278,7 @@ public: float getAvatarSimrate() const { return _avatarSimCounter.rate(); } float getAverageSimsPerSecond() const { return _simCounter.rate(); } - + void takeSnapshot(bool notify, bool includeAnimated = false, float aspectRatio = 0.0f); void shareSnapshot(const QString& filename, const QUrl& href = QUrl("")); @@ -330,6 +328,7 @@ public slots: void toggleEntityScriptServerLogDialog(); void toggleRunningScriptsWidget() const; Q_INVOKABLE void showAssetServerWidget(QString filePath = ""); + Q_INVOKABLE void loadAddAvatarBookmarkDialog() const; void showDialog(const QString& desktopURL, const QString& tabletURL, const QString& name) const; @@ -463,7 +462,6 @@ private: void updateDialogs(float deltaTime) const; void queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions, bool forceResend = false); - static void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum); glm::vec3 getSunDirection() const; @@ -559,7 +557,7 @@ private: SimpleMovingAverage _avatarSimsPerSecond {10}; int _avatarSimsPerSecondReport {0}; quint64 _lastAvatarSimsPerSecondUpdate {0}; - Camera _myCamera; // My view onto the world + FancyCamera _myCamera; // My view onto the world Setting::Handle _previousScriptLocation; Setting::Handle _fieldOfView; @@ -599,8 +597,6 @@ private: bool _aboutToQuit; - Bookmarks* _bookmarks; - bool _notifiedPacketVersionMismatchThisDomain; QThread _settingsThread; diff --git a/interface/src/AvatarBookmarks.cpp b/interface/src/AvatarBookmarks.cpp new file mode 100644 index 0000000000..5cdfc8213f --- /dev/null +++ b/interface/src/AvatarBookmarks.cpp @@ -0,0 +1,81 @@ +// +// AvatarBookmarks.cpp +// interface/src +// +// Created by Triplelexx on 23/03/17. +// Copyright 2017 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 "MainWindow.h" +#include "Menu.h" + +#include "AvatarBookmarks.h" +#include + +AvatarBookmarks::AvatarBookmarks() { + _bookmarksFilename = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + AVATARBOOKMARKS_FILENAME; + readFromFile(); +} + +void AvatarBookmarks::setupMenus(Menu* menubar, MenuWrapper* menu) { + // Add menus/actions + auto bookmarkAction = menubar->addActionToQMenuAndActionHash(menu, MenuOption::BookmarkAvatar); + QObject::connect(bookmarkAction, SIGNAL(triggered()), this, SLOT(addBookmark()), Qt::QueuedConnection); + _bookmarksMenu = menu->addMenu(MenuOption::AvatarBookmarks); + _deleteBookmarksAction = menubar->addActionToQMenuAndActionHash(menu, MenuOption::DeleteAvatarBookmark); + QObject::connect(_deleteBookmarksAction, SIGNAL(triggered()), this, SLOT(deleteBookmark()), Qt::QueuedConnection); + + Bookmarks::setupMenus(menubar, menu); + Bookmarks::sortActions(menubar, _bookmarksMenu); +} + +void AvatarBookmarks::changeToBookmarkedAvatar() { + QAction* action = qobject_cast(sender()); + const QString& address = action->data().toString(); + + auto myAvatar = DependencyManager::get()->getMyAvatar(); + myAvatar->useFullAvatarURL(address); +} + +void AvatarBookmarks::addBookmark() { + bool ok = false; + auto bookmarkName = OffscreenUi::getText(OffscreenUi::ICON_PLACEMARK, "Bookmark Avatar", "Name", QString(), &ok); + if (!ok) { + return; + } + + bookmarkName = bookmarkName.trimmed().replace(QRegExp("(\r\n|[\r\n\t\v ])+"), " "); + if (bookmarkName.length() == 0) { + return; + } + + auto myAvatar = DependencyManager::get()->getMyAvatar(); + const QString& bookmarkAddress = myAvatar->getSkeletonModelURL().toString(); + Bookmarks::addBookmarkToFile(bookmarkName, bookmarkAddress); +} + +void AvatarBookmarks::addBookmarkToMenu(Menu* menubar, const QString& name, const QString& address) { + QAction* changeAction = _bookmarksMenu->newAction(); + changeAction->setData(address); + connect(changeAction, SIGNAL(triggered()), this, SLOT(changeToBookmarkedAvatar())); + if (!_isMenuSorted) { + menubar->addActionToQMenuAndActionHash(_bookmarksMenu, changeAction, name, 0, QAction::NoRole); + } else { + // TODO: this is aggressive but other alternatives have proved less fruitful so far. + menubar->addActionToQMenuAndActionHash(_bookmarksMenu, changeAction, name, 0, QAction::NoRole); + Bookmarks::sortActions(menubar, _bookmarksMenu); + } +} diff --git a/interface/src/AvatarBookmarks.h b/interface/src/AvatarBookmarks.h new file mode 100644 index 0000000000..725af88b0d --- /dev/null +++ b/interface/src/AvatarBookmarks.h @@ -0,0 +1,40 @@ +// +// AvatarBookmarks.h +// interface/src +// +// Created by Triplelexx on 23/03/17. +// Copyright 2017 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_AvatarBookmarks_h +#define hifi_AvatarBookmarks_h + +#include +#include "Bookmarks.h" + +class AvatarBookmarks: public Bookmarks, public Dependency { + Q_OBJECT + SINGLETON_DEPENDENCY + +public: + AvatarBookmarks(); + + void setupMenus(Menu* menubar, MenuWrapper* menu) override; + +public slots: + void addBookmark(); + +protected: + void addBookmarkToMenu(Menu* menubar, const QString& name, const QString& address) override; + +private: + const QString AVATARBOOKMARKS_FILENAME = "avatarbookmarks.json"; + +private slots: + void changeToBookmarkedAvatar(); +}; + +#endif // hifi_AvatarBookmarks_h diff --git a/interface/src/Bookmarks.cpp b/interface/src/Bookmarks.cpp index 476925a0c5..4cbc17f8ce 100644 --- a/interface/src/Bookmarks.cpp +++ b/interface/src/Bookmarks.cpp @@ -11,14 +11,10 @@ #include #include -#include -#include #include -#include #include #include -#include #include #include @@ -27,15 +23,69 @@ #include "InterfaceLogging.h" #include "Bookmarks.h" -#include +Bookmarks::Bookmarks() : +_isMenuSorted(false) +{ +} -const QString Bookmarks::HOME_BOOKMARK = "Home"; +void Bookmarks::setupMenus(Menu* menubar, MenuWrapper* menu) { + // Enable/Disable menus as needed + enableMenuItems(_bookmarks.count() > 0); + // Load Bookmarks + for (auto it = _bookmarks.begin(); it != _bookmarks.end(); ++it) { + QString bookmarkName = it.key(); + QString bookmarkAddress = it.value().toString(); + addBookmarkToMenu(menubar, bookmarkName, bookmarkAddress); + } +} -Bookmarks::Bookmarks() { - _bookmarksFilename = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + BOOKMARKS_FILENAME; - readFromFile(); +void Bookmarks::deleteBookmark() { + QStringList bookmarkList; + QList menuItems = _bookmarksMenu->actions(); + for (int i = 0; i < menuItems.count(); ++i) { + bookmarkList.append(menuItems[i]->text()); + } + + bool ok = false; + auto bookmarkName = OffscreenUi::getItem(OffscreenUi::ICON_PLACEMARK, "Delete Bookmark", "Select the bookmark to delete", bookmarkList, 0, false, &ok); + if (!ok) { + return; + } + + bookmarkName = bookmarkName.trimmed(); + if (bookmarkName.length() == 0) { + return; + } + + removeBookmarkFromMenu(Menu::getInstance(), bookmarkName); + remove(bookmarkName); + + if (_bookmarksMenu->actions().count() == 0) { + enableMenuItems(false); + } +} + +void Bookmarks::addBookmarkToFile(const QString& bookmarkName, const QString& bookmarkAddress) { + Menu* menubar = Menu::getInstance(); + if (contains(bookmarkName)) { + auto offscreenUi = DependencyManager::get(); + auto duplicateBookmarkMessage = offscreenUi->createMessageBox(OffscreenUi::ICON_WARNING, "Duplicate Bookmark", + "The bookmark name you entered already exists in your list.", + QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); + duplicateBookmarkMessage->setProperty("informativeText", "Would you like to overwrite it?"); + + auto result = offscreenUi->waitForMessageBoxResult(duplicateBookmarkMessage); + if (result != QMessageBox::Yes) { + return; + } + removeBookmarkFromMenu(menubar, bookmarkName); + } + + addBookmarkToMenu(menubar, bookmarkName, bookmarkAddress); + insert(bookmarkName, bookmarkAddress); // Overwrites any item with the same bookmarkName. + enableMenuItems(true); } void Bookmarks::insert(const QString& name, const QString& address) { @@ -64,6 +114,33 @@ bool Bookmarks::contains(const QString& name) const { return _bookmarks.contains(name); } +bool Bookmarks::sortOrder(QAction* a, QAction* b) { + return a->text().toLower().localeAwareCompare(b->text().toLower()) < 0; +} + +void Bookmarks::sortActions(Menu* menubar, MenuWrapper* menu) { + QList actions = menu->actions(); + qSort(actions.begin(), actions.end(), sortOrder); + for (QAction* action : menu->actions()) { + menu->removeAction(action); + } + for (QAction* action : actions) { + menu->addAction(action); + } + _isMenuSorted = true; +} + +int Bookmarks::getMenuItemLocation(QList actions, const QString& name) const { + int menuItemLocation = 0; + for (QAction* action : actions) { + if (name.toLower().localeAwareCompare(action->text().toLower()) < 0) { + menuItemLocation = actions.indexOf(action); + break; + } + } + return menuItemLocation; +} + QString Bookmarks::addressForBookmark(const QString& name) const { return _bookmarks.value(name).toString(); } @@ -99,108 +176,6 @@ void Bookmarks::persistToFile() { saveFile.write(data); } -void Bookmarks::setupMenus(Menu* menubar, MenuWrapper* menu) { - // Add menus/actions - auto bookmarkAction = menubar->addActionToQMenuAndActionHash(menu, MenuOption::BookmarkLocation); - QObject::connect(bookmarkAction, SIGNAL(triggered()), this, SLOT(bookmarkLocation()), Qt::QueuedConnection); - auto setHomeAction = menubar->addActionToQMenuAndActionHash(menu, MenuOption::SetHomeLocation); - QObject::connect(setHomeAction, SIGNAL(triggered()), this, SLOT(setHomeLocation()), Qt::QueuedConnection); - _bookmarksMenu = menu->addMenu(MenuOption::Bookmarks); - _deleteBookmarksAction = menubar->addActionToQMenuAndActionHash(menu, MenuOption::DeleteBookmark); - QObject::connect(_deleteBookmarksAction, SIGNAL(triggered()), this, SLOT(deleteBookmark()), Qt::QueuedConnection); - - // Enable/Disable menus as needed - enableMenuItems(_bookmarks.count() > 0); - - // Load bookmarks - for (auto it = _bookmarks.begin(); it != _bookmarks.end(); ++it ) { - QString bookmarkName = it.key(); - QString bookmarkAddress = it.value().toString(); - addLocationToMenu(menubar, bookmarkName, bookmarkAddress); - } -} - -void Bookmarks::bookmarkLocation() { - bool ok = false; - auto bookmarkName = OffscreenUi::getText(OffscreenUi::ICON_PLACEMARK, "Bookmark Location", "Name", QString(), &ok); - if (!ok) { - return; - } - - bookmarkName = bookmarkName.trimmed().replace(QRegExp("(\r\n|[\r\n\t\v ])+"), " "); - if (bookmarkName.length() == 0) { - return; - } - - auto addressManager = DependencyManager::get(); - QString bookmarkAddress = addressManager->currentAddress().toString(); - - Menu* menubar = Menu::getInstance(); - if (contains(bookmarkName)) { - auto offscreenUi = DependencyManager::get(); - auto duplicateBookmarkMessage = offscreenUi->createMessageBox(OffscreenUi::ICON_WARNING, "Duplicate Bookmark", - "The bookmark name you entered already exists in your list.", - QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); - duplicateBookmarkMessage->setProperty("informativeText", "Would you like to overwrite it?"); - - auto result = offscreenUi->waitForMessageBoxResult(duplicateBookmarkMessage); - if (result != QMessageBox::Yes) { - return; - } - removeLocationFromMenu(menubar, bookmarkName); - } - - addLocationToMenu(menubar, bookmarkName, bookmarkAddress); - insert(bookmarkName, bookmarkAddress); // Overwrites any item with the same bookmarkName. - - enableMenuItems(true); -} - -void Bookmarks::setHomeLocation() { - Menu* menubar = Menu::getInstance(); - QString bookmarkName = HOME_BOOKMARK; - auto addressManager = DependencyManager::get(); - QString bookmarkAddress = addressManager->currentAddress().toString(); - - addLocationToMenu(menubar, bookmarkName, bookmarkAddress); - insert(bookmarkName, bookmarkAddress); // Overwrites any item with the same bookmarkName. - - enableMenuItems(true); -} - -void Bookmarks::teleportToBookmark() { - QAction* action = qobject_cast(sender()); - QString address = action->data().toString(); - DependencyManager::get()->handleLookupString(address); -} - -void Bookmarks::deleteBookmark() { - - QStringList bookmarkList; - QList menuItems = _bookmarksMenu->actions(); - for (int i = 0; i < menuItems.count(); i += 1) { - bookmarkList.append(menuItems[i]->text()); - } - - bool ok = false; - auto bookmarkName = OffscreenUi::getItem(OffscreenUi::ICON_PLACEMARK, "Delete Bookmark", "Select the bookmark to delete", bookmarkList, 0, false, &ok); - if (!ok) { - return; - } - - bookmarkName = bookmarkName.trimmed(); - if (bookmarkName.length() == 0) { - return; - } - - removeLocationFromMenu(Menu::getInstance(), bookmarkName); - remove(bookmarkName); - - if (_bookmarksMenu->actions().count() == 0) { - enableMenuItems(false); - } -} - void Bookmarks::enableMenuItems(bool enabled) { if (_bookmarksMenu) { _bookmarksMenu->setEnabled(enabled); @@ -210,17 +185,6 @@ void Bookmarks::enableMenuItems(bool enabled) { } } -void Bookmarks::addLocationToMenu(Menu* menubar, QString& name, QString& address) { - QAction* teleportAction = _bookmarksMenu->newAction(); - teleportAction->setData(address); - connect(teleportAction, SIGNAL(triggered()), this, SLOT(teleportToBookmark())); - - menubar->addActionToQMenuAndActionHash(_bookmarksMenu, teleportAction, - name, 0, QAction::NoRole); -} - -void Bookmarks::removeLocationFromMenu(Menu* menubar, QString& name) { +void Bookmarks::removeBookmarkFromMenu(Menu* menubar, const QString& name) { menubar->removeAction(_bookmarksMenu, name); } - - diff --git a/interface/src/Bookmarks.h b/interface/src/Bookmarks.h index fd9598b7db..6c322197cc 100644 --- a/interface/src/Bookmarks.h +++ b/interface/src/Bookmarks.h @@ -27,37 +27,35 @@ class Bookmarks: public QObject { public: Bookmarks(); - void setupMenus(Menu* menubar, MenuWrapper* menu); - + virtual void setupMenus(Menu* menubar, MenuWrapper* menu); QString addressForBookmark(const QString& name) const; - static const QString HOME_BOOKMARK; +protected: + virtual void addBookmarkToFile(const QString& bookmarkName, const QString& bookmarkAddress); + virtual void addBookmarkToMenu(Menu* menubar, const QString& name, const QString& address) = 0; + void enableMenuItems(bool enabled); + void readFromFile(); + void insert(const QString& name, const QString& address); // Overwrites any existing entry with same name. + void sortActions(Menu* menubar, MenuWrapper* menu); + int getMenuItemLocation(QList actions, const QString& name) const; -private slots: - void bookmarkLocation(); - void setHomeLocation(); - void teleportToBookmark(); - void deleteBookmark(); - -private: - QVariantMap _bookmarks; // { name: address, ... } - + QVariantMap _bookmarks; // { name: url, ... } QPointer _bookmarksMenu; QPointer _deleteBookmarksAction; - - const QString BOOKMARKS_FILENAME = "bookmarks.json"; QString _bookmarksFilename; - - void insert(const QString& name, const QString& address); // Overwrites any existing entry with same name. + bool _isMenuSorted; + +protected slots: + void deleteBookmark(); + +private: void remove(const QString& name); bool contains(const QString& name) const; + static bool sortOrder(QAction* a, QAction* b); - void readFromFile(); void persistToFile(); - void enableMenuItems(bool enabled); - void addLocationToMenu(Menu* menubar, QString& name, QString& address); - void removeLocationFromMenu(Menu* menubar, QString& name); + void removeBookmarkFromMenu(Menu* menubar, const QString& name); }; -#endif // hifi_Bookmarks_h \ No newline at end of file +#endif // hifi_Bookmarks_h diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index cf3261ee88..37f53e3cc2 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -98,18 +98,7 @@ void Camera::setMode(CameraMode mode) { emit modeUpdated(modeToString(mode)); } -QUuid Camera::getCameraEntity() const { - if (_cameraEntity != nullptr) { - return _cameraEntity->getID(); - } - return QUuid(); -}; - -void Camera::setCameraEntity(QUuid entityID) { - _cameraEntity = qApp->getEntities()->getTree()->findEntityByID(entityID); -} - -void Camera::setProjection(const glm::mat4& projection) { +void Camera::setProjection(const glm::mat4& projection) { _projection = projection; } @@ -119,7 +108,7 @@ PickRay Camera::computePickRay(float x, float y) { void Camera::setModeString(const QString& mode) { CameraMode targetMode = stringToMode(mode); - + switch (targetMode) { case CAMERA_MODE_FIRST_PERSON: Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, true); @@ -139,7 +128,7 @@ void Camera::setModeString(const QString& mode) { default: break; } - + qApp->cameraMenuChanged(); if (_mode != targetMode) { @@ -177,12 +166,6 @@ void Camera::loadViewFrustum(ViewFrustum& frustum) const { frustum.calculate(); } -ViewFrustum Camera::toViewFrustum() const { - ViewFrustum result; - loadViewFrustum(result); - return result; -} - QVariantMap Camera::getViewFrustum() { ViewFrustum frustum; loadViewFrustum(frustum); diff --git a/interface/src/Camera.h b/interface/src/Camera.h index cedfb3f185..c5a3b192ba 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -43,15 +43,11 @@ class Camera : public QObject { * @property position {Vec3} The position of the camera. * @property orientation {Quat} The orientation of the camera. * @property mode {string} The current camera mode. - * @property cameraEntity {EntityID} The position and rotation properties of - * the entity specified by this ID are then used as the camera's position and - * orientation. Only works when mode is "entity". * @property frustum {Object} The frustum of the camera. */ Q_PROPERTY(glm::vec3 position READ getPosition WRITE setPosition) Q_PROPERTY(glm::quat orientation READ getOrientation WRITE setOrientation) Q_PROPERTY(QString mode READ getModeString WRITE setModeString) - Q_PROPERTY(QUuid cameraEntity READ getCameraEntity WRITE setCameraEntity) Q_PROPERTY(QVariantMap frustum READ getViewFrustum CONSTANT) public: @@ -65,9 +61,6 @@ public: void setMode(CameraMode m); void loadViewFrustum(ViewFrustum& frustum) const; - ViewFrustum toViewFrustum() const; - - EntityItemPointer getCameraEntityPointer() const { return _cameraEntity; } const glm::mat4& getTransform() const { return _transform; } void setTransform(const glm::mat4& transform); @@ -87,9 +80,6 @@ public slots: glm::quat getOrientation() const { return _orientation; } void setOrientation(const glm::quat& orientation); - QUuid getCameraEntity() const; - void setCameraEntity(QUuid entityID); - /**jsdoc * Compute a {PickRay} based on the current camera configuration and the position x,y on the screen. * @function Camera.computePickRay @@ -143,7 +133,6 @@ private: glm::quat _orientation; bool _isKeepLookingAt{ false }; glm::vec3 _lookingAt; - EntityItemPointer _cameraEntity; }; #endif // hifi_Camera_h diff --git a/interface/src/FancyCamera.cpp b/interface/src/FancyCamera.cpp new file mode 100644 index 0000000000..7bb64a4a8e --- /dev/null +++ b/interface/src/FancyCamera.cpp @@ -0,0 +1,25 @@ +// +// FancyCamera.cpp +// interface/src +// +// Copyright 2017 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 "FancyCamera.h" + +#include "Application.h" + + +QUuid FancyCamera::getCameraEntity() const { + if (_cameraEntity != nullptr) { + return _cameraEntity->getID(); + } + return QUuid(); +}; + +void FancyCamera::setCameraEntity(QUuid entityID) { + _cameraEntity = qApp->getEntities()->getTree()->findEntityByID(entityID); +} diff --git a/interface/src/FancyCamera.h b/interface/src/FancyCamera.h new file mode 100644 index 0000000000..cd231cd929 --- /dev/null +++ b/interface/src/FancyCamera.h @@ -0,0 +1,43 @@ +// +// FancyCamera.h +// interface/src +// +// Copyright 2017 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_FancyCamera_h +#define hifi_FancyCamera_h + +#include "Camera.h" + +#include + +// TODO: come up with a better name than "FancyCamera" +class FancyCamera : public Camera { + Q_OBJECT + + /**jsdoc + * @namespace Camera + * @property cameraEntity {EntityID} The position and rotation properties of + * the entity specified by this ID are then used as the camera's position and + * orientation. Only works when mode is "entity". + */ + Q_PROPERTY(QUuid cameraEntity READ getCameraEntity WRITE setCameraEntity) + +public: + FancyCamera() : Camera() {} + + EntityItemPointer getCameraEntityPointer() const { return _cameraEntity; } + +public slots: + QUuid getCameraEntity() const; + void setCameraEntity(QUuid entityID); + +private: + EntityItemPointer _cameraEntity; +}; + +#endif // hifi_FancyCamera_h diff --git a/interface/src/LocationBookmarks.cpp b/interface/src/LocationBookmarks.cpp new file mode 100644 index 0000000000..b79adcf1b7 --- /dev/null +++ b/interface/src/LocationBookmarks.cpp @@ -0,0 +1,88 @@ +// +// LocationBookmarks.cpp +// interface/src +// +// Created by Triplelexx on 23/03/17. +// Copyright 2017 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 "MainWindow.h" +#include "Menu.h" + +#include "LocationBookmarks.h" +#include + +const QString LocationBookmarks::HOME_BOOKMARK = "Home"; + +LocationBookmarks::LocationBookmarks() { + _bookmarksFilename = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + LOCATIONBOOKMARKS_FILENAME; + readFromFile(); +} + +void LocationBookmarks::setupMenus(Menu* menubar, MenuWrapper* menu) { + // Add menus/actions + auto bookmarkAction = menubar->addActionToQMenuAndActionHash(menu, MenuOption::BookmarkLocation); + QObject::connect(bookmarkAction, SIGNAL(triggered()), this, SLOT(addBookmark()), Qt::QueuedConnection); + auto setHomeAction = menubar->addActionToQMenuAndActionHash(menu, MenuOption::SetHomeLocation); + QObject::connect(setHomeAction, SIGNAL(triggered()), this, SLOT(setHomeLocation()), Qt::QueuedConnection); + _bookmarksMenu = menu->addMenu(MenuOption::LocationBookmarks); + _deleteBookmarksAction = menubar->addActionToQMenuAndActionHash(menu, MenuOption::DeleteBookmark); + QObject::connect(_deleteBookmarksAction, SIGNAL(triggered()), this, SLOT(deleteBookmark()), Qt::QueuedConnection); + + Bookmarks::setupMenus(menubar, menu); + Bookmarks::sortActions(menubar, _bookmarksMenu); +} + +void LocationBookmarks::setHomeLocation() { + auto addressManager = DependencyManager::get(); + QString bookmarkAddress = addressManager->currentAddress().toString(); + Bookmarks::addBookmarkToFile(HOME_BOOKMARK, bookmarkAddress); +} + +void LocationBookmarks::teleportToBookmark() { + QAction* action = qobject_cast(sender()); + QString address = action->data().toString(); + DependencyManager::get()->handleLookupString(address); +} + +void LocationBookmarks::addBookmark() { + bool ok = false; + auto bookmarkName = OffscreenUi::getText(OffscreenUi::ICON_PLACEMARK, "Bookmark Location", "Name", QString(), &ok); + if (!ok) { + return; + } + + bookmarkName = bookmarkName.trimmed().replace(QRegExp("(\r\n|[\r\n\t\v ])+"), " "); + if (bookmarkName.length() == 0) { + return; + } + + auto addressManager = DependencyManager::get(); + QString bookmarkAddress = addressManager->currentAddress().toString(); + Bookmarks::addBookmarkToFile(bookmarkName, bookmarkAddress); +} + +void LocationBookmarks::addBookmarkToMenu(Menu* menubar, const QString& name, const QString& address) { + QAction* teleportAction = _bookmarksMenu->newAction(); + teleportAction->setData(address); + connect(teleportAction, SIGNAL(triggered()), this, SLOT(teleportToBookmark())); + if (!_isMenuSorted) { + menubar->addActionToQMenuAndActionHash(_bookmarksMenu, teleportAction, name, 0, QAction::NoRole); + } else { + // TODO: this is aggressive but other alternatives have proved less fruitful so far. + menubar->addActionToQMenuAndActionHash(_bookmarksMenu, teleportAction, name, 0, QAction::NoRole); + Bookmarks::sortActions(menubar, _bookmarksMenu); + } +} diff --git a/interface/src/LocationBookmarks.h b/interface/src/LocationBookmarks.h new file mode 100644 index 0000000000..1324e96574 --- /dev/null +++ b/interface/src/LocationBookmarks.h @@ -0,0 +1,42 @@ +// +// LocationBookmarks.h +// interface/src +// +// Created by Triplelexx on 23/03/17. +// Copyright 2017 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_LocationBookmarks_h +#define hifi_LocationBookmarks_h + +#include +#include "Bookmarks.h" + +class LocationBookmarks : public Bookmarks, public Dependency { + Q_OBJECT + SINGLETON_DEPENDENCY + +public: + LocationBookmarks(); + + void setupMenus(Menu* menubar, MenuWrapper* menu) override; + static const QString HOME_BOOKMARK; + +public slots: + void addBookmark(); + +protected: + void addBookmarkToMenu(Menu* menubar, const QString& name, const QString& address) override; + +private: + const QString LOCATIONBOOKMARKS_FILENAME = "bookmarks.json"; + +private slots: + void setHomeLocation(); + void teleportToBookmark(); +}; + +#endif // hifi_LocationBookmarks_h diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 2451f42bca..c99178d8cc 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -32,6 +32,7 @@ #include "assets/ATPAssetMigrator.h" #include "audio/AudioScope.h" #include "avatar/AvatarManager.h" +#include "AvatarBookmarks.h" #include "devices/DdeFaceTracker.h" #include "devices/Faceshift.h" #include "MainWindow.h" @@ -40,6 +41,7 @@ #include "ui/DialogsManager.h" #include "ui/StandAloneJSConsole.h" #include "InterfaceLogging.h" +#include "LocationBookmarks.h" #if defined(Q_OS_MAC) || defined(Q_OS_WIN) #include "SpeechRecognizer.h" @@ -194,6 +196,9 @@ Menu::Menu() { 0, // QML Qt::Key_Apostrophe, qApp, SLOT(resetSensors())); + // Avatar > AvatarBookmarks related menus -- Note: the AvatarBookmarks class adds its own submenus here. + auto avatarBookmarks = DependencyManager::get(); + avatarBookmarks->setupMenus(this, avatarMenu); // Display menu ---------------------------------- // FIXME - this is not yet matching Alan's spec because it doesn't have @@ -256,8 +261,9 @@ Menu::Menu() { addActionToQMenuAndActionHash(navigateMenu, MenuOption::AddressBar, Qt::CTRL | Qt::Key_L, dialogsManager.data(), SLOT(showAddressBar())); - // Navigate > Bookmark related menus -- Note: the Bookmark class adds its own submenus here. - qApp->getBookmarks()->setupMenus(this, navigateMenu); + // Navigate > LocationBookmarks related menus -- Note: the LocationBookmarks class adds its own submenus here. + auto locationBookmarks = DependencyManager::get(); + locationBookmarks->setupMenus(this, navigateMenu); // Navigate > Copy Address [advanced] auto addressManager = DependencyManager::get(); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 14b2f4aeaa..b6f70f5339 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -47,10 +47,11 @@ namespace MenuOption { const QString AudioTools = "Show Level Meter"; const QString AutoMuteAudio = "Auto Mute Microphone"; const QString AvatarReceiveStats = "Show Receive Stats"; + const QString AvatarBookmarks = "Avatar Bookmarks"; const QString Back = "Back"; const QString BinaryEyelidControl = "Binary Eyelid Control"; + const QString BookmarkAvatar = "Bookmark Avatar"; const QString BookmarkLocation = "Bookmark Location"; - const QString Bookmarks = "Bookmarks"; const QString CalibrateCamera = "Calibrate Camera"; const QString CameraEntityMode = "Entity Mode"; const QString CenterPlayerInView = "Center Player In View"; @@ -78,6 +79,7 @@ namespace MenuOption { const QString DeadlockInterface = "Deadlock Interface"; const QString DecreaseAvatarSize = "Decrease Avatar Size"; const QString DefaultSkybox = "Default Skybox"; + const QString DeleteAvatarBookmark = "Delete Avatar Bookmark..."; const QString DeleteBookmark = "Delete Bookmark..."; const QString DisableActivityLogger = "Disable Activity Logger"; const QString DisableEyelidAdjustment = "Disable Eyelid Adjustment"; @@ -89,6 +91,7 @@ namespace MenuOption { const QString DisplayModelElementChildProxies = "Display Model Element Children"; const QString DisplayModelElementProxy = "Display Model Element Bounds"; const QString DisplayDebugTimingDetails = "Display Timing Details"; + const QString LocationBookmarks = "Bookmarks"; const QString DontDoPrecisionPicking = "Don't Do Precision Picking"; const QString DontRenderEntitiesAsScene = "Don't Render Entities as Scene"; const QString EchoLocalAudio = "Echo Local Audio"; diff --git a/interface/src/Physics.cpp b/interface/src/Physics.cpp deleted file mode 100644 index 7efa520571..0000000000 --- a/interface/src/Physics.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// -// Physics.cpp -// interface/src -// -// 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 "Util.h" -#include "world.h" -#include "Physics.h" - -// -// Applies static friction: maxVelocity is the largest velocity for which there -// there is friction, and strength is the amount of friction force applied to reduce -// velocity. -// -void applyStaticFriction(float deltaTime, glm::vec3& velocity, float maxVelocity, float strength) { - float v = glm::length(velocity); - if (v < maxVelocity) { - velocity *= glm::clamp((1.0f - deltaTime * strength * (1.0f - v / maxVelocity)), 0.0f, 1.0f); - } -} - -// -// Applies velocity damping, with a strength value for linear and squared velocity damping -// - -void applyDamping(float deltaTime, glm::vec3& velocity, float linearStrength, float squaredStrength) { - if (squaredStrength == 0.0f) { - velocity *= glm::clamp(1.0f - deltaTime * linearStrength, 0.0f, 1.0f); - } else { - velocity *= glm::clamp(1.0f - deltaTime * (linearStrength + glm::length(velocity) * squaredStrength), 0.0f, 1.0f); - } -} - -void applyDampedSpring(float deltaTime, glm::vec3& velocity, glm::vec3& position, glm::vec3& targetPosition, float k, float damping) { - -} diff --git a/interface/src/Physics.h b/interface/src/Physics.h deleted file mode 100644 index 97e873d920..0000000000 --- a/interface/src/Physics.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// Physics.h -// interface/src -// -// Created by Philip on 4/25/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_Physics_h -#define hifi_Physics_h - -void applyStaticFriction(float deltaTime, glm::vec3& velocity, float maxVelocity, float strength); -void applyDamping(float deltaTime, glm::vec3& velocity, float linearStrength, float squaredStrength); - -#endif // hifi_Physics_h diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index b4d5fea360..5b996a3cdf 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -9,44 +9,32 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include +#include "Avatar.h" -#include -#include - -#include -#include -#include -#include +#include +#include #include #include -#include -#include +#include #include #include #include #include #include +#include #include #include -#include #include #include -#include "Application.h" -#include "Avatar.h" #include "AvatarManager.h" #include "AvatarMotionState.h" -#include "Head.h" +#include "Camera.h" #include "Menu.h" -#include "Physics.h" -#include "Util.h" -#include "world.h" #include "InterfaceLogging.h" #include "SceneScriptingInterface.h" #include "SoftAttachmentModel.h" -#include using namespace std; @@ -71,7 +59,8 @@ namespace render { auto avatarPtr = static_pointer_cast(avatar); if (avatarPtr->isInitialized() && args) { PROFILE_RANGE_BATCH(*args->_batch, "renderAvatarPayload"); - avatarPtr->render(args, qApp->getCamera()->getPosition()); + // TODO AVATARS_RENDERER: remove need for qApp + avatarPtr->render(args); } } template <> uint32_t metaFetchMetaSubItems(const AvatarSharedPointer& avatar, ItemIDs& subItems) { @@ -85,7 +74,7 @@ namespace render { } } -Avatar::Avatar(RigPointer rig) : +Avatar::Avatar(QThread* thread, RigPointer rig) : AvatarData(), _skeletonOffset(0.0f), _bodyYawDelta(0.0f), @@ -108,7 +97,7 @@ Avatar::Avatar(RigPointer rig) : _voiceSphereID(GeometryCache::UNKNOWN_ID) { // we may have been created in the network thread, but we live in the main thread - moveToThread(qApp->thread()); + moveToThread(thread); setScale(glm::vec3(1.0f)); // avatar scale is uniform @@ -128,7 +117,7 @@ Avatar::Avatar(RigPointer rig) : Avatar::~Avatar() { assert(isDead()); // mark dead before calling the dtor - auto treeRenderer = qApp->getEntities(); + auto treeRenderer = DependencyManager::get(); EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr; if (entityTree) { entityTree->withWriteLock([&] { @@ -237,7 +226,7 @@ void Avatar::updateAvatarEntities() { return; // wait until MyAvatar gets an ID before doing this. } - auto treeRenderer = qApp->getEntities(); + auto treeRenderer = DependencyManager::get(); EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr; if (!entityTree) { return; @@ -518,7 +507,7 @@ static TextRenderer3D* textRenderer(TextRendererType type) { return displayNameRenderer; } -void Avatar::addToScene(AvatarSharedPointer self, std::shared_ptr scene, render::Transaction& transaction) { +void Avatar::addToScene(AvatarSharedPointer self, const render::ScenePointer& scene, render::Transaction& transaction) { auto avatarPayload = new render::Payload(self); auto avatarPayloadPointer = Avatar::PayloadPointer(avatarPayload); _renderItemID = scene->allocateID(); @@ -530,7 +519,7 @@ void Avatar::addToScene(AvatarSharedPointer self, std::shared_ptr } } -void Avatar::removeFromScene(AvatarSharedPointer self, std::shared_ptr scene, render::Transaction& transaction) { +void Avatar::removeFromScene(AvatarSharedPointer self, const render::ScenePointer& scene, render::Transaction& transaction) { transaction.removeItem(_renderItemID); render::Item::clearID(_renderItemID); _skeletonModel->removeFromScene(scene, transaction); @@ -578,11 +567,13 @@ void Avatar::postUpdate(float deltaTime) { } } -void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { - auto& batch = *renderArgs->_batch; +void Avatar::render(RenderArgs* renderArgs) { + auto& batch = *(renderArgs->_batch); PROFILE_RANGE_BATCH(batch, __FUNCTION__); - if (glm::distance(DependencyManager::get()->getMyAvatar()->getPosition(), getPosition()) < 10.0f) { + glm::vec3 viewPos = renderArgs->getViewFrustum().getPosition(); + const float MAX_DISTANCE_SQUARED_FOR_SHOWING_POINTING_LASERS = 100.0f; // 10^2 + if (glm::distance2(viewPos, getPosition()) < MAX_DISTANCE_SQUARED_FOR_SHOWING_POINTING_LASERS) { auto geometryCache = DependencyManager::get(); // render pointing lasers @@ -641,23 +632,16 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { } } - { // simple frustum check - ViewFrustum frustum; - if (renderArgs->_renderMode == RenderArgs::SHADOW_RENDER_MODE) { - qApp->copyShadowViewFrustum(frustum); - } else { - qApp->copyDisplayViewFrustum(frustum); - } - if (!frustum.sphereIntersectsFrustum(getPosition(), getBoundingRadius())) { - return; - } + ViewFrustum frustum = renderArgs->getViewFrustum(); + if (!frustum.sphereIntersectsFrustum(getPosition(), getBoundingRadius())) { + return; } - glm::vec3 toTarget = cameraPosition - getPosition(); + glm::vec3 toTarget = frustum.getPosition() - getPosition(); float distanceToTarget = glm::length(toTarget); { - fixupModelsInScene(); + fixupModelsInScene(renderArgs->_scene); if (renderArgs->_renderMode != RenderArgs::SHADOW_RENDER_MODE) { // add local lights @@ -686,8 +670,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { const float DISPLAYNAME_DISTANCE = 20.0f; setShowDisplayName(distanceToTarget < DISPLAYNAME_DISTANCE); - auto cameraMode = qApp->getCamera()->getMode(); - if (!isMyAvatar() || cameraMode != CAMERA_MODE_FIRST_PERSON) { + if (!isMyAvatar() || renderArgs->_cameraMode != (int8_t)CAMERA_MODE_FIRST_PERSON) { auto& frustum = renderArgs->getViewFrustum(); auto textPosition = getDisplayNamePosition(); if (frustum.pointIntersectsFrustum(textPosition)) { @@ -712,12 +695,11 @@ glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const { return glm::angleAxis(angle * proportion, axis); } -void Avatar::fixupModelsInScene() { +void Avatar::fixupModelsInScene(const render::ScenePointer& scene) { _attachmentsToDelete.clear(); // check to see if when we added our models to the scene they were ready, if they were not ready, then // fix them up in the scene - render::ScenePointer scene = qApp->getMain3DScene(); render::Transaction transaction; if (_skeletonModel->isRenderable() && _skeletonModel->needsFixupInScene()) { _skeletonModel->removeFromScene(scene, transaction); @@ -1490,8 +1472,7 @@ QList Avatar::getSkeleton() { return QList(); } -void Avatar::addToScene(AvatarSharedPointer myHandle) { - render::ScenePointer scene = qApp->getMain3DScene(); +void Avatar::addToScene(AvatarSharedPointer myHandle, const render::ScenePointer& scene) { if (scene) { render::Transaction transaction; auto nodelist = DependencyManager::get(); @@ -1505,8 +1486,9 @@ void Avatar::addToScene(AvatarSharedPointer myHandle) { qCWarning(interfaceapp) << "AvatarManager::addAvatar() : Unexpected null scene, possibly during application shutdown"; } } -void Avatar::ensureInScene(AvatarSharedPointer self) { + +void Avatar::ensureInScene(AvatarSharedPointer self, const render::ScenePointer& scene) { if (!render::Item::isValidID(_renderItemID)) { - addToScene(self); + addToScene(self, scene); } } diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 7b9d331048..8c055885fd 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -14,17 +14,15 @@ #include #include -#include #include #include #include - #include + #include "Head.h" #include "SkeletonModel.h" -#include "world.h" #include "Rig.h" #include @@ -68,7 +66,7 @@ class Avatar : public AvatarData { Q_PROPERTY(glm::vec3 skeletonOffset READ getSkeletonOffset WRITE setSkeletonOffset) public: - explicit Avatar(RigPointer rig = nullptr); + explicit Avatar(QThread* thread, RigPointer rig = nullptr); ~Avatar(); typedef render::Payload Payload; @@ -79,12 +77,12 @@ public: void simulate(float deltaTime, bool inView); virtual void simulateAttachments(float deltaTime); - virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPosition); + virtual void render(RenderArgs* renderArgs); - void addToScene(AvatarSharedPointer self, std::shared_ptr scene, + void addToScene(AvatarSharedPointer self, const render::ScenePointer& scene, render::Transaction& transaction); - void removeFromScene(AvatarSharedPointer self, std::shared_ptr scene, + void removeFromScene(AvatarSharedPointer self, const render::ScenePointer& scene, render::Transaction& transaction); void updateRenderItem(render::Transaction& transaction); @@ -305,7 +303,7 @@ protected: Transform calculateDisplayNameTransform(const ViewFrustum& view, const glm::vec3& textPosition) const; void renderDisplayName(gpu::Batch& batch, const ViewFrustum& view, const glm::vec3& textPosition) const; virtual bool shouldRenderHead(const RenderArgs* renderArgs) const; - virtual void fixupModelsInScene(); + virtual void fixupModelsInScene(const render::ScenePointer& scene); virtual void updatePalms(); @@ -316,8 +314,8 @@ protected: ThreadSafeValueCache _rightPalmPositionCache { glm::vec3() }; ThreadSafeValueCache _rightPalmRotationCache { glm::quat() }; - void addToScene(AvatarSharedPointer self); - void ensureInScene(AvatarSharedPointer self); + void addToScene(AvatarSharedPointer self, const render::ScenePointer& scene); + void ensureInScene(AvatarSharedPointer self, const render::ScenePointer& scene); bool isInScene() const { return render::Item::isValidID(_renderItemID); } // Some rate tracking support diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index f1170a7085..585776b395 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -69,7 +69,7 @@ void AvatarManager::registerMetaTypes(QScriptEngine* engine) { AvatarManager::AvatarManager(QObject* parent) : _avatarsToFade(), - _myAvatar(std::make_shared(std::make_shared())) + _myAvatar(std::make_shared(qApp->thread(), std::make_shared())) { // register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar qRegisterMetaType >("NodeWeakPointer"); @@ -105,7 +105,7 @@ void AvatarManager::init() { this, &AvatarManager::updateAvatarRenderStatus, Qt::QueuedConnection); if (_shouldRender) { - render::ScenePointer scene = qApp->getMain3DScene(); + const render::ScenePointer& scene = qApp->getMain3DScene(); render::Transaction transaction; _myAvatar->addToScene(_myAvatar, scene, transaction); scene->enqueueTransaction(transaction); @@ -198,7 +198,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { // for ALL avatars... if (_shouldRender) { - avatar->ensureInScene(avatar); + avatar->ensureInScene(avatar, qApp->getMain3DScene()); } if (!avatar->getMotionState()) { ShapeInfo shapeInfo; @@ -306,12 +306,10 @@ void AvatarManager::simulateAvatarFades(float deltaTime) { if (avatar->getTargetScale() <= MIN_FADE_SCALE) { // fading to zero is such a rare event we push unique transaction for each one if (avatar->isInScene()) { - render::ScenePointer scene = qApp->getMain3DScene(); + const render::ScenePointer& scene = qApp->getMain3DScene(); render::Transaction transaction; avatar->removeFromScene(*itr, scene, transaction); - if (scene) { - scene->enqueueTransaction(transaction); - } + scene->enqueueTransaction(transaction); } // only remove from _avatarsToFade if we're sure its motionState has been removed from PhysicsEngine @@ -329,7 +327,7 @@ void AvatarManager::simulateAvatarFades(float deltaTime) { } AvatarSharedPointer AvatarManager::newSharedAvatar() { - return std::make_shared(std::make_shared()); + return std::make_shared(qApp->thread(), std::make_shared()); } void AvatarManager::processAvatarDataPacket(QSharedPointer message, SharedNodePointer sendingNode) { @@ -343,19 +341,19 @@ void AvatarManager::processAvatarDataPacket(QSharedPointer mess if (avatar->isInScene()) { if (!_shouldRender) { // rare transition so we process the transaction immediately - render::ScenePointer scene = qApp->getMain3DScene(); + const render::ScenePointer& scene = qApp->getMain3DScene(); + render::Transaction transaction; + avatar->removeFromScene(avatar, scene, transaction); if (scene) { - render::Transaction transaction; - avatar->removeFromScene(avatar, scene, transaction); scene->enqueueTransaction(transaction); } } } else if (_shouldRender) { // very rare transition so we process the transaction immediately - render::ScenePointer scene = qApp->getMain3DScene(); + const render::ScenePointer& scene = qApp->getMain3DScene(); + render::Transaction transaction; + avatar->addToScene(avatar, scene, transaction); if (scene) { - render::Transaction transaction; - avatar->addToScene(avatar, scene, transaction); scene->enqueueTransaction(transaction); } } @@ -394,7 +392,7 @@ void AvatarManager::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar void AvatarManager::clearOtherAvatars() { // Remove other avatars from the world but don't actually remove them from _avatarHash // each will either be removed on timeout or will re-added to the world on receipt of update. - render::ScenePointer scene = qApp->getMain3DScene(); + const render::ScenePointer& scene = qApp->getMain3DScene(); render::Transaction transaction; QReadLocker locker(&_hashLock); @@ -414,9 +412,7 @@ void AvatarManager::clearOtherAvatars() { } ++avatarIterator; } - if (scene) { - scene->enqueueTransaction(transaction); - } + scene->enqueueTransaction(transaction); _myAvatar->clearLookAtTargetAvatar(); } @@ -522,7 +518,7 @@ void AvatarManager::handleCollisionEvents(const CollisionEvents& collisionEvents void AvatarManager::updateAvatarRenderStatus(bool shouldRenderAvatars) { _shouldRender = shouldRenderAvatars; - render::ScenePointer scene = qApp->getMain3DScene(); + const render::ScenePointer& scene = qApp->getMain3DScene(); render::Transaction transaction; if (_shouldRender) { for (auto avatarData : _avatarHash) { @@ -535,9 +531,7 @@ void AvatarManager::updateAvatarRenderStatus(bool shouldRenderAvatars) { avatar->removeFromScene(avatar, scene, transaction); } } - if (scene) { - scene->enqueueTransaction(transaction); - } + scene->enqueueTransaction(transaction); } AvatarSharedPointer AvatarManager::getAvatarBySessionID(const QUuid& sessionID) const { diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index b86de68894..6eabbd081f 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -23,6 +23,7 @@ #include #include "Avatar.h" +#include "MyAvatar.h" #include "AvatarMotionState.h" #include "ScriptAvatar.h" @@ -42,6 +43,7 @@ public: void init(); std::shared_ptr getMyAvatar() { return _myAvatar; } + glm::vec3 getMyAvatarPosition() const { return _myAvatar->getPosition(); } // Null/Default-constructed QUuids will return MyAvatar Q_INVOKABLE virtual ScriptAvatarData* getAvatar(QUuid avatarID) override { return new ScriptAvatar(getAvatarBySessionID(avatarID)); } @@ -110,7 +112,7 @@ private: QVector _avatarsToFade; - SetOfAvatarMotionStates _motionStatesThatMightUpdate; + QSet _motionStatesThatMightUpdate; VectorOfMotionStates _motionStatesToRemoveFromPhysics; SetOfMotionStates _motionStatesToAddToPhysics; diff --git a/interface/src/avatar/AvatarMotionState.h b/interface/src/avatar/AvatarMotionState.h index 66824d6e37..98b2b69373 100644 --- a/interface/src/avatar/AvatarMotionState.h +++ b/interface/src/avatar/AvatarMotionState.h @@ -83,6 +83,4 @@ protected: uint32_t _dirtyFlags; }; -typedef QSet SetOfAvatarMotionStates; - #endif // hifi_AvatarMotionState_h diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index da09bfba7e..f4f078c9e5 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -48,7 +48,6 @@ #include "AvatarActionHold.h" #include "Menu.h" #include "MyAvatar.h" -#include "Physics.h" #include "Util.h" #include "InterfaceLogging.h" #include "DebugDraw.h" @@ -83,8 +82,8 @@ const float MyAvatar::ZOOM_MIN = 0.5f; const float MyAvatar::ZOOM_MAX = 25.0f; const float MyAvatar::ZOOM_DEFAULT = 1.5f; -MyAvatar::MyAvatar(RigPointer rig) : - Avatar(rig), +MyAvatar::MyAvatar(QThread* thread, RigPointer rig) : + Avatar(thread, rig), _wasPushing(false), _isPushing(false), _isBeingPushed(false), @@ -260,7 +259,7 @@ void MyAvatar::simulateAttachments(float deltaTime) { } QByteArray MyAvatar::toByteArrayStateful(AvatarDataDetail dataDetail) { - CameraMode mode = qApp->getCamera()->getMode(); + CameraMode mode = qApp->getCamera().getMode(); _globalPosition = getPosition(); _globalBoundingBoxDimensions.x = _characterController.getCapsuleRadius(); _globalBoundingBoxDimensions.y = _characterController.getCapsuleHalfHeight(); @@ -752,13 +751,12 @@ controller::Pose MyAvatar::getRightHandTipPose() const { } // virtual -void MyAvatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { +void MyAvatar::render(RenderArgs* renderArgs) { // don't render if we've been asked to disable local rendering if (!_shouldRender) { return; // exit early } - - Avatar::render(renderArgs, cameraPosition); + Avatar::render(renderArgs); } void MyAvatar::overrideAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame) { @@ -927,8 +925,7 @@ void MyAvatar::setEnableDebugDrawIKTargets(bool isEnabled) { } void MyAvatar::setEnableMeshVisible(bool isEnabled) { - render::ScenePointer scene = qApp->getMain3DScene(); - _skeletonModel->setVisibleInScene(isEnabled, scene); + _skeletonModel->setVisibleInScene(isEnabled, qApp->getMain3DScene()); } void MyAvatar::setUseAnimPreAndPostRotations(bool isEnabled) { @@ -1079,7 +1076,7 @@ void MyAvatar::updateLookAtTargetAvatar() { _targetAvatarPosition = glm::vec3(0.0f); glm::vec3 lookForward = getHead()->getFinalOrientationInWorldFrame() * IDENTITY_FORWARD; - glm::vec3 cameraPosition = qApp->getCamera()->getPosition(); + glm::vec3 cameraPosition = qApp->getCamera().getPosition(); float smallestAngleTo = glm::radians(DEFAULT_FIELD_OF_VIEW_DEGREES) / 2.0f; const float KEEP_LOOKING_AT_CURRENT_ANGLE_FACTOR = 1.3f; @@ -1225,8 +1222,7 @@ void MyAvatar::clearJointsData() { void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { Avatar::setSkeletonModelURL(skeletonModelURL); - render::ScenePointer scene = qApp->getMain3DScene(); - _skeletonModel->setVisibleInScene(true, scene); + _skeletonModel->setVisibleInScene(true, qApp->getMain3DScene()); _headBoneSet.clear(); } @@ -1275,7 +1271,7 @@ void MyAvatar::setAttachmentData(const QVector& attachmentData) } glm::vec3 MyAvatar::getSkeletonPosition() const { - CameraMode mode = qApp->getCamera()->getMode(); + CameraMode mode = qApp->getCamera().getMode(); if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT) { // The avatar is rotated PI about the yAxis, so we have to correct for it // to get the skeleton offset contribution in the world-frame. @@ -1540,7 +1536,7 @@ void MyAvatar::attach(const QString& modelURL, const QString& jointName, Avatar::attach(modelURL, jointName, translation, rotation, scale, isSoft, allowDuplicates, useSaved); } -void MyAvatar::setVisibleInSceneIfReady(Model* model, render::ScenePointer scene, bool visible) { +void MyAvatar::setVisibleInSceneIfReady(Model* model, const render::ScenePointer& scene, bool visible) { if (model->isActive() && model->isRenderable()) { model->setVisibleInScene(visible, scene); } @@ -1634,8 +1630,7 @@ void MyAvatar::postUpdate(float deltaTime) { Avatar::postUpdate(deltaTime); - render::ScenePointer scene = qApp->getMain3DScene(); - if (DependencyManager::get()->shouldRenderAvatars() && _skeletonModel->initWhenReady(scene)) { + if (DependencyManager::get()->shouldRenderAvatars() && _skeletonModel->initWhenReady(qApp->getMain3DScene())) { initHeadBones(); _skeletonModel->setCauterizeBoneSet(_headBoneSet); _fstAnimGraphOverrideUrl = _skeletonModel->getGeometry()->getAnimGraphOverrideUrl(); @@ -1704,13 +1699,13 @@ void MyAvatar::preDisplaySide(RenderArgs* renderArgs) { const float RENDER_HEAD_CUTOFF_DISTANCE = 0.3f; bool MyAvatar::cameraInsideHead() const { - const glm::vec3 cameraPosition = qApp->getCamera()->getPosition(); + const glm::vec3 cameraPosition = qApp->getCamera().getPosition(); return glm::length(cameraPosition - getHeadPosition()) < (RENDER_HEAD_CUTOFF_DISTANCE * getUniformScale()); } bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const { bool defaultMode = renderArgs->_renderMode == RenderArgs::DEFAULT_RENDER_MODE; - bool firstPerson = qApp->getCamera()->getMode() == CAMERA_MODE_FIRST_PERSON; + bool firstPerson = qApp->getCamera().getMode() == CAMERA_MODE_FIRST_PERSON; bool insideHead = cameraInsideHead(); return !defaultMode || !firstPerson || !insideHead; } @@ -2265,7 +2260,7 @@ glm::vec3 MyAvatar::getPositionForAudio() { case AudioListenerMode::FROM_HEAD: return getHead()->getPosition(); case AudioListenerMode::FROM_CAMERA: - return qApp->getCamera()->getPosition(); + return qApp->getCamera().getPosition(); case AudioListenerMode::CUSTOM: return _customListenPosition; } @@ -2277,7 +2272,7 @@ glm::quat MyAvatar::getOrientationForAudio() { case AudioListenerMode::FROM_HEAD: return getHead()->getFinalOrientationInWorldFrame(); case AudioListenerMode::FROM_CAMERA: - return qApp->getCamera()->getOrientation(); + return qApp->getCamera().getOrientation(); case AudioListenerMode::CUSTOM: return _customListenOrientation; } @@ -2367,7 +2362,7 @@ void MyAvatar::FollowHelper::decrementTimeRemaining(float dt) { } bool MyAvatar::FollowHelper::shouldActivateRotation(const MyAvatar& myAvatar, const glm::mat4& desiredBodyMatrix, const glm::mat4& currentBodyMatrix) const { - auto cameraMode = qApp->getCamera()->getMode(); + auto cameraMode = qApp->getCamera().getMode(); if (cameraMode == CAMERA_MODE_THIRD_PERSON) { return false; } else { @@ -2515,8 +2510,8 @@ void MyAvatar::setAway(bool value) { glm::mat4 MyAvatar::computeCameraRelativeHandControllerMatrix(const glm::mat4& controllerSensorMatrix) const { // Fetch the current camera transform. - glm::mat4 cameraWorldMatrix = qApp->getCamera()->getTransform(); - if (qApp->getCamera()->getMode() == CAMERA_MODE_MIRROR) { + glm::mat4 cameraWorldMatrix = qApp->getCamera().getTransform(); + if (qApp->getCamera().getMode() == CAMERA_MODE_MIRROR) { cameraWorldMatrix *= createMatFromScaleQuatAndPos(vec3(-1.0f, 1.0f, 1.0f), glm::quat(), glm::vec3()); } @@ -2561,7 +2556,7 @@ glm::quat MyAvatar::getAbsoluteJointRotationInObjectFrame(int index) const { Transform avatarTransform; Transform::mult(avatarTransform, getParentTransform(success), getLocalTransform()); glm::mat4 invAvatarMat = avatarTransform.getInverseMatrix(); - return glmExtractRotation(invAvatarMat * qApp->getCamera()->getTransform()); + return glmExtractRotation(invAvatarMat * qApp->getCamera().getTransform()); } default: { return Avatar::getAbsoluteJointRotationInObjectFrame(index); @@ -2598,7 +2593,7 @@ glm::vec3 MyAvatar::getAbsoluteJointTranslationInObjectFrame(int index) const { Transform avatarTransform; Transform::mult(avatarTransform, getParentTransform(success), getLocalTransform()); glm::mat4 invAvatarMat = avatarTransform.getInverseMatrix(); - return extractTranslation(invAvatarMat * qApp->getCamera()->getTransform()); + return extractTranslation(invAvatarMat * qApp->getCamera().getTransform()); } default: { return Avatar::getAbsoluteJointTranslationInObjectFrame(index); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 097d3a1059..74af44c99a 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -146,7 +146,7 @@ public: }; Q_ENUM(DriveKeys) - explicit MyAvatar(RigPointer rig); + explicit MyAvatar(QThread* thread, RigPointer rig); ~MyAvatar(); void registerMetaTypes(QScriptEngine* engine); @@ -525,7 +525,7 @@ private: void simulate(float deltaTime); void updateFromTrackers(float deltaTime); - virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPositio) override; + virtual void render(RenderArgs* renderArgs) override; virtual bool shouldRenderHead(const RenderArgs* renderArgs) const override; void setShouldRenderLocally(bool shouldRender) { _shouldRender = shouldRender; setEnableMeshVisible(shouldRender); } bool getShouldRenderLocally() const { return _shouldRender; } @@ -551,7 +551,7 @@ private: // These are made private for MyAvatar so that you will use the "use" methods instead virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override; - void setVisibleInSceneIfReady(Model* model, render::ScenePointer scene, bool visiblity); + void setVisibleInSceneIfReady(Model* model, const render::ScenePointer& scene, bool visiblity); // derive avatar body position and orientation from the current HMD Sensor location. // results are in HMD frame diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index e2fed40a6d..95bf5eb028 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -105,9 +105,9 @@ QScriptValue HMDScriptingInterface::getHUDLookAtPosition3D(QScriptContext* conte } bool HMDScriptingInterface::getHUDLookAtPosition3D(glm::vec3& result) const { - Camera* camera = qApp->getCamera(); - glm::vec3 position = camera->getPosition(); - glm::quat orientation = camera->getOrientation(); + const Camera& camera = qApp->getCamera(); + glm::vec3 position = camera.getPosition(); + glm::quat orientation = camera.getOrientation(); glm::vec3 direction = orientation * glm::vec3(0.0f, 0.0f, -1.0f); diff --git a/interface/src/ui/AddressBarDialog.cpp b/interface/src/ui/AddressBarDialog.cpp index ac566d68c7..8aaaac1a57 100644 --- a/interface/src/ui/AddressBarDialog.cpp +++ b/interface/src/ui/AddressBarDialog.cpp @@ -17,6 +17,7 @@ #include "DependencyManager.h" #include "AddressManager.h" #include "DialogsManager.h" +#include "LocationBookmarks.h" HIFI_QML_DEF(AddressBarDialog) @@ -52,7 +53,8 @@ void AddressBarDialog::loadAddress(const QString& address, bool fromSuggestions) void AddressBarDialog::loadHome() { qDebug() << "Called LoadHome"; - QString homeLocation = qApp->getBookmarks()->addressForBookmark(Bookmarks::HOME_BOOKMARK); + auto locationBookmarks = DependencyManager::get(); + QString homeLocation = locationBookmarks->addressForBookmark(LocationBookmarks::HOME_BOOKMARK); const QString DEFAULT_HOME_LOCATION = "localhost"; if (homeLocation == "") { homeLocation = DEFAULT_HOME_LOCATION; diff --git a/interface/src/ui/overlays/Billboardable.cpp b/interface/src/ui/overlays/Billboardable.cpp index a6226a46b0..a01d62bfd1 100644 --- a/interface/src/ui/overlays/Billboardable.cpp +++ b/interface/src/ui/overlays/Billboardable.cpp @@ -31,7 +31,7 @@ QVariant Billboardable::getProperty(const QString &property) { void Billboardable::pointTransformAtCamera(Transform& transform, glm::quat offsetRotation) { if (isFacingAvatar()) { glm::vec3 billboardPos = transform.getTranslation(); - glm::vec3 cameraPos = qApp->getCamera()->getPosition(); + glm::vec3 cameraPos = qApp->getCamera().getPosition(); glm::vec3 look = cameraPos - billboardPos; float elevation = -asinf(look.y / glm::length(look)); float azimuth = atan2f(look.x, look.z); diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index 98ca7110ae..ccaa1d4fbc 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -58,13 +58,13 @@ void ModelOverlay::update(float deltatime) { _isLoaded = _model->isActive(); } -bool ModelOverlay::addToScene(Overlay::Pointer overlay, std::shared_ptr scene, render::Transaction& transaction) { +bool ModelOverlay::addToScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction) { Volume3DOverlay::addToScene(overlay, scene, transaction); _model->addToScene(scene, transaction); return true; } -void ModelOverlay::removeFromScene(Overlay::Pointer overlay, std::shared_ptr scene, render::Transaction& transaction) { +void ModelOverlay::removeFromScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction) { Volume3DOverlay::removeFromScene(overlay, scene, transaction); _model->removeFromScene(scene, transaction); } diff --git a/interface/src/ui/overlays/ModelOverlay.h b/interface/src/ui/overlays/ModelOverlay.h index 245688156f..a3ddeed480 100644 --- a/interface/src/ui/overlays/ModelOverlay.h +++ b/interface/src/ui/overlays/ModelOverlay.h @@ -36,8 +36,8 @@ public: virtual ModelOverlay* createClone() const override; - virtual bool addToScene(Overlay::Pointer overlay, std::shared_ptr scene, render::Transaction& transaction) override; - virtual void removeFromScene(Overlay::Pointer overlay, std::shared_ptr scene, render::Transaction& transaction) override; + virtual bool addToScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction) override; + virtual void removeFromScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction) override; void locationChanged(bool tellPhysics) override; diff --git a/interface/src/ui/overlays/Overlay.cpp b/interface/src/ui/overlays/Overlay.cpp index e3004bd9c6..b650da3522 100644 --- a/interface/src/ui/overlays/Overlay.cpp +++ b/interface/src/ui/overlays/Overlay.cpp @@ -196,13 +196,13 @@ float Overlay::updatePulse() { return _pulse; } -bool Overlay::addToScene(Overlay::Pointer overlay, std::shared_ptr scene, render::Transaction& transaction) { +bool Overlay::addToScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction) { _renderItemID = scene->allocateID(); transaction.resetItem(_renderItemID, std::make_shared(overlay)); return true; } -void Overlay::removeFromScene(Overlay::Pointer overlay, std::shared_ptr scene, render::Transaction& transaction) { +void Overlay::removeFromScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction) { transaction.removeItem(_renderItemID); render::Item::clearID(_renderItemID); } diff --git a/interface/src/ui/overlays/Overlay.h b/interface/src/ui/overlays/Overlay.h index 9849c71a1f..4ad1b070b1 100644 --- a/interface/src/ui/overlays/Overlay.h +++ b/interface/src/ui/overlays/Overlay.h @@ -48,8 +48,8 @@ public: virtual AABox getBounds() const = 0; virtual bool supportsGetProperty() const { return true; } - virtual bool addToScene(Overlay::Pointer overlay, std::shared_ptr scene, render::Transaction& transaction); - virtual void removeFromScene(Overlay::Pointer overlay, std::shared_ptr scene, render::Transaction& transaction); + virtual bool addToScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction); + virtual void removeFromScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction); virtual const render::ShapeKey getShapeKey() { return render::ShapeKey::Builder::ownPipeline(); } diff --git a/libraries/entities-renderer/src/RenderableEntityItem.h b/libraries/entities-renderer/src/RenderableEntityItem.h index 2f053924ab..1c08707e82 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.h +++ b/libraries/entities-renderer/src/RenderableEntityItem.h @@ -54,7 +54,7 @@ namespace render { // Mixin class for implementing basic single item rendering class SimpleRenderableEntityItem { public: - bool addToScene(EntityItemPointer self, std::shared_ptr scene, render::Transaction& transaction) { + bool addToScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) { _myItem = scene->allocateID(); auto renderData = std::make_shared(self, _myItem); @@ -69,7 +69,7 @@ public: return true; } - void removeFromScene(EntityItemPointer self, std::shared_ptr scene, render::Transaction& transaction) { + void removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) { transaction.removeItem(_myItem); render::Item::clearID(_myItem); } @@ -99,8 +99,8 @@ private: #define SIMPLE_RENDERABLE() \ public: \ - virtual bool addToScene(EntityItemPointer self, std::shared_ptr scene, render::Transaction& transaction) override { return _renderHelper.addToScene(self, scene, transaction); } \ - virtual void removeFromScene(EntityItemPointer self, std::shared_ptr scene, render::Transaction& transaction) override { _renderHelper.removeFromScene(self, scene, transaction); } \ + virtual bool addToScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) override { return _renderHelper.addToScene(self, scene, transaction); } \ + virtual void removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) override { _renderHelper.removeFromScene(self, scene, transaction); } \ virtual void locationChanged(bool tellPhysics = true) override { EntityItem::locationChanged(tellPhysics); _renderHelper.notifyChanged(); } \ virtual void dimensionsChanged() override { EntityItem::dimensionsChanged(); _renderHelper.notifyChanged(); } \ void checkFading() { \ diff --git a/libraries/entities-renderer/src/RenderableLightEntityItem.cpp b/libraries/entities-renderer/src/RenderableLightEntityItem.cpp index 0b8592e678..cc292759f0 100644 --- a/libraries/entities-renderer/src/RenderableLightEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableLightEntityItem.cpp @@ -27,7 +27,7 @@ RenderableLightEntityItem::RenderableLightEntityItem(const EntityItemID& entityI { } -bool RenderableLightEntityItem::addToScene(EntityItemPointer self, std::shared_ptr scene, render::Transaction& transaction) { +bool RenderableLightEntityItem::addToScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) { _myItem = scene->allocateID(); auto renderItem = std::make_shared(); @@ -51,7 +51,7 @@ void RenderableLightEntityItem::somethingChangedNotification() { LightEntityItem::somethingChangedNotification(); } -void RenderableLightEntityItem::removeFromScene(EntityItemPointer self, std::shared_ptr scene, render::Transaction& transaction) { +void RenderableLightEntityItem::removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) { transaction.removeItem(_myItem); render::Item::clearID(_myItem); } diff --git a/libraries/entities-renderer/src/RenderableLightEntityItem.h b/libraries/entities-renderer/src/RenderableLightEntityItem.h index 42a5dbc91a..3676023bed 100644 --- a/libraries/entities-renderer/src/RenderableLightEntityItem.h +++ b/libraries/entities-renderer/src/RenderableLightEntityItem.h @@ -30,10 +30,10 @@ public: void updateLightFromEntity(render::Transaction& transaction); - virtual bool addToScene(EntityItemPointer self, std::shared_ptr scene, render::Transaction& transaction) override; + virtual bool addToScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) override; virtual void somethingChangedNotification() override; - virtual void removeFromScene(EntityItemPointer self, std::shared_ptr scene, render::Transaction& transaction) override; + virtual void removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) override; virtual void locationChanged(bool tellPhysics = true) override; diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 99669ef3bf..8b1ba75259 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -91,13 +91,13 @@ bool RenderableModelEntityItem::setProperties(const EntityItemProperties& proper return somethingChanged; } -int RenderableModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, +int RenderableModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, EntityPropertyFlags& propertyFlags, bool overwriteLocalData, bool& somethingChanged) { QString oldModelURL = getModelURL(); - int bytesRead = ModelEntityItem::readEntitySubclassDataFromBuffer(data, bytesLeftToRead, - args, propertyFlags, + int bytesRead = ModelEntityItem::readEntitySubclassDataFromBuffer(data, bytesLeftToRead, + args, propertyFlags, overwriteLocalData, somethingChanged); if (oldModelURL != getModelURL()) { _needsModelReload = true; @@ -137,7 +137,7 @@ void RenderableModelEntityItem::remapTextures() { if (!_model) { return; // nothing to do if we don't have a model } - + if (!_model->isLoaded()) { return; // nothing to do if the model has not yet loaded } @@ -189,16 +189,16 @@ public: RenderableModelEntityItemMeta(EntityItemPointer entity) : entity(entity){ } typedef render::Payload Payload; typedef Payload::DataPointer Pointer; - + EntityItemPointer entity; }; namespace render { - template <> const ItemKey payloadGetKey(const RenderableModelEntityItemMeta::Pointer& payload) { + template <> const ItemKey payloadGetKey(const RenderableModelEntityItemMeta::Pointer& payload) { return ItemKey::Builder::opaqueShape().withTypeMeta(); } - - template <> const Item::Bound payloadGetBound(const RenderableModelEntityItemMeta::Pointer& payload) { + + template <> const Item::Bound payloadGetBound(const RenderableModelEntityItemMeta::Pointer& payload) { if (payload && payload->entity) { bool success; auto result = payload->entity->getAABox(success); @@ -228,7 +228,7 @@ namespace render { } } -bool RenderableModelEntityItem::addToScene(EntityItemPointer self, std::shared_ptr scene, +bool RenderableModelEntityItem::addToScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) { _myMetaItem = scene->allocateID(); @@ -249,7 +249,7 @@ bool RenderableModelEntityItem::addToScene(EntityItemPointer self, std::shared_p return true; } -void RenderableModelEntityItem::removeFromScene(EntityItemPointer self, std::shared_ptr scene, +void RenderableModelEntityItem::removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) { transaction.removeItem(_myMetaItem); render::Item::clearID(_myMetaItem); @@ -437,7 +437,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) { _model->renderDebugMeshBoxes(batch); #endif - render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); + const render::ScenePointer& scene = AbstractViewStateInterface::instance()->getMain3DScene(); // FIXME: this seems like it could be optimized if we tracked our last known visible state in // the renderable item. As it stands now the model checks it's visible/invisible state @@ -502,11 +502,11 @@ ModelPointer RenderableModelEntityItem::getModel(QSharedPointerthread()) { return _model; } - + _needsModelReload = false; // this is the reload // If we have a URL, then we will want to end up returning a model... @@ -526,7 +526,7 @@ ModelPointer RenderableModelEntityItem::getModel(QSharedPointergetMain3DScene(); + const render::ScenePointer& scene = AbstractViewStateInterface::instance()->getMain3DScene(); render::Transaction transaction; _model->removeFromScene(scene, transaction); scene->enqueueTransaction(transaction); @@ -552,7 +552,7 @@ void RenderableModelEntityItem::update(const quint64& now) { properties.setLastEdited(usecTimestampNow()); // we must set the edit time since we're editing it auto extents = _model->getMeshExtents(); properties.setDimensions(extents.maximum - extents.minimum); - qCDebug(entitiesrenderer) << "Autoresizing" << (!getName().isEmpty() ? getName() : getModelURL()) + qCDebug(entitiesrenderer) << "Autoresizing" << (!getName().isEmpty() ? getName() : getModelURL()) << "from mesh extents"; QMetaObject::invokeMethod(DependencyManager::get().data(), "editEntity", Qt::QueuedConnection, @@ -594,8 +594,8 @@ bool RenderableModelEntityItem::supportsDetailedRayIntersection() const { return _model && _model->isLoaded(); } -bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElementPointer& element, float& distance, BoxFace& face, +bool RenderableModelEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, + bool& keepSearching, OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, void** intersectedObject, bool precisionPicking) const { if (!_model) { return true; @@ -1239,11 +1239,10 @@ void RenderableModelEntityItem::locationChanged(bool tellPhysics) { return; } - render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); render::Transaction transaction; transaction.updateItem(myMetaItem); - scene->enqueueTransaction(transaction); + AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction); }); } } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 7eab5172d8..b440aacd7e 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -40,8 +40,8 @@ public: void doInitialModelSimulation(); - virtual bool addToScene(EntityItemPointer self, std::shared_ptr scene, render::Transaction& transaction) override; - virtual void removeFromScene(EntityItemPointer self, std::shared_ptr scene, render::Transaction& transaction) override; + virtual bool addToScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) override; + virtual void removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) override; void updateModelBounds(); diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index fdf9ba888f..34dc86d92a 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -161,7 +161,7 @@ RenderableParticleEffectEntityItem::RenderableParticleEffectEntityItem(const Ent } bool RenderableParticleEffectEntityItem::addToScene(EntityItemPointer self, - render::ScenePointer scene, + const render::ScenePointer& scene, render::Transaction& transaction) { _scene = scene; _renderItemId = _scene->allocateID(); @@ -176,7 +176,7 @@ bool RenderableParticleEffectEntityItem::addToScene(EntityItemPointer self, } void RenderableParticleEffectEntityItem::removeFromScene(EntityItemPointer self, - render::ScenePointer scene, + const render::ScenePointer& scene, render::Transaction& transaction) { transaction.removeItem(_renderItemId); _scene = nullptr; @@ -323,4 +323,4 @@ void RenderableParticleEffectEntityItem::notifyBoundChanged() { }); _scene->enqueueTransaction(transaction); -} \ No newline at end of file +} diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h index 9b31c92b07..daa6ba0691 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.h @@ -25,8 +25,8 @@ public: void updateRenderItem(); - virtual bool addToScene(EntityItemPointer self, render::ScenePointer scene, render::Transaction& transaction) override; - virtual void removeFromScene(EntityItemPointer self, render::ScenePointer scene, render::Transaction& transaction) override; + virtual bool addToScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) override; + virtual void removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) override; protected: virtual void locationChanged(bool tellPhysics = true) override { EntityItem::locationChanged(tellPhysics); notifyBoundChanged(); } diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index ee3b068af9..fd5346093b 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -816,7 +816,7 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) { } bool RenderablePolyVoxEntityItem::addToScene(EntityItemPointer self, - std::shared_ptr scene, + const render::ScenePointer& scene, render::Transaction& transaction) { _myItem = scene->allocateID(); @@ -834,7 +834,7 @@ bool RenderablePolyVoxEntityItem::addToScene(EntityItemPointer self, } void RenderablePolyVoxEntityItem::removeFromScene(EntityItemPointer self, - std::shared_ptr scene, + const render::ScenePointer& scene, render::Transaction& transaction) { transaction.removeItem(_myItem); render::Item::clearID(_myItem); diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h index c0bc8ba610..ff97f09ee1 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h @@ -106,10 +106,10 @@ public: virtual void setZTextureURL(const QString& zTextureURL) override; virtual bool addToScene(EntityItemPointer self, - std::shared_ptr scene, + const render::ScenePointer& scene, render::Transaction& transaction) override; virtual void removeFromScene(EntityItemPointer self, - std::shared_ptr scene, + const render::ScenePointer& scene, render::Transaction& transaction) override; virtual void setXNNeighborID(const EntityItemID& xNNeighborID) override; diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index c9a45465c2..66495a7054 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -217,7 +217,7 @@ namespace render { } } -bool RenderableZoneEntityItem::addToScene(EntityItemPointer self, std::shared_ptr scene, +bool RenderableZoneEntityItem::addToScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) { _myMetaItem = scene->allocateID(); @@ -232,7 +232,7 @@ bool RenderableZoneEntityItem::addToScene(EntityItemPointer self, std::shared_pt return true; } -void RenderableZoneEntityItem::removeFromScene(EntityItemPointer self, std::shared_ptr scene, +void RenderableZoneEntityItem::removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) { transaction.removeItem(_myMetaItem); render::Item::clearID(_myMetaItem); diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.h b/libraries/entities-renderer/src/RenderableZoneEntityItem.h index d86a22509b..c81afdab08 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.h +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.h @@ -38,8 +38,8 @@ public: virtual void render(RenderArgs* args) override; virtual bool contains(const glm::vec3& point) const override; - virtual bool addToScene(EntityItemPointer self, std::shared_ptr scene, render::Transaction& transaction) override; - virtual void removeFromScene(EntityItemPointer self, std::shared_ptr scene, render::Transaction& transaction) override; + virtual bool addToScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) override; + virtual void removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) override; render::ItemID getRenderItemID() const { return _myMetaItem; } diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 1ce916de66..3f75c595a5 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -151,9 +151,9 @@ public: bool& somethingChanged) { somethingChanged = false; return 0; } - virtual bool addToScene(EntityItemPointer self, std::shared_ptr scene, + virtual bool addToScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) { return false; } // by default entity items don't add to scene - virtual void removeFromScene(EntityItemPointer self, std::shared_ptr scene, + virtual void removeFromScene(EntityItemPointer self, const render::ScenePointer& scene, render::Transaction& transaction) { } // by default entity items don't add to scene virtual void render(RenderArgs* args) { } // by default entity items don't know how to render diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index c274d69af6..309182b25e 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -231,8 +231,6 @@ void Model::updateRenderItems() { // We need to update them here so we can correctly update the bounding box. self->updateClusterMatrices(); - render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); - uint32_t deleteGeometryCounter = self->_deleteGeometryCounter; render::Transaction transaction; @@ -266,7 +264,7 @@ void Model::updateRenderItems() { }); } - scene->enqueueTransaction(transaction); + AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction); }); } @@ -534,7 +532,7 @@ void Model::calculateTriangleSets() { } } -void Model::setVisibleInScene(bool newValue, std::shared_ptr scene) { +void Model::setVisibleInScene(bool newValue, const render::ScenePointer& scene) { if (_isVisible != newValue) { _isVisible = newValue; @@ -550,7 +548,7 @@ void Model::setVisibleInScene(bool newValue, std::shared_ptr scen } -void Model::setLayeredInFront(bool layered, std::shared_ptr scene) { +void Model::setLayeredInFront(bool layered, const render::ScenePointer& scene) { if (_isLayeredInFront != layered) { _isLayeredInFront = layered; @@ -565,7 +563,7 @@ void Model::setLayeredInFront(bool layered, std::shared_ptr scene } } -bool Model::addToScene(std::shared_ptr scene, +bool Model::addToScene(const render::ScenePointer& scene, render::Transaction& transaction, render::Item::Status::Getters& statusGetters) { bool readyToRender = _collisionGeometry || isLoaded(); @@ -622,7 +620,7 @@ bool Model::addToScene(std::shared_ptr scene, return somethingAdded; } -void Model::removeFromScene(std::shared_ptr scene, render::Transaction& transaction) { +void Model::removeFromScene(const render::ScenePointer& scene, render::Transaction& transaction) { foreach (auto item, _modelMeshRenderItemsMap.keys()) { transaction.removeItem(item); } @@ -795,7 +793,7 @@ void Model::setURL(const QUrl& url) { { render::Transaction transaction; - render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene(); + const render::ScenePointer& scene = AbstractViewStateInterface::instance()->getMain3DScene(); if (scene) { removeFromScene(scene, transaction); scene->enqueueTransaction(transaction); @@ -1271,7 +1269,7 @@ bool Model::isRenderable() const { return !_meshStates.isEmpty() || (isLoaded() && _renderGeometry->getMeshes().empty()); } -bool Model::initWhenReady(render::ScenePointer scene) { +bool Model::initWhenReady(const render::ScenePointer& scene) { // NOTE: this only called by SkeletonModel if (_addedToScene || !isRenderable()) { return false; diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index e852358bc4..62e045a3c1 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -81,21 +81,21 @@ public: const QUrl& getURL() const { return _url; } // new Scene/Engine rendering support - void setVisibleInScene(bool newValue, std::shared_ptr scene); - void setLayeredInFront(bool layered, std::shared_ptr scene); + void setVisibleInScene(bool newValue, const render::ScenePointer& scene); + void setLayeredInFront(bool layered, const render::ScenePointer& scene); bool needsFixupInScene() const; bool needsReload() const { return _needsReload; } - bool initWhenReady(render::ScenePointer scene); - bool addToScene(std::shared_ptr scene, + bool initWhenReady(const render::ScenePointer& scene); + bool addToScene(const render::ScenePointer& scene, render::Transaction& transaction) { auto getters = render::Item::Status::Getters(0); return addToScene(scene, transaction, getters); } - bool addToScene(std::shared_ptr scene, + bool addToScene(const render::ScenePointer& scene, render::Transaction& transaction, render::Item::Status::Getters& statusGetters); - void removeFromScene(std::shared_ptr scene, render::Transaction& transaction); + void removeFromScene(const render::ScenePointer& scene, render::Transaction& transaction); bool isRenderable() const; bool isVisible() const { return _isVisible; } diff --git a/libraries/shared/src/RenderArgs.h b/libraries/shared/src/RenderArgs.h index 50722c0deb..10a9a20287 100644 --- a/libraries/shared/src/RenderArgs.h +++ b/libraries/shared/src/RenderArgs.h @@ -23,6 +23,10 @@ class AABox; class OctreeRenderer; +namespace render { + class Scene; + using ScenePointer = std::shared_ptr; +} namespace gpu { class Batch; @@ -126,6 +130,8 @@ public: bool _enableTexturing { true }; RenderDetails _details; + render::ScenePointer _scene; // HACK + int8_t _cameraMode { -1 }; // HACK }; #endif // hifi_RenderArgs_h diff --git a/scripts/system/pal.js b/scripts/system/pal.js index 5fbea90025..ae64065216 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -400,6 +400,7 @@ function getProfilePicture(username, callback) { // callback(url) if successfull var matched = !error && html.match(/img class="users-img" src="([^"]*)"/); if (!matched) { print('Error: Unable to get profile picture for', username, error); + callback(''); return; } callback(matched[1]);