Showing the changes to interface/src/Application.cpp (1 of 385 files). Show all
Unified · Split
| @@ -11,6 +11,9 @@ · 10 unmodified lines | |||
| 11 | 11 | ||
| 12 | #include "Application.h" | 12 | #include "Application.h" |
| 13 | 13 | ||
| 14 | #include <chrono> | ||
| 15 | #include <thread> | ||
| 16 | |||
| 14 | #include <gl/Config.h> | 17 | #include <gl/Config.h> |
| 15 | #include <glm/glm.hpp> | 18 | #include <glm/glm.hpp> |
| 16 | #include <glm/gtx/component_wise.hpp> | 19 | #include <glm/gtx/component_wise.hpp> |
| @@ -69,6 +72,7 @@ · 52 unmodified lines | |||
| 69 | #include <ErrorDialog.h> | 72 | #include <ErrorDialog.h> |
| 70 | #include <FileScriptingInterface.h> | 73 | #include <FileScriptingInterface.h> |
| 71 | #include <Finally.h> | 74 | #include <Finally.h> |
| 75 | #include <FingerprintUtils.h> | ||
| 72 | #include <FramebufferCache.h> | 76 | #include <FramebufferCache.h> |
| 73 | #include <gpu/Batch.h> | 77 | #include <gpu/Batch.h> |
| 74 | #include <gpu/Context.h> | 78 | #include <gpu/Context.h> |
| @@ -110,7 +114,9 @@ · 35 unmodified lines | |||
| 110 | #include <render/RenderFetchCullSortTask.h> | 114 | #include <render/RenderFetchCullSortTask.h> |
| 111 | #include <RenderDeferredTask.h> | 115 | #include <RenderDeferredTask.h> |
| 112 | #include <RenderForwardTask.h> | 116 | #include <RenderForwardTask.h> |
| 117 | #include <RenderViewTask.h> | ||
| 113 | #include <ResourceCache.h> | 118 | #include <ResourceCache.h> |
| 119 | #include <ResourceRequest.h> | ||
| 114 | #include <SandboxUtils.h> | 120 | #include <SandboxUtils.h> |
| 115 | #include <SceneScriptingInterface.h> | 121 | #include <SceneScriptingInterface.h> |
| 116 | #include <ScriptEngines.h> | 122 | #include <ScriptEngines.h> |
| @@ -144,10 +150,8 @@ · 27 unmodified lines | |||
| 144 | #include "InterfaceLogging.h" | 150 | #include "InterfaceLogging.h" |
| 145 | #include "LODManager.h" | 151 | #include "LODManager.h" |
| 146 | #include "ModelPackager.h" | 152 | #include "ModelPackager.h" |
| 147 | #include "networking/HFWebEngineProfile.h" | ||
| 148 | #include "networking/HFTabletWebEngineProfile.h" | ||
| 149 | #include "networking/FileTypeProfile.h" | ||
| 150 | #include "scripting/Audio.h" | 153 | #include "scripting/Audio.h" |
| 154 | #include "networking/CloseEventSender.h" | ||
| 151 | #include "scripting/TestScriptingInterface.h" | 155 | #include "scripting/TestScriptingInterface.h" |
| 152 | #include "scripting/AccountScriptingInterface.h" | 156 | #include "scripting/AccountScriptingInterface.h" |
| 153 | #include "scripting/AssetMappingsScriptingInterface.h" | 157 | #include "scripting/AssetMappingsScriptingInterface.h" |
| @@ -244,6 +248,8 @@ static const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStanda · 90 unmodified lines | |||
| 244 | Setting::Handle<int> maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTREE_PPS); | 248 | Setting::Handle<int> maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTREE_PPS); |
| 245 | 249 | ||
| 246 | static const QString MARKETPLACE_CDN_HOSTNAME = "mpassets.highfidelity.com"; | 250 | static const QString MARKETPLACE_CDN_HOSTNAME = "mpassets.highfidelity.com"; |
| 251 | static const int INTERVAL_TO_CHECK_HMD_WORN_STATUS = 500; // milliseconds | ||
| 252 | static const QString DESKTOP_DISPLAY_PLUGIN_NAME = "Desktop"; | ||
| 247 | 253 | ||
| 248 | static const QString SYSTEM_TABLET = "com.highfidelity.interface.tablet.system"; | 254 | static const QString SYSTEM_TABLET = "com.highfidelity.interface.tablet.system"; |
| 249 | 255 | ||
| @@ -438,6 +444,10 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { · 188 unmodified lines | |||
| 438 | const char* portStr = getCmdOption(argc, constArgv, "--listenPort"); | 444 | const char* portStr = getCmdOption(argc, constArgv, "--listenPort"); |
| 439 | const int listenPort = portStr ? atoi(portStr) : INVALID_PORT; | 445 | const int listenPort = portStr ? atoi(portStr) : INVALID_PORT; |
| 440 | 446 | ||
| 447 | static const auto SUPPRESS_SETTINGS_RESET = "--suppress-settings-reset"; | ||
| 448 | bool suppressPrompt = cmdOptionExists(argc, const_cast<const char**>(argv), SUPPRESS_SETTINGS_RESET); | ||
| 449 | bool previousSessionCrashed = CrashHandler::checkForResetSettings(runningMarkerExisted, suppressPrompt); | ||
| 450 | |||
| 441 | Setting::init(); | 451 | Setting::init(); |
| 442 | 452 | ||
| 443 | if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { | 453 | if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { |
| @@ -458,10 +468,6 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { · 14 unmodified lines | |||
| 458 | QCoreApplication::addLibraryPath(audioDLLPath); | 468 | QCoreApplication::addLibraryPath(audioDLLPath); |
| 459 | #endif | 469 | #endif |
| 460 | 470 | ||
| 461 | static const auto SUPPRESS_SETTINGS_RESET = "--suppress-settings-reset"; | ||
| 462 | bool suppressPrompt = cmdOptionExists(argc, const_cast<const char**>(argv), SUPPRESS_SETTINGS_RESET); | ||
| 463 | bool previousSessionCrashed = CrashHandler::checkForResetSettings(runningMarkerExisted, suppressPrompt); | ||
| 464 | |||
| 465 | DependencyManager::registerInheritance<LimitedNodeList, NodeList>(); | 471 | DependencyManager::registerInheritance<LimitedNodeList, NodeList>(); |
| 466 | DependencyManager::registerInheritance<AvatarHashMap, AvatarManager>(); | 472 | DependencyManager::registerInheritance<AvatarHashMap, AvatarManager>(); |
| 467 | DependencyManager::registerInheritance<EntityDynamicFactoryInterface, InterfaceDynamicFactory>(); | 473 | DependencyManager::registerInheritance<EntityDynamicFactoryInterface, InterfaceDynamicFactory>(); |
| @@ -536,6 +542,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { · 68 unmodified lines | |||
| 536 | DependencyManager::set<AvatarBookmarks>(); | 542 | DependencyManager::set<AvatarBookmarks>(); |
| 537 | DependencyManager::set<LocationBookmarks>(); | 543 | DependencyManager::set<LocationBookmarks>(); |
| 538 | DependencyManager::set<Snapshot>(); | 544 | DependencyManager::set<Snapshot>(); |
| 545 | DependencyManager::set<CloseEventSender>(); | ||
| 539 | 546 | ||
| 540 | return previousSessionCrashed; | 547 | return previousSessionCrashed; |
| 541 | } | 548 | } |
| @@ -649,6 +656,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 107 unmodified lines | |||
| 649 | Model::setAbstractViewStateInterface(this); // The model class will sometimes need to know view state details from us | 656 | Model::setAbstractViewStateInterface(this); // The model class will sometimes need to know view state details from us |
| 650 | 657 | ||
| 651 | auto nodeList = DependencyManager::get<NodeList>(); | 658 | auto nodeList = DependencyManager::get<NodeList>(); |
| 659 | nodeList->startThread(); | ||
| 652 | 660 | ||
| 653 | // Set up a watchdog thread to intentionally crash the application on deadlocks | 661 | // Set up a watchdog thread to intentionally crash the application on deadlocks |
| 654 | _deadlockWatchdogThread = new DeadlockWatchdogThread(); | 662 | _deadlockWatchdogThread = new DeadlockWatchdogThread(); |
| @@ -674,25 +682,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 19 unmodified lines | |||
| 674 | 682 | ||
| 675 | updateHeartbeat(); | 683 | updateHeartbeat(); |
| 676 | 684 | ||
| 677 | // start the nodeThread so its event loop is running | ||
| 678 | QThread* nodeThread = new QThread(this); | ||
| 679 | nodeThread->setObjectName("NodeList Thread"); | ||
| 680 | nodeThread->start(); | ||
| 681 | |||
| 682 | // make sure the node thread is given highest priority | ||
| 683 | nodeThread->setPriority(QThread::TimeCriticalPriority); | ||
| 684 | |||
| 685 | // setup a timer for domain-server check ins | 685 | // setup a timer for domain-server check ins |
| 686 | QTimer* domainCheckInTimer = new QTimer(nodeList.data()); | 686 | QTimer* domainCheckInTimer = new QTimer(nodeList.data()); |
| 687 | connect(domainCheckInTimer, &QTimer::timeout, nodeList.data(), &NodeList::sendDomainServerCheckIn); | 687 | connect(domainCheckInTimer, &QTimer::timeout, nodeList.data(), &NodeList::sendDomainServerCheckIn); |
| 688 | domainCheckInTimer->start(DOMAIN_SERVER_CHECK_IN_MSECS); | 688 | domainCheckInTimer->start(DOMAIN_SERVER_CHECK_IN_MSECS); |
| 689 | 689 | ||
| 690 | // put the NodeList and datagram processing on the node thread | ||
| 691 | nodeList->moveToThread(nodeThread); | ||
| 692 | |||
| 693 | // put the audio processing on a separate thread | ||
| 694 | QThread* audioThread = new QThread(); | ||
| 695 | audioThread->setObjectName("Audio Thread"); | ||
| 696 | 690 | ||
| 697 | auto audioIO = DependencyManager::get<AudioClient>(); | 691 | auto audioIO = DependencyManager::get<AudioClient>(); |
| 698 | audioIO->setPositionGetter([]{ | 692 | audioIO->setPositionGetter([]{ |
| @@ -708,7 +702,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 9 unmodified lines | |||
| 708 | return myAvatar ? myAvatar->getOrientationForAudio() : Quaternions::IDENTITY; | 702 | return myAvatar ? myAvatar->getOrientationForAudio() : Quaternions::IDENTITY; |
| 709 | }); | 703 | }); |
| 710 | 704 | ||
| 711 | audioIO->moveToThread(audioThread); | ||
| 712 | recording::Frame::registerFrameHandler(AudioConstants::getAudioFrameName(), [=](recording::Frame::ConstPointer frame) { | 705 | recording::Frame::registerFrameHandler(AudioConstants::getAudioFrameName(), [=](recording::Frame::ConstPointer frame) { |
| 713 | audioIO->handleRecordedAudioInput(frame->data); | 706 | audioIO->handleRecordedAudioInput(frame->data); |
| 714 | }); | 707 | }); |
| @@ -720,11 +713,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 5 unmodified lines | |||
| 720 | recorder->recordFrame(AUDIO_FRAME_TYPE, audio); | 713 | recorder->recordFrame(AUDIO_FRAME_TYPE, audio); |
| 721 | } | 714 | } |
| 722 | }); | 715 | }); |
| 723 | 716 | audioIO->startThread(); | |
| 724 | connect(audioThread, &QThread::started, audioIO.data(), &AudioClient::start); | ||
| 725 | connect(audioIO.data(), &AudioClient::destroyed, audioThread, &QThread::quit); | ||
| 726 | connect(audioThread, &QThread::finished, audioThread, &QThread::deleteLater); | ||
| 727 | audioThread->start(); | ||
| 728 | 717 | ||
| 729 | auto audioScriptingInterface = DependencyManager::set<AudioScriptingInterface, scripting::Audio>(); | 718 | auto audioScriptingInterface = DependencyManager::set<AudioScriptingInterface, scripting::Audio>(); |
| 730 | connect(audioIO.data(), &AudioClient::mutedByMixer, audioScriptingInterface.data(), &AudioScriptingInterface::mutedByMixer); | 719 | connect(audioIO.data(), &AudioClient::mutedByMixer, audioScriptingInterface.data(), &AudioScriptingInterface::mutedByMixer); |
| @@ -750,12 +739,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 19 unmodified lines | |||
| 750 | updateHeartbeat(); | 739 | updateHeartbeat(); |
| 751 | 740 | ||
| 752 | // Setup MessagesClient | 741 | // Setup MessagesClient |
| 753 | auto messagesClient = DependencyManager::get<MessagesClient>(); | 742 | DependencyManager::get<MessagesClient>()->startThread(); |
| 754 | QThread* messagesThread = new QThread; | ||
| 755 | messagesThread->setObjectName("Messages Client Thread"); | ||
| 756 | messagesClient->moveToThread(messagesThread); | ||
| 757 | connect(messagesThread, &QThread::started, messagesClient.data(), &MessagesClient::init); | ||
| 758 | messagesThread->start(); | ||
| 759 | 743 | ||
| 760 | const DomainHandler& domainHandler = nodeList->getDomainHandler(); | 744 | const DomainHandler& domainHandler = nodeList->getDomainHandler(); |
| 761 | 745 | ||
| @@ -950,6 +934,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 188 unmodified lines | |||
| 950 | properties["processor_l3_cache_count"] = procInfo.numProcessorCachesL3; | 934 | properties["processor_l3_cache_count"] = procInfo.numProcessorCachesL3; |
| 951 | } | 935 | } |
| 952 | 936 | ||
| 937 | // add firstRun flag from settings to launch event | ||
| 938 | Setting::Handle<bool> firstRun { Settings::firstRun, true }; | ||
| 939 | properties["first_run"] = firstRun.get(); | ||
| 940 | |||
| 941 | // add the user's machine ID to the launch event | ||
| 942 | properties["machine_fingerprint"] = uuidStringWithoutCurlyBraces(FingerprintUtils::getMachineFingerprint()); | ||
| 943 | |||
| 953 | UserActivityLogger::getInstance().logAction("launch", properties); | 944 | UserActivityLogger::getInstance().logAction("launch", properties); |
| 954 | 945 | ||
| 955 | // Tell our entity edit sender about our known jurisdictions | 946 | // Tell our entity edit sender about our known jurisdictions |
| @@ -1309,6 +1300,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 353 unmodified lines | |||
| 1309 | properties["kbps_in"] = bandwidthRecorder->getCachedTotalAverageInputKilobitsPerSecond(); | 1300 | properties["kbps_in"] = bandwidthRecorder->getCachedTotalAverageInputKilobitsPerSecond(); |
| 1310 | properties["kbps_out"] = bandwidthRecorder->getCachedTotalAverageOutputKilobitsPerSecond(); | 1301 | properties["kbps_out"] = bandwidthRecorder->getCachedTotalAverageOutputKilobitsPerSecond(); |
| 1311 | 1302 | ||
| 1303 | properties["atp_in_kbps"] = bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AssetServer); | ||
| 1304 | |||
| 1312 | auto nodeList = DependencyManager::get<NodeList>(); | 1305 | auto nodeList = DependencyManager::get<NodeList>(); |
| 1313 | SharedNodePointer entityServerNode = nodeList->soloNodeOfType(NodeType::EntityServer); | 1306 | SharedNodePointer entityServerNode = nodeList->soloNodeOfType(NodeType::EntityServer); |
| 1314 | SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NodeType::AudioMixer); | 1307 | SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NodeType::AudioMixer); |
| @@ -1322,8 +1315,61 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 7 unmodified lines | |||
| 1322 | properties["messages_ping"] = messagesMixerNode ? messagesMixerNode->getPingMs() : -1; | 1315 | properties["messages_ping"] = messagesMixerNode ? messagesMixerNode->getPingMs() : -1; |
| 1323 | 1316 | ||
| 1324 | auto loadingRequests = ResourceCache::getLoadingRequests(); | 1317 | auto loadingRequests = ResourceCache::getLoadingRequests(); |
| 1318 | |||
| 1319 | QJsonArray loadingRequestsStats; | ||
| 1320 | for (const auto& request : loadingRequests) { | ||
| 1321 | QJsonObject requestStats; | ||
| 1322 | requestStats["filename"] = request->getURL().fileName(); | ||
| 1323 | requestStats["received"] = request->getBytesReceived(); | ||
| 1324 | requestStats["total"] = request->getBytesTotal(); | ||
| 1325 | requestStats["attempts"] = (int)request->getDownloadAttempts(); | ||
| 1326 | loadingRequestsStats.append(requestStats); | ||
| 1327 | } | ||
| 1328 | |||
| 1325 | properties["active_downloads"] = loadingRequests.size(); | 1329 | properties["active_downloads"] = loadingRequests.size(); |
| 1326 | properties["pending_downloads"] = ResourceCache::getPendingRequestCount(); | 1330 | properties["pending_downloads"] = ResourceCache::getPendingRequestCount(); |
| 1331 | properties["active_downloads_details"] = loadingRequestsStats; | ||
| 1332 | |||
| 1333 | auto statTracker = DependencyManager::get<StatTracker>(); | ||
| 1334 | |||
| 1335 | properties["processing_resources"] = statTracker->getStat("Processing").toInt(); | ||
| 1336 | properties["pending_processing_resources"] = statTracker->getStat("PendingProcessing").toInt(); | ||
| 1337 | |||
| 1338 | QJsonObject startedRequests; | ||
| 1339 | startedRequests["atp"] = statTracker->getStat(STAT_ATP_REQUEST_STARTED).toInt(); | ||
| 1340 | startedRequests["http"] = statTracker->getStat(STAT_HTTP_REQUEST_STARTED).toInt(); | ||
| 1341 | startedRequests["file"] = statTracker->getStat(STAT_FILE_REQUEST_STARTED).toInt(); | ||
| 1342 | startedRequests["total"] = startedRequests["atp"].toInt() + startedRequests["http"].toInt() | ||
| 1343 | + startedRequests["file"].toInt(); | ||
| 1344 | properties["started_requests"] = startedRequests; | ||
| 1345 | |||
| 1346 | QJsonObject successfulRequests; | ||
| 1347 | successfulRequests["atp"] = statTracker->getStat(STAT_ATP_REQUEST_SUCCESS).toInt(); | ||
| 1348 | successfulRequests["http"] = statTracker->getStat(STAT_HTTP_REQUEST_SUCCESS).toInt(); | ||
| 1349 | successfulRequests["file"] = statTracker->getStat(STAT_FILE_REQUEST_SUCCESS).toInt(); | ||
| 1350 | successfulRequests["total"] = successfulRequests["atp"].toInt() + successfulRequests["http"].toInt() | ||
| 1351 | + successfulRequests["file"].toInt(); | ||
| 1352 | properties["successful_requests"] = successfulRequests; | ||
| 1353 | |||
| 1354 | QJsonObject failedRequests; | ||
| 1355 | failedRequests["atp"] = statTracker->getStat(STAT_ATP_REQUEST_FAILED).toInt(); | ||
| 1356 | failedRequests["http"] = statTracker->getStat(STAT_HTTP_REQUEST_FAILED).toInt(); | ||
| 1357 | failedRequests["file"] = statTracker->getStat(STAT_FILE_REQUEST_FAILED).toInt(); | ||
| 1358 | failedRequests["total"] = failedRequests["atp"].toInt() + failedRequests["http"].toInt() | ||
| 1359 | + failedRequests["file"].toInt(); | ||
| 1360 | properties["failed_requests"] = failedRequests; | ||
| 1361 | |||
| 1362 | QJsonObject cacheRequests; | ||
| 1363 | cacheRequests["atp"] = statTracker->getStat(STAT_ATP_REQUEST_CACHE).toInt(); | ||
| 1364 | cacheRequests["http"] = statTracker->getStat(STAT_HTTP_REQUEST_CACHE).toInt(); | ||
| 1365 | cacheRequests["total"] = cacheRequests["atp"].toInt() + cacheRequests["http"].toInt(); | ||
| 1366 | properties["cache_requests"] = cacheRequests; | ||
| 1367 | |||
| 1368 | QJsonObject atpMappingRequests; | ||
| 1369 | atpMappingRequests["started"] = statTracker->getStat(STAT_ATP_MAPPING_REQUEST_STARTED).toInt(); | ||
| 1370 | atpMappingRequests["failed"] = statTracker->getStat(STAT_ATP_MAPPING_REQUEST_FAILED).toInt(); | ||
| 1371 | atpMappingRequests["successful"] = statTracker->getStat(STAT_ATP_MAPPING_REQUEST_SUCCESS).toInt(); | ||
| 1372 | properties["atp_mapping_requests"] = atpMappingRequests; | ||
| 1327 | 1373 | ||
| 1328 | properties["throttled"] = _displayPlugin ? _displayPlugin->isThrottled() : false; | 1374 | properties["throttled"] = _displayPlugin ? _displayPlugin->isThrottled() : false; |
| 1329 | 1375 | ||
| @@ -1339,9 +1385,43 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 9 unmodified lines | |||
| 1339 | properties["deleted_entity_cnt"] = entityActivityTracking.deletedEntityCount; | 1385 | properties["deleted_entity_cnt"] = entityActivityTracking.deletedEntityCount; |
| 1340 | properties["edited_entity_cnt"] = entityActivityTracking.editedEntityCount; | 1386 | properties["edited_entity_cnt"] = entityActivityTracking.editedEntityCount; |
| 1341 | 1387 | ||
| 1388 | NodeToOctreeSceneStats* octreeServerSceneStats = getOcteeSceneStats(); | ||
| 1389 | unsigned long totalServerOctreeElements = 0; | ||
| 1390 | for (NodeToOctreeSceneStatsIterator i = octreeServerSceneStats->begin(); i != octreeServerSceneStats->end(); i++) { | ||
| 1391 | totalServerOctreeElements += i->second.getTotalElements(); | ||
| 1392 | } | ||
| 1393 | |||
| 1394 | properties["local_octree_elements"] = (qint64) OctreeElement::getInternalNodeCount(); | ||
| 1395 | properties["server_octree_elements"] = (qint64) totalServerOctreeElements; | ||
| 1396 | |||
| 1342 | properties["active_display_plugin"] = getActiveDisplayPlugin()->getName(); | 1397 | properties["active_display_plugin"] = getActiveDisplayPlugin()->getName(); |
| 1343 | properties["using_hmd"] = isHMDMode(); | 1398 | properties["using_hmd"] = isHMDMode(); |
| 1344 | 1399 | ||
| 1400 | _autoSwitchDisplayModeSupportedHMDPlugin = nullptr; | ||
| 1401 | foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) { | ||
| 1402 | if (displayPlugin->isHmd() && | ||
| 1403 | displayPlugin->getSupportsAutoSwitch()) { | ||
| 1404 | _autoSwitchDisplayModeSupportedHMDPlugin = displayPlugin; | ||
| 1405 | _autoSwitchDisplayModeSupportedHMDPluginName = | ||
| 1406 | _autoSwitchDisplayModeSupportedHMDPlugin->getName(); | ||
| 1407 | _previousHMDWornStatus = | ||
| 1408 | _autoSwitchDisplayModeSupportedHMDPlugin->isDisplayVisible(); | ||
| 1409 | break; | ||
| 1410 | } | ||
| 1411 | } | ||
| 1412 | |||
| 1413 | if (_autoSwitchDisplayModeSupportedHMDPlugin) { | ||
| 1414 | if (getActiveDisplayPlugin() != _autoSwitchDisplayModeSupportedHMDPlugin && | ||
| 1415 | !_autoSwitchDisplayModeSupportedHMDPlugin->isSessionActive()) { | ||
| 1416 | startHMDStandBySession(); | ||
| 1417 | } | ||
| 1418 | // Poll periodically to check whether the user has worn HMD or not. Switch Display mode accordingly. | ||
| 1419 | // If the user wears HMD then switch to VR mode. If the user removes HMD then switch to Desktop mode. | ||
| 1420 | QTimer* autoSwitchDisplayModeTimer = new QTimer(this); | ||
| 1421 | connect(autoSwitchDisplayModeTimer, SIGNAL(timeout()), this, SLOT(switchDisplayMode())); | ||
| 1422 | autoSwitchDisplayModeTimer->start(INTERVAL_TO_CHECK_HMD_WORN_STATUS); | ||
| 1423 | } | ||
| 1424 | |||
| 1345 | auto glInfo = getGLContextData(); | 1425 | auto glInfo = getGLContextData(); |
| 1346 | properties["gl_info"] = glInfo; | 1426 | properties["gl_info"] = glInfo; |
| 1347 | properties["gpu_used_memory"] = (int)BYTES_TO_MB(gpu::Context::getUsedGPUMemSize()); | 1427 | properties["gpu_used_memory"] = (int)BYTES_TO_MB(gpu::Context::getUsedGPUMemSize()); |
| @@ -1364,6 +1444,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 16 unmodified lines | |||
| 1364 | lastLeftHandPose = leftHandPose; | 1444 | lastLeftHandPose = leftHandPose; |
| 1365 | lastRightHandPose = rightHandPose; | 1445 | lastRightHandPose = rightHandPose; |
| 1366 | 1446 | ||
| 1447 | properties["local_socket_changes"] = DependencyManager::get<StatTracker>()->getStat(LOCAL_SOCKET_CHANGE_STAT).toInt(); | ||
| 1448 | |||
| 1367 | UserActivityLogger::getInstance().logAction("stats", properties); | 1449 | UserActivityLogger::getInstance().logAction("stats", properties); |
| 1368 | }); | 1450 | }); |
| 1369 | sendStatsTimer->start(); | 1451 | sendStatsTimer->start(); |
| @@ -1463,6 +1545,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 93 unmodified lines | |||
| 1463 | updateSystemTabletMode(); | 1545 | updateSystemTabletMode(); |
| 1464 | 1546 | ||
| 1465 | connect(&_myCamera, &Camera::modeUpdated, this, &Application::cameraModeChanged); | 1547 | connect(&_myCamera, &Camera::modeUpdated, this, &Application::cameraModeChanged); |
| 1548 | |||
| 1549 | qCDebug(interfaceapp) << "Metaverse session ID is" << uuidStringWithoutCurlyBraces(accountManager->getSessionID()); | ||
| 1466 | } | 1550 | } |
| 1467 | 1551 | ||
| 1468 | void Application::domainConnectionRefused(const QString& reasonMessage, int reasonCodeInt, const QString& extraInfo) { | 1552 | void Application::domainConnectionRefused(const QString& reasonMessage, int reasonCodeInt, const QString& extraInfo) { |
| @@ -1571,6 +1655,12 @@ void Application::aboutToQuit() { · 102 unmodified lines | |||
| 1571 | } | 1655 | } |
| 1572 | 1656 | ||
| 1573 | getActiveDisplayPlugin()->deactivate(); | 1657 | getActiveDisplayPlugin()->deactivate(); |
| 1658 | if (_autoSwitchDisplayModeSupportedHMDPlugin | ||
| 1659 | && _autoSwitchDisplayModeSupportedHMDPlugin->isSessionActive()) { | ||
| 1660 | _autoSwitchDisplayModeSupportedHMDPlugin->endSession(); | ||
| 1661 | } | ||
| 1662 | // use the CloseEventSender via a QThread to send an event that says the user asked for the app to close | ||
| 1663 | DependencyManager::get<CloseEventSender>()->startThread(); | ||
| 1574 | 1664 | ||
| 1575 | // Hide Running Scripts dialog so that it gets destroyed in an orderly manner; prevents warnings at shutdown. | 1665 | // Hide Running Scripts dialog so that it gets destroyed in an orderly manner; prevents warnings at shutdown. |
| 1576 | DependencyManager::get<OffscreenUi>()->hide("RunningScripts"); | 1666 | DependencyManager::get<OffscreenUi>()->hide("RunningScripts"); |
| @@ -1658,6 +1748,8 @@ void Application::cleanupBeforeQuit() { · 81 unmodified lines | |||
| 1658 | // stop QML | 1748 | // stop QML |
| 1659 | DependencyManager::destroy<OffscreenUi>(); | 1749 | DependencyManager::destroy<OffscreenUi>(); |
| 1660 | 1750 | ||
| 1751 | DependencyManager::destroy<OffscreenQmlSurfaceCache>(); | ||
| 1752 | |||
| 1661 | if (_snapshotSoundInjector != nullptr) { | 1753 | if (_snapshotSoundInjector != nullptr) { |
| 1662 | _snapshotSoundInjector->stop(); | 1754 | _snapshotSoundInjector->stop(); |
| 1663 | } | 1755 | } |
| @@ -1685,6 +1777,10 @@ Application::~Application() { · 21 unmodified lines | |||
| 1685 | 1777 | ||
| 1686 | _physicsEngine->setCharacterController(nullptr); | 1778 | _physicsEngine->setCharacterController(nullptr); |
| 1687 | 1779 | ||
| 1780 | // the _shapeManager should have zero references | ||
| 1781 | _shapeManager.collectGarbage(); | ||
| 1782 | assert(_shapeManager.getNumShapes() == 0); | ||
| 1783 | |||
| 1688 | // shutdown render engine | 1784 | // shutdown render engine |
| 1689 | _main3DScene = nullptr; | 1785 | _main3DScene = nullptr; |
| 1690 | _renderEngine = nullptr; | 1786 | _renderEngine = nullptr; |
| @@ -1713,15 +1809,9 @@ Application::~Application() { · 22 unmodified lines | |||
| 1713 | 1809 | ||
| 1714 | ResourceManager::cleanup(); | 1810 | ResourceManager::cleanup(); |
| 1715 | 1811 | ||
| 1716 | QThread* nodeThread = DependencyManager::get<NodeList>()->thread(); | ||
| 1717 | |||
| 1718 | // remove the NodeList from the DependencyManager | 1812 | // remove the NodeList from the DependencyManager |
| 1719 | DependencyManager::destroy<NodeList>(); | 1813 | DependencyManager::destroy<NodeList>(); |
| 1720 | 1814 | ||
| 1721 | // ask the node thread to quit and wait until it is done | ||
| 1722 | nodeThread->quit(); | ||
| 1723 | nodeThread->wait(); | ||
| 1724 | |||
| 1725 | Leapmotion::destroy(); | 1815 | Leapmotion::destroy(); |
| 1726 | 1816 | ||
| 1727 | if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { | 1817 | if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { |
| @@ -1736,6 +1826,15 @@ Application::~Application() { · 8 unmodified lines | |||
| 1736 | 1826 | ||
| 1737 | _window->deleteLater(); | 1827 | _window->deleteLater(); |
| 1738 | 1828 | ||
| 1829 | // make sure that the quit event has finished sending before we take the application down | ||
| 1830 | auto closeEventSender = DependencyManager::get<CloseEventSender>(); | ||
| 1831 | while (!closeEventSender->hasFinishedQuitEvent() && !closeEventSender->hasTimedOutQuitEvent()) { | ||
| 1832 | // sleep a little so we're not spinning at 100% | ||
| 1833 | std::this_thread::sleep_for(std::chrono::milliseconds(10)); | ||
| 1834 | } | ||
| 1835 | // quit the thread used by the closure event sender | ||
| 1836 | closeEventSender->thread()->quit(); | ||
| 1837 | |||
| 1739 | // Can't log to file passed this point, FileLogger about to be deleted | 1838 | // Can't log to file passed this point, FileLogger about to be deleted |
| 1740 | qInstallMessageHandler(LogHandler::verboseMessageHandler); | 1839 | qInstallMessageHandler(LogHandler::verboseMessageHandler); |
| 1741 | } | 1840 | } |
| @@ -1771,15 +1870,9 @@ void Application::initializeGL() { · 29 unmodified lines | |||
| 1771 | 1870 | ||
| 1772 | // Set up the render engine | 1871 | // Set up the render engine |
| 1773 | render::CullFunctor cullFunctor = LODManager::shouldRender; | 1872 | render::CullFunctor cullFunctor = LODManager::shouldRender; |
| 1774 | _renderEngine->addJob<RenderShadowTask>("RenderShadowTask", cullFunctor); | ||
| 1775 | const auto items = _renderEngine->addJob<RenderFetchCullSortTask>("FetchCullSort", cullFunctor); | ||
| 1776 | assert(items.canCast<RenderFetchCullSortTask::Output>()); | ||
| 1777 | static const QString RENDER_FORWARD = "HIFI_RENDER_FORWARD"; | 1873 | static const QString RENDER_FORWARD = "HIFI_RENDER_FORWARD"; |
| 1778 | if (QProcessEnvironment::systemEnvironment().contains(RENDER_FORWARD)) { | 1874 | bool isDeferred = !QProcessEnvironment::systemEnvironment().contains(RENDER_FORWARD); |
| 1779 | _renderEngine->addJob<RenderForwardTask>("Forward", items); | 1875 | _renderEngine->addJob<RenderViewTask>("RenderMainView", cullFunctor, isDeferred); |
| 1780 | } else { | ||
| 1781 | _renderEngine->addJob<RenderDeferredTask>("RenderDeferredTask", items); | ||
| 1782 | } | ||
| 1783 | _renderEngine->load(); | 1876 | _renderEngine->load(); |
| 1784 | _renderEngine->registerScene(_main3DScene); | 1877 | _renderEngine->registerScene(_main3DScene); |
| 1785 | 1878 | ||
| @@ -1828,14 +1921,10 @@ void Application::initializeUi() { · 42 unmodified lines | |||
| 1828 | UpdateDialog::registerType(); | 1921 | UpdateDialog::registerType(); |
| 1829 | qmlRegisterType<Preference>("Hifi", 1, 0, "Preference"); | 1922 | qmlRegisterType<Preference>("Hifi", 1, 0, "Preference"); |
| 1830 | 1923 | ||
| 1831 | qmlRegisterType<HFWebEngineProfile>("HFWebEngineProfile", 1, 0, "HFWebEngineProfile"); | ||
| 1832 | qmlRegisterType<HFTabletWebEngineProfile>("HFTabletWebEngineProfile", 1, 0, "HFTabletWebEngineProfile"); | ||
| 1833 | qmlRegisterType<FileTypeProfile>("FileTypeProfile", 1, 0, "FileTypeProfile"); | ||
| 1834 | |||
| 1835 | auto offscreenUi = DependencyManager::get<OffscreenUi>(); | 1924 | auto offscreenUi = DependencyManager::get<OffscreenUi>(); |
| 1836 | offscreenUi->create(_glWidget->qglContext()); | 1925 | offscreenUi->create(_glWidget->qglContext()); |
| 1837 | 1926 | ||
| 1838 | auto rootContext = offscreenUi->getRootContext(); | 1927 | auto surfaceContext = offscreenUi->getSurfaceContext(); |
| 1839 | 1928 | ||
| 1840 | offscreenUi->setProxyWindow(_window->windowHandle()); | 1929 | offscreenUi->setProxyWindow(_window->windowHandle()); |
| 1841 | offscreenUi->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/")); | 1930 | offscreenUi->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/")); |
| @@ -1847,7 +1936,7 @@ void Application::initializeUi() { · 5 unmodified lines | |||
| 1847 | // do better detection in the offscreen UI of what has focus | 1936 | // do better detection in the offscreen UI of what has focus |
| 1848 | offscreenUi->setNavigationFocused(false); | 1937 | offscreenUi->setNavigationFocused(false); |
| 1849 | 1938 | ||
| 1850 | auto engine = rootContext->engine(); | 1939 | auto engine = surfaceContext->engine(); |
| 1851 | connect(engine, &QQmlEngine::quit, [] { | 1940 | connect(engine, &QQmlEngine::quit, [] { |
| 1852 | qApp->quit(); | 1941 | qApp->quit(); |
| 1853 | }); | 1942 | }); |
| @@ -1856,78 +1945,77 @@ void Application::initializeUi() { · 2 unmodified lines | |||
| 1856 | 1945 | ||
| 1857 | // For some reason there is already an "Application" object in the QML context, | 1946 | // For some reason there is already an "Application" object in the QML context, |
| 1858 | // though I can't find it. Hence, "ApplicationInterface" | 1947 | // though I can't find it. Hence, "ApplicationInterface" |
| 1859 | rootContext->setContextProperty("ApplicationInterface", this); | 1948 | surfaceContext->setContextProperty("Audio", DependencyManager::get<AudioScriptingInterface>().data()); |
| 1860 | rootContext->setContextProperty("Audio", DependencyManager::get<AudioScriptingInterface>().data()); | 1949 | surfaceContext->setContextProperty("AudioStats", DependencyManager::get<AudioClient>()->getStats().data()); |
| 1861 | rootContext->setContextProperty("AudioStats", DependencyManager::get<AudioClient>()->getStats().data()); | 1950 | surfaceContext->setContextProperty("AudioScope", DependencyManager::get<AudioScope>().data()); |
| 1862 | rootContext->setContextProperty("AudioScope", DependencyManager::get<AudioScope>().data()); | ||
| 1863 | 1951 | ||
| 1864 | rootContext->setContextProperty("Controller", DependencyManager::get<controller::ScriptingInterface>().data()); | 1952 | surfaceContext->setContextProperty("Controller", DependencyManager::get<controller::ScriptingInterface>().data()); |
| 1865 | rootContext->setContextProperty("Entities", DependencyManager::get<EntityScriptingInterface>().data()); | 1953 | surfaceContext->setContextProperty("Entities", DependencyManager::get<EntityScriptingInterface>().data()); |
| 1866 | _fileDownload = new FileScriptingInterface(engine); | 1954 | _fileDownload = new FileScriptingInterface(engine); |
| 1867 | rootContext->setContextProperty("File", _fileDownload); | 1955 | surfaceContext->setContextProperty("File", _fileDownload); |
| 1868 | connect(_fileDownload, &FileScriptingInterface::unzipResult, this, &Application::handleUnzip); | 1956 | connect(_fileDownload, &FileScriptingInterface::unzipResult, this, &Application::handleUnzip); |
| 1869 | rootContext->setContextProperty("MyAvatar", getMyAvatar().get()); | 1957 | surfaceContext->setContextProperty("MyAvatar", getMyAvatar().get()); |
| 1870 | rootContext->setContextProperty("Messages", DependencyManager::get<MessagesClient>().data()); | 1958 | surfaceContext->setContextProperty("Messages", DependencyManager::get<MessagesClient>().data()); |
| 1871 | rootContext->setContextProperty("Recording", DependencyManager::get<RecordingScriptingInterface>().data()); | 1959 | surfaceContext->setContextProperty("Recording", DependencyManager::get<RecordingScriptingInterface>().data()); |
| 1872 | rootContext->setContextProperty("Preferences", DependencyManager::get<Preferences>().data()); | 1960 | surfaceContext->setContextProperty("Preferences", DependencyManager::get<Preferences>().data()); |
| 1873 | rootContext->setContextProperty("AddressManager", DependencyManager::get<AddressManager>().data()); | 1961 | surfaceContext->setContextProperty("AddressManager", DependencyManager::get<AddressManager>().data()); |
| 1874 | rootContext->setContextProperty("FrameTimings", &_frameTimingsScriptingInterface); | 1962 | surfaceContext->setContextProperty("FrameTimings", &_frameTimingsScriptingInterface); |
| 1875 | rootContext->setContextProperty("Rates", new RatesScriptingInterface(this)); | 1963 | surfaceContext->setContextProperty("Rates", new RatesScriptingInterface(this)); |
| 1876 | rootContext->setContextProperty("pathToFonts", "../../"); | ||
| 1877 | 1964 | ||
| 1878 | rootContext->setContextProperty("TREE_SCALE", TREE_SCALE); | 1965 | surfaceContext->setContextProperty("TREE_SCALE", TREE_SCALE); |
| 1879 | rootContext->setContextProperty("Quat", new Quat()); | 1966 | // FIXME Quat and Vec3 won't work with QJSEngine used by QML |
| 1880 | rootContext->setContextProperty("Vec3", new Vec3()); | 1967 | surfaceContext->setContextProperty("Quat", new Quat()); |
| 1881 | rootContext->setContextProperty("Uuid", new ScriptUUID()); | 1968 | surfaceContext->setContextProperty("Vec3", new Vec3()); |
| 1882 | rootContext->setContextProperty("Assets", DependencyManager::get<AssetMappingsScriptingInterface>().data()); | 1969 | surfaceContext->setContextProperty("Uuid", new ScriptUUID()); |
| 1970 | surfaceContext->setContextProperty("Assets", DependencyManager::get<AssetMappingsScriptingInterface>().data()); | ||
| 1883 | 1971 | ||
| 1884 | rootContext->setContextProperty("AvatarList", DependencyManager::get<AvatarManager>().data()); | 1972 | surfaceContext->setContextProperty("AvatarList", DependencyManager::get<AvatarManager>().data()); |
| 1885 | rootContext->setContextProperty("Users", DependencyManager::get<UsersScriptingInterface>().data()); | 1973 | surfaceContext->setContextProperty("Users", DependencyManager::get<UsersScriptingInterface>().data()); |
| 1886 | 1974 | ||
| 1887 | rootContext->setContextProperty("UserActivityLogger", DependencyManager::get<UserActivityLoggerScriptingInterface>().data()); | 1975 | surfaceContext->setContextProperty("UserActivityLogger", DependencyManager::get<UserActivityLoggerScriptingInterface>().data()); |
| 1888 | 1976 | ||
| 1889 | rootContext->setContextProperty("Camera", &_myCamera); | 1977 | surfaceContext->setContextProperty("Camera", &_myCamera); |
| 1890 | 1978 | ||
| 1891 | #if defined(Q_OS_MAC) || defined(Q_OS_WIN) | 1979 | #if defined(Q_OS_MAC) || defined(Q_OS_WIN) |
| 1892 | rootContext->setContextProperty("SpeechRecognizer", DependencyManager::get<SpeechRecognizer>().data()); | 1980 | surfaceContext->setContextProperty("SpeechRecognizer", DependencyManager::get<SpeechRecognizer>().data()); |
| 1893 | #endif | 1981 | #endif |
| 1894 | 1982 | ||
| 1895 | rootContext->setContextProperty("Overlays", &_overlays); | 1983 | surfaceContext->setContextProperty("Overlays", &_overlays); |
| 1896 | rootContext->setContextProperty("Window", DependencyManager::get<WindowScriptingInterface>().data()); | 1984 | surfaceContext->setContextProperty("Window", DependencyManager::get<WindowScriptingInterface>().data()); |
| 1897 | rootContext->setContextProperty("MenuInterface", MenuScriptingInterface::getInstance()); | 1985 | surfaceContext->setContextProperty("MenuInterface", MenuScriptingInterface::getInstance()); |
| 1898 | rootContext->setContextProperty("Stats", Stats::getInstance()); | 1986 | surfaceContext->setContextProperty("Stats", Stats::getInstance()); |
| 1899 | rootContext->setContextProperty("Settings", SettingsScriptingInterface::getInstance()); | 1987 | surfaceContext->setContextProperty("Settings", SettingsScriptingInterface::getInstance()); |
| 1900 | rootContext->setContextProperty("ScriptDiscoveryService", DependencyManager::get<ScriptEngines>().data()); | 1988 | surfaceContext->setContextProperty("ScriptDiscoveryService", DependencyManager::get<ScriptEngines>().data()); |
| 1901 | rootContext->setContextProperty("AvatarBookmarks", DependencyManager::get<AvatarBookmarks>().data()); | 1989 | surfaceContext->setContextProperty("AvatarBookmarks", DependencyManager::get<AvatarBookmarks>().data()); |
| 1902 | rootContext->setContextProperty("LocationBookmarks", DependencyManager::get<LocationBookmarks>().data()); | 1990 | surfaceContext->setContextProperty("LocationBookmarks", DependencyManager::get<LocationBookmarks>().data()); |
| 1903 | 1991 | ||
| 1904 | // Caches | 1992 | // Caches |
| 1905 | rootContext->setContextProperty("AnimationCache", DependencyManager::get<AnimationCache>().data()); | 1993 | surfaceContext->setContextProperty("AnimationCache", DependencyManager::get<AnimationCache>().data()); |
| 1906 | rootContext->setContextProperty("TextureCache", DependencyManager::get<TextureCache>().data()); | 1994 | surfaceContext->setContextProperty("TextureCache", DependencyManager::get<TextureCache>().data()); |
| 1907 | rootContext->setContextProperty("ModelCache", DependencyManager::get<ModelCache>().data()); | 1995 | surfaceContext->setContextProperty("ModelCache", DependencyManager::get<ModelCache>().data()); |
| 1908 | rootContext->setContextProperty("SoundCache", DependencyManager::get<SoundCache>().data()); | 1996 | surfaceContext->setContextProperty("SoundCache", DependencyManager::get<SoundCache>().data()); |
| 1909 | 1997 | ||
| 1910 | rootContext->setContextProperty("Account", AccountScriptingInterface::getInstance()); | 1998 | surfaceContext->setContextProperty("Account", AccountScriptingInterface::getInstance()); |
| 1911 | rootContext->setContextProperty("Tablet", DependencyManager::get<TabletScriptingInterface>().data()); | 1999 | surfaceContext->setContextProperty("Tablet", DependencyManager::get<TabletScriptingInterface>().data()); |
| 1912 | rootContext->setContextProperty("DialogsManager", _dialogsManagerScriptingInterface); | 2000 | surfaceContext->setContextProperty("DialogsManager", _dialogsManagerScriptingInterface); |
| 1913 | rootContext->setContextProperty("GlobalServices", GlobalServicesScriptingInterface::getInstance()); | 2001 | surfaceContext->setContextProperty("GlobalServices", GlobalServicesScriptingInterface::getInstance()); |
| 1914 | rootContext->setContextProperty("FaceTracker", DependencyManager::get<DdeFaceTracker>().data()); | 2002 | surfaceContext->setContextProperty("FaceTracker", DependencyManager::get<DdeFaceTracker>().data()); |
| 1915 | rootContext->setContextProperty("AvatarManager", DependencyManager::get<AvatarManager>().data()); | 2003 | surfaceContext->setContextProperty("AvatarManager", DependencyManager::get<AvatarManager>().data()); |
| 1916 | rootContext->setContextProperty("UndoStack", &_undoStackScriptingInterface); | 2004 | surfaceContext->setContextProperty("UndoStack", &_undoStackScriptingInterface); |
| 1917 | rootContext->setContextProperty("LODManager", DependencyManager::get<LODManager>().data()); | 2005 | surfaceContext->setContextProperty("LODManager", DependencyManager::get<LODManager>().data()); |
| 1918 | rootContext->setContextProperty("Paths", DependencyManager::get<PathUtils>().data()); | 2006 | surfaceContext->setContextProperty("Paths", DependencyManager::get<PathUtils>().data()); |
| 1919 | rootContext->setContextProperty("HMD", DependencyManager::get<HMDScriptingInterface>().data()); | 2007 | surfaceContext->setContextProperty("HMD", DependencyManager::get<HMDScriptingInterface>().data()); |
| 1920 | rootContext->setContextProperty("Scene", DependencyManager::get<SceneScriptingInterface>().data()); | 2008 | surfaceContext->setContextProperty("Scene", DependencyManager::get<SceneScriptingInterface>().data()); |
| 1921 | rootContext->setContextProperty("Render", _renderEngine->getConfiguration().get()); | 2009 | surfaceContext->setContextProperty("Render", _renderEngine->getConfiguration().get()); |
| 1922 | rootContext->setContextProperty("Reticle", getApplicationCompositor().getReticleInterface()); | 2010 | surfaceContext->setContextProperty("Reticle", getApplicationCompositor().getReticleInterface()); |
| 1923 | rootContext->setContextProperty("Snapshot", DependencyManager::get<Snapshot>().data()); | 2011 | surfaceContext->setContextProperty("Snapshot", DependencyManager::get<Snapshot>().data()); |
| 1924 | 2012 | ||
| 1925 | rootContext->setContextProperty("ApplicationCompositor", &getApplicationCompositor()); | 2013 | surfaceContext->setContextProperty("ApplicationCompositor", &getApplicationCompositor()); |
| 1926 | 2014 | ||
| 1927 | rootContext->setContextProperty("AvatarInputs", AvatarInputs::getInstance()); | 2015 | surfaceContext->setContextProperty("AvatarInputs", AvatarInputs::getInstance()); |
| 1928 | 2016 | ||
| 1929 | if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { | 2017 | if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { |
| 1930 | rootContext->setContextProperty("Steam", new SteamScriptingInterface(engine, steamClient.get())); | 2018 | surfaceContext->setContextProperty("Steam", new SteamScriptingInterface(engine, steamClient.get())); |
| 1931 | } | 2019 | } |
| 1932 | 2020 | ||
| 1933 | 2021 | ||
| @@ -2066,7 +2154,7 @@ void Application::paintGL() { · 132 unmodified lines | |||
| 2066 | _myCamera.setOrientation(glm::quat_cast(camMat)); | 2154 | _myCamera.setOrientation(glm::quat_cast(camMat)); |
| 2067 | } else { | 2155 | } else { |
| 2068 | _myCamera.setPosition(myAvatar->getDefaultEyePosition()); | 2156 | _myCamera.setPosition(myAvatar->getDefaultEyePosition()); |
| 2069 | _myCamera.setOrientation(myAvatar->getMyHead()->getCameraOrientation()); | 2157 | _myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation()); |
| 2070 | } | 2158 | } |
| 2071 | } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { | 2159 | } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { |
| 2072 | if (isHMDMode()) { | 2160 | if (isHMDMode()) { |
| @@ -2186,6 +2274,9 @@ void Application::paintGL() { · 113 unmodified lines | |||
| 2186 | }); | 2274 | }); |
| 2187 | renderArgs._context->setStereoProjections(eyeProjections); | 2275 | renderArgs._context->setStereoProjections(eyeProjections); |
| 2188 | renderArgs._context->setStereoViews(eyeOffsets); | 2276 | renderArgs._context->setStereoViews(eyeOffsets); |
| 2277 | |||
| 2278 | // Configure the type of display / stereo | ||
| 2279 | renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); | ||
| 2189 | } | 2280 | } |
| 2190 | renderArgs._blitFramebuffer = finalFramebuffer; | 2281 | renderArgs._blitFramebuffer = finalFramebuffer; |
| 2191 | displaySide(&renderArgs, _myCamera); | 2282 | displaySide(&renderArgs, _myCamera); |
| @@ -2379,15 +2470,16 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { · 187 unmodified lines | |||
| 2379 | 2470 | ||
| 2380 | // Check HMD use (may be technically available without being in use) | 2471 | // Check HMD use (may be technically available without being in use) |
| 2381 | bool hasHMD = PluginUtils::isHMDAvailable(); | 2472 | bool hasHMD = PluginUtils::isHMDAvailable(); |
| 2382 | bool isUsingHMD = hasHMD && hasHandControllers && _displayPlugin->isHmd(); | 2473 | bool isUsingHMD = _displayPlugin->isHmd(); |
| 2474 | bool isUsingHMDAndHandControllers = hasHMD && hasHandControllers && isUsingHMD; | ||
| 2383 | 2475 | ||
| 2384 | Setting::Handle<bool> tutorialComplete{ "tutorialComplete", false }; | 2476 | Setting::Handle<bool> tutorialComplete{ "tutorialComplete", false }; |
| 2385 | Setting::Handle<bool> firstRun{ Settings::firstRun, true }; | 2477 | Setting::Handle<bool> firstRun{ Settings::firstRun, true }; |
| 2386 | 2478 | ||
| 2387 | bool isTutorialComplete = tutorialComplete.get(); | 2479 | bool isTutorialComplete = tutorialComplete.get(); |
| 2388 | bool shouldGoToTutorial = isUsingHMD && hasTutorialContent && !isTutorialComplete; | 2480 | bool shouldGoToTutorial = isUsingHMDAndHandControllers && hasTutorialContent && !isTutorialComplete; |
| 2389 | 2481 | ||
| 2390 | qCDebug(interfaceapp) << "HMD:" << hasHMD << ", Hand Controllers: " << hasHandControllers << ", Using HMD: " << isUsingHMD; | 2482 | qCDebug(interfaceapp) << "HMD:" << hasHMD << ", Hand Controllers: " << hasHandControllers << ", Using HMD: " << isUsingHMDAndHandControllers; |
| 2391 | qCDebug(interfaceapp) << "Tutorial version:" << contentVersion << ", sufficient:" << hasTutorialContent << | 2483 | qCDebug(interfaceapp) << "Tutorial version:" << contentVersion << ", sufficient:" << hasTutorialContent << |
| 2392 | ", complete:" << isTutorialComplete << ", should go:" << shouldGoToTutorial; | 2484 | ", complete:" << isTutorialComplete << ", should go:" << shouldGoToTutorial; |
| 2393 | 2485 | ||
| @@ -2401,10 +2493,18 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { · 7 unmodified lines | |||
| 2401 | 2493 | ||
| 2402 | const QString TUTORIAL_PATH = "/tutorial_begin"; | 2494 | const QString TUTORIAL_PATH = "/tutorial_begin"; |
| 2403 | 2495 | ||
| 2496 | static const QString SENT_TO_TUTORIAL = "tutorial"; | ||
| 2497 | static const QString SENT_TO_PREVIOUS_LOCATION = "previous_location"; | ||
| 2498 | static const QString SENT_TO_ENTRY = "entry"; | ||
| 2499 | static const QString SENT_TO_SANDBOX = "sandbox"; | ||
| 2500 | |||
| 2501 | QString sentTo; | ||
| 2502 | |||
| 2404 | if (shouldGoToTutorial) { | 2503 | if (shouldGoToTutorial) { |
| 2405 | if (sandboxIsRunning) { | 2504 | if (sandboxIsRunning) { |
| 2406 | qCDebug(interfaceapp) << "Home sandbox appears to be running, going to Home."; | 2505 | qCDebug(interfaceapp) << "Home sandbox appears to be running, going to Home."; |
| 2407 | DependencyManager::get<AddressManager>()->goToLocalSandbox(TUTORIAL_PATH); | 2506 | DependencyManager::get<AddressManager>()->goToLocalSandbox(TUTORIAL_PATH); |
| 2507 | sentTo = SENT_TO_TUTORIAL; | ||
| 2408 | } else { | 2508 | } else { |
| 2409 | qCDebug(interfaceapp) << "Home sandbox does not appear to be running, going to Entry."; | 2509 | qCDebug(interfaceapp) << "Home sandbox does not appear to be running, going to Entry."; |
| 2410 | if (firstRun.get()) { | 2510 | if (firstRun.get()) { |
| @@ -2412,8 +2512,10 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { · 1 unmodified line | |||
| 2412 | } | 2512 | } |
| 2413 | if (addressLookupString.isEmpty()) { | 2513 | if (addressLookupString.isEmpty()) { |
| 2414 | DependencyManager::get<AddressManager>()->goToEntry(); | 2514 | DependencyManager::get<AddressManager>()->goToEntry(); |
| 2515 | sentTo = SENT_TO_ENTRY; | ||
| 2415 | } else { | 2516 | } else { |
| 2416 | DependencyManager::get<AddressManager>()->loadSettings(addressLookupString); | 2517 | DependencyManager::get<AddressManager>()->loadSettings(addressLookupString); |
| 2518 | sentTo = SENT_TO_PREVIOUS_LOCATION; | ||
| 2417 | } | 2519 | } |
| 2418 | } | 2520 | } |
| 2419 | } else { | 2521 | } else { |
| @@ -2426,23 +2528,40 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { · 6 unmodified lines | |||
| 2426 | 2528 | ||
| 2427 | // If this is a first run we short-circuit the address passed in | 2529 | // If this is a first run we short-circuit the address passed in |
| 2428 | if (isFirstRun) { | 2530 | if (isFirstRun) { |
| 2429 | if (isUsingHMD) { | 2531 | if (isUsingHMDAndHandControllers) { |
| 2430 | if (sandboxIsRunning) { | 2532 | if (sandboxIsRunning) { |
| 2431 | qCDebug(interfaceapp) << "Home sandbox appears to be running, going to Home."; | 2533 | qCDebug(interfaceapp) << "Home sandbox appears to be running, going to Home."; |
| 2432 | DependencyManager::get<AddressManager>()->goToLocalSandbox(); | 2534 | DependencyManager::get<AddressManager>()->goToLocalSandbox(); |
| 2535 | sentTo = SENT_TO_SANDBOX; | ||
| 2433 | } else { | 2536 | } else { |
| 2434 | qCDebug(interfaceapp) << "Home sandbox does not appear to be running, going to Entry."; | 2537 | qCDebug(interfaceapp) << "Home sandbox does not appear to be running, going to Entry."; |
| 2435 | DependencyManager::get<AddressManager>()->goToEntry(); | 2538 | DependencyManager::get<AddressManager>()->goToEntry(); |
| 2539 | sentTo = SENT_TO_ENTRY; | ||
| 2436 | } | 2540 | } |
| 2437 | } else { | 2541 | } else { |
| 2438 | DependencyManager::get<AddressManager>()->goToEntry(); | 2542 | DependencyManager::get<AddressManager>()->goToEntry(); |
| 2543 | sentTo = SENT_TO_ENTRY; | ||
| 2439 | } | 2544 | } |
| 2440 | } else { | 2545 | } else { |
| 2441 | qCDebug(interfaceapp) << "Not first run... going to" << qPrintable(addressLookupString.isEmpty() ? QString("previous location") : addressLookupString); | 2546 | qCDebug(interfaceapp) << "Not first run... going to" << qPrintable(addressLookupString.isEmpty() ? QString("previous location") : addressLookupString); |
| 2442 | DependencyManager::get<AddressManager>()->loadSettings(addressLookupString); | 2547 | DependencyManager::get<AddressManager>()->loadSettings(addressLookupString); |
| 2548 | sentTo = SENT_TO_PREVIOUS_LOCATION; | ||
| 2443 | } | 2549 | } |
| 2444 | } | 2550 | } |
| 2445 | 2551 | ||
| 2552 | UserActivityLogger::getInstance().logAction("startup_sent_to", { | ||
| 2553 | { "sent_to", sentTo }, | ||
| 2554 | { "sandbox_is_running", sandboxIsRunning }, | ||
| 2555 | { "has_hmd", hasHMD }, | ||
| 2556 | { "has_hand_controllers", hasHandControllers }, | ||
| 2557 | { "is_using_hmd", isUsingHMD }, | ||
| 2558 | { "is_using_hmd_and_hand_controllers", isUsingHMDAndHandControllers }, | ||
| 2559 | { "content_version", contentVersion }, | ||
| 2560 | { "is_tutorial_complete", isTutorialComplete }, | ||
| 2561 | { "has_tutorial_content", hasTutorialContent }, | ||
| 2562 | { "should_go_to_tutorial", shouldGoToTutorial } | ||
| 2563 | }); | ||
| 2564 | |||
| 2446 | _connectionMonitor.init(); | 2565 | _connectionMonitor.init(); |
| 2447 | 2566 | ||
| 2448 | // After all of the constructor is completed, then set firstRun to false. | 2567 | // After all of the constructor is completed, then set firstRun to false. |
| @@ -2777,6 +2896,17 @@ void Application::keyPressEvent(QKeyEvent* event) { · 328 unmodified lines | |||
| 2777 | if (isShifted && isMeta && !isOption) { | 2896 | if (isShifted && isMeta && !isOption) { |
| 2778 | Menu::getInstance()->triggerOption(MenuOption::SuppressShortTimings); | 2897 | Menu::getInstance()->triggerOption(MenuOption::SuppressShortTimings); |
| 2779 | } else if (!isOption && !isShifted && isMeta) { | 2898 | } else if (!isOption && !isShifted && isMeta) { |
| 2899 | AudioInjectorOptions options; | ||
| 2900 | options.localOnly = true; | ||
| 2901 | options.stereo = true; | ||
| 2902 | |||
| 2903 | if (_snapshotSoundInjector) { | ||
| 2904 | _snapshotSoundInjector->setOptions(options); | ||
| 2905 | _snapshotSoundInjector->restart(); | ||
| 2906 | } else { | ||
| 2907 | QByteArray samples = _snapshotSound->getByteArray(); | ||
| 2908 | _snapshotSoundInjector = AudioInjector::playSound(samples, options); | ||
| 2909 | } | ||
| 2780 | takeSnapshot(true); | 2910 | takeSnapshot(true); |
| 2781 | } | 2911 | } |
| 2782 | break; | 2912 | break; |
| @@ -3951,6 +4081,7 @@ void Application::updateMyAvatarLookAtPosition() { · 1168 unmodified lines | |||
| 3951 | lookAtPosition.x = -lookAtPosition.x; | 4081 | lookAtPosition.x = -lookAtPosition.x; |
| 3952 | } | 4082 | } |
| 3953 | if (isHMD) { | 4083 | if (isHMD) { |
| 4084 | // TODO -- this code is probably wrong, getHeadPose() returns something in sensor frame, not avatar | ||
| 3954 | glm::mat4 headPose = getActiveDisplayPlugin()->getHeadPose(); | 4085 | glm::mat4 headPose = getActiveDisplayPlugin()->getHeadPose(); |
| 3955 | glm::quat hmdRotation = glm::quat_cast(headPose); | 4086 | glm::quat hmdRotation = glm::quat_cast(headPose); |
| 3956 | lookAtSpot = _myCamera.getPosition() + myAvatar->getOrientation() * (hmdRotation * lookAtPosition); | 4087 | lookAtSpot = _myCamera.getPosition() + myAvatar->getOrientation() * (hmdRotation * lookAtPosition); |
| @@ -3992,9 +4123,10 @@ void Application::updateMyAvatarLookAtPosition() { · 35 unmodified lines | |||
| 3992 | } | 4123 | } |
| 3993 | } else { | 4124 | } else { |
| 3994 | // I am not looking at anyone else, so just look forward | 4125 | // I am not looking at anyone else, so just look forward |
| 3995 | if (isHMD) { | 4126 | auto headPose = myAvatar->getHeadControllerPoseInSensorFrame(); |
| 3996 | glm::mat4 worldHMDMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); | 4127 | if (headPose.isValid()) { |
| 3997 | lookAtSpot = transformPoint(worldHMDMat, glm::vec3(0.0f, 0.0f, -TREE_SCALE)); | 4128 | glm::mat4 worldHeadMat = myAvatar->getSensorToWorldMatrix() * headPose.getMatrix(); |
| 4129 | lookAtSpot = transformPoint(worldHeadMat, glm::vec3(0.0f, 0.0f, TREE_SCALE)); | ||
| 3998 | } else { | 4130 | } else { |
| 3999 | lookAtSpot = myAvatar->getHead()->getEyePosition() + | 4131 | lookAtSpot = myAvatar->getHead()->getEyePosition() + |
| 4000 | (myAvatar->getHead()->getFinalOrientationInWorldFrame() * glm::vec3(0.0f, 0.0f, -TREE_SCALE)); | 4132 | (myAvatar->getHead()->getFinalOrientationInWorldFrame() * glm::vec3(0.0f, 0.0f, -TREE_SCALE)); |
| @@ -4492,12 +4624,13 @@ void Application::update(float deltaTime) { · 491 unmodified lines | |||
| 4492 | 4624 | ||
| 4493 | getEntities()->getTree()->withWriteLock([&] { | 4625 | getEntities()->getTree()->withWriteLock([&] { |
| 4494 | PerformanceTimer perfTimer("handleOutgoingChanges"); | 4626 | PerformanceTimer perfTimer("handleOutgoingChanges"); |
| 4495 | const VectorOfMotionStates& deactivations = _physicsEngine->getDeactivatedMotionStates(); | ||
| 4496 | _entitySimulation->handleDeactivatedMotionStates(deactivations); | ||
| 4497 | 4627 | ||
| 4498 | const VectorOfMotionStates& outgoingChanges = _physicsEngine->getChangedMotionStates(); | 4628 | const VectorOfMotionStates& outgoingChanges = _physicsEngine->getChangedMotionStates(); |
| 4499 | _entitySimulation->handleChangedMotionStates(outgoingChanges); | 4629 | _entitySimulation->handleChangedMotionStates(outgoingChanges); |
| 4500 | avatarManager->handleChangedMotionStates(outgoingChanges); | 4630 | avatarManager->handleChangedMotionStates(outgoingChanges); |
| 4631 | |||
| 4632 | const VectorOfMotionStates& deactivations = _physicsEngine->getDeactivatedMotionStates(); | ||
| 4633 | _entitySimulation->handleDeactivatedMotionStates(deactivations); | ||
| 4501 | }); | 4634 | }); |
| 4502 | 4635 | ||
| 4503 | if (!_aboutToQuit) { | 4636 | if (!_aboutToQuit) { |
| @@ -4885,12 +5018,6 @@ QRect Application::getDesirableApplicationGeometry() const { · 381 unmodified lines | |||
| 4885 | return applicationGeometry; | 5018 | return applicationGeometry; |
| 4886 | } | 5019 | } |
| 4887 | 5020 | ||
| 4888 | glm::vec3 Application::getSunDirection() const { | ||
| 4889 | // Sun direction is in fact just the location of the sun relative to the origin | ||
| 4890 | auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage(); | ||
| 4891 | return skyStage->getSunLight()->getDirection(); | ||
| 4892 | } | ||
| 4893 | |||
| 4894 | // FIXME, preprocessor guard this check to occur only in DEBUG builds | 5021 | // FIXME, preprocessor guard this check to occur only in DEBUG builds |
| 4895 | static QThread * activeRenderingThread = nullptr; | 5022 | static QThread * activeRenderingThread = nullptr; |
| 4896 | 5023 | ||
| @@ -4947,7 +5074,7 @@ namespace render { · 50 unmodified lines | |||
| 4947 | template <> const ItemKey payloadGetKey(const WorldBoxRenderData::Pointer& stuff) { return ItemKey::Builder::opaqueShape(); } | 5074 | template <> const ItemKey payloadGetKey(const WorldBoxRenderData::Pointer& stuff) { return ItemKey::Builder::opaqueShape(); } |
| 4948 | template <> const Item::Bound payloadGetBound(const WorldBoxRenderData::Pointer& stuff) { return Item::Bound(); } | 5075 | template <> const Item::Bound payloadGetBound(const WorldBoxRenderData::Pointer& stuff) { return Item::Bound(); } |
| 4949 | template <> void payloadRender(const WorldBoxRenderData::Pointer& stuff, RenderArgs* args) { | 5076 | template <> void payloadRender(const WorldBoxRenderData::Pointer& stuff, RenderArgs* args) { |
| 4950 | if (args->_renderMode != RenderArgs::MIRROR_RENDER_MODE && Menu::getInstance()->isOptionChecked(MenuOption::WorldAxes)) { | 5077 | if (Menu::getInstance()->isOptionChecked(MenuOption::WorldAxes)) { |
| 4951 | PerformanceTimer perfTimer("worldBox"); | 5078 | PerformanceTimer perfTimer("worldBox"); |
| 4952 | 5079 | ||
| 4953 | auto& batch = *args->_batch; | 5080 | auto& batch = *args->_batch; |
| @@ -4957,90 +5084,6 @@ namespace render { · 3 unmodified lines | |||
| 4957 | } | 5084 | } |
| 4958 | } | 5085 | } |
| 4959 | 5086 | ||
| 4960 | // Background Render Data & rendering functions | ||
| 4961 | class BackgroundRenderData { | ||
| 4962 | public: | ||
| 4963 | typedef render::Payload<BackgroundRenderData> Payload; | ||
| 4964 | typedef Payload::DataPointer Pointer; | ||
| 4965 | |||
| 4966 | static render::ItemID _item; // unique WorldBoxRenderData | ||
| 4967 | }; | ||
| 4968 | |||
| 4969 | render::ItemID BackgroundRenderData::_item = 0; | ||
| 4970 | |||
| 4971 | namespace render { | ||
| 4972 | template <> const ItemKey payloadGetKey(const BackgroundRenderData::Pointer& stuff) { | ||
| 4973 | return ItemKey::Builder::background(); | ||
| 4974 | } | ||
| 4975 | |||
| 4976 | template <> const Item::Bound payloadGetBound(const BackgroundRenderData::Pointer& stuff) { | ||
| 4977 | return Item::Bound(); | ||
| 4978 | } | ||
| 4979 | |||
| 4980 | template <> void payloadRender(const BackgroundRenderData::Pointer& background, RenderArgs* args) { | ||
| 4981 | Q_ASSERT(args->_batch); | ||
| 4982 | gpu::Batch& batch = *args->_batch; | ||
| 4983 | |||
| 4984 | // Background rendering decision | ||
| 4985 | auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage(); | ||
| 4986 | auto backgroundMode = skyStage->getBackgroundMode(); | ||
| 4987 | |||
| 4988 | switch (backgroundMode) { | ||
| 4989 | case model::SunSkyStage::SKY_DEFAULT: { | ||
| 4990 | auto scene = DependencyManager::get<SceneScriptingInterface>()->getStage(); | ||
| 4991 | auto sceneKeyLight = scene->getKeyLight(); | ||
| 4992 | |||
| 4993 | scene->setSunModelEnable(false); | ||
| 4994 | sceneKeyLight->setColor(ColorUtils::toVec3(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_COLOR)); | ||
| 4995 | sceneKeyLight->setIntensity(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_INTENSITY); | ||
| 4996 | sceneKeyLight->setAmbientIntensity(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_AMBIENT_INTENSITY); | ||
| 4997 | sceneKeyLight->setDirection(KeyLightPropertyGroup::DEFAULT_KEYLIGHT_DIRECTION); | ||
| 4998 | // fall through: render a skybox (if available), or the defaults (if requested) | ||
| 4999 | } | ||
| 5000 | |||
| 5001 | case model::SunSkyStage::SKY_BOX: { | ||
| 5002 | auto skybox = skyStage->getSkybox(); | ||
| 5003 | if (!skybox->empty()) { | ||
| 5004 | PerformanceTimer perfTimer("skybox"); | ||
| 5005 | skybox->render(batch, args->getViewFrustum()); | ||
| 5006 | break; | ||
| 5007 | } | ||
| 5008 | // fall through: render defaults (if requested) | ||
| 5009 | } | ||
| 5010 | |||
| 5011 | case model::SunSkyStage::SKY_DEFAULT_AMBIENT_TEXTURE: { | ||
| 5012 | if (Menu::getInstance()->isOptionChecked(MenuOption::DefaultSkybox)) { | ||
| 5013 | auto scene = DependencyManager::get<SceneScriptingInterface>()->getStage(); | ||
| 5014 | auto sceneKeyLight = scene->getKeyLight(); | ||
| 5015 | auto defaultSkyboxAmbientTexture = qApp->getDefaultSkyboxAmbientTexture(); | ||
| 5016 | if (defaultSkyboxAmbientTexture) { | ||
| 5017 | sceneKeyLight->setAmbientSphere(defaultSkyboxAmbientTexture->getIrradiance()); | ||
| 5018 | sceneKeyLight->setAmbientMap(defaultSkyboxAmbientTexture); | ||
| 5019 | } else { | ||
| 5020 | static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex( | ||
| 5021 | "Failed to get a valid Default Skybox Ambient Texture ? probably because it couldn't be find during initialization step"); | ||
| 5022 | } | ||
| 5023 | // fall through: render defaults skybox | ||
| 5024 | } else { | ||
| 5025 | break; | ||
| 5026 | } | ||
| 5027 | } | ||
| 5028 | |||
| 5029 | case model::SunSkyStage::SKY_DEFAULT_TEXTURE: | ||
| 5030 | if (Menu::getInstance()->isOptionChecked(MenuOption::DefaultSkybox)) { | ||
| 5031 | qApp->getDefaultSkybox()->render(batch, args->getViewFrustum()); | ||
| 5032 | } | ||
| 5033 | break; | ||
| 5034 | |||
| 5035 | // Any other cases require no extra rendering | ||
| 5036 | case model::SunSkyStage::NO_BACKGROUND: | ||
| 5037 | default: | ||
| 5038 | break; | ||
| 5039 | } | ||
| 5040 | } | ||
| 5041 | } | ||
| 5042 | |||
| 5043 | |||
| 5044 | void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool selfAvatarOnly) { | 5087 | void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool selfAvatarOnly) { |
| 5045 | 5088 | ||
| 5046 | // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. | 5089 | // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. |
| @@ -5064,15 +5107,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 17 unmodified lines | |||
| 5064 | // The pending changes collecting the changes here | 5107 | // The pending changes collecting the changes here |
| 5065 | render::Transaction transaction; | 5108 | render::Transaction transaction; |
| 5066 | 5109 | ||
| 5067 | // FIXME: Move this out of here!, Background / skybox should be driven by the enityt content just like the other entities | ||
| 5068 | // Background rendering decision | ||
| 5069 | if (!render::Item::isValidID(BackgroundRenderData::_item)) { | ||
| 5070 | auto backgroundRenderData = make_shared<BackgroundRenderData>(); | ||
| 5071 | auto backgroundRenderPayload = make_shared<BackgroundRenderData::Payload>(backgroundRenderData); | ||
| 5072 | BackgroundRenderData::_item = _main3DScene->allocateID(); | ||
| 5073 | transaction.resetItem(BackgroundRenderData::_item, backgroundRenderPayload); | ||
| 5074 | } | ||
| 5075 | |||
| 5076 | // Assuming nothing gets rendered through that | 5110 | // Assuming nothing gets rendered through that |
| 5077 | if (!selfAvatarOnly) { | 5111 | if (!selfAvatarOnly) { |
| 5078 | if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) { | 5112 | if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) { |
| @@ -5108,12 +5142,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 29 unmodified lines | |||
| 5108 | }); | 5142 | }); |
| 5109 | } | 5143 | } |
| 5110 | 5144 | ||
| 5111 | // Setup the current Zone Entity lighting | ||
| 5112 | { | ||
| 5113 | auto stage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage(); | ||
| 5114 | DependencyManager::get<DeferredLightingEffect>()->setGlobalLight(stage->getSunLight()); | ||
| 5115 | } | ||
| 5116 | |||
| 5117 | { | 5145 | { |
| 5118 | PerformanceTimer perfTimer("SceneProcessTransaction"); | 5146 | PerformanceTimer perfTimer("SceneProcessTransaction"); |
| 5119 | _main3DScene->enqueueTransaction(transaction); | 5147 | _main3DScene->enqueueTransaction(transaction); |
| @@ -6384,21 +6412,6 @@ void Application::loadAddAvatarBookmarkDialog() const { · 1264 unmodified lines | |||
| 6384 | } | 6412 | } |
| 6385 | 6413 | ||
| 6386 | void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRatio) { | 6414 | void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRatio) { |
| 6387 | |||
| 6388 | //keep sound thread out of event loop scope | ||
| 6389 | |||
| 6390 | AudioInjectorOptions options; | ||
| 6391 | options.localOnly = true; | ||
| 6392 | options.stereo = true; | ||
| 6393 | |||
| 6394 | if (_snapshotSoundInjector) { | ||
| 6395 | _snapshotSoundInjector->setOptions(options); | ||
| 6396 | _snapshotSoundInjector->restart(); | ||
| 6397 | } else { | ||
| 6398 | QByteArray samples = _snapshotSound->getByteArray(); | ||
| 6399 | _snapshotSoundInjector = AudioInjector::playSound(samples, options); | ||
| 6400 | } | ||
| 6401 | |||
| 6402 | postLambdaEvent([notify, includeAnimated, aspectRatio, this] { | 6415 | postLambdaEvent([notify, includeAnimated, aspectRatio, this] { |
| 6403 | // Get a screenshot and save it | 6416 | // Get a screenshot and save it |
| 6404 | QString path = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio)); | 6417 | QString path = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio)); |
| @@ -6811,6 +6824,35 @@ void Application::updateDisplayMode() { · 406 unmodified lines | |||
| 6811 | Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin"); | 6824 | Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin"); |
| 6812 | } | 6825 | } |
| 6813 | 6826 | ||
| 6827 | void Application::switchDisplayMode() { | ||
| 6828 | if (!_autoSwitchDisplayModeSupportedHMDPlugin) { | ||
| 6829 | return; | ||
| 6830 | } | ||
| 6831 | bool currentHMDWornStatus = _autoSwitchDisplayModeSupportedHMDPlugin->isDisplayVisible(); | ||
| 6832 | if (currentHMDWornStatus != _previousHMDWornStatus) { | ||
| 6833 | // Switch to respective mode as soon as currentHMDWornStatus changes | ||
| 6834 | if (currentHMDWornStatus) { | ||
| 6835 | qCDebug(interfaceapp) << "Switching from Desktop to HMD mode"; | ||
| 6836 | endHMDSession(); | ||
| 6837 | setActiveDisplayPlugin(_autoSwitchDisplayModeSupportedHMDPluginName); | ||
| 6838 | } else { | ||
| 6839 | qCDebug(interfaceapp) << "Switching from HMD to desktop mode"; | ||
| 6840 | setActiveDisplayPlugin(DESKTOP_DISPLAY_PLUGIN_NAME); | ||
| 6841 | startHMDStandBySession(); | ||
| 6842 | } | ||
| 6843 | emit activeDisplayPluginChanged(); | ||
| 6844 | } | ||
| 6845 | _previousHMDWornStatus = currentHMDWornStatus; | ||
| 6846 | } | ||
| 6847 | |||
| 6848 | void Application::startHMDStandBySession() { | ||
| 6849 | _autoSwitchDisplayModeSupportedHMDPlugin->startStandBySession(); | ||
| 6850 | } | ||
| 6851 | |||
| 6852 | void Application::endHMDSession() { | ||
| 6853 | _autoSwitchDisplayModeSupportedHMDPlugin->endSession(); | ||
| 6854 | } | ||
| 6855 | |||
| 6814 | mat4 Application::getEyeProjection(int eye) const { | 6856 | mat4 Application::getEyeProjection(int eye) const { |
| 6815 | QMutexLocker viewLocker(&_viewMutex); | 6857 | QMutexLocker viewLocker(&_viewMutex); |
| 6816 | if (isHMDMode()) { | 6858 | if (isHMDMode()) { |