Showing the changes to interface/src/Application.cpp (1 of 1116 files). Show all
Unified · Split
| @@ -63,6 +63,7 @@ · 62 unmodified lines | ||
| 63 | 63 | #include <AddressManager.h> |
| 64 | 64 | #include <AnimDebugDraw.h> |
| 65 | 65 | #include <BuildInfo.h> |
| 66 | +#include <AnimationCacheScriptingInterface.h> | |
| 66 | 67 | #include <AssetClient.h> |
| 67 | 68 | #include <AssetUpload.h> |
| 68 | 69 | #include <AutoUpdater.h> |
| @@ -98,6 +99,8 @@ · 29 unmodified lines | ||
| 98 | 99 | #include <MainWindow.h> |
| 99 | 100 | #include <MappingRequest.h> |
| 100 | 101 | #include <MessagesClient.h> |
| 102 | +#include <model-networking/ModelCacheScriptingInterface.h> | |
| 103 | +#include <model-networking/TextureCacheScriptingInterface.h> | |
| 101 | 104 | #include <ModelEntityItem.h> |
| 102 | 105 | #include <NetworkAccessManager.h> |
| 103 | 106 | #include <NetworkingConstants.h> |
| @@ -127,7 +130,7 @@ · 23 unmodified lines | ||
| 127 | 130 | #include <ScriptEngines.h> |
| 128 | 131 | #include <ScriptCache.h> |
| 129 | 132 | #include <ShapeEntityItem.h> |
| 130 | −#include <SoundCache.h> | |
| 133 | +#include <SoundCacheScriptingInterface.h> | |
| 131 | 134 | #include <ui/TabletScriptingInterface.h> |
| 132 | 135 | #include <ui/ToolbarScriptingInterface.h> |
| 133 | 136 | #include <InteractiveWindow.h> |
| @@ -143,6 +146,7 @@ · 9 unmodified lines | ||
| 143 | 146 | #include <QmlFragmentClass.h> |
| 144 | 147 | #include <Preferences.h> |
| 145 | 148 | #include <display-plugins/CompositorHelper.h> |
| 149 | +#include <display-plugins/hmd/HmdDisplayPlugin.h> | |
| 146 | 150 | #include <trackers/EyeTracker.h> |
| 147 | 151 | #include <avatars-renderer/ScriptAvatar.h> |
| 148 | 152 | #include <RenderableEntityItem.h> |
| @@ -262,19 +266,10 @@ class RenderEventHandler : public QObject { · 113 unmodified lines | ||
| 262 | 266 | using Parent = QObject; |
| 263 | 267 | Q_OBJECT |
| 264 | 268 | public: |
| 265 | − RenderEventHandler(QOpenGLContext* context) { | |
| 266 | − _renderContext = new OffscreenGLCanvas(); | |
| 267 | − _renderContext->setObjectName("RenderContext"); | |
| 268 | − _renderContext->create(context); | |
| 269 | − if (!_renderContext->makeCurrent()) { | |
| 270 | − qFatal("Unable to make rendering context current"); | |
| 271 | − } | |
| 272 | − _renderContext->doneCurrent(); | |
| 273 | − | |
| 269 | + RenderEventHandler() { | |
| 274 | 270 | // Transfer to a new thread |
| 275 | 271 | moveToNewNamedThread(this, "RenderThread", [this](QThread* renderThread) { |
| 276 | 272 | hifi::qt::addBlockingForbiddenThread("Render", renderThread); |
| 277 | − _renderContext->moveToThreadWithContext(renderThread); | |
| 278 | 273 | qApp->_lastTimeRendered.start(); |
| 279 | 274 | }, std::bind(&RenderEventHandler::initialize, this), QThread::HighestPriority); |
| 280 | 275 | } |
| @@ -284,9 +279,6 @@ private: · 3 unmodified lines | ||
| 284 | 279 | setObjectName("Render"); |
| 285 | 280 | PROFILE_SET_THREAD_NAME("Render"); |
| 286 | 281 | setCrashAnnotation("render_thread_id", std::to_string((size_t)QThread::currentThreadId())); |
| 287 | − if (!_renderContext->makeCurrent()) { | |
| 288 | − qFatal("Unable to make rendering context current on render thread"); | |
| 289 | − } | |
| 290 | 282 | } |
| 291 | 283 | |
| 292 | 284 | void render() { |
| @@ -307,8 +299,6 @@ private: · 14 unmodified lines | ||
| 307 | 299 | } |
| 308 | 300 | return Parent::event(event); |
| 309 | 301 | } |
| 310 | − | |
| 311 | − OffscreenGLCanvas* _renderContext { nullptr }; | |
| 312 | 302 | }; |
| 313 | 303 | |
| 314 | 304 | |
| @@ -374,6 +364,7 @@ static const int THROTTLED_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / THROTTLED_SI · 59 unmodified lines | ||
| 374 | 364 | static const uint32_t INVALID_FRAME = UINT32_MAX; |
| 375 | 365 | |
| 376 | 366 | static const float PHYSICS_READY_RANGE = 3.0f; // how far from avatar to check for entities that aren't ready for simulation |
| 367 | +static const float INITIAL_QUERY_RADIUS = 10.0f; // priority radius for entities before physics enabled | |
| 377 | 368 | |
| 378 | 369 | static const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); |
| 379 | 370 | |
| @@ -384,6 +375,7 @@ static const int INTERVAL_TO_CHECK_HMD_WORN_STATUS = 500; // milliseconds · 4 unmodified lines | ||
| 384 | 375 | static const QString DESKTOP_DISPLAY_PLUGIN_NAME = "Desktop"; |
| 385 | 376 | static const QString ACTIVE_DISPLAY_PLUGIN_SETTING_NAME = "activeDisplayPlugin"; |
| 386 | 377 | static const QString SYSTEM_TABLET = "com.highfidelity.interface.tablet.system"; |
| 378 | +static const QString AUTO_LOGOUT_SETTING_NAME = "wallet/autoLogout"; | |
| 387 | 379 | |
| 388 | 380 | const std::vector<std::pair<QString, Application::AcceptURLMethod>> Application::_acceptedExtensions { |
| 389 | 381 | { SVO_EXTENSION, &Application::importSVOFromURL }, |
| @@ -734,6 +726,9 @@ static const QString STATE_SNAP_TURN = "SnapTurn"; · 344 unmodified lines | ||
| 734 | 726 | static const QString STATE_ADVANCED_MOVEMENT_CONTROLS = "AdvancedMovement"; |
| 735 | 727 | static const QString STATE_GROUNDED = "Grounded"; |
| 736 | 728 | static const QString STATE_NAV_FOCUSED = "NavigationFocused"; |
| 729 | +static const QString STATE_PLATFORM_WINDOWS = "PlatformWindows"; | |
| 730 | +static const QString STATE_PLATFORM_MAC = "PlatformMac"; | |
| 731 | +static const QString STATE_PLATFORM_ANDROID = "PlatformAndroid"; | |
| 737 | 732 | |
| 738 | 733 | // Statically provided display and input plugins |
| 739 | 734 | extern DisplayPluginList getDisplayPlugins(); |
| @@ -866,16 +861,20 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { · 126 unmodified lines | ||
| 866 | 861 | DependencyManager::set<recording::ClipCache>(); |
| 867 | 862 | DependencyManager::set<GeometryCache>(); |
| 868 | 863 | DependencyManager::set<ModelCache>(); |
| 864 | + DependencyManager::set<ModelCacheScriptingInterface>(); | |
| 869 | 865 | DependencyManager::set<ScriptCache>(); |
| 870 | 866 | DependencyManager::set<SoundCache>(); |
| 867 | + DependencyManager::set<SoundCacheScriptingInterface>(); | |
| 871 | 868 | DependencyManager::set<DdeFaceTracker>(); |
| 872 | 869 | DependencyManager::set<EyeTracker>(); |
| 873 | 870 | DependencyManager::set<AudioClient>(); |
| 874 | 871 | DependencyManager::set<AudioScope>(); |
| 875 | 872 | DependencyManager::set<DeferredLightingEffect>(); |
| 876 | 873 | DependencyManager::set<TextureCache>(); |
| 874 | + DependencyManager::set<TextureCacheScriptingInterface>(); | |
| 877 | 875 | DependencyManager::set<FramebufferCache>(); |
| 878 | 876 | DependencyManager::set<AnimationCache>(); |
| 877 | + DependencyManager::set<AnimationCacheScriptingInterface>(); | |
| 879 | 878 | DependencyManager::set<ModelBlender>(); |
| 880 | 879 | DependencyManager::set<UsersScriptingInterface>(); |
| 881 | 880 | DependencyManager::set<AvatarManager>(); |
| @@ -913,7 +912,8 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { · 31 unmodified lines | ||
| 913 | 912 | DependencyManager::set<MessagesClient>(); |
| 914 | 913 | controller::StateController::setStateVariables({ { STATE_IN_HMD, STATE_CAMERA_FULL_SCREEN_MIRROR, |
| 915 | 914 | STATE_CAMERA_FIRST_PERSON, STATE_CAMERA_THIRD_PERSON, STATE_CAMERA_ENTITY, STATE_CAMERA_INDEPENDENT, |
| 916 | − STATE_SNAP_TURN, STATE_ADVANCED_MOVEMENT_CONTROLS, STATE_GROUNDED, STATE_NAV_FOCUSED } }); | |
| 915 | + STATE_SNAP_TURN, STATE_ADVANCED_MOVEMENT_CONTROLS, STATE_GROUNDED, STATE_NAV_FOCUSED, | |
| 916 | + STATE_PLATFORM_WINDOWS, STATE_PLATFORM_MAC, STATE_PLATFORM_ANDROID } }); | |
| 917 | 917 | DependencyManager::set<UserInputMapper>(); |
| 918 | 918 | DependencyManager::set<controller::ScriptingInterface, ControllerScriptingInterface>(); |
| 919 | 919 | DependencyManager::set<InterfaceParentFinder>(); |
| @@ -1018,7 +1018,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 98 unmodified lines | ||
| 1018 | 1018 | // This is done so as not break previous command line scripts |
| 1019 | 1019 | if (testScriptPath.left(URL_SCHEME_HTTP.length()) == URL_SCHEME_HTTP || |
| 1020 | 1020 | testScriptPath.left(URL_SCHEME_FTP.length()) == URL_SCHEME_FTP) { |
| 1021 | − | |
| 1021 | + | |
| 1022 | 1022 | setProperty(hifi::properties::TEST, QUrl::fromUserInput(testScriptPath)); |
| 1023 | 1023 | } else if (QFileInfo(testScriptPath).exists()) { |
| 1024 | 1024 | setProperty(hifi::properties::TEST, QUrl::fromLocalFile(testScriptPath)); |
| @@ -1099,6 +1099,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 74 unmodified lines | ||
| 1099 | 1099 | // Set File Logger Session UUID |
| 1100 | 1100 | auto avatarManager = DependencyManager::get<AvatarManager>(); |
| 1101 | 1101 | auto myAvatar = avatarManager ? avatarManager->getMyAvatar() : nullptr; |
| 1102 | + if (avatarManager) { | |
| 1103 | + workload::SpacePointer space = getEntities()->getWorkloadSpace(); | |
| 1104 | + avatarManager->setSpace(space); | |
| 1105 | + } | |
| 1102 | 1106 | auto accountManager = DependencyManager::get<AccountManager>(); |
| 1103 | 1107 | |
| 1104 | 1108 | _logger->setSessionID(accountManager->getSessionID()); |
| @@ -1130,8 +1134,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 25 unmodified lines | ||
| 1130 | 1134 | |
| 1131 | 1135 | // setup a timer for domain-server check ins |
| 1132 | 1136 | QTimer* domainCheckInTimer = new QTimer(this); |
| 1133 | − connect(domainCheckInTimer, &QTimer::timeout, [this, nodeList] { | |
| 1134 | − if (!isServerlessMode()) { | |
| 1137 | + QWeakPointer<NodeList> nodeListWeak = nodeList; | |
| 1138 | + connect(domainCheckInTimer, &QTimer::timeout, [this, nodeListWeak] { | |
| 1139 | + auto nodeList = nodeListWeak.lock(); | |
| 1140 | + if (!isServerlessMode() && nodeList) { | |
| 1135 | 1141 | nodeList->sendDomainServerCheckIn(); |
| 1136 | 1142 | } |
| 1137 | 1143 | }); |
| @@ -1141,33 +1147,34 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 3 unmodified lines | ||
| 1141 | 1147 | domainCheckInTimer->deleteLater(); |
| 1142 | 1148 | }); |
| 1143 | 1149 | |
| 1150 | + { | |
| 1151 | + auto audioIO = DependencyManager::get<AudioClient>().data(); | |
| 1152 | + audioIO->setPositionGetter([] { | |
| 1153 | + auto avatarManager = DependencyManager::get<AvatarManager>(); | |
| 1154 | + auto myAvatar = avatarManager ? avatarManager->getMyAvatar() : nullptr; | |
| 1144 | 1155 | |
| 1145 | − auto audioIO = DependencyManager::get<AudioClient>(); | |
| 1146 | − audioIO->setPositionGetter([]{ | |
| 1147 | − auto avatarManager = DependencyManager::get<AvatarManager>(); | |
| 1148 | − auto myAvatar = avatarManager ? avatarManager->getMyAvatar() : nullptr; | |
| 1149 | − | |
| 1150 | − return myAvatar ? myAvatar->getPositionForAudio() : Vectors::ZERO; | |
| 1151 | − }); | |
| 1152 | − audioIO->setOrientationGetter([]{ | |
| 1153 | − auto avatarManager = DependencyManager::get<AvatarManager>(); | |
| 1154 | − auto myAvatar = avatarManager ? avatarManager->getMyAvatar() : nullptr; | |
| 1156 | + return myAvatar ? myAvatar->getPositionForAudio() : Vectors::ZERO; | |
| 1157 | + }); | |
| 1158 | + audioIO->setOrientationGetter([] { | |
| 1159 | + auto avatarManager = DependencyManager::get<AvatarManager>(); | |
| 1160 | + auto myAvatar = avatarManager ? avatarManager->getMyAvatar() : nullptr; | |
| 1155 | 1161 | |
| 1156 | − return myAvatar ? myAvatar->getOrientationForAudio() : Quaternions::IDENTITY; | |
| 1157 | − }); | |
| 1162 | + return myAvatar ? myAvatar->getOrientationForAudio() : Quaternions::IDENTITY; | |
| 1163 | + }); | |
| 1158 | 1164 | |
| 1159 | − recording::Frame::registerFrameHandler(AudioConstants::getAudioFrameName(), [=](recording::Frame::ConstPointer frame) { | |
| 1160 | − audioIO->handleRecordedAudioInput(frame->data); | |
| 1161 | − }); | |
| 1165 | + recording::Frame::registerFrameHandler(AudioConstants::getAudioFrameName(), [&audioIO](recording::Frame::ConstPointer frame) { | |
| 1166 | + audioIO->handleRecordedAudioInput(frame->data); | |
| 1167 | + }); | |
| 1162 | 1168 | |
| 1163 | − connect(audioIO.data(), &AudioClient::inputReceived, [](const QByteArray& audio){ | |
| 1164 | − static auto recorder = DependencyManager::get<recording::Recorder>(); | |
| 1165 | − if (recorder->isRecording()) { | |
| 1166 | − static const recording::FrameType AUDIO_FRAME_TYPE = recording::Frame::registerFrameType(AudioConstants::getAudioFrameName()); | |
| 1167 | − recorder->recordFrame(AUDIO_FRAME_TYPE, audio); | |
| 1168 | − } | |
| 1169 | − }); | |
| 1170 | − audioIO->startThread(); | |
| 1169 | + connect(audioIO, &AudioClient::inputReceived, [](const QByteArray& audio) { | |
| 1170 | + static auto recorder = DependencyManager::get<recording::Recorder>(); | |
| 1171 | + if (recorder->isRecording()) { | |
| 1172 | + static const recording::FrameType AUDIO_FRAME_TYPE = recording::Frame::registerFrameType(AudioConstants::getAudioFrameName()); | |
| 1173 | + recorder->recordFrame(AUDIO_FRAME_TYPE, audio); | |
| 1174 | + } | |
| 1175 | + }); | |
| 1176 | + audioIO->startThread(); | |
| 1177 | + } | |
| 1171 | 1178 | |
| 1172 | 1179 | // Make sure we don't time out during slow operations at startup |
| 1173 | 1180 | updateHeartbeat(); |
| @@ -1238,7 +1245,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 64 unmodified lines | ||
| 1238 | 1245 | accountManager->setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL()); |
| 1239 | 1246 | |
| 1240 | 1247 | // use our MyAvatar position and quat for address manager path |
| 1241 | − addressManager->setPositionGetter([this]{ return getMyAvatar()->getWorldPosition(); }); | |
| 1248 | + addressManager->setPositionGetter([this]{ return getMyAvatar()->getWorldFeetPosition(); }); | |
| 1242 | 1249 | addressManager->setOrientationGetter([this]{ return getMyAvatar()->getWorldOrientation(); }); |
| 1243 | 1250 | |
| 1244 | 1251 | connect(addressManager.data(), &AddressManager::hostChanged, this, &Application::updateWindowTitle); |
| @@ -1266,27 +1273,29 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 21 unmodified lines | ||
| 1266 | 1273 | // Inititalize sample before registering |
| 1267 | 1274 | _sampleSound = DependencyManager::get<SoundCache>()->getSound(PathUtils::resourcesUrl("sounds/sample.wav")); |
| 1268 | 1275 | |
| 1269 | − auto scriptEngines = DependencyManager::get<ScriptEngines>().data(); | |
| 1270 | − scriptEngines->registerScriptInitializer([this](ScriptEnginePointer engine){ | |
| 1271 | − registerScriptEngineWithApplicationServices(engine); | |
| 1272 | − }); | |
| 1276 | + { | |
| 1277 | + auto scriptEngines = DependencyManager::get<ScriptEngines>().data(); | |
| 1278 | + scriptEngines->registerScriptInitializer([this](ScriptEnginePointer engine) { | |
| 1279 | + registerScriptEngineWithApplicationServices(engine); | |
| 1280 | + }); | |
| 1273 | 1281 | |
| 1274 | − connect(scriptEngines, &ScriptEngines::scriptCountChanged, scriptEngines, [this] { | |
| 1275 | − auto scriptEngines = DependencyManager::get<ScriptEngines>(); | |
| 1276 | − if (scriptEngines->getRunningScripts().isEmpty()) { | |
| 1277 | − getMyAvatar()->clearScriptableSettings(); | |
| 1278 | − } | |
| 1279 | − }, Qt::QueuedConnection); | |
| 1282 | + connect(scriptEngines, &ScriptEngines::scriptCountChanged, this, [this] { | |
| 1283 | + auto scriptEngines = DependencyManager::get<ScriptEngines>(); | |
| 1284 | + if (scriptEngines->getRunningScripts().isEmpty()) { | |
| 1285 | + getMyAvatar()->clearScriptableSettings(); | |
| 1286 | + } | |
| 1287 | + }, Qt::QueuedConnection); | |
| 1280 | 1288 | |
| 1281 | − connect(scriptEngines, &ScriptEngines::scriptsReloading, scriptEngines, [this] { | |
| 1282 | − getEntities()->reloadEntityScripts(); | |
| 1283 | − loadAvatarScripts(getMyAvatar()->getScriptUrls()); | |
| 1284 | − }, Qt::QueuedConnection); | |
| 1289 | + connect(scriptEngines, &ScriptEngines::scriptsReloading, this, [this] { | |
| 1290 | + getEntities()->reloadEntityScripts(); | |
| 1291 | + loadAvatarScripts(getMyAvatar()->getScriptUrls()); | |
| 1292 | + }, Qt::QueuedConnection); | |
| 1285 | 1293 | |
| 1286 | − connect(scriptEngines, &ScriptEngines::scriptLoadError, | |
| 1287 | − scriptEngines, [](const QString& filename, const QString& error){ | |
| 1288 | − OffscreenUi::asyncWarning(nullptr, "Error Loading Script", filename + " failed to load."); | |
| 1289 | − }, Qt::QueuedConnection); | |
| 1294 | + connect(scriptEngines, &ScriptEngines::scriptLoadError, | |
| 1295 | + this, [](const QString& filename, const QString& error) { | |
| 1296 | + OffscreenUi::asyncWarning(nullptr, "Error Loading Script", filename + " failed to load."); | |
| 1297 | + }, Qt::QueuedConnection); | |
| 1298 | + } | |
| 1290 | 1299 | |
| 1291 | 1300 | #ifdef _WIN32 |
| 1292 | 1301 | WSADATA WsaData; |
| @@ -1356,10 +1365,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 63 unmodified lines | ||
| 1356 | 1365 | // so we defer the setup of the `scripting::Audio` class until this point |
| 1357 | 1366 | { |
| 1358 | 1367 | auto audioScriptingInterface = DependencyManager::set<AudioScriptingInterface, scripting::Audio>(); |
| 1359 | − connect(audioIO.data(), &AudioClient::mutedByMixer, audioScriptingInterface.data(), &AudioScriptingInterface::mutedByMixer); | |
| 1360 | − connect(audioIO.data(), &AudioClient::receivedFirstPacket, audioScriptingInterface.data(), &AudioScriptingInterface::receivedFirstPacket); | |
| 1361 | − connect(audioIO.data(), &AudioClient::disconnected, audioScriptingInterface.data(), &AudioScriptingInterface::disconnected); | |
| 1362 | − connect(audioIO.data(), &AudioClient::muteEnvironmentRequested, [](glm::vec3 position, float radius) { | |
| 1368 | + auto audioIO = DependencyManager::get<AudioClient>().data(); | |
| 1369 | + connect(audioIO, &AudioClient::mutedByMixer, audioScriptingInterface.data(), &AudioScriptingInterface::mutedByMixer); | |
| 1370 | + connect(audioIO, &AudioClient::receivedFirstPacket, audioScriptingInterface.data(), &AudioScriptingInterface::receivedFirstPacket); | |
| 1371 | + connect(audioIO, &AudioClient::disconnected, audioScriptingInterface.data(), &AudioScriptingInterface::disconnected); | |
| 1372 | + connect(audioIO, &AudioClient::muteEnvironmentRequested, [](glm::vec3 position, float radius) { | |
| 1363 | 1373 | auto audioClient = DependencyManager::get<AudioClient>(); |
| 1364 | 1374 | auto audioScriptingInterface = DependencyManager::get<AudioScriptingInterface>(); |
| 1365 | 1375 | auto myAvatarPosition = DependencyManager::get<AvatarManager>()->getMyAvatar()->getWorldPosition(); |
| @@ -1677,6 +1687,27 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 311 unmodified lines | ||
| 1677 | 1687 | _applicationStateDevice->setInputVariant(STATE_NAV_FOCUSED, []() -> float { |
| 1678 | 1688 | return DependencyManager::get<OffscreenUi>()->navigationFocused() ? 1 : 0; |
| 1679 | 1689 | }); |
| 1690 | + _applicationStateDevice->setInputVariant(STATE_PLATFORM_WINDOWS, []() -> float { | |
| 1691 | +#if defined(Q_OS_WIN) | |
| 1692 | + return 1; | |
| 1693 | +#else | |
| 1694 | + return 0; | |
| 1695 | +#endif | |
| 1696 | + }); | |
| 1697 | + _applicationStateDevice->setInputVariant(STATE_PLATFORM_MAC, []() -> float { | |
| 1698 | +#if defined(Q_OS_MAC) | |
| 1699 | + return 1; | |
| 1700 | +#else | |
| 1701 | + return 0; | |
| 1702 | +#endif | |
| 1703 | + }); | |
| 1704 | + _applicationStateDevice->setInputVariant(STATE_PLATFORM_ANDROID, []() -> float { | |
| 1705 | +#if defined(Q_OS_ANDROID) | |
| 1706 | + return 1; | |
| 1707 | +#else | |
| 1708 | + return 0; | |
| 1709 | +#endif | |
| 1710 | + }); | |
| 1680 | 1711 | |
| 1681 | 1712 | // Setup the _keyboardMouseDevice, _touchscreenDevice, _touchscreenVirtualPadDevice and the user input mapper with the default bindings |
| 1682 | 1713 | userInputMapper->registerDevice(_keyboardMouseDevice->getInputDevice()); |
| @@ -1688,23 +1719,26 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 5 unmodified lines | ||
| 1688 | 1719 | userInputMapper->registerDevice(_touchscreenVirtualPadDevice->getInputDevice()); |
| 1689 | 1720 | } |
| 1690 | 1721 | |
| 1691 | − // this will force the model the look at the correct directory (weird order of operations issue) | |
| 1692 | − scriptEngines->reloadLocalFiles(); | |
| 1693 | − | |
| 1694 | − // do this as late as possible so that all required subsystems are initialized | |
| 1695 | − // If we've overridden the default scripts location, just load default scripts | |
| 1696 | − // otherwise, load 'em all | |
| 1697 | − | |
| 1698 | − // we just want to see if --scripts was set, we've already parsed it and done | |
| 1699 | − // the change in PathUtils. Rather than pass that in the constructor, lets just | |
| 1700 | − // look (this could be debated) | |
| 1701 | − QString scriptsSwitch = QString("--").append(SCRIPTS_SWITCH); | |
| 1702 | − QDir defaultScriptsLocation(getCmdOption(argc, constArgv, scriptsSwitch.toStdString().c_str())); | |
| 1703 | − if (!defaultScriptsLocation.exists()) { | |
| 1704 | − scriptEngines->loadDefaultScripts(); | |
| 1705 | − scriptEngines->defaultScriptsLocationOverridden(true); | |
| 1706 | − } else { | |
| 1707 | − scriptEngines->loadScripts(); | |
| 1722 | + { | |
| 1723 | + auto scriptEngines = DependencyManager::get<ScriptEngines>().data(); | |
| 1724 | + // this will force the model the look at the correct directory (weird order of operations issue) | |
| 1725 | + scriptEngines->reloadLocalFiles(); | |
| 1726 | + | |
| 1727 | + // do this as late as possible so that all required subsystems are initialized | |
| 1728 | + // If we've overridden the default scripts location, just load default scripts | |
| 1729 | + // otherwise, load 'em all | |
| 1730 | + | |
| 1731 | + // we just want to see if --scripts was set, we've already parsed it and done | |
| 1732 | + // the change in PathUtils. Rather than pass that in the constructor, lets just | |
| 1733 | + // look (this could be debated) | |
| 1734 | + QString scriptsSwitch = QString("--").append(SCRIPTS_SWITCH); | |
| 1735 | + QDir defaultScriptsLocation(getCmdOption(argc, constArgv, scriptsSwitch.toStdString().c_str())); | |
| 1736 | + if (!defaultScriptsLocation.exists()) { | |
| 1737 | + scriptEngines->loadDefaultScripts(); | |
| 1738 | + scriptEngines->defaultScriptsLocationOverridden(true); | |
| 1739 | + } else { | |
| 1740 | + scriptEngines->loadScripts(); | |
| 1741 | + } | |
| 1708 | 1742 | } |
| 1709 | 1743 | |
| 1710 | 1744 | // Make sure we don't time out during slow operations at startup |
| @@ -1754,13 +1788,16 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 43 unmodified lines | ||
| 1754 | 1788 | cameraMenuChanged(); |
| 1755 | 1789 | } |
| 1756 | 1790 | |
| 1757 | − // set the local loopback interface for local sounds | |
| 1758 | − AudioInjector::setLocalAudioInterface(audioIO.data()); | |
| 1759 | − auto audioScriptingInterface = DependencyManager::get<AudioScriptingInterface>(); | |
| 1760 | − audioScriptingInterface->setLocalAudioInterface(audioIO.data()); | |
| 1761 | − connect(audioIO.data(), &AudioClient::noiseGateOpened, audioScriptingInterface.data(), &AudioScriptingInterface::noiseGateOpened); | |
| 1762 | − connect(audioIO.data(), &AudioClient::noiseGateClosed, audioScriptingInterface.data(), &AudioScriptingInterface::noiseGateClosed); | |
| 1763 | − connect(audioIO.data(), &AudioClient::inputReceived, audioScriptingInterface.data(), &AudioScriptingInterface::inputReceived); | |
| 1791 | + { | |
| 1792 | + auto audioIO = DependencyManager::get<AudioClient>().data(); | |
| 1793 | + // set the local loopback interface for local sounds | |
| 1794 | + AudioInjector::setLocalAudioInterface(audioIO); | |
| 1795 | + auto audioScriptingInterface = DependencyManager::get<AudioScriptingInterface>(); | |
| 1796 | + audioScriptingInterface->setLocalAudioInterface(audioIO); | |
| 1797 | + connect(audioIO, &AudioClient::noiseGateOpened, audioScriptingInterface.data(), &AudioScriptingInterface::noiseGateOpened); | |
| 1798 | + connect(audioIO, &AudioClient::noiseGateClosed, audioScriptingInterface.data(), &AudioScriptingInterface::noiseGateClosed); | |
| 1799 | + connect(audioIO, &AudioClient::inputReceived, audioScriptingInterface.data(), &AudioScriptingInterface::inputReceived); | |
| 1800 | + } | |
| 1764 | 1801 | |
| 1765 | 1802 | this->installEventFilter(this); |
| 1766 | 1803 | |
| @@ -1817,21 +1854,17 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 50 unmodified lines | ||
| 1817 | 1854 | } |
| 1818 | 1855 | }); |
| 1819 | 1856 | |
| 1820 | − connect(entityScriptingInterface.data(), &EntityScriptingInterface::deletingEntity, [=](const EntityItemID& entityItemID) { | |
| 1857 | + connect(entityScriptingInterface.data(), &EntityScriptingInterface::deletingEntity, [this](const EntityItemID& entityItemID) { | |
| 1821 | 1858 | if (entityItemID == _keyboardFocusedEntity.get()) { |
| 1822 | 1859 | setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); |
| 1823 | 1860 | } |
| 1824 | 1861 | }); |
| 1825 | 1862 | |
| 1826 | − connect(getEntities()->getTree().get(), &EntityTree::deletingEntity, [=](const EntityItemID& entityItemID) { | |
| 1827 | − auto avatarManager = DependencyManager::get<AvatarManager>(); | |
| 1828 | − auto myAvatar = avatarManager ? avatarManager->getMyAvatar() : nullptr; | |
| 1829 | − if (myAvatar) { | |
| 1830 | − myAvatar->clearAvatarEntity(entityItemID); | |
| 1863 | + EntityTree::setAddMaterialToEntityOperator([this](const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName) { | |
| 1864 | + if (_aboutToQuit) { | |
| 1865 | + return false; | |
| 1831 | 1866 | } |
| 1832 | − }); | |
| 1833 | 1867 | |
| 1834 | − EntityTree::setAddMaterialToEntityOperator([&](const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName) { | |
| 1835 | 1868 | // try to find the renderable |
| 1836 | 1869 | auto renderable = getEntities()->renderableForEntityId(entityID); |
| 1837 | 1870 | if (renderable) { |
| @@ -1846,7 +1879,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 8 unmodified lines | ||
| 1846 | 1879 | } |
| 1847 | 1880 | return false; |
| 1848 | 1881 | }); |
| 1849 | − EntityTree::setRemoveMaterialFromEntityOperator([&](const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName) { | |
| 1882 | + EntityTree::setRemoveMaterialFromEntityOperator([this](const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName) { | |
| 1883 | + if (_aboutToQuit) { | |
| 1884 | + return false; | |
| 1885 | + } | |
| 1886 | + | |
| 1850 | 1887 | // try to find the renderable |
| 1851 | 1888 | auto renderable = getEntities()->renderableForEntityId(entityID); |
| 1852 | 1889 | if (renderable) { |
| @@ -1881,7 +1918,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 28 unmodified lines | ||
| 1881 | 1918 | return false; |
| 1882 | 1919 | }); |
| 1883 | 1920 | |
| 1884 | − EntityTree::setAddMaterialToOverlayOperator([&](const QUuid& overlayID, graphics::MaterialLayer material, const std::string& parentMaterialName) { | |
| 1921 | + EntityTree::setAddMaterialToOverlayOperator([this](const QUuid& overlayID, graphics::MaterialLayer material, const std::string& parentMaterialName) { | |
| 1885 | 1922 | auto overlay = _overlays.getOverlay(overlayID); |
| 1886 | 1923 | if (overlay) { |
| 1887 | 1924 | overlay->addMaterial(material, parentMaterialName); |
| @@ -1889,7 +1926,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 1 unmodified line | ||
| 1889 | 1926 | } |
| 1890 | 1927 | return false; |
| 1891 | 1928 | }); |
| 1892 | − EntityTree::setRemoveMaterialFromOverlayOperator([&](const QUuid& overlayID, graphics::MaterialPointer material, const std::string& parentMaterialName) { | |
| 1929 | + EntityTree::setRemoveMaterialFromOverlayOperator([this](const QUuid& overlayID, graphics::MaterialPointer material, const std::string& parentMaterialName) { | |
| 1893 | 1930 | auto overlay = _overlays.getOverlay(overlayID); |
| 1894 | 1931 | if (overlay) { |
| 1895 | 1932 | overlay->removeMaterial(material, parentMaterialName); |
| @@ -1900,13 +1937,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 4 unmodified lines | ||
| 1900 | 1937 | |
| 1901 | 1938 | // Keyboard focus handling for Web overlays. |
| 1902 | 1939 | auto overlays = &(qApp->getOverlays()); |
| 1903 | − connect(overlays, &Overlays::overlayDeleted, [=](const OverlayID& overlayID) { | |
| 1940 | + connect(overlays, &Overlays::overlayDeleted, [this](const OverlayID& overlayID) { | |
| 1904 | 1941 | if (overlayID == _keyboardFocusedOverlay.get()) { |
| 1905 | 1942 | setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); |
| 1906 | 1943 | } |
| 1907 | 1944 | }); |
| 1908 | 1945 | |
| 1909 | − connect(this, &Application::aboutToQuit, [=]() { | |
| 1946 | + connect(this, &Application::aboutToQuit, [this]() { | |
| 1910 | 1947 | setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); |
| 1911 | 1948 | setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); |
| 1912 | 1949 | }); |
| @@ -2175,23 +2212,22 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 262 unmodified lines | ||
| 2175 | 2212 | QVariant testProperty = property(hifi::properties::TEST); |
| 2176 | 2213 | qDebug() << testProperty; |
| 2177 | 2214 | if (testProperty.isValid()) { |
| 2178 | − auto scriptEngines = DependencyManager::get<ScriptEngines>(); | |
| 2179 | 2215 | const auto testScript = property(hifi::properties::TEST).toUrl(); |
| 2180 | 2216 | |
| 2181 | 2217 | // Set last parameter to exit interface when the test script finishes, if so requested |
| 2182 | − scriptEngines->loadScript(testScript, false, false, false, false, quitWhenFinished); | |
| 2218 | + DependencyManager::get<ScriptEngines>()->loadScript(testScript, false, false, false, false, quitWhenFinished); | |
| 2183 | 2219 | |
| 2184 | 2220 | // This is done so we don't get a "connection time-out" message when we haven't passed in a URL. |
| 2185 | 2221 | if (arguments().contains("--url")) { |
| 2186 | 2222 | auto reply = SandboxUtils::getStatus(); |
| 2187 | − connect(reply, &QNetworkReply::finished, this, [=] { | |
| 2223 | + connect(reply, &QNetworkReply::finished, this, [this, reply] { | |
| 2188 | 2224 | handleSandboxStatus(reply); |
| 2189 | 2225 | }); |
| 2190 | 2226 | } |
| 2191 | 2227 | } else { |
| 2192 | 2228 | PROFILE_RANGE(render, "GetSandboxStatus"); |
| 2193 | 2229 | auto reply = SandboxUtils::getStatus(); |
| 2194 | − connect(reply, &QNetworkReply::finished, this, [=] { | |
| 2230 | + connect(reply, &QNetworkReply::finished, this, [this, reply] { | |
| 2195 | 2231 | handleSandboxStatus(reply); |
| 2196 | 2232 | }); |
| 2197 | 2233 | } |
| @@ -2218,8 +2254,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 20 unmodified lines | ||
| 2218 | 2254 | |
| 2219 | 2255 | connect(&_myCamera, &Camera::modeUpdated, this, &Application::cameraModeChanged); |
| 2220 | 2256 | |
| 2221 | − DependencyManager::get<PickManager>()->setShouldPickHUDOperator([&]() { return DependencyManager::get<HMDScriptingInterface>()->isHMDMode(); }); | |
| 2222 | − DependencyManager::get<PickManager>()->setCalculatePos2DFromHUDOperator([&](const glm::vec3& intersection) { | |
| 2257 | + DependencyManager::get<PickManager>()->setShouldPickHUDOperator([]() { return DependencyManager::get<HMDScriptingInterface>()->isHMDMode(); }); | |
| 2258 | + DependencyManager::get<PickManager>()->setCalculatePos2DFromHUDOperator([this](const glm::vec3& intersection) { | |
| 2223 | 2259 | const glm::vec2 MARGIN(25.0f); |
| 2224 | 2260 | glm::vec2 maxPos = _controllerScriptingInterface->getViewportDimensions() - MARGIN; |
| 2225 | 2261 | glm::vec2 pos2D = DependencyManager::get<HMDScriptingInterface>()->overlayFromWorldPoint(intersection); |
| @@ -2229,7 +2265,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 3 unmodified lines | ||
| 2229 | 2265 | // Setup the mouse ray pick and related operators |
| 2230 | 2266 | DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickID(DependencyManager::get<PickManager>()->addPick(PickQuery::Ray, std::make_shared<MouseRayPick>( |
| 2231 | 2267 | PickFilter(PickScriptingInterface::PICK_ENTITIES() | PickScriptingInterface::PICK_INCLUDE_NONCOLLIDABLE()), 0.0f, true))); |
| 2232 | − DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickResultOperator([&](unsigned int rayPickID) { | |
| 2268 | + DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickResultOperator([](unsigned int rayPickID) { | |
| 2233 | 2269 | RayToEntityIntersectionResult entityResult; |
| 2234 | 2270 | entityResult.intersects = false; |
| 2235 | 2271 | auto pickResult = DependencyManager::get<PickManager>()->getPrevPickResultTyped<RayPickResult>(rayPickID); |
| @@ -2245,7 +2281,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 9 unmodified lines | ||
| 2245 | 2281 | } |
| 2246 | 2282 | return entityResult; |
| 2247 | 2283 | }); |
| 2248 | − DependencyManager::get<EntityTreeRenderer>()->setSetPrecisionPickingOperator([&](unsigned int rayPickID, bool value) { | |
| 2284 | + DependencyManager::get<EntityTreeRenderer>()->setSetPrecisionPickingOperator([](unsigned int rayPickID, bool value) { | |
| 2249 | 2285 | DependencyManager::get<PickManager>()->setPrecisionPicking(rayPickID, value); |
| 2250 | 2286 | }); |
| 2251 | 2287 | |
| @@ -2444,23 +2480,42 @@ void Application::cleanupBeforeQuit() { · 192 unmodified lines | ||
| 2444 | 2480 | _keyboardFocusHighlight = nullptr; |
| 2445 | 2481 | } |
| 2446 | 2482 | |
| 2447 | − auto nodeList = DependencyManager::get<NodeList>(); | |
| 2483 | + { | |
| 2484 | + auto nodeList = DependencyManager::get<NodeList>(); | |
| 2448 | 2485 | |
| 2449 | − // send the domain a disconnect packet, force stoppage of domain-server check-ins | |
| 2450 | − nodeList->getDomainHandler().disconnect(); | |
| 2451 | − nodeList->setIsShuttingDown(true); | |
| 2486 | + // send the domain a disconnect packet, force stoppage of domain-server check-ins | |
| 2487 | + nodeList->getDomainHandler().disconnect(); | |
| 2488 | + nodeList->setIsShuttingDown(true); | |
| 2452 | 2489 | |
| 2453 | − // tell the packet receiver we're shutting down, so it can drop packets | |
| 2454 | − nodeList->getPacketReceiver().setShouldDropPackets(true); | |
| 2490 | + // tell the packet receiver we're shutting down, so it can drop packets | |
| 2491 | + nodeList->getPacketReceiver().setShouldDropPackets(true); | |
| 2492 | + } | |
| 2455 | 2493 | |
| 2456 | 2494 | getEntities()->shutdown(); // tell the entities system we're shutting down, so it will stop running scripts |
| 2457 | 2495 | |
| 2458 | 2496 | // Clear any queued processing (I/O, FBX/OBJ/Texture parsing) |
| 2459 | 2497 | QThreadPool::globalInstance()->clear(); |
| 2460 | 2498 | |
| 2499 | + DependencyManager::destroy<RecordingScriptingInterface>(); | |
| 2500 | + | |
| 2501 | + // FIXME: Something is still holding on to the ScriptEnginePointers contained in ScriptEngines, and they hold backpointers to ScriptEngines, | |
| 2502 | + // so this doesn't shut down properly | |
| 2461 | 2503 | DependencyManager::get<ScriptEngines>()->shutdownScripting(); // stop all currently running global scripts |
| 2504 | + // These classes hold ScriptEnginePointers, so they must be destroyed before ScriptEngines | |
| 2505 | + // Must be done after shutdownScripting in case any scripts try to access these things | |
| 2506 | + { | |
| 2507 | + DependencyManager::destroy<StandAloneJSConsole>(); | |
| 2508 | + EntityTreePointer tree = getEntities()->getTree(); | |
| 2509 | + tree->setSimulation(nullptr); | |
| 2510 | + DependencyManager::destroy<EntityTreeRenderer>(); | |
| 2511 | + } | |
| 2462 | 2512 | DependencyManager::destroy<ScriptEngines>(); |
| 2463 | 2513 | |
| 2514 | + bool autoLogout = Setting::Handle<bool>(AUTO_LOGOUT_SETTING_NAME, false).get(); | |
| 2515 | + if (autoLogout) { | |
| 2516 | + DependencyManager::get<AccountManager>()->removeAccountFromFile(); | |
| 2517 | + } | |
| 2518 | + | |
| 2464 | 2519 | _displayPlugin.reset(); |
| 2465 | 2520 | PluginManager::getInstance()->shutdown(); |
| 2466 | 2521 | |
| @@ -2495,6 +2550,8 @@ void Application::cleanupBeforeQuit() { · 28 unmodified lines | ||
| 2495 | 2550 | DependencyManager::destroy<EyeTracker>(); |
| 2496 | 2551 | #endif |
| 2497 | 2552 | |
| 2553 | + DependencyManager::destroy<ContextOverlayInterface>(); // Must be destroyed before TabletScriptingInterface | |
| 2554 | + | |
| 2498 | 2555 | // stop QML |
| 2499 | 2556 | DependencyManager::destroy<TabletScriptingInterface>(); |
| 2500 | 2557 | DependencyManager::destroy<ToolbarScriptingInterface>(); |
| @@ -2506,10 +2563,6 @@ void Application::cleanupBeforeQuit() { · 5 unmodified lines | ||
| 2506 | 2563 | _snapshotSoundInjector->stop(); |
| 2507 | 2564 | } |
| 2508 | 2565 | |
| 2509 | − // FIXME: something else is holding a reference to AudioClient, | |
| 2510 | − // so it must be explicitly synchronously stopped here | |
| 2511 | − DependencyManager::get<AudioClient>()->cleanupBeforeQuit(); | |
| 2512 | − | |
| 2513 | 2566 | // destroy Audio so it and its threads have a chance to go down safely |
| 2514 | 2567 | // this must happen after QML, as there are unexplained audio crashes originating in qtwebengine |
| 2515 | 2568 | DependencyManager::destroy<AudioClient>(); |
| @@ -2526,11 +2579,15 @@ void Application::cleanupBeforeQuit() { · 10 unmodified lines | ||
| 2526 | 2579 | |
| 2527 | 2580 | Application::~Application() { |
| 2528 | 2581 | // remove avatars from physics engine |
| 2529 | − DependencyManager::get<AvatarManager>()->clearOtherAvatars(); | |
| 2530 | − VectorOfMotionStates motionStates; | |
| 2531 | − DependencyManager::get<AvatarManager>()->getObjectsToRemoveFromPhysics(motionStates); | |
| 2532 | − _physicsEngine->removeObjects(motionStates); | |
| 2533 | − DependencyManager::get<AvatarManager>()->deleteAllAvatars(); | |
| 2582 | + auto avatarManager = DependencyManager::get<AvatarManager>(); | |
| 2583 | + avatarManager->clearOtherAvatars(); | |
| 2584 | + | |
| 2585 | + PhysicsEngine::Transaction transaction; | |
| 2586 | + avatarManager->buildPhysicsTransaction(transaction); | |
| 2587 | + _physicsEngine->processTransaction(transaction); | |
| 2588 | + avatarManager->handleProcessedPhysicsTransaction(transaction); | |
| 2589 | + | |
| 2590 | + avatarManager->deleteAllAvatars(); | |
| 2534 | 2591 | |
| 2535 | 2592 | _physicsEngine->setCharacterController(nullptr); |
| 2536 | 2593 | |
| @@ -2549,9 +2606,6 @@ Application::~Application() { · 12 unmodified lines | ||
| 2549 | 2606 | _entityClipboard->eraseAllOctreeElements(); |
| 2550 | 2607 | _entityClipboard.reset(); |
| 2551 | 2608 | |
| 2552 | − EntityTreePointer tree = getEntities()->getTree(); | |
| 2553 | − tree->setSimulation(nullptr); | |
| 2554 | − | |
| 2555 | 2609 | _octreeProcessor.terminate(); |
| 2556 | 2610 | _entityEditSender.terminate(); |
| 2557 | 2611 | |
| @@ -2562,12 +2616,18 @@ Application::~Application() { · 4 unmodified lines | ||
| 2562 | 2616 | |
| 2563 | 2617 | DependencyManager::destroy<CompositorHelper>(); // must be destroyed before the FramebufferCache |
| 2564 | 2618 | |
| 2619 | + DependencyManager::destroy<SoundCacheScriptingInterface>(); | |
| 2620 | + | |
| 2565 | 2621 | DependencyManager::destroy<AvatarManager>(); |
| 2622 | + DependencyManager::destroy<AnimationCacheScriptingInterface>(); | |
| 2566 | 2623 | DependencyManager::destroy<AnimationCache>(); |
| 2567 | 2624 | DependencyManager::destroy<FramebufferCache>(); |
| 2625 | + DependencyManager::destroy<TextureCacheScriptingInterface>(); | |
| 2568 | 2626 | DependencyManager::destroy<TextureCache>(); |
| 2627 | + DependencyManager::destroy<ModelCacheScriptingInterface>(); | |
| 2569 | 2628 | DependencyManager::destroy<ModelCache>(); |
| 2570 | 2629 | DependencyManager::destroy<ScriptCache>(); |
| 2630 | + DependencyManager::destroy<SoundCacheScriptingInterface>(); | |
| 2571 | 2631 | DependencyManager::destroy<SoundCache>(); |
| 2572 | 2632 | DependencyManager::destroy<OctreeStatsProvider>(); |
| 2573 | 2633 | DependencyManager::destroy<GeometryCache>(); |
| @@ -2596,7 +2656,7 @@ Application::~Application() { · 22 unmodified lines | ||
| 2596 | 2656 | |
| 2597 | 2657 | // Can't log to file passed this point, FileLogger about to be deleted |
| 2598 | 2658 | qInstallMessageHandler(LogHandler::verboseMessageHandler); |
| 2599 | − | |
| 2659 | + | |
| 2600 | 2660 | _renderEventHandler->deleteLater(); |
| 2601 | 2661 | } |
| 2602 | 2662 | |
| @@ -2660,26 +2720,14 @@ void Application::initializeGL() { · 57 unmodified lines | ||
| 2660 | 2720 | } |
| 2661 | 2721 | } |
| 2662 | 2722 | |
| 2663 | − // Build an offscreen GL context for the main thread. | |
| 2664 | − _offscreenContext = new OffscreenGLCanvas(); | |
| 2665 | − _offscreenContext->setObjectName("MainThreadContext"); | |
| 2666 | − _offscreenContext->create(_glWidget->qglContext()); | |
| 2667 | − if (!_offscreenContext->makeCurrent()) { | |
| 2668 | − qFatal("Unable to make offscreen context current"); | |
| 2669 | − } | |
| 2670 | − _offscreenContext->doneCurrent(); | |
| 2671 | − _offscreenContext->setThreadContext(); | |
| 2723 | + _renderEventHandler = new RenderEventHandler(); | |
| 2672 | 2724 | |
| 2725 | + // Build an offscreen GL context for the main thread. | |
| 2673 | 2726 | _glWidget->makeCurrent(); |
| 2674 | 2727 | glClearColor(0.2f, 0.2f, 0.2f, 1); |
| 2675 | 2728 | glClear(GL_COLOR_BUFFER_BIT); |
| 2676 | 2729 | _glWidget->swapBuffers(); |
| 2677 | 2730 | |
| 2678 | − // Move the GL widget context to the render event handler thread | |
| 2679 | − _renderEventHandler = new RenderEventHandler(_glWidget->qglContext()); | |
| 2680 | − if (!_offscreenContext->makeCurrent()) { | |
| 2681 | − qFatal("Unable to make offscreen context current"); | |
| 2682 | − } | |
| 2683 | 2731 | |
| 2684 | 2732 | // Create the GPU backend |
| 2685 | 2733 | |
| @@ -2688,15 +2736,10 @@ void Application::initializeGL() { · 2 unmodified lines | ||
| 2688 | 2736 | // contexts |
| 2689 | 2737 | _glWidget->makeCurrent(); |
| 2690 | 2738 | gpu::Context::init<gpu::gl::GLBackend>(); |
| 2691 | − qApp->setProperty(hifi::properties::gl::MAKE_PROGRAM_CALLBACK, | |
| 2692 | − QVariant::fromValue((void*)(&gpu::gl::GLBackend::makeProgram))); | |
| 2693 | 2739 | _glWidget->makeCurrent(); |
| 2694 | 2740 | _gpuContext = std::make_shared<gpu::Context>(); |
| 2695 | 2741 | |
| 2696 | 2742 | DependencyManager::get<TextureCache>()->setGPUContext(_gpuContext); |
| 2697 | − | |
| 2698 | − // Restore the default main thread context | |
| 2699 | − _offscreenContext->makeCurrent(); | |
| 2700 | 2743 | } |
| 2701 | 2744 | |
| 2702 | 2745 | static const QString SPLASH_SKYBOX{ "{\"ProceduralEntity\":{ \"version\":2, \"shaderUrl\":\"qrc:///shaders/splashSkybox.frag\" } }" }; |
| @@ -2717,6 +2760,10 @@ void Application::initializeDisplayPlugins() { · 14 unmodified lines | ||
| 2717 | 2760 | QObject::connect(displayPlugin.get(), &DisplayPlugin::recommendedFramebufferSizeChanged, |
| 2718 | 2761 | [this](const QSize& size) { resizeGL(); }); |
| 2719 | 2762 | QObject::connect(displayPlugin.get(), &DisplayPlugin::resetSensorsRequested, this, &Application::requestReset); |
| 2763 | + if (displayPlugin->isHmd()) { | |
| 2764 | + QObject::connect(dynamic_cast<HmdDisplayPlugin*>(displayPlugin.get()), &HmdDisplayPlugin::hmdMountedChanged, | |
| 2765 | + DependencyManager::get<HMDScriptingInterface>().data(), &HMDScriptingInterface::mountedChanged); | |
| 2766 | + } | |
| 2720 | 2767 | } |
| 2721 | 2768 | |
| 2722 | 2769 | // The default display plugin needs to be activated first, otherwise the display plugin thread |
| @@ -2731,8 +2778,6 @@ void Application::initializeDisplayPlugins() { · 8 unmodified lines | ||
| 2731 | 2778 | // Submit a default frame to render until the engine starts up |
| 2732 | 2779 | updateRenderArgs(0.0f); |
| 2733 | 2780 | |
| 2734 | − _offscreenContext->makeCurrent(); | |
| 2735 | − | |
| 2736 | 2781 | #define ENABLE_SPLASH_FRAME 0 |
| 2737 | 2782 | #if ENABLE_SPLASH_FRAME |
| 2738 | 2783 | { |
| @@ -2774,8 +2819,6 @@ void Application::initializeDisplayPlugins() { · 35 unmodified lines | ||
| 2774 | 2819 | } |
| 2775 | 2820 | |
| 2776 | 2821 | void Application::initializeRenderEngine() { |
| 2777 | − _offscreenContext->makeCurrent(); | |
| 2778 | − | |
| 2779 | 2822 | // FIXME: on low end systems os the shaders take up to 1 minute to compile, so we pause the deadlock watchdog thread. |
| 2780 | 2823 | DeadlockWatchdogThread::withPause([&] { |
| 2781 | 2824 | // Set up the render engine |
| @@ -2907,6 +2950,15 @@ void Application::initializeUi() { · 125 unmodified lines | ||
| 2907 | 2950 | |
| 2908 | 2951 | // Pre-create a couple of Web3D overlays to speed up tablet UI |
| 2909 | 2952 | auto offscreenSurfaceCache = DependencyManager::get<OffscreenQmlSurfaceCache>(); |
| 2953 | + offscreenSurfaceCache->setOnRootContextCreated([&](const QString& rootObject, QQmlContext* surfaceContext) { | |
| 2954 | + if (rootObject == TabletScriptingInterface::QML) { | |
| 2955 | + // in Qt 5.10.0 there is already an "Audio" object in the QML context | |
| 2956 | + // though I failed to find it (from QtMultimedia??). So.. let it be "AudioScriptingInterface" | |
| 2957 | + surfaceContext->setContextProperty("AudioScriptingInterface", DependencyManager::get<AudioScriptingInterface>().data()); | |
| 2958 | + surfaceContext->setContextProperty("Account", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED | |
| 2959 | + } | |
| 2960 | + }); | |
| 2961 | + | |
| 2910 | 2962 | offscreenSurfaceCache->reserve(TabletScriptingInterface::QML, 1); |
| 2911 | 2963 | offscreenSurfaceCache->reserve(Web3DOverlay::QML, 2); |
| 2912 | 2964 | |
| @@ -2989,10 +3041,11 @@ void Application::onDesktopRootContextCreated(QQmlContext* surfaceContext) { · 76 unmodified lines | ||
| 2989 | 3041 | surfaceContext->setContextProperty("LocationBookmarks", DependencyManager::get<LocationBookmarks>().data()); |
| 2990 | 3042 | |
| 2991 | 3043 | // Caches |
| 2992 | − surfaceContext->setContextProperty("AnimationCache", DependencyManager::get<AnimationCache>().data()); | |
| 2993 | − surfaceContext->setContextProperty("TextureCache", DependencyManager::get<TextureCache>().data()); | |
| 2994 | − surfaceContext->setContextProperty("ModelCache", DependencyManager::get<ModelCache>().data()); | |
| 2995 | − surfaceContext->setContextProperty("SoundCache", DependencyManager::get<SoundCache>().data()); | |
| 3044 | + surfaceContext->setContextProperty("AnimationCache", DependencyManager::get<AnimationCacheScriptingInterface>().data()); | |
| 3045 | + surfaceContext->setContextProperty("TextureCache", DependencyManager::get<TextureCacheScriptingInterface>().data()); | |
| 3046 | + surfaceContext->setContextProperty("ModelCache", DependencyManager::get<ModelCacheScriptingInterface>().data()); | |
| 3047 | + surfaceContext->setContextProperty("SoundCache", DependencyManager::get<SoundCacheScriptingInterface>().data()); | |
| 3048 | + | |
| 2996 | 3049 | surfaceContext->setContextProperty("InputConfiguration", DependencyManager::get<InputConfiguration>().data()); |
| 2997 | 3050 | |
| 2998 | 3051 | surfaceContext->setContextProperty("Account", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED |
| @@ -3247,8 +3300,7 @@ void Application::showHelp() { · 248 unmodified lines | ||
| 3247 | 3300 | QUrlQuery queryString; |
| 3248 | 3301 | queryString.addQueryItem("handControllerName", handControllerName); |
| 3249 | 3302 | queryString.addQueryItem("defaultTab", defaultTab); |
| 3250 | − auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>(); | |
| 3251 | − TabletProxy* tablet = dynamic_cast<TabletProxy*>(tabletScriptingInterface->getTablet(SYSTEM_TABLET)); | |
| 3303 | + TabletProxy* tablet = dynamic_cast<TabletProxy*>(DependencyManager::get<TabletScriptingInterface>()->getTablet(SYSTEM_TABLET)); | |
| 3252 | 3304 | tablet->gotoWebScreen(PathUtils::resourcesUrl() + INFO_HELP_PATH + "?" + queryString.toString()); |
| 3253 | 3305 | DependencyManager::get<HMDScriptingInterface>()->openTablet(); |
| 3254 | 3306 | //InfoView::show(INFO_HELP_PATH, false, queryString.toString()); |
| @@ -3561,6 +3613,10 @@ static void dumpEventQueue(QThread* thread) { · 306 unmodified lines | ||
| 3561 | 3613 | |
| 3562 | 3614 | bool Application::event(QEvent* event) { |
| 3563 | 3615 | |
| 3616 | + if (_aboutToQuit) { | |
| 3617 | + return false; | |
| 3618 | + } | |
| 3619 | + | |
| 3564 | 3620 | if (!Menu::getInstance()) { |
| 3565 | 3621 | return false; |
| 3566 | 3622 | } |
| @@ -3650,6 +3706,10 @@ bool Application::event(QEvent* event) { · 83 unmodified lines | ||
| 3650 | 3706 | |
| 3651 | 3707 | bool Application::eventFilter(QObject* object, QEvent* event) { |
| 3652 | 3708 | |
| 3709 | + if (_aboutToQuit && event->type() != QEvent::DeferredDelete && event->type() != QEvent::Destroy) { | |
| 3710 | + return true; | |
| 3711 | + } | |
| 3712 | + | |
| 3653 | 3713 | if (event->type() == QEvent::Leave) { |
| 3654 | 3714 | getApplicationCompositor().handleLeaveEvent(); |
| 3655 | 3715 | } |
| @@ -3674,7 +3734,10 @@ static bool _altPressed{ false }; · 18 unmodified lines | ||
| 3674 | 3734 | |
| 3675 | 3735 | void Application::keyPressEvent(QKeyEvent* event) { |
| 3676 | 3736 | _altPressed = event->key() == Qt::Key_Alt; |
| 3677 | − _keysPressed.insert(event->key()); | |
| 3737 | + | |
| 3738 | + if (!event->isAutoRepeat()) { | |
| 3739 | + _keysPressed.insert(event->key(), *event); | |
| 3740 | + } | |
| 3678 | 3741 | |
| 3679 | 3742 | _controllerScriptingInterface->emitKeyPressEvent(event); // send events to any registered scripts |
| 3680 | 3743 | // if one of our scripts have asked to capture this event, then stop processing it |
| @@ -3885,7 +3948,9 @@ void Application::keyPressEvent(QKeyEvent* event) { · 204 unmodified lines | ||
| 3885 | 3948 | } |
| 3886 | 3949 | |
| 3887 | 3950 | void Application::keyReleaseEvent(QKeyEvent* event) { |
| 3888 | − _keysPressed.remove(event->key()); | |
| 3951 | + if (!event->isAutoRepeat()) { | |
| 3952 | + _keysPressed.remove(event->key()); | |
| 3953 | + } | |
| 3889 | 3954 | |
| 3890 | 3955 | #if defined(Q_OS_ANDROID) |
| 3891 | 3956 | if (event->key() == Qt::Key_Back) { |
| @@ -3921,11 +3986,14 @@ void Application::focusOutEvent(QFocusEvent* event) { · 29 unmodified lines | ||
| 3921 | 3986 | #endif |
| 3922 | 3987 | |
| 3923 | 3988 | // synthesize events for keys currently pressed, since we may not get their release events |
| 3924 | − foreach (int key, _keysPressed) { | |
| 3925 | − QKeyEvent keyEvent(QEvent::KeyRelease, key, Qt::NoModifier); | |
| 3926 | − keyReleaseEvent(&keyEvent); | |
| 3989 | + // Because our key event handlers may manipulate _keysPressed, lets swap the keys pressed into a local copy, | |
| 3990 | + // clearing the existing list. | |
| 3991 | + QHash<int, QKeyEvent> keysPressed; | |
| 3992 | + std::swap(keysPressed, _keysPressed); | |
| 3993 | + for (auto& ev : keysPressed) { | |
| 3994 | + QKeyEvent synthesizedEvent { QKeyEvent::KeyRelease, ev.key(), Qt::NoModifier, ev.text() }; | |
| 3995 | + keyReleaseEvent(&synthesizedEvent); | |
| 3927 | 3996 | } |
| 3928 | − _keysPressed.clear(); | |
| 3929 | 3997 | } |
| 3930 | 3998 | |
| 3931 | 3999 | void Application::maybeToggleMenuVisible(QMouseEvent* event) const { |
| @@ -3953,10 +4021,6 @@ void Application::maybeToggleMenuVisible(QMouseEvent* event) const { · 21 unmodified lines | ||
| 3953 | 4021 | void Application::mouseMoveEvent(QMouseEvent* event) { |
| 3954 | 4022 | PROFILE_RANGE(app_input_mouse, __FUNCTION__); |
| 3955 | 4023 | |
| 3956 | − if (_aboutToQuit) { | |
| 3957 | − return; | |
| 3958 | − } | |
| 3959 | − | |
| 3960 | 4024 | maybeToggleMenuVisible(event); |
| 3961 | 4025 | |
| 3962 | 4026 | auto& compositor = getApplicationCompositor(); |
| @@ -4021,11 +4085,9 @@ void Application::mousePressEvent(QMouseEvent* event) { · 58 unmodified lines | ||
| 4021 | 4085 | event->screenPos(), event->button(), |
| 4022 | 4086 | event->buttons(), event->modifiers()); |
| 4023 | 4087 | |
| 4024 | − if (!_aboutToQuit) { | |
| 4025 | − getOverlays().mousePressEvent(&mappedEvent); | |
| 4026 | − if (!_controllerScriptingInterface->areEntityClicksCaptured()) { | |
| 4027 | − getEntities()->mousePressEvent(&mappedEvent); | |
| 4028 | − } | |
| 4088 | + getOverlays().mousePressEvent(&mappedEvent); | |
| 4089 | + if (!_controllerScriptingInterface->areEntityClicksCaptured()) { | |
| 4090 | + getEntities()->mousePressEvent(&mappedEvent); | |
| 4029 | 4091 | } |
| 4030 | 4092 | |
| 4031 | 4093 | _controllerScriptingInterface->emitMousePressEvent(&mappedEvent); // send events to any registered scripts |
| @@ -4062,14 +4124,11 @@ void Application::mouseDoublePressEvent(QMouseEvent* event) { · 30 unmodified lines | ||
| 4062 | 4124 | event->screenPos(), event->button(), |
| 4063 | 4125 | event->buttons(), event->modifiers()); |
| 4064 | 4126 | |
| 4065 | − if (!_aboutToQuit) { | |
| 4066 | − getOverlays().mouseDoublePressEvent(&mappedEvent); | |
| 4067 | − if (!_controllerScriptingInterface->areEntityClicksCaptured()) { | |
| 4068 | − getEntities()->mouseDoublePressEvent(&mappedEvent); | |
| 4069 | − } | |
| 4127 | + getOverlays().mouseDoublePressEvent(&mappedEvent); | |
| 4128 | + if (!_controllerScriptingInterface->areEntityClicksCaptured()) { | |
| 4129 | + getEntities()->mouseDoublePressEvent(&mappedEvent); | |
| 4070 | 4130 | } |
| 4071 | 4131 | |
| 4072 | − | |
| 4073 | 4132 | // if one of our scripts have asked to capture this event, then stop processing it |
| 4074 | 4133 | if (_controllerScriptingInterface->isMouseCaptured()) { |
| 4075 | 4134 | return; |
| @@ -4088,10 +4147,8 @@ void Application::mouseReleaseEvent(QMouseEvent* event) { · 12 unmodified lines | ||
| 4088 | 4147 | event->screenPos(), event->button(), |
| 4089 | 4148 | event->buttons(), event->modifiers()); |
| 4090 | 4149 | |
| 4091 | − if (!_aboutToQuit) { | |
| 4092 | − getOverlays().mouseReleaseEvent(&mappedEvent); | |
| 4093 | − getEntities()->mouseReleaseEvent(&mappedEvent); | |
| 4094 | − } | |
| 4150 | + getOverlays().mouseReleaseEvent(&mappedEvent); | |
| 4151 | + getEntities()->mouseReleaseEvent(&mappedEvent); | |
| 4095 | 4152 | |
| 4096 | 4153 | _controllerScriptingInterface->emitMouseReleaseEvent(&mappedEvent); // send events to any registered scripts |
| 4097 | 4154 | |
| @@ -4242,7 +4299,6 @@ bool Application::shouldPaint() const { · 144 unmodified lines | ||
| 4242 | 4299 | return false; |
| 4243 | 4300 | } |
| 4244 | 4301 | |
| 4245 | − | |
| 4246 | 4302 | auto displayPlugin = getActiveDisplayPlugin(); |
| 4247 | 4303 | |
| 4248 | 4304 | #ifdef DEBUG_PAINT_DELAY |
| @@ -4512,7 +4568,6 @@ void Application::idle() { · 263 unmodified lines | ||
| 4512 | 4568 | if (offscreenUi->size() != fromGlm(uiSize)) { |
| 4513 | 4569 | qCDebug(interfaceapp) << "Device pixel ratio changed, triggering resize to " << uiSize; |
| 4514 | 4570 | offscreenUi->resize(fromGlm(uiSize)); |
| 4515 | − _offscreenContext->makeCurrent(); | |
| 4516 | 4571 | } |
| 4517 | 4572 | } |
| 4518 | 4573 | |
| @@ -4550,11 +4605,14 @@ void Application::idle() { · 31 unmodified lines | ||
| 4550 | 4605 | _lastTimeUpdated.start(); |
| 4551 | 4606 | |
| 4552 | 4607 | // If the offscreen Ui has something active that is NOT the root, then assume it has keyboard focus. |
| 4553 | − if (_keyboardDeviceHasFocus && offscreenUi && offscreenUi->getWindow()->activeFocusItem() != offscreenUi->getRootItem()) { | |
| 4554 | − _keyboardMouseDevice->pluginFocusOutEvent(); | |
| 4555 | − _keyboardDeviceHasFocus = false; | |
| 4556 | − } else if (offscreenUi && offscreenUi->getWindow()->activeFocusItem() == offscreenUi->getRootItem()) { | |
| 4557 | − _keyboardDeviceHasFocus = true; | |
| 4608 | + if (offscreenUi && offscreenUi->getWindow()) { | |
| 4609 | + auto activeFocusItem = offscreenUi->getWindow()->activeFocusItem(); | |
| 4610 | + if (_keyboardDeviceHasFocus && activeFocusItem != offscreenUi->getRootItem()) { | |
| 4611 | + _keyboardMouseDevice->pluginFocusOutEvent(); | |
| 4612 | + _keyboardDeviceHasFocus = false; | |
| 4613 | + } else if (activeFocusItem == offscreenUi->getRootItem()) { | |
| 4614 | + _keyboardDeviceHasFocus = true; | |
| 4615 | + } | |
| 4558 | 4616 | } |
| 4559 | 4617 | |
| 4560 | 4618 | checkChangeCursor(); |
| @@ -4567,10 +4625,6 @@ void Application::idle() { · 6 unmodified lines | ||
| 4567 | 4625 | bool showWarnings = getLogger()->extraDebugging(); |
| 4568 | 4626 | PerformanceWarning warn(showWarnings, "idle()"); |
| 4569 | 4627 | |
| 4570 | − if (!_offscreenContext->makeCurrent()) { | |
| 4571 | − qFatal("Unable to make main thread context current"); | |
| 4572 | − } | |
| 4573 | − | |
| 4574 | 4628 | { |
| 4575 | 4629 | _gameWorkload.updateViews(_viewFrustum, getMyAvatar()->getHeadPosition()); |
| 4576 | 4630 | _gameWorkload._engine->run(); |
| @@ -4719,7 +4773,7 @@ bool Application::exportEntities(const QString& filename, · 142 unmodified lines | ||
| 4719 | 4773 | exportTree->createRootElement(); |
| 4720 | 4774 | glm::vec3 root(TREE_SCALE, TREE_SCALE, TREE_SCALE); |
| 4721 | 4775 | bool success = true; |
| 4722 | − entityTree->withReadLock([&] { | |
| 4776 | + entityTree->withReadLock([entityIDs, entityTree, givenOffset, myAvatarID, &root, &entities, &success, &exportTree] { | |
| 4723 | 4777 | for (auto entityID : entityIDs) { // Gather entities and properties. |
| 4724 | 4778 | auto entityItem = entityTree->findEntityByEntityItemID(entityID); |
| 4725 | 4779 | if (!entityItem) { |
| @@ -4839,6 +4893,7 @@ void Application::loadSettings() { · 113 unmodified lines | ||
| 4839 | 4893 | } |
| 4840 | 4894 | |
| 4841 | 4895 | isFirstPerson = (qApp->isHMDMode()); |
| 4896 | + | |
| 4842 | 4897 | } else { |
| 4843 | 4898 | // if this is not the first run, the camera will be initialized differently depending on user settings |
| 4844 | 4899 | |
| @@ -4897,7 +4952,6 @@ QVector<EntityItemID> Application::pasteEntities(float x, float y, float z) { · 52 unmodified lines | ||
| 4897 | 4952 | } |
| 4898 | 4953 | |
| 4899 | 4954 | void Application::init() { |
| 4900 | − _offscreenContext->makeCurrent(); | |
| 4901 | 4955 | // Make sure Login state is up to date |
| 4902 | 4956 | DependencyManager::get<DialogsManager>()->toggleLoginDialog(); |
| 4903 | 4957 | if (!DISABLE_DEFERRED) { |
| @@ -5007,8 +5061,9 @@ void Application::updateLOD(float deltaTime) const { · 103 unmodified lines | ||
| 5007 | 5061 | float presentTime = getActiveDisplayPlugin()->getAveragePresentTime(); |
| 5008 | 5062 | float engineRunTime = (float)(_renderEngine->getConfiguration().get()->getCPURunTime()); |
| 5009 | 5063 | float gpuTime = getGPUContext()->getFrameTimerGPUAverage(); |
| 5064 | + float batchTime = getGPUContext()->getFrameTimerBatchAverage(); | |
| 5010 | 5065 | auto lodManager = DependencyManager::get<LODManager>(); |
| 5011 | − lodManager->setRenderTimes(presentTime, engineRunTime, gpuTime); | |
| 5066 | + lodManager->setRenderTimes(presentTime, engineRunTime, batchTime, gpuTime); | |
| 5012 | 5067 | lodManager->autoAdjustLOD(deltaTime); |
| 5013 | 5068 | } else { |
| 5014 | 5069 | DependencyManager::get<LODManager>()->resetLODAdjust(); |
| @@ -5246,6 +5301,7 @@ void Application::resetPhysicsReadyInformation() { · 231 unmodified lines | ||
| 5246 | 5301 | _nearbyEntitiesCountAtLastPhysicsCheck = 0; |
| 5247 | 5302 | _nearbyEntitiesStabilityCount = 0; |
| 5248 | 5303 | _physicsEnabled = false; |
| 5304 | + _octreeProcessor.startEntitySequence(); | |
| 5249 | 5305 | } |
| 5250 | 5306 | |
| 5251 | 5307 | |
| @@ -5259,6 +5315,7 @@ void Application::reloadResourceCaches() { · 7 unmodified lines | ||
| 5259 | 5315 | queryOctree(NodeType::EntityServer, PacketType::EntityQuery); |
| 5260 | 5316 | |
| 5261 | 5317 | DependencyManager::get<AssetClient>()->clearCache(); |
| 5318 | + DependencyManager::get<ScriptCache>()->clearCache(); | |
| 5262 | 5319 | |
| 5263 | 5320 | DependencyManager::get<AnimationCache>()->refreshAll(); |
| 5264 | 5321 | DependencyManager::get<ModelCache>()->refreshAll(); |
| @@ -5286,7 +5343,7 @@ void Application::setKeyboardFocusHighlight(const glm::vec3& position, const glm · 21 unmodified lines | ||
| 5286 | 5343 | _keyboardFocusHighlight->setPulseMin(0.5); |
| 5287 | 5344 | _keyboardFocusHighlight->setPulseMax(1.0); |
| 5288 | 5345 | _keyboardFocusHighlight->setColorPulse(1.0); |
| 5289 | − _keyboardFocusHighlight->setIgnoreRayIntersection(true); | |
| 5346 | + _keyboardFocusHighlight->setIgnorePickIntersection(true); | |
| 5290 | 5347 | _keyboardFocusHighlight->setDrawInFront(false); |
| 5291 | 5348 | _keyboardFocusHighlightID = getOverlays().addOverlay(_keyboardFocusHighlight); |
| 5292 | 5349 | } |
| @@ -5466,6 +5523,10 @@ static bool domainLoadingInProgress = false; · 173 unmodified lines | ||
| 5466 | 5523 | void Application::update(float deltaTime) { |
| 5467 | 5524 | PROFILE_RANGE_EX(app, __FUNCTION__, 0xffff0000, (uint64_t)_renderFrameCount + 1); |
| 5468 | 5525 | |
| 5526 | + if (_aboutToQuit) { | |
| 5527 | + return; | |
| 5528 | + } | |
| 5529 | + | |
| 5469 | 5530 | if (!_physicsEnabled) { |
| 5470 | 5531 | if (!domainLoadingInProgress) { |
| 5471 | 5532 | PROFILE_ASYNC_BEGIN(app, "Scene Loading", ""); |
| @@ -5475,17 +5536,16 @@ void Application::update(float deltaTime) { · 3 unmodified lines | ||
| 5475 | 5536 | // we haven't yet enabled physics. we wait until we think we have all the collision information |
| 5476 | 5537 | // for nearby entities before starting bullet up. |
| 5477 | 5538 | quint64 now = usecTimestampNow(); |
| 5478 | − const int PHYSICS_CHECK_TIMEOUT = 2 * USECS_PER_SECOND; | |
| 5479 | − | |
| 5480 | − if (now - _lastPhysicsCheckTime > PHYSICS_CHECK_TIMEOUT || _fullSceneReceivedCounter > _fullSceneCounterAtLastPhysicsCheck) { | |
| 5539 | + if (isServerlessMode() || _octreeProcessor.isLoadSequenceComplete()) { | |
| 5481 | 5540 | // we've received a new full-scene octree stats packet, or it's been long enough to try again anyway |
| 5482 | 5541 | _lastPhysicsCheckTime = now; |
| 5483 | 5542 | _fullSceneCounterAtLastPhysicsCheck = _fullSceneReceivedCounter; |
| 5543 | + _lastQueriedViews.clear(); // Force new view. | |
| 5484 | 5544 | |
| 5485 | 5545 | // process octree stats packets are sent in between full sends of a scene (this isn't currently true). |
| 5486 | 5546 | // We keep physics disabled until we've received a full scene and everything near the avatar in that |
| 5487 | 5547 | // scene is ready to compute its collision shape. |
| 5488 | − if (nearbyEntitiesAreReadyForPhysics() && getMyAvatar()->isReadyForPhysics()) { | |
| 5548 | + if (getMyAvatar()->isReadyForPhysics()) { | |
| 5489 | 5549 | _physicsEnabled = true; |
| 5490 | 5550 | getMyAvatar()->updateMotionBehaviorFromMenu(); |
| 5491 | 5551 | } |
| @@ -5690,12 +5750,10 @@ void Application::update(float deltaTime) { · 198 unmodified lines | ||
| 5690 | 5750 | |
| 5691 | 5751 | t1 = std::chrono::high_resolution_clock::now(); |
| 5692 | 5752 | |
| 5693 | − avatarManager->getObjectsToRemoveFromPhysics(motionStates); | |
| 5694 | − _physicsEngine->removeObjects(motionStates); | |
| 5695 | − avatarManager->getObjectsToAddToPhysics(motionStates); | |
| 5696 | − _physicsEngine->addObjects(motionStates); | |
| 5697 | − avatarManager->getObjectsToChange(motionStates); | |
| 5698 | − _physicsEngine->changeObjects(motionStates); | |
| 5753 | + PhysicsEngine::Transaction transaction; | |
| 5754 | + avatarManager->buildPhysicsTransaction(transaction); | |
| 5755 | + _physicsEngine->processTransaction(transaction); | |
| 5756 | + avatarManager->handleProcessedPhysicsTransaction(transaction); | |
| 5699 | 5757 | |
| 5700 | 5758 | myAvatar->prepareForPhysicsSimulation(); |
| 5701 | 5759 | _physicsEngine->forEachDynamic([&](EntityDynamicPointer dynamic) { |
| @@ -5732,15 +5790,13 @@ void Application::update(float deltaTime) { · 30 unmodified lines | ||
| 5732 | 5790 | _entitySimulation->handleDeactivatedMotionStates(deactivations); |
| 5733 | 5791 | }); |
| 5734 | 5792 | |
| 5735 | − if (!_aboutToQuit) { | |
| 5736 | − // handleCollisionEvents() AFTER handleChangedMotionStates() | |
| 5737 | − { | |
| 5738 | − PROFILE_RANGE(simulation_physics, "CollisionEvents"); | |
| 5739 | − avatarManager->handleCollisionEvents(collisionEvents); | |
| 5740 | − // Collision events (and their scripts) must not be handled when we're locked, above. (That would risk | |
| 5741 | − // deadlock.) | |
| 5742 | − _entitySimulation->handleCollisionEvents(collisionEvents); | |
| 5743 | − } | |
| 5793 | + // handleCollisionEvents() AFTER handleChangedMotionStates() | |
| 5794 | + { | |
| 5795 | + PROFILE_RANGE(simulation_physics, "CollisionEvents"); | |
| 5796 | + avatarManager->handleCollisionEvents(collisionEvents); | |
| 5797 | + // Collision events (and their scripts) must not be handled when we're locked, above. (That would risk | |
| 5798 | + // deadlock.) | |
| 5799 | + _entitySimulation->handleCollisionEvents(collisionEvents); | |
| 5744 | 5800 | } |
| 5745 | 5801 | |
| 5746 | 5802 | { |
| @@ -5758,24 +5814,20 @@ void Application::update(float deltaTime) { · 11 unmodified lines | ||
| 5758 | 5814 | } |
| 5759 | 5815 | auto t4 = std::chrono::high_resolution_clock::now(); |
| 5760 | 5816 | |
| 5761 | − if (!_aboutToQuit) { | |
| 5762 | − // NOTE: the getEntities()->update() call below will wait for lock | |
| 5763 | − // and will provide non-physical entity motion | |
| 5764 | − getEntities()->update(true); // update the models... | |
| 5765 | − } | |
| 5817 | + // NOTE: the getEntities()->update() call below will wait for lock | |
| 5818 | + // and will provide non-physical entity motion | |
| 5819 | + getEntities()->update(true); // update the models... | |
| 5766 | 5820 | |
| 5767 | 5821 | auto t5 = std::chrono::high_resolution_clock::now(); |
| 5768 | 5822 | |
| 5769 | 5823 | workload::Timings timings(6); |
| 5770 | − timings[0] = (t4 - t0); | |
| 5771 | − timings[1] = (t5 - t4); | |
| 5772 | − timings[2] = (t4 - t3); | |
| 5773 | − timings[3] = (t3 - t2); | |
| 5774 | − timings[4] = (t2 - t1); | |
| 5775 | − timings[5] = (t1 - t0); | |
| 5776 | − | |
| 5824 | + timings[0] = t1 - t0; // prePhysics entities | |
| 5825 | + timings[1] = t2 - t1; // prePhysics avatars | |
| 5826 | + timings[2] = t3 - t2; // stepPhysics | |
| 5827 | + timings[3] = t4 - t3; // postPhysics | |
| 5828 | + timings[4] = t5 - t4; // non-physical kinematics | |
| 5829 | + timings[5] = workload::Timing_ns((int32_t)(NSECS_PER_SECOND * deltaTime)); // game loop duration | |
| 5777 | 5830 | _gameWorkload.updateSimulationTimings(timings); |
| 5778 | − | |
| 5779 | 5831 | } |
| 5780 | 5832 | } |
| 5781 | 5833 | } else { |
| @@ -5965,7 +6017,7 @@ void Application::updateRenderArgs(float deltaTime) { · 183 unmodified lines | ||
| 5965 | 6017 | _viewFrustum.calculate(); |
| 5966 | 6018 | } |
| 5967 | 6019 | appRenderArgs._renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), |
| 5968 | − lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, | |
| 6020 | + lodManager->getBoundaryLevelAdjust(), lodManager->getLODAngleHalfTan(), RenderArgs::DEFAULT_RENDER_MODE, | |
| 5969 | 6021 | RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); |
| 5970 | 6022 | appRenderArgs._renderArgs._scene = getMain3DScene(); |
| 5971 | 6023 | |
| @@ -6127,11 +6179,23 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType) { · 155 unmodified lines | ||
| 6127 | 6179 | return; // bail early if settings are not loaded |
| 6128 | 6180 | } |
| 6129 | 6181 | |
| 6130 | − _octreeQuery.setConicalViews(_conicalViews); | |
| 6182 | + const bool isModifiedQuery = !_physicsEnabled; | |
| 6183 | + if (isModifiedQuery) { | |
| 6184 | + // Create modified view that is a simple sphere. | |
| 6185 | + ConicalViewFrustum sphericalView; | |
| 6186 | + sphericalView.setSimpleRadius(INITIAL_QUERY_RADIUS); | |
| 6187 | + _octreeQuery.setConicalViews({ sphericalView }); | |
| 6188 | + _octreeQuery.setOctreeSizeScale(DEFAULT_OCTREE_SIZE_SCALE); | |
| 6189 | + static constexpr float MIN_LOD_ADJUST = -20.0f; | |
| 6190 | + _octreeQuery.setBoundaryLevelAdjust(MIN_LOD_ADJUST); | |
| 6191 | + } else { | |
| 6192 | + _octreeQuery.setConicalViews(_conicalViews); | |
| 6193 | + auto lodManager = DependencyManager::get<LODManager>(); | |
| 6194 | + _octreeQuery.setOctreeSizeScale(lodManager->getOctreeSizeScale()); | |
| 6195 | + _octreeQuery.setBoundaryLevelAdjust(lodManager->getBoundaryLevelAdjust()); | |
| 6196 | + } | |
| 6197 | + _octreeQuery.setReportInitialCompletion(isModifiedQuery); | |
| 6131 | 6198 | |
| 6132 | − auto lodManager = DependencyManager::get<LODManager>(); | |
| 6133 | − _octreeQuery.setOctreeSizeScale(lodManager->getOctreeSizeScale()); | |
| 6134 | − _octreeQuery.setBoundaryLevelAdjust(lodManager->getBoundaryLevelAdjust()); | |
| 6135 | 6199 | |
| 6136 | 6200 | auto nodeList = DependencyManager::get<NodeList>(); |
| 6137 | 6201 | |
| @@ -6156,6 +6220,10 @@ bool Application::isHMDMode() const { · 18 unmodified lines | ||
| 6156 | 6220 | return getActiveDisplayPlugin()->isHmd(); |
| 6157 | 6221 | } |
| 6158 | 6222 | |
| 6223 | +float Application::getNumCollisionObjects() const { | |
| 6224 | + return _physicsEngine ? _physicsEngine->getNumCollisionObjects() : 0; | |
| 6225 | +} | |
| 6226 | + | |
| 6159 | 6227 | float Application::getTargetRenderFrameRate() const { return getActiveDisplayPlugin()->getTargetFrameRate(); } |
| 6160 | 6228 | |
| 6161 | 6229 | QRect Application::getDesirableApplicationGeometry() const { |
| @@ -6188,6 +6256,9 @@ PickRay Application::computePickRay(float x, float y) const { · 26 unmodified lines | ||
| 6188 | 6256 | getApplicationCompositor().computeHmdPickRay(pickPoint, result.origin, result.direction); |
| 6189 | 6257 | } else { |
| 6190 | 6258 | pickPoint /= getCanvasSize(); |
| 6259 | + if (_myCamera.getMode() == CameraMode::CAMERA_MODE_MIRROR) { | |
| 6260 | + pickPoint.x = 1.0f - pickPoint.x; | |
| 6261 | + } | |
| 6191 | 6262 | QMutexLocker viewLocker(&_viewMutex); |
| 6192 | 6263 | _viewFrustum.computePickRay(pickPoint.x, pickPoint.y, result.origin, result.direction); |
| 6193 | 6264 | } |
| @@ -6292,7 +6363,6 @@ void Application::clearDomainOctreeDetails() { · 98 unmodified lines | ||
| 6292 | 6363 | } |
| 6293 | 6364 | |
| 6294 | 6365 | void Application::clearDomainAvatars() { |
| 6295 | − getMyAvatar()->setAvatarEntityDataChanged(true); // to recreate worn entities | |
| 6296 | 6366 | DependencyManager::get<AvatarManager>()->clearOtherAvatars(); |
| 6297 | 6367 | } |
| 6298 | 6368 | |
| @@ -6310,7 +6380,6 @@ void Application::domainURLChanged(QUrl domainURL) { · 11 unmodified lines | ||
| 6310 | 6380 | void Application::resettingDomain() { |
| 6311 | 6381 | _notifiedPacketVersionMismatchThisDomain = false; |
| 6312 | 6382 | |
| 6313 | − auto nodeList = DependencyManager::get<NodeList>(); | |
| 6314 | 6383 | clearDomainOctreeDetails(); |
| 6315 | 6384 | } |
| 6316 | 6385 | |
| @@ -6358,8 +6427,8 @@ void Application::nodeActivated(SharedNodePointer node) { · 41 unmodified lines | ||
| 6358 | 6427 | if (_avatarOverrideUrl.isValid()) { |
| 6359 | 6428 | getMyAvatar()->useFullAvatarURL(_avatarOverrideUrl); |
| 6360 | 6429 | } |
| 6361 | − static const QUrl empty{}; | |
| 6362 | − if (getMyAvatar()->getFullAvatarURLFromPreferences() != getMyAvatar()->cannonicalSkeletonModelURL(empty)) { | |
| 6430 | + | |
| 6431 | + if (getMyAvatar()->getFullAvatarURLFromPreferences() != getMyAvatar()->getSkeletonModelURL()) { | |
| 6363 | 6432 | getMyAvatar()->resetFullAvatarURL(); |
| 6364 | 6433 | } |
| 6365 | 6434 | getMyAvatar()->markIdentityDataChanged(); |
| @@ -6523,9 +6592,6 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe · 157 unmodified lines | ||
| 6523 | 6592 | entityScriptingInterface->setPacketSender(&_entityEditSender); |
| 6524 | 6593 | entityScriptingInterface->setEntityTree(getEntities()->getTree()); |
| 6525 | 6594 | |
| 6526 | − // give the script engine to the RecordingScriptingInterface for its callbacks | |
| 6527 | − DependencyManager::get<RecordingScriptingInterface>()->setScriptEngine(scriptEngine); | |
| 6528 | − | |
| 6529 | 6595 | if (property(hifi::properties::TEST).isValid()) { |
| 6530 | 6596 | scriptEngine->registerGlobalObject("Test", TestScriptingInterface::getInstance()); |
| 6531 | 6597 | } |
| @@ -6577,11 +6643,12 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe · 45 unmodified lines | ||
| 6577 | 6643 | scriptEngine->registerGetterSetter("location", LocationScriptingInterface::locationGetter, |
| 6578 | 6644 | LocationScriptingInterface::locationSetter); |
| 6579 | 6645 | |
| 6646 | + bool clientScript = scriptEngine->isClientScript(); | |
| 6647 | + scriptEngine->registerFunction("OverlayWindow", clientScript ? QmlWindowClass::constructor : QmlWindowClass::restricted_constructor); | |
| 6580 | 6648 | #if !defined(Q_OS_ANDROID) |
| 6581 | − scriptEngine->registerFunction("OverlayWebWindow", QmlWebWindowClass::constructor); | |
| 6649 | + scriptEngine->registerFunction("OverlayWebWindow", clientScript ? QmlWebWindowClass::constructor : QmlWebWindowClass::restricted_constructor); | |
| 6582 | 6650 | #endif |
| 6583 | − scriptEngine->registerFunction("OverlayWindow", QmlWindowClass::constructor); | |
| 6584 | − scriptEngine->registerFunction("QmlFragment", QmlFragmentClass::constructor); | |
| 6651 | + scriptEngine->registerFunction("QmlFragment", clientScript ? QmlFragmentClass::constructor : QmlFragmentClass::restricted_constructor); | |
| 6585 | 6652 | |
| 6586 | 6653 | scriptEngine->registerGlobalObject("Menu", MenuScriptingInterface::getInstance()); |
| 6587 | 6654 | scriptEngine->registerGlobalObject("DesktopPreviewProvider", DependencyManager::get<DesktopPreviewProvider>().data()); |
| @@ -6599,10 +6666,10 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe · 11 unmodified lines | ||
| 6599 | 6666 | scriptEngine->registerGlobalObject("Pointers", DependencyManager::get<PointerScriptingInterface>().data()); |
| 6600 | 6667 | |
| 6601 | 6668 | // Caches |
| 6602 | − scriptEngine->registerGlobalObject("AnimationCache", DependencyManager::get<AnimationCache>().data()); | |
| 6603 | − scriptEngine->registerGlobalObject("TextureCache", DependencyManager::get<TextureCache>().data()); | |
| 6604 | − scriptEngine->registerGlobalObject("ModelCache", DependencyManager::get<ModelCache>().data()); | |
| 6605 | − scriptEngine->registerGlobalObject("SoundCache", DependencyManager::get<SoundCache>().data()); | |
| 6669 | + scriptEngine->registerGlobalObject("AnimationCache", DependencyManager::get<AnimationCacheScriptingInterface>().data()); | |
| 6670 | + scriptEngine->registerGlobalObject("TextureCache", DependencyManager::get<TextureCacheScriptingInterface>().data()); | |
| 6671 | + scriptEngine->registerGlobalObject("ModelCache", DependencyManager::get<ModelCacheScriptingInterface>().data()); | |
| 6672 | + scriptEngine->registerGlobalObject("SoundCache", DependencyManager::get<SoundCacheScriptingInterface>().data()); | |
| 6606 | 6673 | |
| 6607 | 6674 | scriptEngine->registerGlobalObject("DialogsManager", _dialogsManagerScriptingInterface); |
| 6608 | 6675 | |
| @@ -6663,19 +6730,16 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe · 54 unmodified lines | ||
| 6663 | 6730 | |
| 6664 | 6731 | registerInteractiveWindowMetaType(scriptEngine.data()); |
| 6665 | 6732 | |
| 6666 | − DependencyManager::get<PickScriptingInterface>()->registerMetaTypes(scriptEngine.data()); | |
| 6733 | + auto pickScriptingInterface = DependencyManager::get<PickScriptingInterface>(); | |
| 6734 | + pickScriptingInterface->registerMetaTypes(scriptEngine.data()); | |
| 6667 | 6735 | |
| 6668 | 6736 | // connect this script engines printedMessage signal to the global ScriptEngines these various messages |
| 6669 | − connect(scriptEngine.data(), &ScriptEngine::printedMessage, | |
| 6670 | − DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onPrintedMessage); | |
| 6671 | − connect(scriptEngine.data(), &ScriptEngine::errorMessage, | |
| 6672 | − DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onErrorMessage); | |
| 6673 | − connect(scriptEngine.data(), &ScriptEngine::warningMessage, | |
| 6674 | − DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onWarningMessage); | |
| 6675 | − connect(scriptEngine.data(), &ScriptEngine::infoMessage, | |
| 6676 | − DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onInfoMessage); | |
| 6677 | − connect(scriptEngine.data(), &ScriptEngine::clearDebugWindow, | |
| 6678 | − DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onClearDebugWindow); | |
| 6737 | + auto scriptEngines = DependencyManager::get<ScriptEngines>().data(); | |
| 6738 | + connect(scriptEngine.data(), &ScriptEngine::printedMessage, scriptEngines, &ScriptEngines::onPrintedMessage); | |
| 6739 | + connect(scriptEngine.data(), &ScriptEngine::errorMessage, scriptEngines, &ScriptEngines::onErrorMessage); | |
| 6740 | + connect(scriptEngine.data(), &ScriptEngine::warningMessage, scriptEngines, &ScriptEngines::onWarningMessage); | |
| 6741 | + connect(scriptEngine.data(), &ScriptEngine::infoMessage, scriptEngines, &ScriptEngines::onInfoMessage); | |
| 6742 | + connect(scriptEngine.data(), &ScriptEngine::clearDebugWindow, scriptEngines, &ScriptEngines::onClearDebugWindow); | |
| 6679 | 6743 | |
| 6680 | 6744 | } |
| 6681 | 6745 | |
| @@ -6983,10 +7047,9 @@ void Application::showDialog(const QUrl& widgetUrl, const QUrl& tabletUrl, const · 301 unmodified lines | ||
| 6983 | 7047 | } |
| 6984 | 7048 | |
| 6985 | 7049 | void Application::showScriptLogs() { |
| 6986 | − auto scriptEngines = DependencyManager::get<ScriptEngines>(); | |
| 6987 | 7050 | QUrl defaultScriptsLoc = PathUtils::defaultScriptsLocation(); |
| 6988 | 7051 | defaultScriptsLoc.setPath(defaultScriptsLoc.path() + "developer/debugging/debugWindow.js"); |
| 6989 | − scriptEngines->loadScript(defaultScriptsLoc.toString()); | |
| 7052 | + DependencyManager::get<ScriptEngines>()->loadScript(defaultScriptsLoc.toString()); | |
| 6990 | 7053 | } |
| 6991 | 7054 | |
| 6992 | 7055 | void Application::showAssetServerWidget(QString filePath) { |
| @@ -7239,6 +7302,8 @@ void Application::addAssetToWorldAddEntity(QString filePath, QString mapping) { · 246 unmodified lines | ||
| 7239 | 7302 | } |
| 7240 | 7303 | properties.setCollisionless(true); // Temporarily set so that doesn't collide with avatar. |
| 7241 | 7304 | properties.setVisible(false); // Temporarily set so that don't see at large unresized dimensions. |
| 7305 | + bool grabbable = (Menu::getInstance()->isOptionChecked(MenuOption::CreateEntitiesGrabbable)); | |
| 7306 | + properties.setUserData(grabbable ? GRABBABLE_USER_DATA : NOT_GRABBABLE_USER_DATA); | |
| 7242 | 7307 | glm::vec3 positionOffset = getMyAvatar()->getWorldOrientation() * (getMyAvatar()->getSensorToWorldScale() * glm::vec3(0.0f, 0.0f, -2.0f)); |
| 7243 | 7308 | properties.setPosition(getMyAvatar()->getWorldPosition() + positionOffset); |
| 7244 | 7309 | properties.setRotation(getMyAvatar()->getWorldOrientation()); |
| @@ -7281,7 +7346,6 @@ void Application::addAssetToWorldCheckModelSize() { · 36 unmodified lines | ||
| 7281 | 7346 | auto name = properties.getName(); |
| 7282 | 7347 | auto dimensions = properties.getDimensions(); |
| 7283 | 7348 | |
| 7284 | − const QString GRABBABLE_USER_DATA = "{\"grabbableKey\":{\"grabbable\":true}}"; | |
| 7285 | 7349 | bool doResize = false; |
| 7286 | 7350 | |
| 7287 | 7351 | const glm::vec3 DEFAULT_DIMENSIONS = glm::vec3(0.1f, 0.1f, 0.1f); |
| @@ -7325,7 +7389,8 @@ void Application::addAssetToWorldCheckModelSize() { · 37 unmodified lines | ||
| 7325 | 7389 | if (!name.toLower().endsWith(PNG_EXTENSION) && !name.toLower().endsWith(JPG_EXTENSION)) { |
| 7326 | 7390 | properties.setCollisionless(false); |
| 7327 | 7391 | } |
| 7328 | − properties.setUserData(GRABBABLE_USER_DATA); | |
| 7392 | + bool grabbable = (Menu::getInstance()->isOptionChecked(MenuOption::CreateEntitiesGrabbable)); | |
| 7393 | + properties.setUserData(grabbable ? GRABBABLE_USER_DATA : NOT_GRABBABLE_USER_DATA); | |
| 7329 | 7394 | properties.setLastEdited(usecTimestampNow()); |
| 7330 | 7395 | entityScriptingInterface->editEntity(entityID, properties); |
| 7331 | 7396 | } |
| @@ -7550,7 +7615,6 @@ void Application::openUrl(const QUrl& url) const { · 218 unmodified lines | ||
| 7550 | 7615 | } |
| 7551 | 7616 | |
| 7552 | 7617 | void Application::loadDialog() { |
| 7553 | − auto scriptEngines = DependencyManager::get<ScriptEngines>(); | |
| 7554 | 7618 | ModalDialogListener* dlg = OffscreenUi::getOpenFileNameAsync(_glWidget, tr("Open Script"), |
| 7555 | 7619 | getPreviousScriptLocation(), |
| 7556 | 7620 | tr("JavaScript Files (*.js)")); |
| @@ -8273,7 +8337,7 @@ QOpenGLContext* Application::getPrimaryContext() { · 716 unmodified lines | ||
| 8273 | 8337 | } |
| 8274 | 8338 | |
| 8275 | 8339 | bool Application::makeRenderingContextCurrent() { |
| 8276 | − return _offscreenContext->makeCurrent(); | |
| 8340 | + return true; | |
| 8277 | 8341 | } |
| 8278 | 8342 | |
| 8279 | 8343 | bool Application::isForeground() const { |