Showing the changes to interface/src/Application.cpp (1 of 1002 files). Show all
Unified · Split
| @@ -102,7 +102,7 @@ · 101 unmodified lines | |||
| 102 | #include <MessagesClient.h> | 102 | #include <MessagesClient.h> |
| 103 | #include <hfm/ModelFormatRegistry.h> | 103 | #include <hfm/ModelFormatRegistry.h> |
| 104 | #include <model-networking/ModelCacheScriptingInterface.h> | 104 | #include <model-networking/ModelCacheScriptingInterface.h> |
| 105 | #include <model-networking/TextureCacheScriptingInterface.h> | 105 | #include <material-networking/TextureCacheScriptingInterface.h> |
| 106 | #include <ModelEntityItem.h> | 106 | #include <ModelEntityItem.h> |
| 107 | #include <NetworkAccessManager.h> | 107 | #include <NetworkAccessManager.h> |
| 108 | #include <NetworkingConstants.h> | 108 | #include <NetworkingConstants.h> |
| @@ -120,6 +120,7 @@ · 11 unmodified lines | |||
| 120 | #include <plugins/PluginManager.h> | 120 | #include <plugins/PluginManager.h> |
| 121 | #include <plugins/PluginUtils.h> | 121 | #include <plugins/PluginUtils.h> |
| 122 | #include <plugins/SteamClientPlugin.h> | 122 | #include <plugins/SteamClientPlugin.h> |
| 123 | #include <plugins/OculusPlatformPlugin.h> | ||
| 123 | #include <plugins/InputConfiguration.h> | 124 | #include <plugins/InputConfiguration.h> |
| 124 | #include <RecordingScriptingInterface.h> | 125 | #include <RecordingScriptingInterface.h> |
| 125 | #include <render/EngineStats.h> | 126 | #include <render/EngineStats.h> |
| @@ -151,7 +152,9 @@ · 25 unmodified lines | |||
| 151 | #include <trackers/EyeTracker.h> | 152 | #include <trackers/EyeTracker.h> |
| 152 | #include <avatars-renderer/ScriptAvatar.h> | 153 | #include <avatars-renderer/ScriptAvatar.h> |
| 153 | #include <RenderableEntityItem.h> | 154 | #include <RenderableEntityItem.h> |
| 154 | #include <model-networking/MaterialCache.h> | 155 | #include <RenderableTextEntityItem.h> |
| 156 | #include <RenderableWebEntityItem.h> | ||
| 157 | #include <material-networking/MaterialCache.h> | ||
| 155 | #include "recording/ClipCache.h" | 158 | #include "recording/ClipCache.h" |
| 156 | 159 | ||
| 157 | #include "AudioClient.h" | 160 | #include "AudioClient.h" |
| @@ -159,6 +162,7 @@ · 1 unmodified line | |||
| 159 | #include "avatar/AvatarManager.h" | 162 | #include "avatar/AvatarManager.h" |
| 160 | #include "avatar/MyHead.h" | 163 | #include "avatar/MyHead.h" |
| 161 | #include "avatar/AvatarPackager.h" | 164 | #include "avatar/AvatarPackager.h" |
| 165 | #include "avatar/MyCharacterController.h" | ||
| 162 | #include "CrashRecoveryHandler.h" | 166 | #include "CrashRecoveryHandler.h" |
| 163 | #include "CrashHandler.h" | 167 | #include "CrashHandler.h" |
| 164 | #include "devices/DdeFaceTracker.h" | 168 | #include "devices/DdeFaceTracker.h" |
| @@ -195,15 +199,12 @@ · 30 unmodified lines | |||
| 195 | #include "ui/AvatarInputs.h" | 199 | #include "ui/AvatarInputs.h" |
| 196 | #include "ui/DialogsManager.h" | 200 | #include "ui/DialogsManager.h" |
| 197 | #include "ui/LoginDialog.h" | 201 | #include "ui/LoginDialog.h" |
| 198 | #include "ui/overlays/Cube3DOverlay.h" | ||
| 199 | #include "ui/overlays/Web3DOverlay.h" | ||
| 200 | #include "ui/Snapshot.h" | 202 | #include "ui/Snapshot.h" |
| 201 | #include "ui/SnapshotAnimated.h" | 203 | #include "ui/SnapshotAnimated.h" |
| 202 | #include "ui/StandAloneJSConsole.h" | 204 | #include "ui/StandAloneJSConsole.h" |
| 203 | #include "ui/Stats.h" | 205 | #include "ui/Stats.h" |
| 204 | #include "ui/AnimStats.h" | 206 | #include "ui/AnimStats.h" |
| 205 | #include "ui/UpdateDialog.h" | 207 | #include "ui/UpdateDialog.h" |
| 206 | #include "ui/overlays/Overlays.h" | ||
| 207 | #include "ui/DomainConnectionModel.h" | 208 | #include "ui/DomainConnectionModel.h" |
| 208 | #include "ui/Keyboard.h" | 209 | #include "ui/Keyboard.h" |
| 209 | #include "Util.h" | 210 | #include "Util.h" |
| @@ -232,6 +233,7 @@ · 22 unmodified lines | |||
| 232 | #include "commerce/Ledger.h" | 233 | #include "commerce/Ledger.h" |
| 233 | #include "commerce/Wallet.h" | 234 | #include "commerce/Wallet.h" |
| 234 | #include "commerce/QmlCommerce.h" | 235 | #include "commerce/QmlCommerce.h" |
| 236 | #include "commerce/QmlMarketplace.h" | ||
| 235 | #include "ResourceRequestObserver.h" | 237 | #include "ResourceRequestObserver.h" |
| 236 | 238 | ||
| 237 | #include "webbrowser/WebBrowserSuggestionsEngine.h" | 239 | #include "webbrowser/WebBrowserSuggestionsEngine.h" |
| @@ -347,6 +349,8 @@ static const QString ACTIVE_DISPLAY_PLUGIN_SETTING_NAME = "activeDisplayPlugin"; · 109 unmodified lines | |||
| 347 | static const QString SYSTEM_TABLET = "com.highfidelity.interface.tablet.system"; | 349 | static const QString SYSTEM_TABLET = "com.highfidelity.interface.tablet.system"; |
| 348 | static const QString KEEP_ME_LOGGED_IN_SETTING_NAME = "keepMeLoggedIn"; | 350 | static const QString KEEP_ME_LOGGED_IN_SETTING_NAME = "keepMeLoggedIn"; |
| 349 | 351 | ||
| 352 | static const float FOCUS_HIGHLIGHT_EXPANSION_FACTOR = 1.05f; | ||
| 353 | |||
| 350 | #if defined(Q_OS_ANDROID) | 354 | #if defined(Q_OS_ANDROID) |
| 351 | static const QString TESTER_FILE = "/sdcard/_hifi_test_device.txt"; | 355 | static const QString TESTER_FILE = "/sdcard/_hifi_test_device.txt"; |
| 352 | #endif | 356 | #endif |
| @@ -599,8 +603,9 @@ void messageHandler(QtMsgType type, const QMessageLogContext& context, const QSt · 246 unmodified lines | |||
| 599 | __android_log_write(ANDROID_LOG_FATAL,"Interface",local); | 603 | __android_log_write(ANDROID_LOG_FATAL,"Interface",local); |
| 600 | abort(); | 604 | abort(); |
| 601 | } | 605 | } |
| 602 | #endif | 606 | #else |
| 603 | qApp->getLogger()->addMessage(qPrintable(logMessage)); | 607 | qApp->getLogger()->addMessage(qPrintable(logMessage)); |
| 608 | #endif | ||
| 604 | } | 609 | } |
| 605 | } | 610 | } |
| 606 | 611 | ||
| @@ -618,7 +623,7 @@ public: · 11 unmodified lines | |||
| 618 | case NestableType::Entity: | 623 | case NestableType::Entity: |
| 619 | return getEntityModelProvider(static_cast<EntityItemID>(uuid)); | 624 | return getEntityModelProvider(static_cast<EntityItemID>(uuid)); |
| 620 | case NestableType::Overlay: | 625 | case NestableType::Overlay: |
| 621 | return getOverlayModelProvider(static_cast<OverlayID>(uuid)); | 626 | return nullptr; |
| 622 | case NestableType::Avatar: | 627 | case NestableType::Avatar: |
| 623 | return getAvatarModelProvider(uuid); | 628 | return getAvatarModelProvider(uuid); |
| 624 | } | 629 | } |
| @@ -642,22 +647,6 @@ private: · 17 unmodified lines | |||
| 642 | return provider; | 647 | return provider; |
| 643 | } | 648 | } |
| 644 | 649 | ||
| 645 | scriptable::ModelProviderPointer getOverlayModelProvider(OverlayID overlayID) { | ||
| 646 | scriptable::ModelProviderPointer provider; | ||
| 647 | auto &overlays = qApp->getOverlays(); | ||
| 648 | if (auto overlay = overlays.getOverlay(overlayID)) { | ||
| 649 | if (auto base3d = std::dynamic_pointer_cast<Base3DOverlay>(overlay)) { | ||
| 650 | provider = std::dynamic_pointer_cast<scriptable::ModelProvider>(base3d); | ||
| 651 | provider->modelProviderType = NestableType::Overlay; | ||
| 652 | } else { | ||
| 653 | qCWarning(interfaceapp) << "no renderer for overlay ID" << overlayID.toString(); | ||
| 654 | } | ||
| 655 | } else { | ||
| 656 | qCWarning(interfaceapp) << "overlay not found" << overlayID.toString(); | ||
| 657 | } | ||
| 658 | return provider; | ||
| 659 | } | ||
| 660 | |||
| 661 | scriptable::ModelProviderPointer getAvatarModelProvider(QUuid sessionUUID) { | 650 | scriptable::ModelProviderPointer getAvatarModelProvider(QUuid sessionUUID) { |
| 662 | scriptable::ModelProviderPointer provider; | 651 | scriptable::ModelProviderPointer provider; |
| 663 | auto avatarManager = DependencyManager::get<AvatarManager>(); | 652 | auto avatarManager = DependencyManager::get<AvatarManager>(); |
| @@ -762,6 +751,11 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { · 98 unmodified lines | |||
| 762 | static const auto SUPPRESS_SETTINGS_RESET = "--suppress-settings-reset"; | 751 | static const auto SUPPRESS_SETTINGS_RESET = "--suppress-settings-reset"; |
| 763 | bool suppressPrompt = cmdOptionExists(argc, const_cast<const char**>(argv), SUPPRESS_SETTINGS_RESET); | 752 | bool suppressPrompt = cmdOptionExists(argc, const_cast<const char**>(argv), SUPPRESS_SETTINGS_RESET); |
| 764 | 753 | ||
| 754 | // set the OCULUS_STORE property so the oculus plugin can know if we ran from the Oculus Store | ||
| 755 | static const auto OCULUS_STORE_ARG = "--oculus-store"; | ||
| 756 | bool isStore = cmdOptionExists(argc, const_cast<const char**>(argv), OCULUS_STORE_ARG); | ||
| 757 | qApp->setProperty(hifi::properties::OCULUS_STORE, isStore); | ||
| 758 | |||
| 765 | // Ignore any previous crashes if running from command line with a test script. | 759 | // Ignore any previous crashes if running from command line with a test script. |
| 766 | bool inTestMode { false }; | 760 | bool inTestMode { false }; |
| 767 | for (int i = 0; i < argc; ++i) { | 761 | for (int i = 0; i < argc; ++i) { |
| @@ -803,6 +797,9 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { · 35 unmodified lines | |||
| 803 | if (auto steamClient = pluginManager->getSteamClientPlugin()) { | 797 | if (auto steamClient = pluginManager->getSteamClientPlugin()) { |
| 804 | steamClient->init(); | 798 | steamClient->init(); |
| 805 | } | 799 | } |
| 800 | if (auto oculusPlatform = pluginManager->getOculusPlatformPlugin()) { | ||
| 801 | oculusPlatform->init(); | ||
| 802 | } | ||
| 806 | 803 | ||
| 807 | PROFILE_SET_THREAD_NAME("Main Thread"); | 804 | PROFILE_SET_THREAD_NAME("Main Thread"); |
| 808 | 805 | ||
| @@ -923,6 +920,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { · 114 unmodified lines | |||
| 923 | DependencyManager::set<Wallet>(); | 920 | DependencyManager::set<Wallet>(); |
| 924 | DependencyManager::set<WalletScriptingInterface>(); | 921 | DependencyManager::set<WalletScriptingInterface>(); |
| 925 | DependencyManager::set<TTSScriptingInterface>(); | 922 | DependencyManager::set<TTSScriptingInterface>(); |
| 923 | DependencyManager::set<QmlCommerce>(); | ||
| 926 | 924 | ||
| 927 | DependencyManager::set<FadeEffect>(); | 925 | DependencyManager::set<FadeEffect>(); |
| 928 | DependencyManager::set<ResourceRequestObserver>(); | 926 | DependencyManager::set<ResourceRequestObserver>(); |
| @@ -937,9 +935,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { · 8 unmodified lines | |||
| 937 | // FIXME move to header, or better yet, design some kind of UI manager | 935 | // FIXME move to header, or better yet, design some kind of UI manager |
| 938 | // to take care of highlighting keyboard focused items, rather than | 936 | // to take care of highlighting keyboard focused items, rather than |
| 939 | // continuing to overburden Application.cpp | 937 | // continuing to overburden Application.cpp |
| 940 | std::shared_ptr<Cube3DOverlay> _keyboardFocusHighlight{ nullptr }; | 938 | QUuid _keyboardFocusHighlightID; |
| 941 | OverlayID _keyboardFocusHighlightID{ UNKNOWN_OVERLAY_ID }; | ||
| 942 | |||
| 943 | 939 | ||
| 944 | OffscreenGLCanvas* _qmlShareContext { nullptr }; | 940 | OffscreenGLCanvas* _qmlShareContext { nullptr }; |
| 945 | 941 | ||
| @@ -980,7 +976,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 34 unmodified lines | |||
| 980 | QApplication(argc, argv), | 976 | QApplication(argc, argv), |
| 981 | _window(new MainWindow(desktop())), | 977 | _window(new MainWindow(desktop())), |
| 982 | _sessionRunTimer(startupTimer), | 978 | _sessionRunTimer(startupTimer), |
| 979 | #ifndef Q_OS_ANDROID | ||
| 983 | _logger(new FileLogger(this)), | 980 | _logger(new FileLogger(this)), |
| 981 | #endif | ||
| 984 | _previousSessionCrashed(setupEssentials(argc, argv, runningMarkerExisted)), | 982 | _previousSessionCrashed(setupEssentials(argc, argv, runningMarkerExisted)), |
| 985 | _entitySimulation(new PhysicalEntitySimulation()), | 983 | _entitySimulation(new PhysicalEntitySimulation()), |
| 986 | _physicsEngine(new PhysicsEngine(Vectors::ZERO)), | 984 | _physicsEngine(new PhysicsEngine(Vectors::ZERO)), |
| @@ -1114,7 +1112,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 127 unmodified lines | |||
| 1114 | } | 1112 | } |
| 1115 | auto accountManager = DependencyManager::get<AccountManager>(); | 1113 | auto accountManager = DependencyManager::get<AccountManager>(); |
| 1116 | 1114 | ||
| 1115 | #ifndef Q_OS_ANDROID | ||
| 1117 | _logger->setSessionID(accountManager->getSessionID()); | 1116 | _logger->setSessionID(accountManager->getSessionID()); |
| 1117 | #endif | ||
| 1118 | 1118 | ||
| 1119 | setCrashAnnotation("metaverse_session_id", accountManager->getSessionID().toString().toStdString()); | 1119 | setCrashAnnotation("metaverse_session_id", accountManager->getSessionID().toString().toStdString()); |
| 1120 | setCrashAnnotation("main_thread_id", std::to_string((size_t)QThread::currentThreadId())); | 1120 | setCrashAnnotation("main_thread_id", std::to_string((size_t)QThread::currentThreadId())); |
| @@ -1135,10 +1135,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 14 unmodified lines | |||
| 1135 | qCDebug(interfaceapp) << "[VERSION] We will use DEVELOPMENT global services."; | 1135 | qCDebug(interfaceapp) << "[VERSION] We will use DEVELOPMENT global services."; |
| 1136 | #endif | 1136 | #endif |
| 1137 | 1137 | ||
| 1138 | // set the OCULUS_STORE property so the oculus plugin can know if we ran from the Oculus Store | 1138 | bool isStore = property(hifi::properties::OCULUS_STORE).toBool(); |
| 1139 | static const QString OCULUS_STORE_ARG = "--oculus-store"; | 1139 | |
| 1140 | bool isStore = arguments().indexOf(OCULUS_STORE_ARG) != -1; | ||
| 1141 | setProperty(hifi::properties::OCULUS_STORE, isStore); | ||
| 1142 | DependencyManager::get<WalletScriptingInterface>()->setLimitedCommerce(isStore); // Or we could make it a separate arg, or if either arg is set, etc. And should this instead by a hifi::properties? | 1140 | DependencyManager::get<WalletScriptingInterface>()->setLimitedCommerce(isStore); // Or we could make it a separate arg, or if either arg is set, etc. And should this instead by a hifi::properties? |
| 1143 | 1141 | ||
| 1144 | updateHeartbeat(); | 1142 | updateHeartbeat(); |
| @@ -1204,9 +1202,14 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 59 unmodified lines | |||
| 1204 | connect(&domainHandler, SIGNAL(connectedToDomain(QUrl)), SLOT(updateWindowTitle())); | 1202 | connect(&domainHandler, SIGNAL(connectedToDomain(QUrl)), SLOT(updateWindowTitle())); |
| 1205 | connect(&domainHandler, SIGNAL(disconnectedFromDomain()), SLOT(updateWindowTitle())); | 1203 | connect(&domainHandler, SIGNAL(disconnectedFromDomain()), SLOT(updateWindowTitle())); |
| 1206 | connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, [this]() { | 1204 | connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, [this]() { |
| 1207 | getOverlays().deleteOverlay(getTabletScreenID()); | 1205 | auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>(); |
| 1208 | getOverlays().deleteOverlay(getTabletHomeButtonID()); | 1206 | if (tabletScriptingInterface) { |
| 1209 | getOverlays().deleteOverlay(getTabletFrameID()); | 1207 | tabletScriptingInterface->setQmlTabletRoot(SYSTEM_TABLET, nullptr); |
| 1208 | } | ||
| 1209 | auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); | ||
| 1210 | entityScriptingInterface->deleteEntity(getTabletScreenID()); | ||
| 1211 | entityScriptingInterface->deleteEntity(getTabletHomeButtonID()); | ||
| 1212 | entityScriptingInterface->deleteEntity(getTabletFrameID()); | ||
| 1210 | _failedToConnectToEntityServer = false; | 1213 | _failedToConnectToEntityServer = false; |
| 1211 | }); | 1214 | }); |
| 1212 | 1215 | ||
| @@ -1296,10 +1299,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 83 unmodified lines | |||
| 1296 | if (isHMDMode()) { | 1299 | if (isHMDMode()) { |
| 1297 | emit loginDialogFocusDisabled(); | 1300 | emit loginDialogFocusDisabled(); |
| 1298 | dialogsManager->hideLoginDialog(); | 1301 | dialogsManager->hideLoginDialog(); |
| 1299 | createLoginDialogOverlay(); | 1302 | createLoginDialog(); |
| 1300 | } else { | 1303 | } else { |
| 1301 | getOverlays().deleteOverlay(_loginDialogOverlayID); | 1304 | DependencyManager::get<EntityScriptingInterface>()->deleteEntity(_loginDialogID); |
| 1302 | _loginDialogOverlayID = OverlayID(); | 1305 | _loginDialogID = QUuid(); |
| 1303 | _loginStateManager.tearDown(); | 1306 | _loginStateManager.tearDown(); |
| 1304 | dialogsManager->showLoginDialog(); | 1307 | dialogsManager->showLoginDialog(); |
| 1305 | emit loginDialogFocusEnabled(); | 1308 | emit loginDialogFocusEnabled(); |
| @@ -1896,66 +1899,56 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 590 unmodified lines | |||
| 1896 | SpacemouseManager::getInstance().init(); | 1899 | SpacemouseManager::getInstance().init(); |
| 1897 | #endif | 1900 | #endif |
| 1898 | 1901 | ||
| 1899 | // If the user clicks an an entity, we will check that it's an unlocked web entity, and if so, set the focus to it | 1902 | // If the user clicks on an object, we will check that it's a web surface, and if so, set the focus to it |
| 1900 | auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); | 1903 | auto pointerManager = DependencyManager::get<PointerManager>(); |
| 1901 | connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, | 1904 | auto keyboardFocusOperator = [this](const QUuid& id, const PointerEvent& event) { |
| 1902 | [this](const EntityItemID& entityItemID, const PointerEvent& event) { | ||
| 1903 | if (event.shouldFocus()) { | 1905 | if (event.shouldFocus()) { |
| 1904 | if (getEntities()->wantsKeyboardFocus(entityItemID)) { | 1906 | auto keyboard = DependencyManager::get<Keyboard>(); |
| 1905 | setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); | 1907 | if (getEntities()->wantsKeyboardFocus(id)) { |
| 1906 | setKeyboardFocusEntity(entityItemID); | 1908 | setKeyboardFocusEntity(id); |
| 1907 | } else { | 1909 | } else if (!keyboard->containsID(id)) { // FIXME: this is a hack to make the keyboard work for now, since the keys would otherwise steal focus |
| 1908 | setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); | 1910 | setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); |
| 1909 | } | 1911 | } |
| 1910 | } | 1912 | } |
| 1911 | }); | 1913 | }; |
| 1914 | connect(pointerManager.data(), &PointerManager::triggerBeginEntity, keyboardFocusOperator); | ||
| 1915 | connect(pointerManager.data(), &PointerManager::triggerBeginOverlay, keyboardFocusOperator); | ||
| 1912 | 1916 | ||
| 1913 | connect(entityScriptingInterface.data(), &EntityScriptingInterface::deletingEntity, [this](const EntityItemID& entityItemID) { | 1917 | auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); |
| 1918 | connect(entityScriptingInterface.data(), &EntityScriptingInterface::deletingEntity, this, [this](const EntityItemID& entityItemID) { | ||
| 1914 | if (entityItemID == _keyboardFocusedEntity.get()) { | 1919 | if (entityItemID == _keyboardFocusedEntity.get()) { |
| 1915 | setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); | 1920 | setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); |
| 1916 | } | 1921 | } |
| 1917 | }); | 1922 | }, Qt::QueuedConnection); |
| 1918 | 1923 | ||
| 1919 | EntityTree::setAddMaterialToEntityOperator([this](const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName) { | 1924 | EntityTreeRenderer::setAddMaterialToEntityOperator([this](const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName) { |
| 1920 | if (_aboutToQuit) { | 1925 | if (_aboutToQuit) { |
| 1921 | return false; | 1926 | return false; |
| 1922 | } | 1927 | } |
| 1923 | 1928 | ||
| 1924 | // try to find the renderable | ||
| 1925 | auto renderable = getEntities()->renderableForEntityId(entityID); | 1929 | auto renderable = getEntities()->renderableForEntityId(entityID); |
| 1926 | if (renderable) { | 1930 | if (renderable) { |
| 1927 | renderable->addMaterial(material, parentMaterialName); | 1931 | renderable->addMaterial(material, parentMaterialName); |
| 1928 | } | ||
| 1929 | |||
| 1930 | // even if we don't find it, try to find the entity | ||
| 1931 | auto entity = getEntities()->getEntity(entityID); | ||
| 1932 | if (entity) { | ||
| 1933 | entity->addMaterial(material, parentMaterialName); | ||
| 1934 | return true; | 1932 | return true; |
| 1935 | } | 1933 | } |
| 1934 | |||
| 1936 | return false; | 1935 | return false; |
| 1937 | }); | 1936 | }); |
| 1938 | EntityTree::setRemoveMaterialFromEntityOperator([this](const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName) { | 1937 | EntityTreeRenderer::setRemoveMaterialFromEntityOperator([this](const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName) { |
| 1939 | if (_aboutToQuit) { | 1938 | if (_aboutToQuit) { |
| 1940 | return false; | 1939 | return false; |
| 1941 | } | 1940 | } |
| 1942 | 1941 | ||
| 1943 | // try to find the renderable | ||
| 1944 | auto renderable = getEntities()->renderableForEntityId(entityID); | 1942 | auto renderable = getEntities()->renderableForEntityId(entityID); |
| 1945 | if (renderable) { | 1943 | if (renderable) { |
| 1946 | renderable->removeMaterial(material, parentMaterialName); | 1944 | renderable->removeMaterial(material, parentMaterialName); |
| 1947 | } | ||
| 1948 | |||
| 1949 | // even if we don't find it, try to find the entity | ||
| 1950 | auto entity = getEntities()->getEntity(entityID); | ||
| 1951 | if (entity) { | ||
| 1952 | entity->removeMaterial(material, parentMaterialName); | ||
| 1953 | return true; | 1945 | return true; |
| 1954 | } | 1946 | } |
| 1947 | |||
| 1955 | return false; | 1948 | return false; |
| 1956 | }); | 1949 | }); |
| 1957 | 1950 | ||
| 1958 | EntityTree::setAddMaterialToAvatarOperator([](const QUuid& avatarID, graphics::MaterialLayer material, const std::string& parentMaterialName) { | 1951 | EntityTreeRenderer::setAddMaterialToAvatarOperator([](const QUuid& avatarID, graphics::MaterialLayer material, const std::string& parentMaterialName) { |
| 1959 | auto avatarManager = DependencyManager::get<AvatarManager>(); | 1952 | auto avatarManager = DependencyManager::get<AvatarManager>(); |
| 1960 | auto avatar = avatarManager->getAvatarBySessionID(avatarID); | 1953 | auto avatar = avatarManager->getAvatarBySessionID(avatarID); |
| 1961 | if (avatar) { | 1954 | if (avatar) { |
| @@ -1964,7 +1957,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 2 unmodified lines | |||
| 1964 | } | 1957 | } |
| 1965 | return false; | 1958 | return false; |
| 1966 | }); | 1959 | }); |
| 1967 | EntityTree::setRemoveMaterialFromAvatarOperator([](const QUuid& avatarID, graphics::MaterialPointer material, const std::string& parentMaterialName) { | 1960 | EntityTreeRenderer::setRemoveMaterialFromAvatarOperator([](const QUuid& avatarID, graphics::MaterialPointer material, const std::string& parentMaterialName) { |
| 1968 | auto avatarManager = DependencyManager::get<AvatarManager>(); | 1961 | auto avatarManager = DependencyManager::get<AvatarManager>(); |
| 1969 | auto avatar = avatarManager->getAvatarBySessionID(avatarID); | 1962 | auto avatar = avatarManager->getAvatarBySessionID(avatarID); |
| 1970 | if (avatar) { | 1963 | if (avatar) { |
| @@ -1974,33 +1967,25 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 3 unmodified lines | |||
| 1974 | return false; | 1967 | return false; |
| 1975 | }); | 1968 | }); |
| 1976 | 1969 | ||
| 1977 | EntityTree::setAddMaterialToOverlayOperator([this](const QUuid& overlayID, graphics::MaterialLayer material, const std::string& parentMaterialName) { | 1970 | EntityTree::setGetEntityObjectOperator([this](const QUuid& id) -> QObject* { |
| 1978 | auto overlay = _overlays.getOverlay(overlayID); | 1971 | auto entities = getEntities(); |
| 1979 | if (overlay) { | 1972 | if (auto entity = entities->renderableForEntityId(id)) { |
| 1980 | overlay->addMaterial(material, parentMaterialName); | 1973 | return qobject_cast<QObject*>(entity.get()); |
| 1981 | return true; | ||
| 1982 | } | ||
| 1983 | return false; | ||
| 1984 | }); | ||
| 1985 | EntityTree::setRemoveMaterialFromOverlayOperator([this](const QUuid& overlayID, graphics::MaterialPointer material, const std::string& parentMaterialName) { | ||
| 1986 | auto overlay = _overlays.getOverlay(overlayID); | ||
| 1987 | if (overlay) { | ||
| 1988 | overlay->removeMaterial(material, parentMaterialName); | ||
| 1989 | return true; | ||
| 1990 | } | 1974 | } |
| 1991 | return false; | 1975 | return nullptr; |
| 1992 | }); | 1976 | }); |
| 1993 | 1977 | ||
| 1994 | // Keyboard focus handling for Web overlays. | 1978 | EntityTree::setTextSizeOperator([this](const QUuid& id, const QString& text) { |
| 1995 | auto overlays = &(qApp->getOverlays()); | 1979 | auto entities = getEntities(); |
| 1996 | connect(overlays, &Overlays::overlayDeleted, [this](const OverlayID& overlayID) { | 1980 | if (auto entity = entities->renderableForEntityId(id)) { |
| 1997 | if (overlayID == _keyboardFocusedOverlay.get()) { | 1981 | if (auto renderable = std::dynamic_pointer_cast<render::entities::TextEntityRenderer>(entity)) { |
| 1998 | setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); | 1982 | return renderable->textSize(text); |
| 1983 | } | ||
| 1999 | } | 1984 | } |
| 1985 | return QSizeF(0.0f, 0.0f); | ||
| 2000 | }); | 1986 | }); |
| 2001 | 1987 | ||
| 2002 | connect(this, &Application::aboutToQuit, [this]() { | 1988 | connect(this, &Application::aboutToQuit, [this]() { |
| 2003 | setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); | ||
| 2004 | setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); | 1989 | setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); |
| 2005 | }); | 1990 | }); |
| 2006 | 1991 | ||
| @@ -2211,7 +2196,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 204 unmodified lines | |||
| 2211 | || ((rightHandPose.valid || lastRightHandPose.valid) && (rightHandPose != lastRightHandPose)); | 2196 | || ((rightHandPose.valid || lastRightHandPose.valid) && (rightHandPose != lastRightHandPose)); |
| 2212 | lastLeftHandPose = leftHandPose; | 2197 | lastLeftHandPose = leftHandPose; |
| 2213 | lastRightHandPose = rightHandPose; | 2198 | lastRightHandPose = rightHandPose; |
| 2214 | properties["avatar_identity_requests_sent"] = DependencyManager::get<AvatarManager>()->getIdentityRequestsSent(); | ||
| 2215 | 2199 | ||
| 2216 | UserActivityLogger::getInstance().logAction("stats", properties); | 2200 | UserActivityLogger::getInstance().logAction("stats", properties); |
| 2217 | }); | 2201 | }); |
| @@ -2296,7 +2280,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 78 unmodified lines | |||
| 2296 | 2280 | ||
| 2297 | // Setup the mouse ray pick and related operators | 2281 | // Setup the mouse ray pick and related operators |
| 2298 | { | 2282 | { |
| 2299 | auto mouseRayPick = std::make_shared<RayPick>(Vectors::ZERO, Vectors::UP, PickFilter(PickScriptingInterface::PICK_ENTITIES()), 0.0f, true); | 2283 | auto mouseRayPick = std::make_shared<RayPick>(Vectors::ZERO, Vectors::UP, PickFilter(PickScriptingInterface::PICK_ENTITIES() | PickScriptingInterface::PICK_LOCAL_ENTITIES()), 0.0f, true); |
| 2300 | mouseRayPick->parentTransform = std::make_shared<MouseTransformNode>(); | 2284 | mouseRayPick->parentTransform = std::make_shared<MouseTransformNode>(); |
| 2301 | mouseRayPick->setJointState(PickQuery::JOINT_STATE_MOUSE); | 2285 | mouseRayPick->setJointState(PickQuery::JOINT_STATE_MOUSE); |
| 2302 | auto mouseRayPickID = DependencyManager::get<PickManager>()->addPick(PickQuery::Ray, mouseRayPick); | 2286 | auto mouseRayPickID = DependencyManager::get<PickManager>()->addPick(PickQuery::Ray, mouseRayPick); |
| @@ -2322,11 +2306,104 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 19 unmodified lines | |||
| 2322 | DependencyManager::get<PickManager>()->setPrecisionPicking(rayPickID, value); | 2306 | DependencyManager::get<PickManager>()->setPrecisionPicking(rayPickID, value); |
| 2323 | }); | 2307 | }); |
| 2324 | 2308 | ||
| 2325 | EntityTreeRenderer::setGetAvatarUpOperator([] { | 2309 | EntityItem::setBillboardRotationOperator([this](const glm::vec3& position, const glm::quat& rotation, BillboardMode billboardMode) { |
| 2326 | return DependencyManager::get<AvatarManager>()->getMyAvatar()->getWorldOrientation() * Vectors::UP; | 2310 | if (billboardMode == BillboardMode::YAW) { |
| 2311 | //rotate about vertical to face the camera | ||
| 2312 | ViewFrustum frustum; | ||
| 2313 | copyViewFrustum(frustum); | ||
| 2314 | glm::vec3 dPosition = frustum.getPosition() - position; | ||
| 2315 | // If x and z are 0, atan(x, z) is undefined, so default to 0 degrees | ||
| 2316 | float yawRotation = dPosition.x == 0.0f && dPosition.z == 0.0f ? 0.0f : glm::atan(dPosition.x, dPosition.z); | ||
| 2317 | return glm::quat(glm::vec3(0.0f, yawRotation, 0.0f)); | ||
| 2318 | } else if (billboardMode == BillboardMode::FULL) { | ||
| 2319 | ViewFrustum frustum; | ||
| 2320 | copyViewFrustum(frustum); | ||
| 2321 | glm::vec3 cameraPos = frustum.getPosition(); | ||
| 2322 | // use the referencial from the avatar, y isn't always up | ||
| 2323 | glm::vec3 avatarUP = DependencyManager::get<AvatarManager>()->getMyAvatar()->getWorldOrientation() * Vectors::UP; | ||
| 2324 | // check to see if glm::lookAt will work / using glm::lookAt variable name | ||
| 2325 | glm::highp_vec3 s(glm::cross(position - cameraPos, avatarUP)); | ||
| 2326 | |||
| 2327 | // make sure s is not NaN for any component | ||
| 2328 | if (glm::length2(s) > 0.0f) { | ||
| 2329 | return glm::conjugate(glm::toQuat(glm::lookAt(cameraPos, position, avatarUP))); | ||
| 2330 | } | ||
| 2331 | } | ||
| 2332 | return rotation; | ||
| 2333 | }); | ||
| 2334 | |||
| 2335 | render::entities::WebEntityRenderer::setAcquireWebSurfaceOperator([this](const QString& url, bool htmlContent, QSharedPointer<OffscreenQmlSurface>& webSurface, bool& cachedWebSurface) { | ||
| 2336 | bool isTablet = url == TabletScriptingInterface::QML; | ||
| 2337 | if (htmlContent) { | ||
| 2338 | webSurface = DependencyManager::get<OffscreenQmlSurfaceCache>()->acquire(render::entities::WebEntityRenderer::QML); | ||
| 2339 | cachedWebSurface = true; | ||
| 2340 | auto rootItemLoadedFunctor = [url, webSurface] { | ||
| 2341 | webSurface->getRootItem()->setProperty(render::entities::WebEntityRenderer::URL_PROPERTY, url); | ||
| 2342 | }; | ||
| 2343 | if (webSurface->getRootItem()) { | ||
| 2344 | rootItemLoadedFunctor(); | ||
| 2345 | } else { | ||
| 2346 | QObject::connect(webSurface.data(), &hifi::qml::OffscreenSurface::rootContextCreated, rootItemLoadedFunctor); | ||
| 2347 | } | ||
| 2348 | } else { | ||
| 2349 | // FIXME: the tablet should use the OffscreenQmlSurfaceCache | ||
| 2350 | webSurface = QSharedPointer<OffscreenQmlSurface>(new OffscreenQmlSurface(), [](OffscreenQmlSurface* webSurface) { | ||
| 2351 | AbstractViewStateInterface::instance()->sendLambdaEvent([webSurface] { | ||
| 2352 | // WebEngineView may run other threads (wasapi), so they must be deleted for a clean shutdown | ||
| 2353 | // if the application has already stopped its event loop, delete must be explicit | ||
| 2354 | delete webSurface; | ||
| 2355 | }); | ||
| 2356 | }); | ||
| 2357 | auto rootItemLoadedFunctor = [webSurface, url, isTablet] { | ||
| 2358 | Application::setupQmlSurface(webSurface->getSurfaceContext(), isTablet || url == LOGIN_DIALOG.toString()); | ||
| 2359 | }; | ||
| 2360 | if (webSurface->getRootItem()) { | ||
| 2361 | rootItemLoadedFunctor(); | ||
| 2362 | } else { | ||
| 2363 | QObject::connect(webSurface.data(), &hifi::qml::OffscreenSurface::rootContextCreated, rootItemLoadedFunctor); | ||
| 2364 | } | ||
| 2365 | webSurface->load(url); | ||
| 2366 | cachedWebSurface = false; | ||
| 2367 | } | ||
| 2368 | const uint8_t DEFAULT_MAX_FPS = 10; | ||
| 2369 | const uint8_t TABLET_FPS = 90; | ||
| 2370 | webSurface->setMaxFps(isTablet ? TABLET_FPS : DEFAULT_MAX_FPS); | ||
| 2371 | }); | ||
| 2372 | render::entities::WebEntityRenderer::setReleaseWebSurfaceOperator([this](QSharedPointer<OffscreenQmlSurface>& webSurface, bool& cachedWebSurface, std::vector<QMetaObject::Connection>& connections) { | ||
| 2373 | QQuickItem* rootItem = webSurface->getRootItem(); | ||
| 2374 | |||
| 2375 | // Fix for crash in QtWebEngineCore when rapidly switching domains | ||
| 2376 | // Call stop on the QWebEngineView before destroying OffscreenQMLSurface. | ||
| 2377 | if (rootItem && !cachedWebSurface) { | ||
| 2378 | // stop loading | ||
| 2379 | QMetaObject::invokeMethod(rootItem, "stop"); | ||
| 2380 | } | ||
| 2381 | |||
| 2382 | webSurface->pause(); | ||
| 2383 | |||
| 2384 | for (auto& connection : connections) { | ||
| 2385 | QObject::disconnect(connection); | ||
| 2386 | } | ||
| 2387 | connections.clear(); | ||
| 2388 | |||
| 2389 | // If the web surface was fetched out of the cache, release it back into the cache | ||
| 2390 | if (cachedWebSurface) { | ||
| 2391 | // If it's going back into the cache make sure to explicitly set the URL to a blank page | ||
| 2392 | // in order to stop any resource consumption or audio related to the page. | ||
| 2393 | if (rootItem) { | ||
| 2394 | rootItem->setProperty("url", "about:blank"); | ||
| 2395 | } | ||
| 2396 | auto offscreenCache = DependencyManager::get<OffscreenQmlSurfaceCache>(); | ||
| 2397 | if (offscreenCache) { | ||
| 2398 | offscreenCache->release(render::entities::WebEntityRenderer::QML, webSurface); | ||
| 2399 | } | ||
| 2400 | cachedWebSurface = false; | ||
| 2401 | } | ||
| 2402 | webSurface.reset(); | ||
| 2327 | }); | 2403 | }); |
| 2328 | 2404 | ||
| 2329 | // Preload Tablet sounds | 2405 | // Preload Tablet sounds |
| 2406 | DependencyManager::get<EntityScriptingInterface>()->setEntityTree(qApp->getEntities()->getTree()); | ||
| 2330 | DependencyManager::get<TabletScriptingInterface>()->preloadSounds(); | 2407 | DependencyManager::get<TabletScriptingInterface>()->preloadSounds(); |
| 2331 | DependencyManager::get<Keyboard>()->createKeyboard(); | 2408 | DependencyManager::get<Keyboard>()->createKeyboard(); |
| 2332 | 2409 | ||
| @@ -2352,7 +2429,6 @@ void Application::updateVerboseLogging() { · 19 unmodified lines | |||
| 2352 | bool enable = menu->isOptionChecked(MenuOption::VerboseLogging); | 2429 | bool enable = menu->isOptionChecked(MenuOption::VerboseLogging); |
| 2353 | 2430 | ||
| 2354 | QString rules = | 2431 | QString rules = |
| 2355 | "hifi.*.debug=%1\n" | ||
| 2356 | "hifi.*.info=%1\n" | 2432 | "hifi.*.info=%1\n" |
| 2357 | "hifi.audio-stream.debug=false\n" | 2433 | "hifi.audio-stream.debug=false\n" |
| 2358 | "hifi.audio-stream.info=false"; | 2434 | "hifi.audio-stream.info=false"; |
| @@ -2535,11 +2611,10 @@ void Application::cleanupBeforeQuit() { · 176 unmodified lines | |||
| 2535 | _applicationStateDevice.reset(); | 2611 | _applicationStateDevice.reset(); |
| 2536 | 2612 | ||
| 2537 | { | 2613 | { |
| 2538 | if (_keyboardFocusHighlightID != UNKNOWN_OVERLAY_ID) { | 2614 | if (_keyboardFocusHighlightID != UNKNOWN_ENTITY_ID) { |
| 2539 | getOverlays().deleteOverlay(_keyboardFocusHighlightID); | 2615 | DependencyManager::get<EntityScriptingInterface>()->deleteEntity(_keyboardFocusHighlightID); |
| 2540 | _keyboardFocusHighlightID = UNKNOWN_OVERLAY_ID; | 2616 | _keyboardFocusHighlightID = UNKNOWN_ENTITY_ID; |
| 2541 | } | 2617 | } |
| 2542 | _keyboardFocusHighlight = nullptr; | ||
| 2543 | } | 2618 | } |
| 2544 | 2619 | ||
| 2545 | { | 2620 | { |
| @@ -2609,6 +2684,7 @@ void Application::cleanupBeforeQuit() { · 63 unmodified lines | |||
| 2609 | DependencyManager::destroy<ContextOverlayInterface>(); // Must be destroyed before TabletScriptingInterface | 2684 | DependencyManager::destroy<ContextOverlayInterface>(); // Must be destroyed before TabletScriptingInterface |
| 2610 | 2685 | ||
| 2611 | // stop QML | 2686 | // stop QML |
| 2687 | DependencyManager::destroy<QmlCommerce>(); | ||
| 2612 | DependencyManager::destroy<TabletScriptingInterface>(); | 2688 | DependencyManager::destroy<TabletScriptingInterface>(); |
| 2613 | DependencyManager::destroy<ToolbarScriptingInterface>(); | 2689 | DependencyManager::destroy<ToolbarScriptingInterface>(); |
| 2614 | DependencyManager::destroy<OffscreenUi>(); | 2690 | DependencyManager::destroy<OffscreenUi>(); |
| @@ -2648,7 +2724,14 @@ Application::~Application() { · 33 unmodified lines | |||
| 2648 | avatarManager->handleProcessedPhysicsTransaction(transaction); | 2724 | avatarManager->handleProcessedPhysicsTransaction(transaction); |
| 2649 | 2725 | ||
| 2650 | avatarManager->deleteAllAvatars(); | 2726 | avatarManager->deleteAllAvatars(); |
| 2651 | 2727 | ||
| 2728 | auto myCharacterController = getMyAvatar()->getCharacterController(); | ||
| 2729 | myCharacterController->clearDetailedMotionStates(); | ||
| 2730 | |||
| 2731 | myCharacterController->buildPhysicsTransaction(transaction); | ||
| 2732 | _physicsEngine->processTransaction(transaction); | ||
| 2733 | myCharacterController->handleProcessedPhysicsTransaction(transaction); | ||
| 2734 | |||
| 2652 | _physicsEngine->setCharacterController(nullptr); | 2735 | _physicsEngine->setCharacterController(nullptr); |
| 2653 | 2736 | ||
| 2654 | // the _shapeManager should have zero references | 2737 | // the _shapeManager should have zero references |
| @@ -2671,6 +2754,11 @@ Application::~Application() { · 16 unmodified lines | |||
| 2671 | if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { | 2754 | if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { |
| 2672 | steamClient->shutdown(); | 2755 | steamClient->shutdown(); |
| 2673 | } | 2756 | } |
| 2757 | |||
| 2758 | if (auto oculusPlatform = PluginManager::getInstance()->getOculusPlatformPlugin()) { | ||
| 2759 | oculusPlatform->shutdown(); | ||
| 2760 | } | ||
| 2761 | |||
| 2674 | DependencyManager::destroy<PluginManager>(); | 2762 | DependencyManager::destroy<PluginManager>(); |
| 2675 | 2763 | ||
| 2676 | DependencyManager::destroy<CompositorHelper>(); // must be destroyed before the FramebufferCache | 2764 | DependencyManager::destroy<CompositorHelper>(); // must be destroyed before the FramebufferCache |
| @@ -2897,7 +2985,7 @@ void Application::initializeUi() { · 220 unmodified lines | |||
| 2897 | Tooltip::registerType(); | 2985 | Tooltip::registerType(); |
| 2898 | UpdateDialog::registerType(); | 2986 | UpdateDialog::registerType(); |
| 2899 | QmlContextCallback commerceCallback = [](QQmlContext* context) { | 2987 | QmlContextCallback commerceCallback = [](QQmlContext* context) { |
| 2900 | context->setContextProperty("Commerce", new QmlCommerce()); | 2988 | context->setContextProperty("Commerce", DependencyManager::get<QmlCommerce>().data()); |
| 2901 | }; | 2989 | }; |
| 2902 | OffscreenQmlSurface::addWhitelistContextHandler({ | 2990 | OffscreenQmlSurface::addWhitelistContextHandler({ |
| 2903 | QUrl{ "hifi/commerce/checkout/Checkout.qml" }, | 2991 | QUrl{ "hifi/commerce/checkout/Checkout.qml" }, |
| @@ -2922,7 +3010,24 @@ void Application::initializeUi() { · 18 unmodified lines | |||
| 2922 | QUrl{ "hifi/dialogs/security/SecurityImageChange.qml" }, | 3010 | QUrl{ "hifi/dialogs/security/SecurityImageChange.qml" }, |
| 2923 | QUrl{ "hifi/dialogs/security/SecurityImageModel.qml" }, | 3011 | QUrl{ "hifi/dialogs/security/SecurityImageModel.qml" }, |
| 2924 | QUrl{ "hifi/dialogs/security/SecurityImageSelection.qml" }, | 3012 | QUrl{ "hifi/dialogs/security/SecurityImageSelection.qml" }, |
| 3013 | QUrl{ "hifi/tablet/TabletMenu.qml" }, | ||
| 3014 | QUrl{ "hifi/commerce/marketplace/Marketplace.qml" }, | ||
| 2925 | }, commerceCallback); | 3015 | }, commerceCallback); |
| 3016 | |||
| 3017 | QmlContextCallback marketplaceCallback = [](QQmlContext* context) { | ||
| 3018 | context->setContextProperty("MarketplaceScriptingInterface", new QmlMarketplace()); | ||
| 3019 | }; | ||
| 3020 | OffscreenQmlSurface::addWhitelistContextHandler({ | ||
| 3021 | QUrl{ "hifi/commerce/marketplace/Marketplace.qml" }, | ||
| 3022 | }, marketplaceCallback); | ||
| 3023 | |||
| 3024 | QmlContextCallback platformInfoCallback = [](QQmlContext* context) { | ||
| 3025 | context->setContextProperty("PlatformInfo", new PlatformInfoScriptingInterface()); | ||
| 3026 | }; | ||
| 3027 | OffscreenQmlSurface::addWhitelistContextHandler({ | ||
| 3028 | QUrl{ "hifi/commerce/marketplace/Marketplace.qml" }, | ||
| 3029 | }, platformInfoCallback); | ||
| 3030 | |||
| 2926 | QmlContextCallback ttsCallback = [](QQmlContext* context) { | 3031 | QmlContextCallback ttsCallback = [](QQmlContext* context) { |
| 2927 | context->setContextProperty("TextToSpeech", DependencyManager::get<TTSScriptingInterface>().data()); | 3032 | context->setContextProperty("TextToSpeech", DependencyManager::get<TTSScriptingInterface>().data()); |
| 2928 | }; | 3033 | }; |
| @@ -3013,7 +3118,7 @@ void Application::initializeUi() { · 84 unmodified lines | |||
| 3013 | }); | 3118 | }); |
| 3014 | 3119 | ||
| 3015 | #if !defined(DISABLE_QML) | 3120 | #if !defined(DISABLE_QML) |
| 3016 | // Pre-create a couple of Web3D overlays to speed up tablet UI | 3121 | // Pre-create a couple of offscreen surfaces to speed up tablet UI |
| 3017 | auto offscreenSurfaceCache = DependencyManager::get<OffscreenQmlSurfaceCache>(); | 3122 | auto offscreenSurfaceCache = DependencyManager::get<OffscreenQmlSurfaceCache>(); |
| 3018 | offscreenSurfaceCache->setOnRootContextCreated([&](const QString& rootObject, QQmlContext* surfaceContext) { | 3123 | offscreenSurfaceCache->setOnRootContextCreated([&](const QString& rootObject, QQmlContext* surfaceContext) { |
| 3019 | if (rootObject == TabletScriptingInterface::QML) { | 3124 | if (rootObject == TabletScriptingInterface::QML) { |
| @@ -3025,7 +3130,7 @@ void Application::initializeUi() { · 5 unmodified lines | |||
| 3025 | }); | 3130 | }); |
| 3026 | 3131 | ||
| 3027 | offscreenSurfaceCache->reserve(TabletScriptingInterface::QML, 1); | 3132 | offscreenSurfaceCache->reserve(TabletScriptingInterface::QML, 1); |
| 3028 | offscreenSurfaceCache->reserve(Web3DOverlay::QML, 2); | 3133 | offscreenSurfaceCache->reserve(render::entities::WebEntityRenderer::QML, 2); |
| 3029 | #endif | 3134 | #endif |
| 3030 | 3135 | ||
| 3031 | flushMenuUpdates(); | 3136 | flushMenuUpdates(); |
| @@ -3165,6 +3270,61 @@ void Application::onDesktopRootItemCreated(QQuickItem* rootItem) { · 133 unmodified lines | |||
| 3165 | #endif | 3270 | #endif |
| 3166 | } | 3271 | } |
| 3167 | 3272 | ||
| 3273 | void Application::setupQmlSurface(QQmlContext* surfaceContext, bool setAdditionalContextProperties) { | ||
| 3274 | surfaceContext->setContextProperty("Users", DependencyManager::get<UsersScriptingInterface>().data()); | ||
| 3275 | surfaceContext->setContextProperty("HMD", DependencyManager::get<HMDScriptingInterface>().data()); | ||
| 3276 | surfaceContext->setContextProperty("UserActivityLogger", DependencyManager::get<UserActivityLoggerScriptingInterface>().data()); | ||
| 3277 | surfaceContext->setContextProperty("Preferences", DependencyManager::get<Preferences>().data()); | ||
| 3278 | surfaceContext->setContextProperty("Vec3", new Vec3()); | ||
| 3279 | surfaceContext->setContextProperty("Quat", new Quat()); | ||
| 3280 | surfaceContext->setContextProperty("MyAvatar", DependencyManager::get<AvatarManager>()->getMyAvatar().get()); | ||
| 3281 | surfaceContext->setContextProperty("Entities", DependencyManager::get<EntityScriptingInterface>().data()); | ||
| 3282 | surfaceContext->setContextProperty("Snapshot", DependencyManager::get<Snapshot>().data()); | ||
| 3283 | |||
| 3284 | if (setAdditionalContextProperties) { | ||
| 3285 | auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>(); | ||
| 3286 | auto flags = tabletScriptingInterface->getFlags(); | ||
| 3287 | |||
| 3288 | surfaceContext->setContextProperty("offscreenFlags", flags); | ||
| 3289 | surfaceContext->setContextProperty("AddressManager", DependencyManager::get<AddressManager>().data()); | ||
| 3290 | |||
| 3291 | surfaceContext->setContextProperty("Settings", SettingsScriptingInterface::getInstance()); | ||
| 3292 | surfaceContext->setContextProperty("MenuInterface", MenuScriptingInterface::getInstance()); | ||
| 3293 | surfaceContext->setContextProperty("KeyboardScriptingInterface", DependencyManager::get<KeyboardScriptingInterface>().data()); | ||
| 3294 | |||
| 3295 | surfaceContext->setContextProperty("Account", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED | ||
| 3296 | surfaceContext->setContextProperty("GlobalServices", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED | ||
| 3297 | surfaceContext->setContextProperty("AccountServices", AccountServicesScriptingInterface::getInstance()); | ||
| 3298 | |||
| 3299 | // in Qt 5.10.0 there is already an "Audio" object in the QML context | ||
| 3300 | // though I failed to find it (from QtMultimedia??). So.. let it be "AudioScriptingInterface" | ||
| 3301 | surfaceContext->setContextProperty("AudioScriptingInterface", DependencyManager::get<AudioScriptingInterface>().data()); | ||
| 3302 | |||
| 3303 | surfaceContext->setContextProperty("AudioStats", DependencyManager::get<AudioClient>()->getStats().data()); | ||
| 3304 | surfaceContext->setContextProperty("fileDialogHelper", new FileDialogHelper()); | ||
| 3305 | surfaceContext->setContextProperty("ScriptDiscoveryService", DependencyManager::get<ScriptEngines>().data()); | ||
| 3306 | surfaceContext->setContextProperty("Assets", DependencyManager::get<AssetMappingsScriptingInterface>().data()); | ||
| 3307 | surfaceContext->setContextProperty("LODManager", DependencyManager::get<LODManager>().data()); | ||
| 3308 | surfaceContext->setContextProperty("OctreeStats", DependencyManager::get<OctreeStatsProvider>().data()); | ||
| 3309 | surfaceContext->setContextProperty("DCModel", DependencyManager::get<DomainConnectionModel>().data()); | ||
| 3310 | surfaceContext->setContextProperty("AvatarInputs", AvatarInputs::getInstance()); | ||
| 3311 | surfaceContext->setContextProperty("AvatarList", DependencyManager::get<AvatarManager>().data()); | ||
| 3312 | surfaceContext->setContextProperty("DialogsManager", DialogsManagerScriptingInterface::getInstance()); | ||
| 3313 | surfaceContext->setContextProperty("InputConfiguration", DependencyManager::get<InputConfiguration>().data()); | ||
| 3314 | surfaceContext->setContextProperty("SoundCache", DependencyManager::get<SoundCacheScriptingInterface>().data()); | ||
| 3315 | surfaceContext->setContextProperty("AvatarBookmarks", DependencyManager::get<AvatarBookmarks>().data()); | ||
| 3316 | surfaceContext->setContextProperty("Render", AbstractViewStateInterface::instance()->getRenderEngine()->getConfiguration().get()); | ||
| 3317 | surfaceContext->setContextProperty("Workload", qApp->getGameWorkload()._engine->getConfiguration().get()); | ||
| 3318 | surfaceContext->setContextProperty("Controller", DependencyManager::get<controller::ScriptingInterface>().data()); | ||
| 3319 | surfaceContext->setContextProperty("Pointers", DependencyManager::get<PointerScriptingInterface>().data()); | ||
| 3320 | surfaceContext->setContextProperty("Window", DependencyManager::get<WindowScriptingInterface>().data()); | ||
| 3321 | surfaceContext->setContextProperty("Reticle", qApp->getApplicationCompositor().getReticleInterface()); | ||
| 3322 | surfaceContext->setContextProperty("HiFiAbout", AboutUtil::getInstance()); | ||
| 3323 | surfaceContext->setContextProperty("WalletScriptingInterface", DependencyManager::get<WalletScriptingInterface>().data()); | ||
| 3324 | surfaceContext->setContextProperty("ResourceRequestObserver", DependencyManager::get<ResourceRequestObserver>().data()); | ||
| 3325 | } | ||
| 3326 | } | ||
| 3327 | |||
| 3168 | void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) { | 3328 | void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) { |
| 3169 | PROFILE_RANGE(render, __FUNCTION__); | 3329 | PROFILE_RANGE(render, __FUNCTION__); |
| 3170 | PerformanceTimer perfTimer("updateCamera"); | 3330 | PerformanceTimer perfTimer("updateCamera"); |
| @@ -3421,8 +3581,10 @@ void Application::resizeGL() { · 250 unmodified lines | |||
| 3421 | auto renderConfig = _graphicsEngine.getRenderEngine()->getConfiguration(); | 3581 | auto renderConfig = _graphicsEngine.getRenderEngine()->getConfiguration(); |
| 3422 | assert(renderConfig); | 3582 | assert(renderConfig); |
| 3423 | auto mainView = renderConfig->getConfig("RenderMainView.RenderDeferredTask"); | 3583 | auto mainView = renderConfig->getConfig("RenderMainView.RenderDeferredTask"); |
| 3424 | assert(mainView); | 3584 | // mainView can be null if we're rendering in forward mode |
| 3425 | mainView->setProperty("resolutionScale", renderResolutionScale); | 3585 | if (mainView) { |
| 3586 | mainView->setProperty("resolutionScale", renderResolutionScale); | ||
| 3587 | } | ||
| 3426 | displayPlugin->setRenderResolutionScale(renderResolutionScale); | 3588 | displayPlugin->setRenderResolutionScale(renderResolutionScale); |
| 3427 | } | 3589 | } |
| 3428 | 3590 | ||
| @@ -3677,8 +3839,8 @@ static inline bool isKeyEvent(QEvent::Type type) { · 248 unmodified lines | |||
| 3677 | return type == QEvent::KeyPress || type == QEvent::KeyRelease; | 3839 | return type == QEvent::KeyPress || type == QEvent::KeyRelease; |
| 3678 | } | 3840 | } |
| 3679 | 3841 | ||
| 3680 | bool Application::handleKeyEventForFocusedEntityOrOverlay(QEvent* event) { | 3842 | bool Application::handleKeyEventForFocusedEntity(QEvent* event) { |
| 3681 | if (!_keyboardFocusedEntity.get().isInvalidID()) { | 3843 | if (_keyboardFocusedEntity.get() != UNKNOWN_ENTITY_ID) { |
| 3682 | switch (event->type()) { | 3844 | switch (event->type()) { |
| 3683 | case QEvent::KeyPress: | 3845 | case QEvent::KeyPress: |
| 3684 | case QEvent::KeyRelease: | 3846 | case QEvent::KeyRelease: |
| @@ -3699,28 +3861,6 @@ bool Application::handleKeyEventForFocusedEntityOrOverlay(QEvent* event) { · 14 unmodified lines | |||
| 3699 | } | 3861 | } |
| 3700 | } | 3862 | } |
| 3701 | 3863 | ||
| 3702 | if (_keyboardFocusedOverlay.get() != UNKNOWN_OVERLAY_ID) { | ||
| 3703 | switch (event->type()) { | ||
| 3704 | case QEvent::KeyPress: | ||
| 3705 | case QEvent::KeyRelease: { | ||
| 3706 | // Only Web overlays can have focus. | ||
| 3707 | auto overlay = std::dynamic_pointer_cast<Web3DOverlay>(getOverlays().getOverlay(_keyboardFocusedOverlay.get())); | ||
| 3708 | if (overlay && overlay->getEventHandler()) { | ||
| 3709 | event->setAccepted(false); | ||
| 3710 | QCoreApplication::sendEvent(overlay->getEventHandler(), event); | ||
| 3711 | if (event->isAccepted()) { | ||
| 3712 | _lastAcceptedKeyPress = usecTimestampNow(); | ||
| 3713 | return true; | ||
| 3714 | } | ||
| 3715 | } | ||
| 3716 | } | ||
| 3717 | break; | ||
| 3718 | |||
| 3719 | default: | ||
| 3720 | break; | ||
| 3721 | } | ||
| 3722 | } | ||
| 3723 | |||
| 3724 | return false; | 3864 | return false; |
| 3725 | } | 3865 | } |
| 3726 | 3866 | ||
| @@ -3763,8 +3903,8 @@ bool Application::event(QEvent* event) { · 36 unmodified lines | |||
| 3763 | return false; | 3903 | return false; |
| 3764 | } | 3904 | } |
| 3765 | 3905 | ||
| 3766 | // Allow focused Entities and Overlays to handle keyboard input | 3906 | // Allow focused Entities to handle keyboard input |
| 3767 | if (isKeyEvent(event->type()) && handleKeyEventForFocusedEntityOrOverlay(event)) { | 3907 | if (isKeyEvent(event->type()) && handleKeyEventForFocusedEntity(event)) { |
| 3768 | return true; | 3908 | return true; |
| 3769 | } | 3909 | } |
| 3770 | 3910 | ||
| @@ -3970,6 +4110,19 @@ void Application::keyPressEvent(QKeyEvent* event) { · 199 unmodified lines | |||
| 3970 | } | 4110 | } |
| 3971 | break; | 4111 | break; |
| 3972 | 4112 | ||
| 4113 | case Qt::Key_G: | ||
| 4114 | if (isShifted && isMeta && Menu::getInstance() && Menu::getInstance()->getMenu("Developer")->isVisible()) { | ||
| 4115 | static const QString HIFI_FRAMES_FOLDER_VAR = "HIFI_FRAMES_FOLDER"; | ||
| 4116 | static const QString GPU_FRAME_FOLDER = QProcessEnvironment::systemEnvironment().contains(HIFI_FRAMES_FOLDER_VAR) | ||
| 4117 | ? QProcessEnvironment::systemEnvironment().value(HIFI_FRAMES_FOLDER_VAR) | ||
| 4118 | : "hifiFrames"; | ||
| 4119 | static QString GPU_FRAME_TEMPLATE = GPU_FRAME_FOLDER + "/{DATE}_{TIME}"; | ||
| 4120 | QString fullPath = FileUtils::computeDocumentPath(FileUtils::replaceDateTimeTokens(GPU_FRAME_TEMPLATE)); | ||
| 4121 | if (FileUtils::canCreateFile(fullPath)) { | ||
| 4122 | getActiveDisplayPlugin()->captureFrame(fullPath.toStdString()); | ||
| 4123 | } | ||
| 4124 | } | ||
| 4125 | break; | ||
| 3973 | case Qt::Key_X: | 4126 | case Qt::Key_X: |
| 3974 | if (isShifted && isMeta) { | 4127 | if (isShifted && isMeta) { |
| 3975 | auto offscreenUi = getOffscreenUI(); | 4128 | auto offscreenUi = getOffscreenUI(); |
| @@ -4041,7 +4194,9 @@ void Application::keyPressEvent(QKeyEvent* event) { · 65 unmodified lines | |||
| 4041 | if (!isShifted && !isMeta && !isOption && !event->isAutoRepeat()) { | 4194 | if (!isShifted && !isMeta && !isOption && !event->isAutoRepeat()) { |
| 4042 | AudioInjectorOptions options; | 4195 | AudioInjectorOptions options; |
| 4043 | options.localOnly = true; | 4196 | options.localOnly = true; |
| 4197 | options.positionSet = false; // system sound | ||
| 4044 | options.stereo = true; | 4198 | options.stereo = true; |
| 4199 | |||
| 4045 | Setting::Handle<bool> notificationSounds{ MenuOption::NotificationSounds, true }; | 4200 | Setting::Handle<bool> notificationSounds{ MenuOption::NotificationSounds, true }; |
| 4046 | Setting::Handle<bool> notificationSoundSnapshot{ MenuOption::NotificationSoundsSnapshot, true }; | 4201 | Setting::Handle<bool> notificationSoundSnapshot{ MenuOption::NotificationSoundsSnapshot, true }; |
| 4047 | if (notificationSounds.get() && notificationSoundSnapshot.get()) { | 4202 | if (notificationSounds.get() && notificationSoundSnapshot.get()) { |
| @@ -4230,9 +4385,9 @@ void Application::mouseMoveEvent(QMouseEvent* event) { · 182 unmodified lines | |||
| 4230 | buttons, event->modifiers()); | 4385 | buttons, event->modifiers()); |
| 4231 | 4386 | ||
| 4232 | if (compositor.getReticleVisible() || !isHMDMode() || !compositor.getReticleOverDesktop() || | 4387 | if (compositor.getReticleVisible() || !isHMDMode() || !compositor.getReticleOverDesktop() || |
| 4233 | getOverlays().getOverlayAtPoint(glm::vec2(transformedPos.x(), transformedPos.y())) != UNKNOWN_OVERLAY_ID) { | 4388 | getOverlays().getOverlayAtPoint(glm::vec2(transformedPos.x(), transformedPos.y())) != UNKNOWN_ENTITY_ID) { |
| 4234 | getOverlays().mouseMoveEvent(&mappedEvent); | ||
| 4235 | getEntities()->mouseMoveEvent(&mappedEvent); | 4389 | getEntities()->mouseMoveEvent(&mappedEvent); |
| 4390 | getOverlays().mouseMoveEvent(&mappedEvent); | ||
| 4236 | } | 4391 | } |
| 4237 | 4392 | ||
| 4238 | _controllerScriptingInterface->emitMouseMoveEvent(&mappedEvent); // send events to any registered scripts | 4393 | _controllerScriptingInterface->emitMouseMoveEvent(&mappedEvent); // send events to any registered scripts |
| @@ -4264,15 +4419,16 @@ void Application::mousePressEvent(QMouseEvent* event) { · 25 unmodified lines | |||
| 4264 | #else | 4419 | #else |
| 4265 | QPointF transformedPos; | 4420 | QPointF transformedPos; |
| 4266 | #endif | 4421 | #endif |
| 4267 | QMouseEvent mappedEvent(event->type(), | ||
| 4268 | transformedPos, | ||
| 4269 | event->screenPos(), event->button(), | ||
| 4270 | event->buttons(), event->modifiers()); | ||
| 4271 | 4422 | ||
| 4272 | getOverlays().mousePressEvent(&mappedEvent); | 4423 | QMouseEvent mappedEvent(event->type(), transformedPos, event->screenPos(), event->button(), event->buttons(), event->modifiers()); |
| 4424 | std::pair<float, QUuid> entityResult; | ||
| 4273 | if (!_controllerScriptingInterface->areEntityClicksCaptured()) { | 4425 | if (!_controllerScriptingInterface->areEntityClicksCaptured()) { |
| 4274 | getEntities()->mousePressEvent(&mappedEvent); | 4426 | entityResult = getEntities()->mousePressEvent(&mappedEvent); |
| 4275 | } | 4427 | } |
| 4428 | std::pair<float, QUuid> overlayResult = getOverlays().mousePressEvent(&mappedEvent); | ||
| 4429 | |||
| 4430 | QUuid focusedEntity = entityResult.first < overlayResult.first ? entityResult.second : overlayResult.second; | ||
| 4431 | setKeyboardFocusEntity(getEntities()->wantsKeyboardFocus(focusedEntity) ? focusedEntity : UNKNOWN_ENTITY_ID); | ||
| 4276 | 4432 | ||
| 4277 | _controllerScriptingInterface->emitMousePressEvent(&mappedEvent); // send events to any registered scripts | 4433 | _controllerScriptingInterface->emitMousePressEvent(&mappedEvent); // send events to any registered scripts |
| 4278 | 4434 | ||
| @@ -4312,10 +4468,10 @@ void Application::mouseDoublePressEvent(QMouseEvent* event) { · 33 unmodified lines | |||
| 4312 | event->screenPos(), event->button(), | 4468 | event->screenPos(), event->button(), |
| 4313 | event->buttons(), event->modifiers()); | 4469 | event->buttons(), event->modifiers()); |
| 4314 | 4470 | ||
| 4315 | getOverlays().mouseDoublePressEvent(&mappedEvent); | ||
| 4316 | if (!_controllerScriptingInterface->areEntityClicksCaptured()) { | 4471 | if (!_controllerScriptingInterface->areEntityClicksCaptured()) { |
| 4317 | getEntities()->mouseDoublePressEvent(&mappedEvent); | 4472 | getEntities()->mouseDoublePressEvent(&mappedEvent); |
| 4318 | } | 4473 | } |
| 4474 | getOverlays().mouseDoublePressEvent(&mappedEvent); | ||
| 4319 | 4475 | ||
| 4320 | // if one of our scripts have asked to capture this event, then stop processing it | 4476 | // if one of our scripts have asked to capture this event, then stop processing it |
| 4321 | if (_controllerScriptingInterface->isMouseCaptured()) { | 4477 | if (_controllerScriptingInterface->isMouseCaptured()) { |
| @@ -4339,8 +4495,8 @@ void Application::mouseReleaseEvent(QMouseEvent* event) { · 17 unmodified lines | |||
| 4339 | event->screenPos(), event->button(), | 4495 | event->screenPos(), event->button(), |
| 4340 | event->buttons(), event->modifiers()); | 4496 | event->buttons(), event->modifiers()); |
| 4341 | 4497 | ||
| 4342 | getOverlays().mouseReleaseEvent(&mappedEvent); | ||
| 4343 | getEntities()->mouseReleaseEvent(&mappedEvent); | 4498 | getEntities()->mouseReleaseEvent(&mappedEvent); |
| 4499 | getOverlays().mouseReleaseEvent(&mappedEvent); | ||
| 4344 | 4500 | ||
| 4345 | _controllerScriptingInterface->emitMouseReleaseEvent(&mappedEvent); // send events to any registered scripts | 4501 | _controllerScriptingInterface->emitMouseReleaseEvent(&mappedEvent); // send events to any registered scripts |
| 4346 | 4502 | ||
| @@ -4751,6 +4907,10 @@ void Application::idle() { · 404 unmodified lines | |||
| 4751 | steamClient->runCallbacks(); | 4907 | steamClient->runCallbacks(); |
| 4752 | } | 4908 | } |
| 4753 | 4909 | ||
| 4910 | if (auto oculusPlugin = PluginManager::getInstance()->getOculusPlatformPlugin()) { | ||
| 4911 | oculusPlugin->handleOVREvents(); | ||
| 4912 | } | ||
| 4913 | |||
| 4754 | float secondsSinceLastUpdate = (float)_lastTimeUpdated.nsecsElapsed() / NSECS_PER_MSEC / MSECS_PER_SECOND; | 4914 | float secondsSinceLastUpdate = (float)_lastTimeUpdated.nsecsElapsed() / NSECS_PER_MSEC / MSECS_PER_SECOND; |
| 4755 | _lastTimeUpdated.start(); | 4915 | _lastTimeUpdated.start(); |
| 4756 | 4916 | ||
| @@ -4784,7 +4944,11 @@ void Application::idle() { · 27 unmodified lines | |||
| 4784 | // Normally we check PipelineWarnings, but since idle will often take more than 10ms we only show these idle timing | 4944 | // Normally we check PipelineWarnings, but since idle will often take more than 10ms we only show these idle timing |
| 4785 | // details if we're in ExtraDebugging mode. However, the ::update() and its subcomponents will show their timing | 4945 | // details if we're in ExtraDebugging mode. However, the ::update() and its subcomponents will show their timing |
| 4786 | // details normally. | 4946 | // details normally. |
| 4947 | #ifdef Q_OS_ANDROID | ||
| 4948 | bool showWarnings = false; | ||
| 4949 | #else | ||
| 4787 | bool showWarnings = getLogger()->extraDebugging(); | 4950 | bool showWarnings = getLogger()->extraDebugging(); |
| 4951 | #endif | ||
| 4788 | PerformanceWarning warn(showWarnings, "idle()"); | 4952 | PerformanceWarning warn(showWarnings, "idle()"); |
| 4789 | 4953 | ||
| 4790 | { | 4954 | { |
| @@ -4798,31 +4962,19 @@ void Application::idle() { · 7 unmodified lines | |||
| 4798 | update(glm::clamp(secondsSinceLastUpdate, 0.0f, BIGGEST_DELTA_TIME_SECS)); | 4962 | update(glm::clamp(secondsSinceLastUpdate, 0.0f, BIGGEST_DELTA_TIME_SECS)); |
| 4799 | } | 4963 | } |
| 4800 | 4964 | ||
| 4801 | 4965 | { // Update keyboard focus highlight | |
| 4802 | // Update focus highlight for entity or overlay. | 4966 | if (!_keyboardFocusedEntity.get().isInvalidID()) { |
| 4803 | { | ||
| 4804 | if (!_keyboardFocusedEntity.get().isInvalidID() || _keyboardFocusedOverlay.get() != UNKNOWN_OVERLAY_ID) { | ||
| 4805 | const quint64 LOSE_FOCUS_AFTER_ELAPSED_TIME = 30 * USECS_PER_SECOND; // if idle for 30 seconds, drop focus | 4967 | const quint64 LOSE_FOCUS_AFTER_ELAPSED_TIME = 30 * USECS_PER_SECOND; // if idle for 30 seconds, drop focus |
| 4806 | quint64 elapsedSinceAcceptedKeyPress = usecTimestampNow() - _lastAcceptedKeyPress; | 4968 | quint64 elapsedSinceAcceptedKeyPress = usecTimestampNow() - _lastAcceptedKeyPress; |
| 4807 | if (elapsedSinceAcceptedKeyPress > LOSE_FOCUS_AFTER_ELAPSED_TIME) { | 4969 | if (elapsedSinceAcceptedKeyPress > LOSE_FOCUS_AFTER_ELAPSED_TIME) { |
| 4808 | setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); | 4970 | setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); |
| 4809 | setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); | ||
| 4810 | } else { | 4971 | } else { |
| 4811 | // update position of highlight overlay | 4972 | if (auto entity = getEntities()->getTree()->findEntityByID(_keyboardFocusedEntity.get())) { |
| 4812 | if (!_keyboardFocusedEntity.get().isInvalidID()) { | 4973 | EntityItemProperties properties; |
| 4813 | auto entity = getEntities()->getTree()->findEntityByID(_keyboardFocusedEntity.get()); | 4974 | properties.setPosition(entity->getWorldPosition()); |
| 4814 | if (entity && _keyboardFocusHighlight) { | 4975 | properties.setRotation(entity->getWorldOrientation()); |
| 4815 | _keyboardFocusHighlight->setWorldOrientation(entity->getWorldOrientation()); | 4976 | properties.setDimensions(entity->getScaledDimensions() * FOCUS_HIGHLIGHT_EXPANSION_FACTOR); |
| 4816 | _keyboardFocusHighlight->setWorldPosition(entity->getWorldPosition()); | 4977 | DependencyManager::get<EntityScriptingInterface>()->editEntity(_keyboardFocusHighlightID, properties); |
| 4817 | } | ||
| 4818 | } else { | ||
| 4819 | // Only Web overlays can have focus. | ||
| 4820 | auto overlay = | ||
| 4821 | std::dynamic_pointer_cast<Web3DOverlay>(getOverlays().getOverlay(_keyboardFocusedOverlay.get())); | ||
| 4822 | if (overlay && _keyboardFocusHighlight) { | ||
| 4823 | _keyboardFocusHighlight->setWorldOrientation(overlay->getWorldOrientation()); | ||
| 4824 | _keyboardFocusHighlight->setWorldPosition(overlay->getWorldPosition()); | ||
| 4825 | } | ||
| 4826 | } | 4978 | } |
| 4827 | } | 4979 | } |
| 4828 | } | 4980 | } |
| @@ -5620,118 +5772,80 @@ void Application::rotationModeChanged() const { · 791 unmodified lines | |||
| 5620 | } | 5772 | } |
| 5621 | 5773 | ||
| 5622 | void Application::setKeyboardFocusHighlight(const glm::vec3& position, const glm::quat& rotation, const glm::vec3& dimensions) { | 5774 | void Application::setKeyboardFocusHighlight(const glm::vec3& position, const glm::quat& rotation, const glm::vec3& dimensions) { |
| 5623 | // Create focus | ||
| 5624 | if (qApp->getLoginDialogPoppedUp()) { | 5775 | if (qApp->getLoginDialogPoppedUp()) { |
| 5625 | return; | 5776 | return; |
| 5626 | } | 5777 | } |
| 5627 | if (_keyboardFocusHighlightID == UNKNOWN_OVERLAY_ID || !getOverlays().isAddedOverlay(_keyboardFocusHighlightID)) { | 5778 | |
| 5628 | _keyboardFocusHighlight = std::make_shared<Cube3DOverlay>(); | 5779 | auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); |
| 5629 | _keyboardFocusHighlight->setAlpha(1.0f); | 5780 | if (_keyboardFocusHighlightID == UNKNOWN_ENTITY_ID || !entityScriptingInterface->isAddedEntity(_keyboardFocusHighlightID)) { |
| 5630 | _keyboardFocusHighlight->setColor({ 0xFF, 0xEF, 0x00 }); | 5781 | EntityItemProperties properties; |
| 5631 | _keyboardFocusHighlight->setIsSolid(false); | 5782 | properties.setType(EntityTypes::Box); |
| 5632 | _keyboardFocusHighlight->setPulseMin(0.5); | 5783 | properties.setAlpha(1.0f); |
| 5633 | _keyboardFocusHighlight->setPulseMax(1.0); | 5784 | properties.setColor({ 0xFF, 0xEF, 0x00 }); |
| 5634 | _keyboardFocusHighlight->setColorPulse(1.0); | 5785 | properties.setPrimitiveMode(PrimitiveMode::LINES); |
| 5635 | _keyboardFocusHighlight->setIgnorePickIntersection(true); | 5786 | properties.getPulse().setMin(0.5); |
| 5636 | _keyboardFocusHighlight->setDrawInFront(false); | 5787 | properties.getPulse().setMax(1.0f); |
| 5637 | _keyboardFocusHighlightID = getOverlays().addOverlay(_keyboardFocusHighlight); | 5788 | properties.getPulse().setColorMode(PulseMode::IN_PHASE); |
| 5789 | properties.setIgnorePickIntersection(true); | ||
| 5790 | _keyboardFocusHighlightID = entityScriptingInterface->addEntityInternal(properties, entity::HostType::LOCAL); | ||
| 5638 | } | 5791 | } |
| 5639 | 5792 | ||
| 5640 | // Position focus | 5793 | // Position focus |
| 5641 | _keyboardFocusHighlight->setWorldOrientation(rotation); | 5794 | EntityItemProperties properties; |
| 5642 | _keyboardFocusHighlight->setWorldPosition(position); | 5795 | properties.setPosition(position); |
| 5643 | _keyboardFocusHighlight->setDimensions(dimensions); | 5796 | properties.setRotation(rotation); |
| 5644 | _keyboardFocusHighlight->setVisible(true); | 5797 | properties.setDimensions(dimensions); |
| 5798 | properties.setVisible(true); | ||
| 5799 | entityScriptingInterface->editEntity(_keyboardFocusHighlightID, properties); | ||
| 5645 | } | 5800 | } |
| 5646 | 5801 | ||
| 5647 | QUuid Application::getKeyboardFocusEntity() const { | 5802 | QUuid Application::getKeyboardFocusEntity() const { |
| 5648 | return _keyboardFocusedEntity.get(); | 5803 | return _keyboardFocusedEntity.get(); |
| 5649 | } | 5804 | } |
| 5650 | 5805 | ||
| 5651 | static const float FOCUS_HIGHLIGHT_EXPANSION_FACTOR = 1.05f; | 5806 | void Application::setKeyboardFocusEntity(const QUuid& id) { |
| 5652 | 5807 | if (_keyboardFocusedEntity.get() != id) { | |
| 5653 | void Application::setKeyboardFocusEntity(const EntityItemID& entityItemID) { | 5808 | if (qApp->getLoginDialogPoppedUp() && !_loginDialogID.isNull()) { |
| 5654 | if (qApp->getLoginDialogPoppedUp()) { | 5809 | if (id == _loginDialogID) { |
| 5655 | return; | ||
| 5656 | } | ||
| 5657 | if (_keyboardFocusedEntity.get() != entityItemID) { | ||
| 5658 | _keyboardFocusedEntity.set(entityItemID); | ||
| 5659 | |||
| 5660 | if (_keyboardFocusHighlight && _keyboardFocusedOverlay.get() == UNKNOWN_OVERLAY_ID) { | ||
| 5661 | _keyboardFocusHighlight->setVisible(false); | ||
| 5662 | } | ||
| 5663 | |||
| 5664 | if (entityItemID == UNKNOWN_ENTITY_ID) { | ||
| 5665 | return; | ||
| 5666 | } | ||
| 5667 | |||
| 5668 | auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); | ||
| 5669 | auto properties = entityScriptingInterface->getEntityProperties(entityItemID); | ||
| 5670 | if (!properties.getLocked() && properties.getVisible()) { | ||
| 5671 | |||
| 5672 | auto entities = getEntities(); | ||
| 5673 | auto entityId = _keyboardFocusedEntity.get(); | ||
| 5674 | if (entities->wantsKeyboardFocus(entityId)) { | ||
| 5675 | entities->setProxyWindow(entityId, _window->windowHandle()); | ||
| 5676 | if (_keyboardMouseDevice->isActive()) { | ||
| 5677 | _keyboardMouseDevice->pluginFocusOutEvent(); | ||
| 5678 | } | ||
| 5679 | _lastAcceptedKeyPress = usecTimestampNow(); | ||
| 5680 | |||
| 5681 | auto entity = getEntities()->getEntity(entityId); | ||
| 5682 | if (entity) { | ||
| 5683 | setKeyboardFocusHighlight(entity->getWorldPosition(), entity->getWorldOrientation(), | ||
| 5684 | entity->getScaledDimensions() * FOCUS_HIGHLIGHT_EXPANSION_FACTOR); | ||
| 5685 | } | ||
| 5686 | } | ||
| 5687 | } | ||
| 5688 | } | ||
| 5689 | } | ||
| 5690 | |||
| 5691 | OverlayID Application::getKeyboardFocusOverlay() { | ||
| 5692 | return _keyboardFocusedOverlay.get(); | ||
| 5693 | } | ||
| 5694 | |||
| 5695 | void Application::setKeyboardFocusOverlay(const OverlayID& overlayID) { | ||
| 5696 | if (overlayID != _keyboardFocusedOverlay.get()) { | ||
| 5697 | if (qApp->getLoginDialogPoppedUp() && !_loginDialogOverlayID.isNull()) { | ||
| 5698 | if (overlayID == _loginDialogOverlayID) { | ||
| 5699 | emit loginDialogFocusEnabled(); | 5810 | emit loginDialogFocusEnabled(); |
| 5700 | } else { | 5811 | } else { |
| 5701 | // that's the only overlay we want in focus; | 5812 | // that's the only entity we want in focus; |
| 5702 | return; | 5813 | return; |
| 5703 | } | 5814 | } |
| 5704 | } | 5815 | } |
| 5705 | 5816 | ||
| 5706 | _keyboardFocusedOverlay.set(overlayID); | 5817 | _keyboardFocusedEntity.set(id); |
| 5707 | |||
| 5708 | if (_keyboardFocusHighlight && _keyboardFocusedEntity.get() == UNKNOWN_ENTITY_ID) { | ||
| 5709 | _keyboardFocusHighlight->setVisible(false); | ||
| 5710 | } | ||
| 5711 | |||
| 5712 | if (overlayID == UNKNOWN_OVERLAY_ID) { | ||
| 5713 | return; | ||
| 5714 | } | ||
| 5715 | 5818 | ||
| 5716 | auto overlayType = getOverlays().getOverlayType(overlayID); | 5819 | auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); |
| 5717 | auto isVisible = getOverlays().getProperty(overlayID, "visible").value.toBool(); | 5820 | if (id != UNKNOWN_ENTITY_ID) { |
| 5718 | if (overlayType == Web3DOverlay::TYPE && isVisible) { | 5821 | EntityPropertyFlags desiredProperties; |
| 5719 | auto overlay = std::dynamic_pointer_cast<Web3DOverlay>(getOverlays().getOverlay(overlayID)); | 5822 | desiredProperties += PROP_VISIBLE; |
| 5720 | overlay->setProxyWindow(_window->windowHandle()); | 5823 | desiredProperties += PROP_SHOW_KEYBOARD_FOCUS_HIGHLIGHT; |
| 5824 | auto properties = entityScriptingInterface->getEntityProperties(id); | ||
| 5825 | if (properties.getVisible()) { | ||
| 5826 | auto entities = getEntities(); | ||
| 5827 | auto entityId = _keyboardFocusedEntity.get(); | ||
| 5828 | if (entities->wantsKeyboardFocus(entityId)) { | ||
| 5829 | entities->setProxyWindow(entityId, _window->windowHandle()); | ||
| 5830 | if (_keyboardMouseDevice->isActive()) { | ||
| 5831 | _keyboardMouseDevice->pluginFocusOutEvent(); | ||
| 5832 | } | ||
| 5833 | _lastAcceptedKeyPress = usecTimestampNow(); | ||
| 5721 | 5834 | ||
| 5722 | if (_keyboardMouseDevice->isActive()) { | 5835 | if (properties.getShowKeyboardFocusHighlight()) { |
| 5723 | _keyboardMouseDevice->pluginFocusOutEvent(); | 5836 | if (auto entity = entities->getEntity(entityId)) { |
| 5724 | } | 5837 | setKeyboardFocusHighlight(entity->getWorldPosition(), entity->getWorldOrientation(), |
| 5725 | _lastAcceptedKeyPress = usecTimestampNow(); | 5838 | entity->getScaledDimensions() * FOCUS_HIGHLIGHT_EXPANSION_FACTOR); |
| 5726 | 5839 | return; | |
| 5727 | if (overlay->getProperty("showKeyboardFocusHighlight").toBool()) { | 5840 | } |
| 5728 | auto size = overlay->getSize() * FOCUS_HIGHLIGHT_EXPANSION_FACTOR; | 5841 | } |
| 5729 | const float OVERLAY_DEPTH = 0.0105f; | 5842 | } |
| 5730 | setKeyboardFocusHighlight(overlay->getWorldPosition(), overlay->getWorldOrientation(), glm::vec3(size.x, size.y, OVERLAY_DEPTH)); | ||
| 5731 | } else if (_keyboardFocusHighlight) { | ||
| 5732 | _keyboardFocusHighlight->setVisible(false); | ||
| 5733 | } | 5843 | } |
| 5734 | } | 5844 | } |
| 5845 | |||
| 5846 | EntityItemProperties properties; | ||
| 5847 | properties.setVisible(false); | ||
| 5848 | entityScriptingInterface->editEntity(_keyboardFocusHighlightID, properties); | ||
| 5735 | } | 5849 | } |
| 5736 | } | 5850 | } |
| 5737 | 5851 | ||
| @@ -5935,6 +6049,13 @@ void Application::update(float deltaTime) { · 197 unmodified lines | |||
| 5935 | 6049 | ||
| 5936 | auto userInputMapper = DependencyManager::get<UserInputMapper>(); | 6050 | auto userInputMapper = DependencyManager::get<UserInputMapper>(); |
| 5937 | 6051 | ||
| 6052 | controller::HmdAvatarAlignmentType hmdAvatarAlignmentType; | ||
| 6053 | if (myAvatar->getHmdAvatarAlignmentType() == "eyes") { | ||
| 6054 | hmdAvatarAlignmentType = controller::HmdAvatarAlignmentType::Eyes; | ||
| 6055 | } else { | ||
| 6056 | hmdAvatarAlignmentType = controller::HmdAvatarAlignmentType::Head; | ||
| 6057 | } | ||
| 6058 | |||
| 5938 | controller::InputCalibrationData calibrationData = { | 6059 | controller::InputCalibrationData calibrationData = { |
| 5939 | myAvatar->getSensorToWorldMatrix(), | 6060 | myAvatar->getSensorToWorldMatrix(), |
| 5940 | createMatFromQuatAndPos(myAvatar->getWorldOrientation(), myAvatar->getWorldPosition()), | 6061 | createMatFromQuatAndPos(myAvatar->getWorldOrientation(), myAvatar->getWorldPosition()), |
| @@ -5948,7 +6069,8 @@ void Application::update(float deltaTime) { · 7 unmodified lines | |||
| 5948 | myAvatar->getRightArmCalibrationMat(), | 6069 | myAvatar->getRightArmCalibrationMat(), |
| 5949 | myAvatar->getLeftArmCalibrationMat(), | 6070 | myAvatar->getLeftArmCalibrationMat(), |
| 5950 | myAvatar->getRightHandCalibrationMat(), | 6071 | myAvatar->getRightHandCalibrationMat(), |
| 5951 | myAvatar->getLeftHandCalibrationMat() | 6072 | myAvatar->getLeftHandCalibrationMat(), |
| 6073 | hmdAvatarAlignmentType | ||
| 5952 | }; | 6074 | }; |
| 5953 | 6075 | ||
| 5954 | InputPluginPointer keyboardMousePlugin; | 6076 | InputPluginPointer keyboardMousePlugin; |
| @@ -6100,6 +6222,19 @@ void Application::update(float deltaTime) { · 145 unmodified lines | |||
| 6100 | auto grabManager = DependencyManager::get<GrabManager>(); | 6222 | auto grabManager = DependencyManager::get<GrabManager>(); |
| 6101 | grabManager->simulateGrabs(); | 6223 | grabManager->simulateGrabs(); |
| 6102 | 6224 | ||
| 6225 | // TODO: break these out into distinct perfTimers when they prove interesting | ||
| 6226 | { | ||
| 6227 | PROFILE_RANGE(app, "PickManager"); | ||
| 6228 | PerformanceTimer perfTimer("pickManager"); | ||
| 6229 | DependencyManager::get<PickManager>()->update(); | ||
| 6230 | } | ||
| 6231 | |||
| 6232 | { | ||
| 6233 | PROFILE_RANGE(app, "PointerManager"); | ||
| 6234 | PerformanceTimer perfTimer("pointerManager"); | ||
| 6235 | DependencyManager::get<PointerManager>()->update(); | ||
| 6236 | } | ||
| 6237 | |||
| 6103 | QSharedPointer<AvatarManager> avatarManager = DependencyManager::get<AvatarManager>(); | 6238 | QSharedPointer<AvatarManager> avatarManager = DependencyManager::get<AvatarManager>(); |
| 6104 | 6239 | ||
| 6105 | { | 6240 | { |
| @@ -6113,36 +6248,57 @@ void Application::update(float deltaTime) { · 7 unmodified lines | |||
| 6113 | PROFILE_RANGE(simulation_physics, "PrePhysics"); | 6248 | PROFILE_RANGE(simulation_physics, "PrePhysics"); |
| 6114 | PerformanceTimer perfTimer("prePhysics)"); | 6249 | PerformanceTimer perfTimer("prePhysics)"); |
| 6115 | { | 6250 | { |
| 6251 | PROFILE_RANGE(simulation_physics, "RemoveEntities"); | ||
| 6116 | const VectorOfMotionStates& motionStates = _entitySimulation->getObjectsToRemoveFromPhysics(); | 6252 | const VectorOfMotionStates& motionStates = _entitySimulation->getObjectsToRemoveFromPhysics(); |
| 6117 | _physicsEngine->removeObjects(motionStates); | 6253 | { |
| 6254 | PROFILE_RANGE_EX(simulation_physics, "NumObjs", 0xffff0000, (uint64_t)motionStates.size()); | ||
| 6255 | _physicsEngine->removeObjects(motionStates); | ||
| 6256 | } | ||
| 6118 | _entitySimulation->deleteObjectsRemovedFromPhysics(); | 6257 | _entitySimulation->deleteObjectsRemovedFromPhysics(); |
| 6119 | } | 6258 | } |
| 6120 | 6259 | ||
| 6121 | VectorOfMotionStates motionStates; | 6260 | { |
| 6122 | getEntities()->getTree()->withReadLock([&] { | 6261 | PROFILE_RANGE(simulation_physics, "AddEntities"); |
| 6123 | _entitySimulation->getObjectsToAddToPhysics(motionStates); | 6262 | VectorOfMotionStates motionStates; |
| 6124 | _physicsEngine->addObjects(motionStates); | 6263 | getEntities()->getTree()->withReadLock([&] { |
| 6125 | 6264 | _entitySimulation->getObjectsToAddToPhysics(motionStates); | |
| 6126 | }); | 6265 | PROFILE_RANGE_EX(simulation_physics, "NumObjs", 0xffff0000, (uint64_t)motionStates.size()); |
| 6127 | getEntities()->getTree()->withReadLock([&] { | 6266 | _physicsEngine->addObjects(motionStates); |
| 6128 | _entitySimulation->getObjectsToChange(motionStates); | 6267 | }); |
| 6129 | VectorOfMotionStates stillNeedChange = _physicsEngine->changeObjects(motionStates); | 6268 | } |
| 6130 | _entitySimulation->setObjectsToChange(stillNeedChange); | 6269 | { |
| 6131 | }); | 6270 | VectorOfMotionStates motionStates; |
| 6271 | PROFILE_RANGE(simulation_physics, "ChangeEntities"); | ||
| 6272 | getEntities()->getTree()->withReadLock([&] { | ||
| 6273 | _entitySimulation->getObjectsToChange(motionStates); | ||
| 6274 | VectorOfMotionStates stillNeedChange = _physicsEngine->changeObjects(motionStates); | ||
| 6275 | _entitySimulation->setObjectsToChange(stillNeedChange); | ||
| 6276 | }); | ||
| 6277 | } | ||
| 6132 | 6278 | ||
| 6133 | _entitySimulation->applyDynamicChanges(); | 6279 | _entitySimulation->applyDynamicChanges(); |
| 6134 | 6280 | ||
| 6135 | t1 = std::chrono::high_resolution_clock::now(); | 6281 | t1 = std::chrono::high_resolution_clock::now(); |
| 6136 | 6282 | ||
| 6137 | PhysicsEngine::Transaction transaction; | 6283 | { |
| 6138 | avatarManager->buildPhysicsTransaction(transaction); | 6284 | PROFILE_RANGE(simulation_physics, "Avatars"); |
| 6139 | _physicsEngine->processTransaction(transaction); | 6285 | PhysicsEngine::Transaction transaction; |
| 6140 | avatarManager->handleProcessedPhysicsTransaction(transaction); | 6286 | avatarManager->buildPhysicsTransaction(transaction); |
| 6287 | _physicsEngine->processTransaction(transaction); | ||
| 6288 | avatarManager->handleProcessedPhysicsTransaction(transaction); | ||
| 6289 | myAvatar->getCharacterController()->buildPhysicsTransaction(transaction); | ||
| 6290 | _physicsEngine->processTransaction(transaction); | ||
| 6291 | myAvatar->getCharacterController()->handleProcessedPhysicsTransaction(transaction); | ||
| 6292 | myAvatar->prepareForPhysicsSimulation(); | ||
| 6293 | _physicsEngine->enableGlobalContactAddedCallback(myAvatar->isFlying()); | ||
| 6294 | } | ||
| 6141 | 6295 | ||
| 6142 | myAvatar->prepareForPhysicsSimulation(); | 6296 | { |
| 6143 | _physicsEngine->forEachDynamic([&](EntityDynamicPointer dynamic) { | 6297 | PROFILE_RANGE(simulation_physics, "PrepareActions"); |
| 6144 | dynamic->prepareForPhysicsSimulation(); | 6298 | _physicsEngine->forEachDynamic([&](EntityDynamicPointer dynamic) { |
| 6145 | }); | 6299 | dynamic->prepareForPhysicsSimulation(); |
| 6300 | }); | ||
| 6301 | } | ||
| 6146 | } | 6302 | } |
| 6147 | auto t2 = std::chrono::high_resolution_clock::now(); | 6303 | auto t2 = std::chrono::high_resolution_clock::now(); |
| 6148 | { | 6304 | { |
| @@ -6245,22 +6401,9 @@ void Application::update(float deltaTime) { · 96 unmodified lines | |||
| 6245 | 6401 | ||
| 6246 | updateLOD(deltaTime); | 6402 | updateLOD(deltaTime); |
| 6247 | 6403 | ||
| 6248 | if (!_loginDialogOverlayID.isNull()) { | 6404 | if (!_loginDialogID.isNull()) { |
| 6249 | _loginStateManager.update(getMyAvatar()->getDominantHand(), _loginDialogOverlayID); | 6405 | _loginStateManager.update(getMyAvatar()->getDominantHand(), _loginDialogID); |
| 6250 | updateLoginDialogOverlayPosition(); | 6406 | updateLoginDialogPosition(); |
| 6251 | } | ||
| 6252 | |||
| 6253 | // TODO: break these out into distinct perfTimers when they prove interesting | ||
| 6254 | { | ||
| 6255 | PROFILE_RANGE(app, "PickManager"); | ||
| 6256 | PerformanceTimer perfTimer("pickManager"); | ||
| 6257 | DependencyManager::get<PickManager>()->update(); | ||
| 6258 | } | ||
| 6259 | |||
| 6260 | { | ||
| 6261 | PROFILE_RANGE(app, "PointerManager"); | ||
| 6262 | PerformanceTimer perfTimer("pointerManager"); | ||
| 6263 | DependencyManager::get<PointerManager>()->update(); | ||
| 6264 | } | 6407 | } |
| 6265 | 6408 | ||
| 6266 | { | 6409 | { |
| @@ -6284,7 +6427,7 @@ void Application::update(float deltaTime) { · 17 unmodified lines | |||
| 6284 | // TODO: Fix this by modeling the way the secondary camera works on how the main camera works | 6427 | // TODO: Fix this by modeling the way the secondary camera works on how the main camera works |
| 6285 | // ie. Use a camera object stored in the game logic and informs the Engine on where the secondary | 6428 | // ie. Use a camera object stored in the game logic and informs the Engine on where the secondary |
| 6286 | // camera should be. | 6429 | // camera should be. |
| 6287 | // updateSecondaryCameraViewFrustum(); | 6430 | updateSecondaryCameraViewFrustum(); |
| 6288 | } | 6431 | } |
| 6289 | 6432 | ||
| 6290 | quint64 now = usecTimestampNow(); | 6433 | quint64 now = usecTimestampNow(); |
| @@ -6843,17 +6986,19 @@ void Application::nodeActivated(SharedNodePointer node) { · 552 unmodified lines | |||
| 6843 | 6986 | ||
| 6844 | #if !defined(DISABLE_QML) | 6987 | #if !defined(DISABLE_QML) |
| 6845 | auto offscreenUi = getOffscreenUI(); | 6988 | auto offscreenUi = getOffscreenUI(); |
| 6846 | auto assetDialog = offscreenUi ? offscreenUi->getRootItem()->findChild<QQuickItem*>("AssetServer") : nullptr; | ||
| 6847 | 6989 | ||
| 6848 | if (assetDialog) { | 6990 | if (offscreenUi) { |
| 6849 | auto nodeList = DependencyManager::get<NodeList>(); | 6991 | auto nodeList = DependencyManager::get<NodeList>(); |
| 6850 | 6992 | ||
| 6851 | if (nodeList->getThisNodeCanWriteAssets()) { | 6993 | if (nodeList->getThisNodeCanWriteAssets()) { |
| 6852 | // call reload on the shown asset browser dialog to get the mappings (if permissions allow) | 6994 | // call reload on the shown asset browser dialog to get the mappings (if permissions allow) |
| 6853 | QMetaObject::invokeMethod(assetDialog, "reload"); | 6995 | auto assetDialog = offscreenUi ? offscreenUi->getRootItem()->findChild<QQuickItem*>("AssetServer") : nullptr; |
| 6996 | if (assetDialog) { | ||
| 6997 | QMetaObject::invokeMethod(assetDialog, "reload"); | ||
| 6998 | } | ||
| 6854 | } else { | 6999 | } else { |
| 6855 | // we switched to an Asset Server that we can't modify, hide the Asset Browser | 7000 | // we switched to an Asset Server that we can't modify, hide the Asset Browser |
| 6856 | assetDialog->setVisible(false); | 7001 | offscreenUi->hide("AssetServer"); |
| 6857 | } | 7002 | } |
| 6858 | } | 7003 | } |
| 6859 | #endif | 7004 | #endif |
| @@ -7026,7 +7171,6 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe · 166 unmodified lines | |||
| 7026 | connect(scriptEngine.data(), &ScriptEngine::finished, clipboardScriptable, &ClipboardScriptingInterface::deleteLater); | 7171 | connect(scriptEngine.data(), &ScriptEngine::finished, clipboardScriptable, &ClipboardScriptingInterface::deleteLater); |
| 7027 | 7172 | ||
| 7028 | scriptEngine->registerGlobalObject("Overlays", &_overlays); | 7173 | scriptEngine->registerGlobalObject("Overlays", &_overlays); |
| 7029 | qScriptRegisterMetaType(scriptEngine.data(), OverlayPropertyResultToScriptValue, OverlayPropertyResultFromScriptValue); | ||
| 7030 | qScriptRegisterMetaType(scriptEngine.data(), RayToOverlayIntersectionResultToScriptValue, | 7174 | qScriptRegisterMetaType(scriptEngine.data(), RayToOverlayIntersectionResultToScriptValue, |
| 7031 | RayToOverlayIntersectionResultFromScriptValue); | 7175 | RayToOverlayIntersectionResultFromScriptValue); |
| 7032 | 7176 | ||
| @@ -7143,8 +7287,6 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe · 110 unmodified lines | |||
| 7143 | scriptEngine->registerGlobalObject("HifiAbout", AboutUtil::getInstance()); | 7287 | scriptEngine->registerGlobalObject("HifiAbout", AboutUtil::getInstance()); |
| 7144 | scriptEngine->registerGlobalObject("ResourceRequestObserver", DependencyManager::get<ResourceRequestObserver>().data()); | 7288 | scriptEngine->registerGlobalObject("ResourceRequestObserver", DependencyManager::get<ResourceRequestObserver>().data()); |
| 7145 | 7289 | ||
| 7146 | qScriptRegisterMetaType(scriptEngine.data(), OverlayIDtoScriptValue, OverlayIDfromScriptValue); | ||
| 7147 | |||
| 7148 | registerInteractiveWindowMetaType(scriptEngine.data()); | 7290 | registerInteractiveWindowMetaType(scriptEngine.data()); |
| 7149 | 7291 | ||
| 7150 | auto pickScriptingInterface = DependencyManager::get<PickScriptingInterface>(); | 7292 | auto pickScriptingInterface = DependencyManager::get<PickScriptingInterface>(); |
| @@ -8025,8 +8167,7 @@ void Application::openUrl(const QUrl& url) const { · 874 unmodified lines | |||
| 8025 | if (url.scheme() == URL_SCHEME_HIFI) { | 8167 | if (url.scheme() == URL_SCHEME_HIFI) { |
| 8026 | DependencyManager::get<AddressManager>()->handleLookupString(url.toString()); | 8168 | DependencyManager::get<AddressManager>()->handleLookupString(url.toString()); |
| 8027 | } else if (url.scheme() == URL_SCHEME_HIFIAPP) { | 8169 | } else if (url.scheme() == URL_SCHEME_HIFIAPP) { |
| 8028 | QmlCommerce commerce; | 8170 | DependencyManager::get<QmlCommerce>()->openSystemApp(url.path()); |
| 8029 | commerce.openSystemApp(url.path()); | ||
| 8030 | } else { | 8171 | } else { |
| 8031 | // address manager did not handle - ask QDesktopServices to handle | 8172 | // address manager did not handle - ask QDesktopServices to handle |
| 8032 | QDesktopServices::openUrl(url); | 8173 | QDesktopServices::openUrl(url); |
| @@ -8112,7 +8253,18 @@ void Application::toggleLogDialog() { · 79 unmodified lines | |||
| 8112 | return; | 8253 | return; |
| 8113 | } | 8254 | } |
| 8114 | if (! _logDialog) { | 8255 | if (! _logDialog) { |
| 8256 | |||
| 8257 | bool keepOnTop =_keepLogWindowOnTop.get(); | ||
| 8258 | #ifdef Q_OS_WIN | ||
| 8259 | _logDialog = new LogDialog(keepOnTop ? qApp->getWindow() : nullptr, getLogger()); | ||
| 8260 | #elif !defined(Q_OS_ANDROID) | ||
| 8115 | _logDialog = new LogDialog(nullptr, getLogger()); | 8261 | _logDialog = new LogDialog(nullptr, getLogger()); |
| 8262 | |||
| 8263 | if (keepOnTop) { | ||
| 8264 | Qt::WindowFlags flags = _logDialog->windowFlags() | Qt::Tool; | ||
| 8265 | _logDialog->setWindowFlags(flags); | ||
| 8266 | } | ||
| 8267 | #endif | ||
| 8116 | } | 8268 | } |
| 8117 | 8269 | ||
| 8118 | if (_logDialog->isVisible()) { | 8270 | if (_logDialog->isVisible()) { |
| @@ -8122,6 +8274,19 @@ void Application::toggleLogDialog() { · 3 unmodified lines | |||
| 8122 | } | 8274 | } |
| 8123 | } | 8275 | } |
| 8124 | 8276 | ||
| 8277 | void Application::recreateLogWindow(int keepOnTop) { | ||
| 8278 | _keepLogWindowOnTop.set(keepOnTop != 0); | ||
| 8279 | if (_logDialog) { | ||
| 8280 | bool toggle = _logDialog->isVisible(); | ||
| 8281 | _logDialog->close(); | ||
| 8282 | _logDialog = nullptr; | ||
| 8283 | |||
| 8284 | if (toggle) { | ||
| 8285 | toggleLogDialog(); | ||
| 8286 | } | ||
| 8287 | } | ||
| 8288 | } | ||
| 8289 | |||
| 8125 | void Application::toggleEntityScriptServerLogDialog() { | 8290 | void Application::toggleEntityScriptServerLogDialog() { |
| 8126 | if (! _entityScriptServerLogDialog) { | 8291 | if (! _entityScriptServerLogDialog) { |
| 8127 | _entityScriptServerLogDialog = new EntityScriptServerLogDialog(nullptr); | 8292 | _entityScriptServerLogDialog = new EntityScriptServerLogDialog(nullptr); |
| @@ -8643,45 +8808,47 @@ void Application::setShowBulletConstraintLimits(bool value) { · 515 unmodified lines | |||
| 8643 | _physicsEngine->setShowBulletConstraintLimits(value); | 8808 | _physicsEngine->setShowBulletConstraintLimits(value); |
| 8644 | } | 8809 | } |
| 8645 | 8810 | ||
| 8646 | void Application::createLoginDialogOverlay() { | 8811 | void Application::createLoginDialog() { |
| 8647 | const glm::vec2 LOGIN_OVERLAY_DIMENSIONS{ 0.89f, 0.5f }; | 8812 | const glm::vec3 LOGIN_DIMENSIONS { 0.89f, 0.5f, 0.01f }; |
| 8648 | const auto OVERLAY_OFFSET = glm::vec2(0.7f, -0.1f); | 8813 | const auto OFFSET = glm::vec2(0.7f, -0.1f); |
| 8649 | auto cameraPosition = _myCamera.getPosition(); | 8814 | auto cameraPosition = _myCamera.getPosition(); |
| 8650 | auto cameraOrientation = _myCamera.getOrientation(); | 8815 | auto cameraOrientation = _myCamera.getOrientation(); |
| 8651 | auto upVec = getMyAvatar()->getWorldOrientation() * Vectors::UNIT_Y; | 8816 | auto upVec = getMyAvatar()->getWorldOrientation() * Vectors::UNIT_Y; |
| 8652 | auto headLookVec = (cameraOrientation * Vectors::FRONT); | 8817 | auto headLookVec = (cameraOrientation * Vectors::FRONT); |
| 8653 | // DEFAULT_DPI / tablet scale percentage | 8818 | // DEFAULT_DPI / tablet scale percentage |
| 8654 | const float OVERLAY_DPI = 31.0f / (75.0f / 100.0f); | 8819 | const float DPI = 31.0f / (75.0f / 100.0f); |
| 8655 | auto offset = headLookVec * OVERLAY_OFFSET.x; | 8820 | auto offset = headLookVec * OFFSET.x; |
| 8656 | auto overlayPosition = (cameraPosition + offset) + (upVec * OVERLAY_OFFSET.y); | 8821 | auto position = (cameraPosition + offset) + (upVec * OFFSET.y); |
| 8657 | QVariantMap overlayProperties = { | 8822 | |
| 8658 | { "name", "LoginDialogOverlay" }, | 8823 | EntityItemProperties properties; |
| 8659 | { "url", OVERLAY_LOGIN_DIALOG }, | 8824 | properties.setType(EntityTypes::Web); |
| 8660 | { "position", vec3toVariant(overlayPosition) }, | 8825 | properties.setName("LoginDialogEntity"); |
| 8661 | { "orientation", quatToVariant(cameraOrientation) }, | 8826 | properties.setSourceUrl(LOGIN_DIALOG.toString()); |
| 8662 | { "isSolid", true }, | 8827 | properties.setPosition(position); |
| 8663 | { "grabbable", false }, | 8828 | properties.setRotation(cameraOrientation); |
| 8664 | { "ignorePickIntersection", false }, | 8829 | properties.setDimensions(LOGIN_DIMENSIONS); |
| 8665 | { "alpha", 1.0 }, | 8830 | properties.setPrimitiveMode(PrimitiveMode::SOLID); |
| 8666 | { "dimensions", vec2ToVariant(LOGIN_OVERLAY_DIMENSIONS)}, | 8831 | properties.getGrab().setGrabbable(false); |
| 8667 | { "dpi", OVERLAY_DPI }, | 8832 | properties.setIgnorePickIntersection(false); |
| 8668 | { "visible", true } | 8833 | properties.setAlpha(1.0f); |
| 8669 | }; | 8834 | properties.setDPI(DPI); |
| 8670 | auto& overlays = getOverlays(); | 8835 | properties.setVisible(true); |
| 8671 | _loginDialogOverlayID = overlays.addOverlay("web3d", overlayProperties); | 8836 | |
| 8672 | auto loginOverlay = std::dynamic_pointer_cast<Web3DOverlay>(overlays.getOverlay(_loginDialogOverlayID)); | 8837 | auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); |
| 8838 | _loginDialogID = entityScriptingInterface->addEntityInternal(properties, entity::HostType::LOCAL); | ||
| 8839 | |||
| 8673 | auto keyboard = DependencyManager::get<Keyboard>().data(); | 8840 | auto keyboard = DependencyManager::get<Keyboard>().data(); |
| 8674 | if (!keyboard->getAnchorID().isNull() && !_loginDialogOverlayID.isNull()) { | 8841 | if (!keyboard->getAnchorID().isNull() && !_loginDialogID.isNull()) { |
| 8675 | const auto KEYBOARD_LOCAL_ORIENTATION = glm::quat(0.0f, 0.0, 1.0f, 0.25f); | ||
| 8676 | auto keyboardLocalOffset = cameraOrientation * glm::vec3(-0.4f * getMyAvatar()->getSensorToWorldScale(), -0.3f, 0.2f); | 8842 | auto keyboardLocalOffset = cameraOrientation * glm::vec3(-0.4f * getMyAvatar()->getSensorToWorldScale(), -0.3f, 0.2f); |
| 8677 | QVariantMap properties { | 8843 | |
| 8678 | { "position", vec3toVariant(overlayPosition + keyboardLocalOffset) }, | 8844 | EntityItemProperties properties; |
| 8679 | { "orientation", quatToVariant(cameraOrientation * KEYBOARD_LOCAL_ORIENTATION) }, | 8845 | properties.setPosition(position + keyboardLocalOffset); |
| 8680 | }; | 8846 | properties.setRotation(cameraOrientation * Quaternions::Y_180); |
| 8681 | overlays.editOverlay(keyboard->getAnchorID(), properties); | 8847 | |
| 8848 | entityScriptingInterface->editEntity(keyboard->getAnchorID(), properties); | ||
| 8682 | keyboard->setResetKeyboardPositionOnRaise(false); | 8849 | keyboard->setResetKeyboardPositionOnRaise(false); |
| 8683 | } | 8850 | } |
| 8684 | setKeyboardFocusOverlay(_loginDialogOverlayID); | 8851 | setKeyboardFocusEntity(_loginDialogID); |
| 8685 | emit loginDialogFocusEnabled(); | 8852 | emit loginDialogFocusEnabled(); |
| 8686 | getApplicationCompositor().getReticleInterface()->setAllowMouseCapture(false); | 8853 | getApplicationCompositor().getReticleInterface()->setAllowMouseCapture(false); |
| 8687 | getApplicationCompositor().getReticleInterface()->setVisible(false); | 8854 | getApplicationCompositor().getReticleInterface()->setVisible(false); |
| @@ -8690,38 +8857,43 @@ void Application::createLoginDialogOverlay() { · 2 unmodified lines | |||
| 8690 | } | 8857 | } |
| 8691 | } | 8858 | } |
| 8692 | 8859 | ||
| 8693 | void Application::updateLoginDialogOverlayPosition() { | 8860 | void Application::updateLoginDialogPosition() { |
| 8694 | const float LOOK_AWAY_THRESHOLD_ANGLE = 70.0f; | 8861 | const float LOOK_AWAY_THRESHOLD_ANGLE = 70.0f; |
| 8695 | const auto OVERLAY_OFFSET = glm::vec2(0.7f, -0.1f); | 8862 | const auto OFFSET = glm::vec2(0.7f, -0.1f); |
| 8696 | auto& overlays = getOverlays(); | 8863 | |
| 8697 | auto loginOverlay = std::dynamic_pointer_cast<Web3DOverlay>(overlays.getOverlay(_loginDialogOverlayID)); | 8864 | auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); |
| 8698 | auto overlayPositionVec = loginOverlay->getWorldPosition(); | 8865 | EntityPropertyFlags desiredProperties; |
| 8866 | desiredProperties += PROP_POSITION; | ||
| 8867 | auto properties = entityScriptingInterface->getEntityProperties(_loginDialogID, desiredProperties); | ||
| 8868 | auto positionVec = properties.getPosition(); | ||
| 8699 | auto cameraPositionVec = _myCamera.getPosition(); | 8869 | auto cameraPositionVec = _myCamera.getPosition(); |
| 8700 | auto cameraOrientation = cancelOutRollAndPitch(_myCamera.getOrientation()); | 8870 | auto cameraOrientation = cancelOutRollAndPitch(_myCamera.getOrientation()); |
| 8701 | auto headLookVec = (cameraOrientation * Vectors::FRONT); | 8871 | auto headLookVec = (cameraOrientation * Vectors::FRONT); |
| 8702 | auto overlayToHeadVec = overlayPositionVec - cameraPositionVec; | 8872 | auto entityToHeadVec = positionVec - cameraPositionVec; |
| 8703 | auto pointAngle = (glm::acos(glm::dot(glm::normalize(overlayToHeadVec), glm::normalize(headLookVec))) * 180.0f / PI); | 8873 | auto pointAngle = (glm::acos(glm::dot(glm::normalize(entityToHeadVec), glm::normalize(headLookVec))) * 180.0f / PI); |
| 8704 | auto upVec = getMyAvatar()->getWorldOrientation() * Vectors::UNIT_Y; | 8874 | auto upVec = getMyAvatar()->getWorldOrientation() * Vectors::UNIT_Y; |
| 8705 | auto offset = headLookVec * OVERLAY_OFFSET.x; | 8875 | auto offset = headLookVec * OFFSET.x; |
| 8706 | auto newOverlayPositionVec = (cameraPositionVec + offset) + (upVec * OVERLAY_OFFSET.y); | 8876 | auto newPositionVec = (cameraPositionVec + offset) + (upVec * OFFSET.y); |
| 8707 | auto newOverlayOrientation = glm::inverse(glm::quat_cast(glm::lookAt(newOverlayPositionVec, cameraPositionVec, upVec))) * Quaternions::Y_180; | ||
| 8708 | 8877 | ||
| 8709 | bool overlayOutOfBounds = glm::distance(overlayPositionVec, cameraPositionVec) > 1.0f; | 8878 | bool outOfBounds = glm::distance(positionVec, cameraPositionVec) > 1.0f; |
| 8710 | 8879 | ||
| 8711 | if (pointAngle > LOOK_AWAY_THRESHOLD_ANGLE || overlayOutOfBounds) { | 8880 | if (pointAngle > LOOK_AWAY_THRESHOLD_ANGLE || outOfBounds) { |
| 8712 | QVariantMap properties { | 8881 | { |
| 8713 | {"position", vec3toVariant(newOverlayPositionVec)}, | 8882 | EntityItemProperties properties; |
| 8714 | {"orientation", quatToVariant(newOverlayOrientation)} | 8883 | properties.setPosition(newPositionVec); |
| 8715 | }; | 8884 | properties.setRotation(cameraOrientation); |
| 8716 | overlays.editOverlay(_loginDialogOverlayID, properties); | 8885 | entityScriptingInterface->editEntity(_loginDialogID, properties); |
| 8717 | const auto KEYBOARD_LOCAL_ORIENTATION = glm::quat(0.0f, 0.0, 1.0f, 0.25f); | 8886 | } |
| 8718 | auto keyboardLocalOffset = newOverlayOrientation * glm::vec3(-0.4f * getMyAvatar()->getSensorToWorldScale(), -0.3f, 0.2f); | 8887 | |
| 8719 | QVariantMap keyboardProperties { | 8888 | { |
| 8720 | { "position", vec3toVariant(newOverlayPositionVec + keyboardLocalOffset) }, | 8889 | glm::vec3 keyboardLocalOffset = cameraOrientation * glm::vec3(-0.4f * getMyAvatar()->getSensorToWorldScale(), -0.3f, 0.2f); |
| 8721 | { "orientation", quatToVariant(newOverlayOrientation * KEYBOARD_LOCAL_ORIENTATION) }, | 8890 | glm::quat keyboardOrientation = cameraOrientation * glm::quat(glm::radians(glm::vec3(-30.0f, 180.0f, 0.0f))); |
| 8722 | }; | 8891 | |
| 8723 | auto keyboard = DependencyManager::get<Keyboard>().data(); | 8892 | EntityItemProperties properties; |
| 8724 | overlays.editOverlay(keyboard->getAnchorID(), keyboardProperties); | 8893 | properties.setPosition(newPositionVec + keyboardLocalOffset); |
| 8894 | properties.setRotation(keyboardOrientation); | ||
| 8895 | entityScriptingInterface->editEntity(DependencyManager::get<Keyboard>()->getAnchorID(), properties); | ||
| 8896 | } | ||
| 8725 | } | 8897 | } |
| 8726 | } | 8898 | } |
| 8727 | 8899 | ||
| @@ -8738,10 +8910,9 @@ void Application::onDismissedLoginDialog() { · 10 unmodified lines | |||
| 8738 | loginDialogPoppedUp.set(false); | 8910 | loginDialogPoppedUp.set(false); |
| 8739 | auto keyboard = DependencyManager::get<Keyboard>().data(); | 8911 | auto keyboard = DependencyManager::get<Keyboard>().data(); |
| 8740 | keyboard->setResetKeyboardPositionOnRaise(true); | 8912 | keyboard->setResetKeyboardPositionOnRaise(true); |
| 8741 | if (!_loginDialogOverlayID.isNull()) { | 8913 | if (!_loginDialogID.isNull()) { |
| 8742 | // deleting overlay. | 8914 | DependencyManager::get<EntityScriptingInterface>()->deleteEntity(_loginDialogID); |
| 8743 | getOverlays().deleteOverlay(_loginDialogOverlayID); | 8915 | _loginDialogID = QUuid(); |
| 8744 | _loginDialogOverlayID = OverlayID(); | ||
| 8745 | _loginStateManager.tearDown(); | 8916 | _loginStateManager.tearDown(); |
| 8746 | } | 8917 | } |
| 8747 | resumeAfterLoginDialogActionTaken(); | 8918 | resumeAfterLoginDialogActionTaken(); |
| @@ -8907,12 +9078,12 @@ void Application::updateSystemTabletMode() { · 159 unmodified lines | |||
| 8907 | } | 9078 | } |
| 8908 | } | 9079 | } |
| 8909 | 9080 | ||
| 8910 | OverlayID Application::getTabletScreenID() const { | 9081 | QUuid Application::getTabletScreenID() const { |
| 8911 | auto HMD = DependencyManager::get<HMDScriptingInterface>(); | 9082 | auto HMD = DependencyManager::get<HMDScriptingInterface>(); |
| 8912 | return HMD->getCurrentTabletScreenID(); | 9083 | return HMD->getCurrentTabletScreenID(); |
| 8913 | } | 9084 | } |
| 8914 | 9085 | ||
| 8915 | OverlayID Application::getTabletHomeButtonID() const { | 9086 | QUuid Application::getTabletHomeButtonID() const { |
| 8916 | auto HMD = DependencyManager::get<HMDScriptingInterface>(); | 9087 | auto HMD = DependencyManager::get<HMDScriptingInterface>(); |
| 8917 | return HMD->getCurrentHomeButtonID(); | 9088 | return HMD->getCurrentHomeButtonID(); |
| 8918 | } | 9089 | } |
| @@ -8923,7 +9094,7 @@ QUuid Application::getTabletFrameID() const { · 4 unmodified lines | |||
| 8923 | } | 9094 | } |
| 8924 | 9095 | ||
| 8925 | QVector<QUuid> Application::getTabletIDs() const { | 9096 | QVector<QUuid> Application::getTabletIDs() const { |
| 8926 | // Most important overlays first. | 9097 | // Most important first. |
| 8927 | QVector<QUuid> result; | 9098 | QVector<QUuid> result; |
| 8928 | auto HMD = DependencyManager::get<HMDScriptingInterface>(); | 9099 | auto HMD = DependencyManager::get<HMDScriptingInterface>(); |
| 8929 | result << HMD->getCurrentTabletScreenID(); | 9100 | result << HMD->getCurrentTabletScreenID(); |