Showing the changes to interface/src/Application.cpp (1 of 406 files). Show all
Unified · Split
| @@ -9,11 +9,9 @@ · 8 unmodified lines | |||
| 9 | // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html | 9 | // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html |
| 10 | // | 10 | // |
| 11 | 11 | ||
| 12 | #include <sstream> | 12 | #include "Application.h" |
| 13 | 13 | ||
| 14 | #include <stdlib.h> | 14 | #include <sstream> |
| 15 | #include <cmath> | ||
| 16 | #include <math.h> | ||
| 17 | 15 | ||
| 18 | #include <glm/glm.hpp> | 16 | #include <glm/glm.hpp> |
| 19 | #include <glm/gtx/component_wise.hpp> | 17 | #include <glm/gtx/component_wise.hpp> |
| @@ -21,9 +19,6 @@ · 1 unmodified line | |||
| 21 | #include <glm/gtx/vector_angle.hpp> | 19 | #include <glm/gtx/vector_angle.hpp> |
| 22 | #include <glm/gtc/type_ptr.hpp> | 20 | #include <glm/gtc/type_ptr.hpp> |
| 23 | 21 | ||
| 24 | // include this before QGLWidget, which includes an earlier version of OpenGL | ||
| 25 | #include "InterfaceConfig.h" | ||
| 26 | |||
| 27 | #include <QAbstractNativeEventFilter> | 22 | #include <QAbstractNativeEventFilter> |
| 28 | #include <QActionGroup> | 23 | #include <QActionGroup> |
| 29 | #include <QColorDialog> | 24 | #include <QColorDialog> |
| @@ -58,13 +53,13 @@ · 28 unmodified lines | |||
| 58 | #include <AccountManager.h> | 53 | #include <AccountManager.h> |
| 59 | #include <AddressManager.h> | 54 | #include <AddressManager.h> |
| 60 | #include <CursorManager.h> | 55 | #include <CursorManager.h> |
| 61 | #include <AmbientOcclusionEffect.h> | ||
| 62 | #include <AudioInjector.h> | 56 | #include <AudioInjector.h> |
| 63 | #include <AutoUpdater.h> | 57 | #include <AutoUpdater.h> |
| 64 | #include <DeferredLightingEffect.h> | 58 | #include <DeferredLightingEffect.h> |
| 65 | #include <DependencyManager.h> | 59 | #include <DependencyManager.h> |
| 66 | #include <EntityScriptingInterface.h> | 60 | #include <EntityScriptingInterface.h> |
| 67 | #include <ErrorDialog.h> | 61 | #include <ErrorDialog.h> |
| 62 | #include <FramebufferCache.h> | ||
| 68 | #include <gpu/Batch.h> | 63 | #include <gpu/Batch.h> |
| 69 | #include <gpu/Context.h> | 64 | #include <gpu/Context.h> |
| 70 | #include <gpu/GLBackend.h> | 65 | #include <gpu/GLBackend.h> |
| @@ -80,11 +75,10 @@ · 9 unmodified lines | |||
| 80 | #include <ObjectMotionState.h> | 75 | #include <ObjectMotionState.h> |
| 81 | #include <OctalCode.h> | 76 | #include <OctalCode.h> |
| 82 | #include <OctreeSceneStats.h> | 77 | #include <OctreeSceneStats.h> |
| 83 | #include <PacketHeaders.h> | 78 | #include <udt/PacketHeaders.h> |
| 84 | #include <PathUtils.h> | 79 | #include <PathUtils.h> |
| 85 | #include <PerfStat.h> | 80 | #include <PerfStat.h> |
| 86 | #include <PhysicsEngine.h> | 81 | #include <PhysicsEngine.h> |
| 87 | #include <ProgramObject.h> | ||
| 88 | #include <RenderDeferredTask.h> | 82 | #include <RenderDeferredTask.h> |
| 89 | #include <ResourceCache.h> | 83 | #include <ResourceCache.h> |
| 90 | #include <SceneScriptingInterface.h> | 84 | #include <SceneScriptingInterface.h> |
| @@ -92,14 +86,15 @@ · 1 unmodified line | |||
| 92 | #include <SettingHandle.h> | 86 | #include <SettingHandle.h> |
| 93 | #include <SimpleAverage.h> | 87 | #include <SimpleAverage.h> |
| 94 | #include <SoundCache.h> | 88 | #include <SoundCache.h> |
| 89 | #include <TextureCache.h> | ||
| 95 | #include <Tooltip.h> | 90 | #include <Tooltip.h> |
| 96 | #include <UserActivityLogger.h> | 91 | #include <UserActivityLogger.h> |
| 97 | #include <UUID.h> | 92 | #include <UUID.h> |
| 98 | #include <VrMenu.h> | 93 | #include <VrMenu.h> |
| 99 | 94 | ||
| 100 | #include "Application.h" | ||
| 101 | #include "AudioClient.h" | 95 | #include "AudioClient.h" |
| 102 | #include "DiscoverabilityManager.h" | 96 | #include "DiscoverabilityManager.h" |
| 97 | #include "GLCanvas.h" | ||
| 103 | #include "InterfaceVersion.h" | 98 | #include "InterfaceVersion.h" |
| 104 | #include "LODManager.h" | 99 | #include "LODManager.h" |
| 105 | #include "Menu.h" | 100 | #include "Menu.h" |
| @@ -174,8 +169,6 @@ public: · 68 unmodified lines | |||
| 174 | using namespace std; | 169 | using namespace std; |
| 175 | 170 | ||
| 176 | // Starfield information | 171 | // Starfield information |
| 177 | static unsigned STARFIELD_NUM_STARS = 50000; | ||
| 178 | static unsigned STARFIELD_SEED = 1; | ||
| 179 | static uint8_t THROTTLED_IDLE_TIMER_DELAY = 10; | 172 | static uint8_t THROTTLED_IDLE_TIMER_DELAY = 10; |
| 180 | 173 | ||
| 181 | const qint64 MAXIMUM_CACHE_SIZE = 10 * BYTES_PER_GIGABYTES; // 10GB | 174 | const qint64 MAXIMUM_CACHE_SIZE = 10 * BYTES_PER_GIGABYTES; // 10GB |
| @@ -271,8 +264,9 @@ bool setupEssentials(int& argc, char** argv) { · 89 unmodified lines | |||
| 271 | auto audio = DependencyManager::set<AudioClient>(); | 264 | auto audio = DependencyManager::set<AudioClient>(); |
| 272 | auto audioScope = DependencyManager::set<AudioScope>(); | 265 | auto audioScope = DependencyManager::set<AudioScope>(); |
| 273 | auto deferredLightingEffect = DependencyManager::set<DeferredLightingEffect>(); | 266 | auto deferredLightingEffect = DependencyManager::set<DeferredLightingEffect>(); |
| 274 | auto ambientOcclusionEffect = DependencyManager::set<AmbientOcclusionEffect>(); | ||
| 275 | auto textureCache = DependencyManager::set<TextureCache>(); | 267 | auto textureCache = DependencyManager::set<TextureCache>(); |
| 268 | auto framebufferCache = DependencyManager::set<FramebufferCache>(); | ||
| 269 | |||
| 276 | auto animationCache = DependencyManager::set<AnimationCache>(); | 270 | auto animationCache = DependencyManager::set<AnimationCache>(); |
| 277 | auto ddeFaceTracker = DependencyManager::set<DdeFaceTracker>(); | 271 | auto ddeFaceTracker = DependencyManager::set<DdeFaceTracker>(); |
| 278 | auto modelBlender = DependencyManager::set<ModelBlender>(); | 272 | auto modelBlender = DependencyManager::set<ModelBlender>(); |
| @@ -303,7 +297,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 24 unmodified lines | |||
| 303 | _window(new MainWindow(desktop())), | 297 | _window(new MainWindow(desktop())), |
| 304 | _toolWindow(NULL), | 298 | _toolWindow(NULL), |
| 305 | _friendsWindow(NULL), | 299 | _friendsWindow(NULL), |
| 306 | _datagramProcessor(), | ||
| 307 | _undoStack(), | 300 | _undoStack(), |
| 308 | _undoStackScriptingInterface(&_undoStack), | 301 | _undoStackScriptingInterface(&_undoStack), |
| 309 | _frameCount(0), | 302 | _frameCount(0), |
| @@ -321,7 +314,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 11 unmodified lines | |||
| 321 | _previousScriptLocation("LastScriptLocation"), | 314 | _previousScriptLocation("LastScriptLocation"), |
| 322 | _scriptsLocationHandle("scriptsLocation"), | 315 | _scriptsLocationHandle("scriptsLocation"), |
| 323 | _fieldOfView("fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES), | 316 | _fieldOfView("fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES), |
| 324 | _viewTransform(), | ||
| 325 | _scaleMirror(1.0f), | 317 | _scaleMirror(1.0f), |
| 326 | _rotateMirror(0.0f), | 318 | _rotateMirror(0.0f), |
| 327 | _raiseMirror(0.0f), | 319 | _raiseMirror(0.0f), |
| @@ -338,9 +330,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 10 unmodified lines | |||
| 338 | _lastNackTime(usecTimestampNow()), | 330 | _lastNackTime(usecTimestampNow()), |
| 339 | _lastSendDownstreamAudioStats(usecTimestampNow()), | 331 | _lastSendDownstreamAudioStats(usecTimestampNow()), |
| 340 | _isVSyncOn(true), | 332 | _isVSyncOn(true), |
| 341 | _isThrottleFPSEnabled(false), | 333 | _isThrottleFPSEnabled(true), |
| 342 | _aboutToQuit(false), | 334 | _aboutToQuit(false), |
| 343 | _notifiedPacketVersionMismatchThisDomain(false), | 335 | _notifiedPacketVersionMismatchThisDomain(false), |
| 336 | _glWidget(new GLCanvas()), | ||
| 344 | _domainConnectionRefusals(QList<QString>()), | 337 | _domainConnectionRefusals(QList<QString>()), |
| 345 | _maxOctreePPS(maxOctreePacketsPerSecond.get()), | 338 | _maxOctreePPS(maxOctreePacketsPerSecond.get()), |
| 346 | _lastFaceTrackerUpdate(0), | 339 | _lastFaceTrackerUpdate(0), |
| @@ -371,24 +364,17 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 24 unmodified lines | |||
| 371 | _bookmarks = new Bookmarks(); // Before setting up the menu | 364 | _bookmarks = new Bookmarks(); // Before setting up the menu |
| 372 | 365 | ||
| 373 | _runningScriptsWidget = new RunningScriptsWidget(_window); | 366 | _runningScriptsWidget = new RunningScriptsWidget(_window); |
| 374 | _renderEngine->addTask(render::TaskPointer(new RenderDeferredTask())); | 367 | _renderEngine->addTask(make_shared<RenderDeferredTask>()); |
| 375 | _renderEngine->registerScene(_main3DScene); | 368 | _renderEngine->registerScene(_main3DScene); |
| 376 | 369 | ||
| 377 | // start the nodeThread so its event loop is running | 370 | // start the nodeThread so its event loop is running |
| 378 | QThread* nodeThread = new QThread(this); | 371 | QThread* nodeThread = new QThread(this); |
| 379 | nodeThread->setObjectName("Datagram Processor Thread"); | 372 | nodeThread->setObjectName("NodeList Thread"); |
| 380 | nodeThread->start(); | 373 | nodeThread->start(); |
| 381 | 374 | ||
| 382 | // make sure the node thread is given highest priority | 375 | // make sure the node thread is given highest priority |
| 383 | nodeThread->setPriority(QThread::TimeCriticalPriority); | 376 | nodeThread->setPriority(QThread::TimeCriticalPriority); |
| 384 | 377 | ||
| 385 | _datagramProcessor = new DatagramProcessor(nodeList.data()); | ||
| 386 | |||
| 387 | // have the NodeList use deleteLater from DM customDeleter | ||
| 388 | nodeList->setCustomDeleter([](Dependency* dependency) { | ||
| 389 | static_cast<NodeList*>(dependency)->deleteLater(); | ||
| 390 | }); | ||
| 391 | |||
| 392 | // setup a timer for domain-server check ins | 378 | // setup a timer for domain-server check ins |
| 393 | QTimer* domainCheckInTimer = new QTimer(nodeList.data()); | 379 | QTimer* domainCheckInTimer = new QTimer(nodeList.data()); |
| 394 | connect(domainCheckInTimer, &QTimer::timeout, nodeList.data(), &NodeList::sendDomainServerCheckIn); | 380 | connect(domainCheckInTimer, &QTimer::timeout, nodeList.data(), &NodeList::sendDomainServerCheckIn); |
| @@ -404,9 +390,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 9 unmodified lines | |||
| 404 | ResourceCache* geometryCache = geometryCacheP.data(); | 390 | ResourceCache* geometryCache = geometryCacheP.data(); |
| 405 | connect(this, &Application::checkBackgroundDownloads, geometryCache, &ResourceCache::checkAsynchronousGets); | 391 | connect(this, &Application::checkBackgroundDownloads, geometryCache, &ResourceCache::checkAsynchronousGets); |
| 406 | 392 | ||
| 407 | // connect the DataProcessor processDatagrams slot to the QUDPSocket readyRead() signal | ||
| 408 | connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, _datagramProcessor, &DatagramProcessor::processDatagrams); | ||
| 409 | |||
| 410 | // put the audio processing on a separate thread | 393 | // put the audio processing on a separate thread |
| 411 | QThread* audioThread = new QThread(); | 394 | QThread* audioThread = new QThread(); |
| 412 | audioThread->setObjectName("Audio Thread"); | 395 | audioThread->setObjectName("Audio Thread"); |
| @@ -417,14 +400,27 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 4 unmodified lines | |||
| 417 | audioIO->setOrientationGetter(getOrientationForAudio); | 400 | audioIO->setOrientationGetter(getOrientationForAudio); |
| 418 | 401 | ||
| 419 | audioIO->moveToThread(audioThread); | 402 | audioIO->moveToThread(audioThread); |
| 403 | |||
| 404 | auto& audioScriptingInterface = AudioScriptingInterface::getInstance(); | ||
| 405 | |||
| 420 | connect(audioThread, &QThread::started, audioIO.data(), &AudioClient::start); | 406 | connect(audioThread, &QThread::started, audioIO.data(), &AudioClient::start); |
| 421 | connect(audioIO.data(), &AudioClient::destroyed, audioThread, &QThread::quit); | 407 | connect(audioIO.data(), &AudioClient::destroyed, audioThread, &QThread::quit); |
| 422 | connect(audioThread, &QThread::finished, audioThread, &QThread::deleteLater); | 408 | connect(audioThread, &QThread::finished, audioThread, &QThread::deleteLater); |
| 423 | connect(audioIO.data(), &AudioClient::muteToggled, this, &Application::audioMuteToggled); | 409 | connect(audioIO.data(), &AudioClient::muteToggled, this, &Application::audioMuteToggled); |
| 424 | connect(audioIO.data(), &AudioClient::receivedFirstPacket, | 410 | connect(audioIO.data(), &AudioClient::mutedByMixer, &audioScriptingInterface, &AudioScriptingInterface::mutedByMixer); |
| 425 | &AudioScriptingInterface::getInstance(), &AudioScriptingInterface::receivedFirstPacket); | 411 | connect(audioIO.data(), &AudioClient::receivedFirstPacket, &audioScriptingInterface, &AudioScriptingInterface::receivedFirstPacket); |
| 426 | connect(audioIO.data(), &AudioClient::disconnected, | 412 | connect(audioIO.data(), &AudioClient::disconnected, &audioScriptingInterface, &AudioScriptingInterface::disconnected); |
| 427 | &AudioScriptingInterface::getInstance(), &AudioScriptingInterface::disconnected); | 413 | connect(audioIO.data(), &AudioClient::muteEnvironmentRequested, [](glm::vec3 position, float radius) { |
| 414 | auto audioClient = DependencyManager::get<AudioClient>(); | ||
| 415 | float distance = glm::distance(DependencyManager::get<AvatarManager>()->getMyAvatar()->getPosition(), | ||
| 416 | position); | ||
| 417 | bool shouldMute = !audioClient->isMuted() && (distance < radius); | ||
| 418 | |||
| 419 | if (shouldMute) { | ||
| 420 | audioClient->toggleMute(); | ||
| 421 | AudioScriptingInterface::getInstance().environmentMuted(); | ||
| 422 | } | ||
| 423 | }); | ||
| 428 | 424 | ||
| 429 | audioThread->start(); | 425 | audioThread->start(); |
| 430 | 426 | ||
| @@ -457,7 +453,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 26 unmodified lines | |||
| 457 | connect(nodeList.data(), &NodeList::uuidChanged, _myAvatar, &MyAvatar::setSessionUUID); | 453 | connect(nodeList.data(), &NodeList::uuidChanged, _myAvatar, &MyAvatar::setSessionUUID); |
| 458 | connect(nodeList.data(), &NodeList::uuidChanged, this, &Application::setSessionUUID); | 454 | connect(nodeList.data(), &NodeList::uuidChanged, this, &Application::setSessionUUID); |
| 459 | connect(nodeList.data(), &NodeList::limitOfSilentDomainCheckInsReached, nodeList.data(), &NodeList::reset); | 455 | connect(nodeList.data(), &NodeList::limitOfSilentDomainCheckInsReached, nodeList.data(), &NodeList::reset); |
| 460 | connect(nodeList.data(), &NodeList::packetVersionMismatch, this, &Application::notifyPacketVersionMismatch); | 456 | connect(&nodeList->getPacketReceiver(), &PacketReceiver::packetVersionMismatch, |
| 457 | this, &Application::notifyPacketVersionMismatch); | ||
| 461 | 458 | ||
| 462 | // connect to appropriate slots on AccountManager | 459 | // connect to appropriate slots on AccountManager |
| 463 | AccountManager& accountManager = AccountManager::getInstance(); | 460 | AccountManager& accountManager = AccountManager::getInstance(); |
| @@ -537,7 +534,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 73 unmodified lines | |||
| 537 | // the GL surface | 534 | // the GL surface |
| 538 | _glWidget->setCursor(Qt::BlankCursor); | 535 | _glWidget->setCursor(Qt::BlankCursor); |
| 539 | #endif | 536 | #endif |
| 540 | 537 | ||
| 541 | // enable mouse tracking; otherwise, we only get drag events | 538 | // enable mouse tracking; otherwise, we only get drag events |
| 542 | _glWidget->setMouseTracking(true); | 539 | _glWidget->setMouseTracking(true); |
| 543 | 540 | ||
| @@ -571,10 +568,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 27 unmodified lines | |||
| 571 | 568 | ||
| 572 | // hook up bandwidth estimator | 569 | // hook up bandwidth estimator |
| 573 | QSharedPointer<BandwidthRecorder> bandwidthRecorder = DependencyManager::get<BandwidthRecorder>(); | 570 | QSharedPointer<BandwidthRecorder> bandwidthRecorder = DependencyManager::get<BandwidthRecorder>(); |
| 574 | connect(nodeList.data(), SIGNAL(dataSent(const quint8, const int)), | 571 | connect(nodeList.data(), &LimitedNodeList::dataSent, |
| 575 | bandwidthRecorder.data(), SLOT(updateOutboundData(const quint8, const int))); | 572 | bandwidthRecorder.data(), &BandwidthRecorder::updateOutboundData); |
| 576 | connect(nodeList.data(), SIGNAL(dataReceived(const quint8, const int)), | 573 | connect(&nodeList->getPacketReceiver(), &PacketReceiver::dataReceived, |
| 577 | bandwidthRecorder.data(), SLOT(updateInboundData(const quint8, const int))); | 574 | bandwidthRecorder.data(), &BandwidthRecorder::updateInboundData); |
| 578 | 575 | ||
| 579 | connect(&_myAvatar->getSkeletonModel(), &SkeletonModel::skeletonLoaded, | 576 | connect(&_myAvatar->getSkeletonModel(), &SkeletonModel::skeletonLoaded, |
| 580 | this, &Application::checkSkeleton, Qt::QueuedConnection); | 577 | this, &Application::checkSkeleton, Qt::QueuedConnection); |
| @@ -606,7 +603,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 25 unmodified lines | |||
| 606 | _settingsTimer.setSingleShot(false); | 603 | _settingsTimer.setSingleShot(false); |
| 607 | _settingsTimer.setInterval(SAVE_SETTINGS_INTERVAL); | 604 | _settingsTimer.setInterval(SAVE_SETTINGS_INTERVAL); |
| 608 | _settingsThread.start(); | 605 | _settingsThread.start(); |
| 609 | 606 | ||
| 610 | if (Menu::getInstance()->isOptionChecked(MenuOption::IndependentMode)) { | 607 | if (Menu::getInstance()->isOptionChecked(MenuOption::IndependentMode)) { |
| 611 | Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, true); | 608 | Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, true); |
| 612 | cameraMenuChanged(); | 609 | cameraMenuChanged(); |
| @@ -637,10 +634,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 24 unmodified lines | |||
| 637 | ddeTracker->init(); | 634 | ddeTracker->init(); |
| 638 | connect(ddeTracker.data(), &FaceTracker::muteToggled, this, &Application::faceTrackerMuteToggled); | 635 | connect(ddeTracker.data(), &FaceTracker::muteToggled, this, &Application::faceTrackerMuteToggled); |
| 639 | #endif | 636 | #endif |
| 640 | 637 | ||
| 641 | auto applicationUpdater = DependencyManager::get<AutoUpdater>(); | 638 | auto applicationUpdater = DependencyManager::get<AutoUpdater>(); |
| 642 | connect(applicationUpdater.data(), &AutoUpdater::newVersionIsAvailable, dialogsManager.data(), &DialogsManager::showUpdateDialog); | 639 | connect(applicationUpdater.data(), &AutoUpdater::newVersionIsAvailable, dialogsManager.data(), &DialogsManager::showUpdateDialog); |
| 643 | applicationUpdater->checkForUpdate(); | 640 | applicationUpdater->checkForUpdate(); |
| 641 | |||
| 642 | auto& packetReceiver = nodeList->getPacketReceiver(); | ||
| 643 | packetReceiver.registerListener(PacketType::DomainConnectionDenied, this, "handleDomainConnectionDeniedPacket"); | ||
| 644 | } | 644 | } |
| 645 | 645 | ||
| 646 | void Application::aboutToQuit() { | 646 | void Application::aboutToQuit() { |
| @@ -653,8 +653,10 @@ void Application::aboutToQuit() { · 6 unmodified lines | |||
| 653 | void Application::cleanupBeforeQuit() { | 653 | void Application::cleanupBeforeQuit() { |
| 654 | 654 | ||
| 655 | _entities.clear(); // this will allow entity scripts to properly shutdown | 655 | _entities.clear(); // this will allow entity scripts to properly shutdown |
| 656 | 656 | ||
| 657 | _datagramProcessor->shutdown(); // tell the datagram processor we're shutting down, so it can short circuit | 657 | // tell the packet receiver we're shutting down, so it can drop packets |
| 658 | DependencyManager::get<NodeList>()->getPacketReceiver().setShouldDropPackets(true); | ||
| 659 | |||
| 658 | _entities.shutdown(); // tell the entities system we're shutting down, so it will stop running scripts | 660 | _entities.shutdown(); // tell the entities system we're shutting down, so it will stop running scripts |
| 659 | ScriptEngine::stopAllScripts(this); // stop all currently running global scripts | 661 | ScriptEngine::stopAllScripts(this); // stop all currently running global scripts |
| 660 | 662 | ||
| @@ -731,12 +733,15 @@ Application::~Application() { · 70 unmodified lines | |||
| 731 | DependencyManager::destroy<OffscreenUi>(); | 733 | DependencyManager::destroy<OffscreenUi>(); |
| 732 | DependencyManager::destroy<AvatarManager>(); | 734 | DependencyManager::destroy<AvatarManager>(); |
| 733 | DependencyManager::destroy<AnimationCache>(); | 735 | DependencyManager::destroy<AnimationCache>(); |
| 736 | DependencyManager::destroy<FramebufferCache>(); | ||
| 734 | DependencyManager::destroy<TextureCache>(); | 737 | DependencyManager::destroy<TextureCache>(); |
| 735 | DependencyManager::destroy<GeometryCache>(); | 738 | DependencyManager::destroy<GeometryCache>(); |
| 736 | DependencyManager::destroy<ScriptCache>(); | 739 | DependencyManager::destroy<ScriptCache>(); |
| 737 | DependencyManager::destroy<SoundCache>(); | 740 | DependencyManager::destroy<SoundCache>(); |
| 738 | 741 | ||
| 739 | QThread* nodeThread = DependencyManager::get<NodeList>()->thread(); | 742 | QThread* nodeThread = DependencyManager::get<NodeList>()->thread(); |
| 743 | |||
| 744 | // remove the NodeList from the DependencyManager | ||
| 740 | DependencyManager::destroy<NodeList>(); | 745 | DependencyManager::destroy<NodeList>(); |
| 741 | 746 | ||
| 742 | // ask the node thread to quit and wait until it is done | 747 | // ask the node thread to quit and wait until it is done |
| @@ -762,32 +767,8 @@ void Application::initializeGL() { · 19 unmodified lines | |||
| 762 | } | 767 | } |
| 763 | #endif | 768 | #endif |
| 764 | 769 | ||
| 765 | qCDebug(interfaceapp) << "GL Version: " << QString((const char*) glGetString(GL_VERSION)); | 770 | // Where the gpuContext is created and where the TRUE Backend is created and assigned |
| 766 | qCDebug(interfaceapp) << "GL Shader Language Version: " << QString((const char*) glGetString(GL_SHADING_LANGUAGE_VERSION)); | 771 | _gpuContext = std::make_shared<gpu::Context>(new gpu::GLBackend()); |
| 767 | qCDebug(interfaceapp) << "GL Vendor: " << QString((const char*) glGetString(GL_VENDOR)); | ||
| 768 | qCDebug(interfaceapp) << "GL Renderer: " << QString((const char*) glGetString(GL_RENDERER)); | ||
| 769 | |||
| 770 | #ifdef WIN32 | ||
| 771 | GLenum err = glewInit(); | ||
| 772 | if (GLEW_OK != err) { | ||
| 773 | /* Problem: glewInit failed, something is seriously wrong. */ | ||
| 774 | qCDebug(interfaceapp, "Error: %s\n", glewGetErrorString(err)); | ||
| 775 | } | ||
| 776 | qCDebug(interfaceapp, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION)); | ||
| 777 | |||
| 778 | if (wglewGetExtension("WGL_EXT_swap_control")) { | ||
| 779 | int swapInterval = wglGetSwapIntervalEXT(); | ||
| 780 | qCDebug(interfaceapp, "V-Sync is %s\n", (swapInterval > 0 ? "ON" : "OFF")); | ||
| 781 | } | ||
| 782 | #endif | ||
| 783 | |||
| 784 | #if defined(Q_OS_LINUX) | ||
| 785 | // TODO: Write the correct code for Linux... | ||
| 786 | /* if (wglewGetExtension("WGL_EXT_swap_control")) { | ||
| 787 | int swapInterval = wglGetSwapIntervalEXT(); | ||
| 788 | qCDebug(interfaceapp, "V-Sync is %s\n", (swapInterval > 0 ? "ON" : "OFF")); | ||
| 789 | }*/ | ||
| 790 | #endif | ||
| 791 | 772 | ||
| 792 | initDisplay(); | 773 | initDisplay(); |
| 793 | qCDebug(interfaceapp, "Initialized Display."); | 774 | qCDebug(interfaceapp, "Initialized Display."); |
| @@ -876,8 +857,9 @@ void Application::paintGL() { · 82 unmodified lines | |||
| 876 | _glWidget->makeCurrent(); | 857 | _glWidget->makeCurrent(); |
| 877 | 858 | ||
| 878 | auto lodManager = DependencyManager::get<LODManager>(); | 859 | auto lodManager = DependencyManager::get<LODManager>(); |
| 879 | gpu::Context context(new gpu::GLBackend()); | 860 | |
| 880 | RenderArgs renderArgs(&context, nullptr, getViewFrustum(), lodManager->getOctreeSizeScale(), | 861 | |
| 862 | RenderArgs renderArgs(_gpuContext, nullptr, getViewFrustum(), lodManager->getOctreeSizeScale(), | ||
| 881 | lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, | 863 | lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, |
| 882 | RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); | 864 | RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); |
| 883 | 865 | ||
| @@ -887,30 +869,56 @@ void Application::paintGL() { · 3 unmodified lines | |||
| 887 | OculusManager::beginFrameTiming(); | 869 | OculusManager::beginFrameTiming(); |
| 888 | } | 870 | } |
| 889 | 871 | ||
| 890 | 872 | ||
| 891 | PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); | 873 | PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); |
| 892 | bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); | 874 | bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); |
| 893 | PerformanceWarning warn(showWarnings, "Application::paintGL()"); | 875 | PerformanceWarning warn(showWarnings, "Application::paintGL()"); |
| 894 | resizeGL(); | 876 | resizeGL(); |
| 895 | 877 | ||
| 878 | // Before anything else, let's sync up the gpuContext with the true glcontext used in case anything happened | ||
| 879 | renderArgs._context->syncCache(); | ||
| 880 | |||
| 881 | if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { | ||
| 882 | auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor(); | ||
| 883 | |||
| 884 | renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; | ||
| 885 | renderRearViewMirror(&renderArgs, _mirrorViewRect); | ||
| 886 | renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; | ||
| 887 | |||
| 888 | { | ||
| 889 | float ratio = ((float)QApplication::desktop()->windowHandle()->devicePixelRatio() * getRenderResolutionScale()); | ||
| 890 | auto mirrorViewport = glm::ivec4(0, 0, _mirrorViewRect.width() * ratio, _mirrorViewRect.height() * ratio); | ||
| 891 | auto mirrorViewportDest = mirrorViewport; | ||
| 892 | |||
| 893 | auto selfieFbo = DependencyManager::get<FramebufferCache>()->getSelfieFramebuffer(); | ||
| 894 | gpu::Batch batch; | ||
| 895 | batch.setFramebuffer(selfieFbo); | ||
| 896 | batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f)); | ||
| 897 | batch.blit(primaryFbo, mirrorViewport, selfieFbo, mirrorViewportDest); | ||
| 898 | batch.setFramebuffer(nullptr); | ||
| 899 | renderArgs._context->render(batch); | ||
| 900 | } | ||
| 901 | } | ||
| 902 | |||
| 896 | { | 903 | { |
| 897 | PerformanceTimer perfTimer("renderOverlay"); | 904 | PerformanceTimer perfTimer("renderOverlay"); |
| 898 | 905 | ||
| 899 | // NOTE: There is no batch associated with this renderArgs | 906 | // NOTE: There is no batch associated with this renderArgs |
| 900 | // the ApplicationOverlay class assumes it's viewport is setup to be the device size | 907 | // the ApplicationOverlay class assumes it's viewport is setup to be the device size |
| 901 | QSize size = qApp->getDeviceSize(); | 908 | QSize size = qApp->getDeviceSize(); |
| 902 | renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height()); | 909 | renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height()); |
| 903 | _applicationOverlay.renderOverlay(&renderArgs); | 910 | _applicationOverlay.renderOverlay(&renderArgs); |
| 904 | } | 911 | } |
| 905 | 912 | ||
| 906 | glEnable(GL_LINE_SMOOTH); | ||
| 907 | |||
| 908 | if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { | 913 | if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { |
| 909 | Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, _myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN); | 914 | Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, _myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN); |
| 910 | Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(_myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN)); | 915 | Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(_myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN)); |
| 911 | Application::getInstance()->cameraMenuChanged(); | 916 | Application::getInstance()->cameraMenuChanged(); |
| 912 | } | 917 | } |
| 913 | 918 | ||
| 919 | // The render mode is default or mirror if the camera is in mirror mode, assigned further below | ||
| 920 | renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; | ||
| 921 | |||
| 914 | if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { | 922 | if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { |
| 915 | // Always use the default eye position, not the actual head eye position. | 923 | // Always use the default eye position, not the actual head eye position. |
| 916 | // Using the latter will cause the camera to wobble with idle animations, | 924 | // Using the latter will cause the camera to wobble with idle animations, |
| @@ -947,6 +955,7 @@ void Application::paintGL() { · 30 unmodified lines | |||
| 947 | glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) + | 955 | glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) + |
| 948 | (_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * | 956 | (_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * |
| 949 | glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); | 957 | glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); |
| 958 | renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; | ||
| 950 | } | 959 | } |
| 951 | 960 | ||
| 952 | // Update camera position | 961 | // Update camera position |
| @@ -954,17 +963,6 @@ void Application::paintGL() { · 1 unmodified line | |||
| 954 | _myCamera.update(1.0f / _fps); | 963 | _myCamera.update(1.0f / _fps); |
| 955 | } | 964 | } |
| 956 | 965 | ||
| 957 | // Sync up the View Furstum with the camera | ||
| 958 | // FIXME: it's happening again in the updateSHadow and it shouldn't, this should be the place | ||
| 959 | loadViewFrustum(_myCamera, _viewFrustum); | ||
| 960 | |||
| 961 | if (getShadowsEnabled()) { | ||
| 962 | renderArgs._renderMode = RenderArgs::SHADOW_RENDER_MODE; | ||
| 963 | updateShadowMap(&renderArgs); | ||
| 964 | } | ||
| 965 | |||
| 966 | renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; | ||
| 967 | |||
| 968 | if (OculusManager::isConnected()) { | 966 | if (OculusManager::isConnected()) { |
| 969 | //When in mirror mode, use camera rotation. Otherwise, use body rotation | 967 | //When in mirror mode, use camera rotation. Otherwise, use body rotation |
| 970 | if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { | 968 | if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { |
| @@ -976,45 +974,28 @@ void Application::paintGL() { · 5 unmodified lines | |||
| 976 | TV3DManager::display(&renderArgs, _myCamera); | 974 | TV3DManager::display(&renderArgs, _myCamera); |
| 977 | } else { | 975 | } else { |
| 978 | PROFILE_RANGE(__FUNCTION__ "/mainRender"); | 976 | PROFILE_RANGE(__FUNCTION__ "/mainRender"); |
| 979 | |||
| 980 | auto primaryFBO = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer(); | ||
| 981 | GLuint fbo = gpu::GLBackend::getFramebufferID(primaryFBO); | ||
| 982 | glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); | ||
| 983 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||
| 984 | |||
| 985 | // Viewport is assigned to the size of the framebuffer | 977 | // Viewport is assigned to the size of the framebuffer |
| 986 | QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize(); | 978 | QSize size = DependencyManager::get<FramebufferCache>()->getFrameBufferSize(); |
| 987 | glViewport(0, 0, size.width(), size.height()); | ||
| 988 | renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height()); | 979 | renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height()); |
| 989 | |||
| 990 | glMatrixMode(GL_MODELVIEW); | ||
| 991 | glPushMatrix(); | ||
| 992 | glLoadIdentity(); | ||
| 993 | displaySide(&renderArgs, _myCamera); | ||
| 994 | glPopMatrix(); | ||
| 995 | 980 | ||
| 996 | renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; | ||
| 997 | if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { | ||
| 998 | renderRearViewMirror(&renderArgs, _mirrorViewRect); | ||
| 999 | } | ||
| 1000 | 981 | ||
| 1001 | renderArgs._renderMode = RenderArgs::NORMAL_RENDER_MODE; | 982 | displaySide(&renderArgs, _myCamera); |
| 1002 | 983 | ||
| 1003 | auto finalFbo = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer(); | 984 | { |
| 985 | auto geometryCache = DependencyManager::get<GeometryCache>(); | ||
| 986 | auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor(); | ||
| 987 | gpu::Batch batch; | ||
| 988 | batch.blit(primaryFbo, glm::ivec4(0, 0, _renderResolution.x, _renderResolution.y), | ||
| 989 | nullptr, glm::ivec4(0, 0, _glWidget->getDeviceSize().width(), _glWidget->getDeviceSize().height())); | ||
| 1004 | 990 | ||
| 1005 | glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); | 991 | batch.setFramebuffer(nullptr); |
| 1006 | glBindFramebuffer(GL_READ_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(finalFbo)); | 992 | |
| 1007 | glBlitFramebuffer(0, 0, _renderResolution.x, _renderResolution.y, | 993 | renderArgs._context->render(batch); |
| 1008 | 0, 0, _glWidget->getDeviceSize().width(), _glWidget->getDeviceSize().height(), | 994 | } |
| 1009 | GL_COLOR_BUFFER_BIT, GL_LINEAR); | ||
| 1010 | glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); | ||
| 1011 | |||
| 1012 | glBindTexture(GL_TEXTURE_2D, 0); // ??? | ||
| 1013 | 995 | ||
| 1014 | _compositor.displayOverlayTexture(&renderArgs); | 996 | _compositor.displayOverlayTexture(&renderArgs); |
| 1015 | } | 997 | } |
| 1016 | 998 | ||
| 1017 | |||
| 1018 | if (!OculusManager::isConnected() || OculusManager::allowSwap()) { | 999 | if (!OculusManager::isConnected() || OculusManager::allowSwap()) { |
| 1019 | PROFILE_RANGE(__FUNCTION__ "/bufferSwap"); | 1000 | PROFILE_RANGE(__FUNCTION__ "/bufferSwap"); |
| 1020 | _glWidget->swapBuffers(); | 1001 | _glWidget->swapBuffers(); |
| @@ -1024,6 +1005,7 @@ void Application::paintGL() { · 3 unmodified lines | |||
| 1024 | OculusManager::endFrameTiming(); | 1005 | OculusManager::endFrameTiming(); |
| 1025 | } | 1006 | } |
| 1026 | _frameCount++; | 1007 | _frameCount++; |
| 1008 | _numFramesSinceLastResize++; | ||
| 1027 | Stats::getInstance()->setRenderDetails(renderArgs._details); | 1009 | Stats::getInstance()->setRenderDetails(renderArgs._details); |
| 1028 | } | 1010 | } |
| 1029 | 1011 | ||
| @@ -1077,13 +1059,11 @@ void Application::resizeGL() { · 47 unmodified lines | |||
| 1077 | } | 1059 | } |
| 1078 | 1060 | ||
| 1079 | if (_renderResolution != toGlm(renderSize)) { | 1061 | if (_renderResolution != toGlm(renderSize)) { |
| 1062 | _numFramesSinceLastResize = 0; | ||
| 1080 | _renderResolution = toGlm(renderSize); | 1063 | _renderResolution = toGlm(renderSize); |
| 1081 | DependencyManager::get<TextureCache>()->setFrameBufferSize(renderSize); | 1064 | DependencyManager::get<FramebufferCache>()->setFrameBufferSize(renderSize); |
| 1082 | |||
| 1083 | glViewport(0, 0, _renderResolution.x, _renderResolution.y); // shouldn't this account for the menu??? | ||
| 1084 | 1065 | ||
| 1085 | updateProjectionMatrix(); | 1066 | loadViewFrustum(_myCamera, _viewFrustum); |
| 1086 | glLoadIdentity(); | ||
| 1087 | } | 1067 | } |
| 1088 | 1068 | ||
| 1089 | resetCameras(_myCamera, _renderResolution); | 1069 | resetCameras(_myCamera, _renderResolution); |
| @@ -1093,32 +1073,6 @@ void Application::resizeGL() { · 3 unmodified lines | |||
| 1093 | auto canvasSize = _glWidget->size(); | 1073 | auto canvasSize = _glWidget->size(); |
| 1094 | offscreenUi->resize(canvasSize); | 1074 | offscreenUi->resize(canvasSize); |
| 1095 | _glWidget->makeCurrent(); | 1075 | _glWidget->makeCurrent(); |
| 1096 | |||
| 1097 | } | ||
| 1098 | |||
| 1099 | void Application::updateProjectionMatrix() { | ||
| 1100 | updateProjectionMatrix(_myCamera); | ||
| 1101 | } | ||
| 1102 | |||
| 1103 | void Application::updateProjectionMatrix(Camera& camera, bool updateViewFrustum) { | ||
| 1104 | _projectionMatrix = camera.getProjection(); | ||
| 1105 | |||
| 1106 | glMatrixMode(GL_PROJECTION); | ||
| 1107 | glLoadMatrixf(glm::value_ptr(_projectionMatrix)); | ||
| 1108 | |||
| 1109 | // Tell our viewFrustum about this change, using the application camera | ||
| 1110 | if (updateViewFrustum) { | ||
| 1111 | loadViewFrustum(camera, _viewFrustum); | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | glMatrixMode(GL_MODELVIEW); | ||
| 1115 | } | ||
| 1116 | |||
| 1117 | void Application::controlledBroadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes) { | ||
| 1118 | foreach(NodeType_t type, destinationNodeTypes) { | ||
| 1119 | // Perform the broadcast for one type | ||
| 1120 | DependencyManager::get<NodeList>()->broadcastToNodes(packet, NodeSet() << type); | ||
| 1121 | } | ||
| 1122 | } | 1076 | } |
| 1123 | 1077 | ||
| 1124 | bool Application::importSVOFromURL(const QString& urlString) { | 1078 | bool Application::importSVOFromURL(const QString& urlString) { |
| @@ -1267,12 +1221,6 @@ void Application::keyPressEvent(QKeyEvent* event) { · 142 unmodified lines | |||
| 1267 | Menu::getInstance()->triggerOption(MenuOption::Stars); | 1221 | Menu::getInstance()->triggerOption(MenuOption::Stars); |
| 1268 | break; | 1222 | break; |
| 1269 | 1223 | ||
| 1270 | case Qt::Key_W: | ||
| 1271 | if (isOption && !isShifted && !isMeta) { | ||
| 1272 | Menu::getInstance()->triggerOption(MenuOption::Wireframe); | ||
| 1273 | } | ||
| 1274 | break; | ||
| 1275 | |||
| 1276 | case Qt::Key_S: | 1224 | case Qt::Key_S: |
| 1277 | if (isShifted && isMeta && !isOption) { | 1225 | if (isShifted && isMeta && !isOption) { |
| 1278 | Menu::getInstance()->triggerOption(MenuOption::SuppressShortTimings); | 1226 | Menu::getInstance()->triggerOption(MenuOption::SuppressShortTimings); |
| @@ -1786,10 +1734,21 @@ bool Application::acceptSnapshot(const QString& urlString) { · 507 unmodified lines | |||
| 1786 | } | 1734 | } |
| 1787 | 1735 | ||
| 1788 | void Application::sendPingPackets() { | 1736 | void Application::sendPingPackets() { |
| 1789 | QByteArray pingPacket = DependencyManager::get<NodeList>()->constructPingPacket(); | 1737 | |
| 1790 | controlledBroadcastToNodes(pingPacket, NodeSet() | 1738 | auto nodeList = DependencyManager::get<NodeList>(); |
| 1791 | << NodeType::EntityServer | 1739 | |
| 1792 | << NodeType::AudioMixer << NodeType::AvatarMixer); | 1740 | nodeList->eachMatchingNode([](const SharedNodePointer& node)->bool { |
| 1741 | switch (node->getType()) { | ||
| 1742 | case NodeType::AvatarMixer: | ||
| 1743 | case NodeType::AudioMixer: | ||
| 1744 | case NodeType::EntityServer: | ||
| 1745 | return true; | ||
| 1746 | default: | ||
| 1747 | return false; | ||
| 1748 | } | ||
| 1749 | }, [nodeList](const SharedNodePointer& node) { | ||
| 1750 | nodeList->sendPacket(nodeList->constructPingPacket(), *node); | ||
| 1751 | }); | ||
| 1793 | } | 1752 | } |
| 1794 | 1753 | ||
| 1795 | // Every second, check the frame rates and other stuff | 1754 | // Every second, check the frame rates and other stuff |
| @@ -1802,7 +1761,6 @@ void Application::checkFPS() { · 6 unmodified lines | |||
| 1802 | 1761 | ||
| 1803 | _fps = (float)_frameCount / diffTime; | 1762 | _fps = (float)_frameCount / diffTime; |
| 1804 | _frameCount = 0; | 1763 | _frameCount = 0; |
| 1805 | _datagramProcessor->resetCounters(); | ||
| 1806 | _timerStart.start(); | 1764 | _timerStart.start(); |
| 1807 | } | 1765 | } |
| 1808 | 1766 | ||
| @@ -1868,11 +1826,15 @@ void Application::idle() { · 59 unmodified lines | |||
| 1868 | _idleLoopMeasuredJitter = _idleLoopStdev.getStDev(); | 1826 | _idleLoopMeasuredJitter = _idleLoopStdev.getStDev(); |
| 1869 | _idleLoopStdev.reset(); | 1827 | _idleLoopStdev.reset(); |
| 1870 | } | 1828 | } |
| 1871 | |||
| 1872 | } | 1829 | } |
| 1830 | |||
| 1873 | // After finishing all of the above work, ensure the idle timer is set to the proper interval, | 1831 | // After finishing all of the above work, ensure the idle timer is set to the proper interval, |
| 1874 | // depending on whether we're throttling or not | 1832 | // depending on whether we're throttling or not. |
| 1875 | idleTimer->start(_glWidget->isThrottleRendering() ? THROTTLED_IDLE_TIMER_DELAY : 1); | 1833 | // Once rendering is off on another thread we should be able to have Application::idle run at start(0) in |
| 1834 | // perpetuity and not expect events to get backed up. | ||
| 1835 | |||
| 1836 | static const int IDLE_TIMER_DELAY_MS = 2; | ||
| 1837 | idleTimer->start(_glWidget->isThrottleRendering() ? THROTTLED_IDLE_TIMER_DELAY : IDLE_TIMER_DELAY_MS); | ||
| 1876 | } | 1838 | } |
| 1877 | 1839 | ||
| 1878 | // check for any requested background downloads. | 1840 | // check for any requested background downloads. |
| @@ -1955,7 +1917,6 @@ void Application::setEnableVRMode(bool enableVRMode) { · 76 unmodified lines | |||
| 1955 | OculusManager::connect(_glWidget->context()->contextHandle()); | 1917 | OculusManager::connect(_glWidget->context()->contextHandle()); |
| 1956 | _glWidget->setFocus(); | 1918 | _glWidget->setFocus(); |
| 1957 | _glWidget->makeCurrent(); | 1919 | _glWidget->makeCurrent(); |
| 1958 | glClear(GL_COLOR_BUFFER_BIT); | ||
| 1959 | } | 1920 | } |
| 1960 | OculusManager::recalibrate(); | 1921 | OculusManager::recalibrate(); |
| 1961 | } else { | 1922 | } else { |
| @@ -2151,12 +2112,6 @@ QVector<EntityItemID> Application::pasteEntities(float x, float y, float z) { · 189 unmodified lines | |||
| 2151 | } | 2112 | } |
| 2152 | 2113 | ||
| 2153 | void Application::initDisplay() { | 2114 | void Application::initDisplay() { |
| 2154 | glEnable(GL_BLEND); | ||
| 2155 | glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); | ||
| 2156 | glShadeModel(GL_SMOOTH); | ||
| 2157 | glEnable(GL_LIGHTING); | ||
| 2158 | glEnable(GL_LIGHT0); | ||
| 2159 | glEnable(GL_DEPTH_TEST); | ||
| 2160 | } | 2115 | } |
| 2161 | 2116 | ||
| 2162 | void Application::init() { | 2117 | void Application::init() { |
| @@ -2166,7 +2121,6 @@ void Application::init() { · 3 unmodified lines | |||
| 2166 | _environment.init(); | 2121 | _environment.init(); |
| 2167 | 2122 | ||
| 2168 | DependencyManager::get<DeferredLightingEffect>()->init(this); | 2123 | DependencyManager::get<DeferredLightingEffect>()->init(this); |
| 2169 | DependencyManager::get<AmbientOcclusionEffect>()->init(this); | ||
| 2170 | 2124 | ||
| 2171 | // TODO: move _myAvatar out of Application. Move relevant code to MyAvataar or AvatarManager | 2125 | // TODO: move _myAvatar out of Application. Move relevant code to MyAvataar or AvatarManager |
| 2172 | DependencyManager::get<AvatarManager>()->init(); | 2126 | DependencyManager::get<AvatarManager>()->init(); |
| @@ -2262,8 +2216,8 @@ void Application::shrinkMirrorView() { · 89 unmodified lines | |||
| 2262 | 2216 | ||
| 2263 | const float HEAD_SPHERE_RADIUS = 0.1f; | 2217 | const float HEAD_SPHERE_RADIUS = 0.1f; |
| 2264 | 2218 | ||
| 2265 | bool Application::isLookingAtMyAvatar(Avatar* avatar) { | 2219 | bool Application::isLookingAtMyAvatar(AvatarSharedPointer avatar) { |
| 2266 | glm::vec3 theirLookAt = avatar->getHead()->getLookAtPosition(); | 2220 | glm::vec3 theirLookAt = dynamic_pointer_cast<Avatar>(avatar)->getHead()->getLookAtPosition(); |
| 2267 | glm::vec3 myEyePosition = _myAvatar->getHead()->getEyePosition(); | 2221 | glm::vec3 myEyePosition = _myAvatar->getHead()->getEyePosition(); |
| 2268 | if (pointInSphere(theirLookAt, myEyePosition, HEAD_SPHERE_RADIUS * _myAvatar->getScale())) { | 2222 | if (pointInSphere(theirLookAt, myEyePosition, HEAD_SPHERE_RADIUS * _myAvatar->getScale())) { |
| 2269 | return true; | 2223 | return true; |
| @@ -2327,7 +2281,7 @@ void Application::updateMyAvatarLookAtPosition() { · 57 unmodified lines | |||
| 2327 | if (lookingAt && _myAvatar != lookingAt.get()) { | 2281 | if (lookingAt && _myAvatar != lookingAt.get()) { |
| 2328 | // If I am looking at someone else, look directly at one of their eyes | 2282 | // If I am looking at someone else, look directly at one of their eyes |
| 2329 | isLookingAtSomeone = true; | 2283 | isLookingAtSomeone = true; |
| 2330 | Head* lookingAtHead = static_cast<Avatar*>(lookingAt.get())->getHead(); | 2284 | auto lookingAtHead = static_pointer_cast<Avatar>(lookingAt)->getHead(); |
| 2331 | 2285 | ||
| 2332 | const float MAXIMUM_FACE_ANGLE = 65.0f * RADIANS_PER_DEGREE; | 2286 | const float MAXIMUM_FACE_ANGLE = 65.0f * RADIANS_PER_DEGREE; |
| 2333 | glm::vec3 lookingAtFaceOrientation = lookingAtHead->getFinalOrientationInWorldFrame() * IDENTITY_FRONT; | 2287 | glm::vec3 lookingAtFaceOrientation = lookingAtHead->getFinalOrientationInWorldFrame() * IDENTITY_FRONT; |
| @@ -2357,23 +2311,21 @@ void Application::updateMyAvatarLookAtPosition() { · 23 unmodified lines | |||
| 2357 | lookAtSpot = _myAvatar->getHead()->getEyePosition() + | 2311 | lookAtSpot = _myAvatar->getHead()->getEyePosition() + |
| 2358 | (_myAvatar->getHead()->getFinalOrientationInWorldFrame() * glm::vec3(0.0f, 0.0f, -TREE_SCALE)); | 2312 | (_myAvatar->getHead()->getFinalOrientationInWorldFrame() * glm::vec3(0.0f, 0.0f, -TREE_SCALE)); |
| 2359 | } | 2313 | } |
| 2360 | } | ||
| 2361 | 2314 | ||
| 2362 | // Deflect the eyes a bit to match the detected gaze from Faceshift if active. | 2315 | // Deflect the eyes a bit to match the detected gaze from the face tracker if active. |
| 2363 | // DDE doesn't track eyes. | 2316 | if (tracker && !tracker->isMuted()) { |
| 2364 | if (tracker && typeid(*tracker) == typeid(Faceshift) && !tracker->isMuted()) { | 2317 | float eyePitch = tracker->getEstimatedEyePitch(); |
| 2365 | float eyePitch = tracker->getEstimatedEyePitch(); | 2318 | float eyeYaw = tracker->getEstimatedEyeYaw(); |
| 2366 | float eyeYaw = tracker->getEstimatedEyeYaw(); | 2319 | const float GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT = 0.1f; |
| 2367 | const float GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT = 0.1f; | 2320 | glm::vec3 origin = _myAvatar->getHead()->getEyePosition(); |
| 2368 | glm::vec3 origin = _myAvatar->getHead()->getEyePosition(); | 2321 | float deflection = tracker->getEyeDeflection(); |
| 2369 | float pitchSign = (_myCamera.getMode() == CAMERA_MODE_MIRROR) ? -1.0f : 1.0f; | 2322 | if (isLookingAtSomeone) { |
| 2370 | float deflection = DependencyManager::get<Faceshift>()->getEyeDeflection(); | 2323 | deflection *= GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT; |
| 2371 | if (isLookingAtSomeone) { | 2324 | } |
| 2372 | deflection *= GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT; | 2325 | lookAtSpot = origin + _myCamera.getRotation() * glm::quat(glm::radians(glm::vec3( |
| 2373 | } | 2326 | eyePitch * deflection, eyeYaw * deflection, 0.0f))) * |
| 2374 | lookAtSpot = origin + _myCamera.getRotation() * glm::quat(glm::radians(glm::vec3( | ||
| 2375 | eyePitch * pitchSign * deflection, eyeYaw * deflection, 0.0f))) * | ||
| 2376 | glm::inverse(_myCamera.getRotation()) * (lookAtSpot - origin); | 2327 | glm::inverse(_myCamera.getRotation()) * (lookAtSpot - origin); |
| 2328 | } | ||
| 2377 | } | 2329 | } |
| 2378 | 2330 | ||
| 2379 | _myAvatar->getHead()->setLookAtPosition(lookAtSpot); | 2331 | _myAvatar->getHead()->setLookAtPosition(lookAtSpot); |
| @@ -2534,10 +2486,18 @@ void Application::update(float deltaTime) { · 154 unmodified lines | |||
| 2534 | _myAvatar->setDriveKeys(DOWN, _userInputMapper.getActionState(UserInputMapper::VERTICAL_DOWN)); | 2486 | _myAvatar->setDriveKeys(DOWN, _userInputMapper.getActionState(UserInputMapper::VERTICAL_DOWN)); |
| 2535 | _myAvatar->setDriveKeys(LEFT, _userInputMapper.getActionState(UserInputMapper::LATERAL_LEFT)); | 2487 | _myAvatar->setDriveKeys(LEFT, _userInputMapper.getActionState(UserInputMapper::LATERAL_LEFT)); |
| 2536 | _myAvatar->setDriveKeys(RIGHT, _userInputMapper.getActionState(UserInputMapper::LATERAL_RIGHT)); | 2488 | _myAvatar->setDriveKeys(RIGHT, _userInputMapper.getActionState(UserInputMapper::LATERAL_RIGHT)); |
| 2537 | _myAvatar->setDriveKeys(ROT_UP, _userInputMapper.getActionState(UserInputMapper::PITCH_UP)); | 2489 | if (deltaTime > FLT_EPSILON) { |
| 2538 | _myAvatar->setDriveKeys(ROT_DOWN, _userInputMapper.getActionState(UserInputMapper::PITCH_DOWN)); | 2490 | // For rotations what we really want are meausures of "angles per second" (in order to prevent |
| 2539 | _myAvatar->setDriveKeys(ROT_LEFT, _userInputMapper.getActionState(UserInputMapper::YAW_LEFT)); | 2491 | // fps-dependent spin rates) so we need to scale the units of the controller contribution. |
| 2540 | _myAvatar->setDriveKeys(ROT_RIGHT, _userInputMapper.getActionState(UserInputMapper::YAW_RIGHT)); | 2492 | // (TODO?: maybe we should similarly scale ALL action state info, or change the expected behavior |
| 2493 | // controllers to provide a delta_per_second value rather than a raw delta.) | ||
| 2494 | const float EXPECTED_FRAME_RATE = 60.0f; | ||
| 2495 | float timeFactor = EXPECTED_FRAME_RATE * deltaTime; | ||
| 2496 | _myAvatar->setDriveKeys(ROT_UP, _userInputMapper.getActionState(UserInputMapper::PITCH_UP) / timeFactor); | ||
| 2497 | _myAvatar->setDriveKeys(ROT_DOWN, _userInputMapper.getActionState(UserInputMapper::PITCH_DOWN) / timeFactor); | ||
| 2498 | _myAvatar->setDriveKeys(ROT_LEFT, _userInputMapper.getActionState(UserInputMapper::YAW_LEFT) / timeFactor); | ||
| 2499 | _myAvatar->setDriveKeys(ROT_RIGHT, _userInputMapper.getActionState(UserInputMapper::YAW_RIGHT) / timeFactor); | ||
| 2500 | } | ||
| 2541 | } | 2501 | } |
| 2542 | _myAvatar->setDriveKeys(BOOM_IN, _userInputMapper.getActionState(UserInputMapper::BOOM_IN)); | 2502 | _myAvatar->setDriveKeys(BOOM_IN, _userInputMapper.getActionState(UserInputMapper::BOOM_IN)); |
| 2543 | _myAvatar->setDriveKeys(BOOM_OUT, _userInputMapper.getActionState(UserInputMapper::BOOM_OUT)); | 2503 | _myAvatar->setDriveKeys(BOOM_OUT, _userInputMapper.getActionState(UserInputMapper::BOOM_OUT)); |
| @@ -2658,7 +2618,7 @@ void Application::update(float deltaTime) { · 114 unmodified lines | |||
| 2658 | _lastQueriedTime = now; | 2618 | _lastQueriedTime = now; |
| 2659 | 2619 | ||
| 2660 | if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) { | 2620 | if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) { |
| 2661 | queryOctree(NodeType::EntityServer, PacketTypeEntityQuery, _entityServerJurisdictions); | 2621 | queryOctree(NodeType::EntityServer, PacketType::EntityQuery, _entityServerJurisdictions); |
| 2662 | } | 2622 | } |
| 2663 | _lastQueriedViewFrustum = _viewFrustum; | 2623 | _lastQueriedViewFrustum = _viewFrustum; |
| 2664 | } | 2624 | } |
| @@ -2691,16 +2651,17 @@ int Application::sendNackPackets() { · 26 unmodified lines | |||
| 2691 | return 0; | 2651 | return 0; |
| 2692 | } | 2652 | } |
| 2693 | 2653 | ||
| 2694 | int packetsSent = 0; | 2654 | // iterates through all nodes in NodeList |
| 2695 | char packet[MAX_PACKET_SIZE]; | ||
| 2696 | |||
| 2697 | // iterates thru all nodes in NodeList | ||
| 2698 | auto nodeList = DependencyManager::get<NodeList>(); | 2655 | auto nodeList = DependencyManager::get<NodeList>(); |
| 2699 | 2656 | ||
| 2657 | int packetsSent = 0; | ||
| 2658 | |||
| 2700 | nodeList->eachNode([&](const SharedNodePointer& node){ | 2659 | nodeList->eachNode([&](const SharedNodePointer& node){ |
| 2701 | 2660 | ||
| 2702 | if (node->getActiveSocket() && node->getType() == NodeType::EntityServer) { | 2661 | if (node->getActiveSocket() && node->getType() == NodeType::EntityServer) { |
| 2703 | 2662 | ||
| 2663 | NLPacketList nackPacketList(PacketType::OctreeDataNack); | ||
| 2664 | |||
| 2704 | QUuid nodeUUID = node->getUUID(); | 2665 | QUuid nodeUUID = node->getUUID(); |
| 2705 | 2666 | ||
| 2706 | // if there are octree packets from this node that are waiting to be processed, | 2667 | // if there are octree packets from this node that are waiting to be processed, |
| @@ -2716,55 +2677,36 @@ int Application::sendNackPackets() { · 9 unmodified lines | |||
| 2716 | _octreeSceneStatsLock.unlock(); | 2677 | _octreeSceneStatsLock.unlock(); |
| 2717 | return; | 2678 | return; |
| 2718 | } | 2679 | } |
| 2719 | 2680 | ||
| 2720 | // get sequence number stats of node, prune its missing set, and make a copy of the missing set | 2681 | // get sequence number stats of node, prune its missing set, and make a copy of the missing set |
| 2721 | SequenceNumberStats& sequenceNumberStats = _octreeServerSceneStats[nodeUUID].getIncomingOctreeSequenceNumberStats(); | 2682 | SequenceNumberStats& sequenceNumberStats = _octreeServerSceneStats[nodeUUID].getIncomingOctreeSequenceNumberStats(); |
| 2722 | sequenceNumberStats.pruneMissingSet(); | 2683 | sequenceNumberStats.pruneMissingSet(); |
| 2723 | const QSet<OCTREE_PACKET_SEQUENCE> missingSequenceNumbers = sequenceNumberStats.getMissingSet(); | 2684 | const QSet<OCTREE_PACKET_SEQUENCE> missingSequenceNumbers = sequenceNumberStats.getMissingSet(); |
| 2724 | 2685 | ||
| 2725 | _octreeSceneStatsLock.unlock(); | 2686 | _octreeSceneStatsLock.unlock(); |
| 2726 | 2687 | ||
| 2727 | // construct nack packet(s) for this node | 2688 | // construct nack packet(s) for this node |
| 2728 | int numSequenceNumbersAvailable = missingSequenceNumbers.size(); | 2689 | auto it = missingSequenceNumbers.constBegin(); |
| 2729 | QSet<OCTREE_PACKET_SEQUENCE>::const_iterator missingSequenceNumbersIterator = missingSequenceNumbers.constBegin(); | 2690 | while (it != missingSequenceNumbers.constEnd()) { |
| 2730 | while (numSequenceNumbersAvailable > 0) { | 2691 | OCTREE_PACKET_SEQUENCE missingNumber = *it; |
| 2731 | 2692 | nackPacketList.writePrimitive(missingNumber); | |
| 2732 | char* dataAt = packet; | 2693 | ++it; |
| 2733 | int bytesRemaining = MAX_PACKET_SIZE; | 2694 | } |
| 2734 | 2695 | ||
| 2735 | // pack header | 2696 | if (nackPacketList.getNumPackets()) { |
| 2736 | int numBytesPacketHeader = nodeList->populatePacketHeader(packet, PacketTypeOctreeDataNack); | 2697 | packetsSent += nackPacketList.getNumPackets(); |
| 2737 | dataAt += numBytesPacketHeader; | 2698 | |
| 2738 | bytesRemaining -= numBytesPacketHeader; | 2699 | // send the packet list |
| 2739 | 2700 | nodeList->sendPacketList(nackPacketList, *node); | |
| 2740 | // calculate and pack the number of sequence numbers | ||
| 2741 | int numSequenceNumbersRoomFor = (bytesRemaining - sizeof(uint16_t)) / sizeof(OCTREE_PACKET_SEQUENCE); | ||
| 2742 | uint16_t numSequenceNumbers = min(numSequenceNumbersAvailable, numSequenceNumbersRoomFor); | ||
| 2743 | uint16_t* numSequenceNumbersAt = (uint16_t*)dataAt; | ||
| 2744 | *numSequenceNumbersAt = numSequenceNumbers; | ||
| 2745 | dataAt += sizeof(uint16_t); | ||
| 2746 | |||
| 2747 | // pack sequence numbers | ||
| 2748 | for (int i = 0; i < numSequenceNumbers; i++) { | ||
| 2749 | OCTREE_PACKET_SEQUENCE* sequenceNumberAt = (OCTREE_PACKET_SEQUENCE*)dataAt; | ||
| 2750 | *sequenceNumberAt = *missingSequenceNumbersIterator; | ||
| 2751 | dataAt += sizeof(OCTREE_PACKET_SEQUENCE); | ||
| 2752 | |||
| 2753 | missingSequenceNumbersIterator++; | ||
| 2754 | } | ||
| 2755 | numSequenceNumbersAvailable -= numSequenceNumbers; | ||
| 2756 | |||
| 2757 | // send it | ||
| 2758 | nodeList->writeUnverifiedDatagram(packet, dataAt - packet, node); | ||
| 2759 | packetsSent++; | ||
| 2760 | } | 2701 | } |
| 2761 | } | 2702 | } |
| 2762 | }); | 2703 | }); |
| 2763 | 2704 | ||
| 2705 | |||
| 2764 | return packetsSent; | 2706 | return packetsSent; |
| 2765 | } | 2707 | } |
| 2766 | 2708 | ||
| 2767 | void Application::queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions) { | 2709 | void Application::queryOctree(NodeType_t serverType, PacketType::Value packetType, NodeToJurisdictionMap& jurisdictions) { |
| 2768 | 2710 | ||
| 2769 | //qCDebug(interfaceapp) << ">>> inside... queryOctree()... _viewFrustum.getFieldOfView()=" << _viewFrustum.getFieldOfView(); | 2711 | //qCDebug(interfaceapp) << ">>> inside... queryOctree()... _viewFrustum.getFieldOfView()=" << _viewFrustum.getFieldOfView(); |
| 2770 | bool wantExtraDebugging = getLogger()->extraDebugging(); | 2712 | bool wantExtraDebugging = getLogger()->extraDebugging(); |
| @@ -2787,9 +2729,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node · 16 unmodified lines | |||
| 2787 | _octreeQuery.setOctreeSizeScale(lodManager->getOctreeSizeScale()); | 2729 | _octreeQuery.setOctreeSizeScale(lodManager->getOctreeSizeScale()); |
| 2788 | _octreeQuery.setBoundaryLevelAdjust(lodManager->getBoundaryLevelAdjust()); | 2730 | _octreeQuery.setBoundaryLevelAdjust(lodManager->getBoundaryLevelAdjust()); |
| 2789 | 2731 | ||
| 2790 | unsigned char queryPacket[MAX_PACKET_SIZE]; | 2732 | // Iterate all of the nodes, and get a count of how many octree servers we have... |
| 2791 | |||
| 2792 | // Iterate all of the nodes, and get a count of how many voxel servers we have... | ||
| 2793 | int totalServers = 0; | 2733 | int totalServers = 0; |
| 2794 | int inViewServers = 0; | 2734 | int inViewServers = 0; |
| 2795 | int unknownJurisdictionServers = 0; | 2735 | int unknownJurisdictionServers = 0; |
| @@ -2856,6 +2796,8 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node · 60 unmodified lines | |||
| 2856 | qCDebug(interfaceapp, "perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer); | 2796 | qCDebug(interfaceapp, "perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer); |
| 2857 | } | 2797 | } |
| 2858 | 2798 | ||
| 2799 | auto queryPacket = NLPacket::create(packetType); | ||
| 2800 | |||
| 2859 | nodeList->eachNode([&](const SharedNodePointer& node){ | 2801 | nodeList->eachNode([&](const SharedNodePointer& node){ |
| 2860 | // only send to the NodeTypes that are serverType | 2802 | // only send to the NodeTypes that are serverType |
| 2861 | if (node->getActiveSocket() && node->getType() == serverType) { | 2803 | if (node->getActiveSocket() && node->getType() == serverType) { |
| @@ -2930,19 +2872,13 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node · 68 unmodified lines | |||
| 2930 | } else { | 2872 | } else { |
| 2931 | _octreeQuery.setMaxQueryPacketsPerSecond(0); | 2873 | _octreeQuery.setMaxQueryPacketsPerSecond(0); |
| 2932 | } | 2874 | } |
| 2933 | // set up the packet for sending... | ||
| 2934 | unsigned char* endOfQueryPacket = queryPacket; | ||
| 2935 | 2875 | ||
| 2936 | // insert packet type/version and node UUID | 2876 | // encode the query data |
| 2937 | endOfQueryPacket += nodeList->populatePacketHeader(reinterpret_cast<char*>(endOfQueryPacket), packetType); | 2877 | int packetSize = _octreeQuery.getBroadcastData(reinterpret_cast<unsigned char*>(queryPacket->getPayload())); |
| 2938 | 2878 | queryPacket->setPayloadSize(packetSize); | |
| 2939 | // encode the query data... | ||
| 2940 | endOfQueryPacket += _octreeQuery.getBroadcastData(endOfQueryPacket); | ||
| 2941 | |||
| 2942 | int packetLength = endOfQueryPacket - queryPacket; | ||
| 2943 | 2879 | ||
| 2944 | // make sure we still have an active socket | 2880 | // make sure we still have an active socket |
| 2945 | nodeList->writeUnverifiedDatagram(reinterpret_cast<const char*>(queryPacket), packetLength, node); | 2881 | nodeList->sendUnreliablePacket(*queryPacket, *node); |
| 2946 | } | 2882 | } |
| 2947 | }); | 2883 | }); |
| 2948 | } | 2884 | } |
| @@ -3006,169 +2942,6 @@ glm::vec3 Application::getSunDirection() { · 57 unmodified lines | |||
| 3006 | // FIXME, preprocessor guard this check to occur only in DEBUG builds | 2942 | // FIXME, preprocessor guard this check to occur only in DEBUG builds |
| 3007 | static QThread * activeRenderingThread = nullptr; | 2943 | static QThread * activeRenderingThread = nullptr; |
| 3008 | 2944 | ||
| 3009 | void Application::updateShadowMap(RenderArgs* renderArgs) { | ||
| 3010 | activeRenderingThread = QThread::currentThread(); | ||
| 3011 | |||
| 3012 | PerformanceTimer perfTimer("shadowMap"); | ||
| 3013 | auto shadowFramebuffer = DependencyManager::get<TextureCache>()->getShadowFramebuffer(); | ||
| 3014 | glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(shadowFramebuffer)); | ||
| 3015 | |||
| 3016 | glEnable(GL_DEPTH_TEST); | ||
| 3017 | glClear(GL_DEPTH_BUFFER_BIT); | ||
| 3018 | |||
| 3019 | glm::vec3 lightDirection = getSunDirection(); | ||
| 3020 | glm::quat rotation = rotationBetween(IDENTITY_FRONT, lightDirection); | ||
| 3021 | glm::quat inverseRotation = glm::inverse(rotation); | ||
| 3022 | |||
| 3023 | const float SHADOW_MATRIX_DISTANCES[] = { 0.0f, 2.0f, 6.0f, 14.0f, 30.0f }; | ||
| 3024 | const glm::vec2 MAP_COORDS[] = { glm::vec2(0.0f, 0.0f), glm::vec2(0.5f, 0.0f), | ||
| 3025 | glm::vec2(0.0f, 0.5f), glm::vec2(0.5f, 0.5f) }; | ||
| 3026 | |||
| 3027 | float frustumScale = 1.0f / (_viewFrustum.getFarClip() - _viewFrustum.getNearClip()); | ||
| 3028 | loadViewFrustum(_myCamera, _viewFrustum); | ||
| 3029 | |||
| 3030 | int matrixCount = 1; | ||
| 3031 | //int targetSize = fbo->width(); | ||
| 3032 | int sourceSize = shadowFramebuffer->getWidth(); | ||
| 3033 | int targetSize = shadowFramebuffer->getWidth(); | ||
| 3034 | float targetScale = 1.0f; | ||
| 3035 | if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) { | ||
| 3036 | matrixCount = CASCADED_SHADOW_MATRIX_COUNT; | ||
| 3037 | targetSize = sourceSize / 2; | ||
| 3038 | targetScale = 0.5f; | ||
| 3039 | } | ||
| 3040 | for (int i = 0; i < matrixCount; i++) { | ||
| 3041 | const glm::vec2& coord = MAP_COORDS[i]; | ||
| 3042 | glViewport(coord.s * sourceSize, coord.t * sourceSize, targetSize, targetSize); | ||
| 3043 | |||
| 3044 | // if simple shadow then since the resolution is twice as much as with cascaded, cover 2 regions with the map, not just one | ||
| 3045 | int regionIncrement = (matrixCount == 1 ? 2 : 1); | ||
| 3046 | float nearScale = SHADOW_MATRIX_DISTANCES[i] * frustumScale; | ||
| 3047 | float farScale = SHADOW_MATRIX_DISTANCES[i + regionIncrement] * frustumScale; | ||
| 3048 | glm::vec3 points[] = { | ||
| 3049 | glm::mix(_viewFrustum.getNearTopLeft(), _viewFrustum.getFarTopLeft(), nearScale), | ||
| 3050 | glm::mix(_viewFrustum.getNearTopRight(), _viewFrustum.getFarTopRight(), nearScale), | ||
| 3051 | glm::mix(_viewFrustum.getNearBottomLeft(), _viewFrustum.getFarBottomLeft(), nearScale), | ||
| 3052 | glm::mix(_viewFrustum.getNearBottomRight(), _viewFrustum.getFarBottomRight(), nearScale), | ||
| 3053 | glm::mix(_viewFrustum.getNearTopLeft(), _viewFrustum.getFarTopLeft(), farScale), | ||
| 3054 | glm::mix(_viewFrustum.getNearTopRight(), _viewFrustum.getFarTopRight(), farScale), | ||
| 3055 | glm::mix(_viewFrustum.getNearBottomLeft(), _viewFrustum.getFarBottomLeft(), farScale), | ||
| 3056 | glm::mix(_viewFrustum.getNearBottomRight(), _viewFrustum.getFarBottomRight(), farScale) }; | ||
| 3057 | glm::vec3 center; | ||
| 3058 | for (size_t j = 0; j < sizeof(points) / sizeof(points[0]); j++) { | ||
| 3059 | center += points[j]; | ||
| 3060 | } | ||
| 3061 | center /= (float)(sizeof(points) / sizeof(points[0])); | ||
| 3062 | float radius = 0.0f; | ||
| 3063 | for (size_t j = 0; j < sizeof(points) / sizeof(points[0]); j++) { | ||
| 3064 | radius = qMax(radius, glm::distance(points[j], center)); | ||
| 3065 | } | ||
| 3066 | if (i < 3) { | ||
| 3067 | const float RADIUS_SCALE = 0.5f; | ||
| 3068 | _shadowDistances[i] = -glm::distance(_viewFrustum.getPosition(), center) - radius * RADIUS_SCALE; | ||
| 3069 | } | ||
| 3070 | center = inverseRotation * center; | ||
| 3071 | |||
| 3072 | // to reduce texture "shimmer," move in texel increments | ||
| 3073 | float texelSize = (2.0f * radius) / targetSize; | ||
| 3074 | center = glm::vec3(roundf(center.x / texelSize) * texelSize, roundf(center.y / texelSize) * texelSize, | ||
| 3075 | roundf(center.z / texelSize) * texelSize); | ||
| 3076 | |||
| 3077 | glm::vec3 minima(center.x - radius, center.y - radius, center.z - radius); | ||
| 3078 | glm::vec3 maxima(center.x + radius, center.y + radius, center.z + radius); | ||
| 3079 | |||
| 3080 | // stretch out our extents in z so that we get all of the avatars | ||
| 3081 | minima.z -= _viewFrustum.getFarClip() * 0.5f; | ||
| 3082 | maxima.z += _viewFrustum.getFarClip() * 0.5f; | ||
| 3083 | |||
| 3084 | // save the combined matrix for rendering | ||
| 3085 | _shadowMatrices[i] = glm::transpose(glm::translate(glm::vec3(coord, 0.0f)) * | ||
| 3086 | glm::scale(glm::vec3(targetScale, targetScale, 1.0f)) * | ||
| 3087 | glm::translate(glm::vec3(0.5f, 0.5f, 0.5f)) * glm::scale(glm::vec3(0.5f, 0.5f, 0.5f)) * | ||
| 3088 | glm::ortho(minima.x, maxima.x, minima.y, maxima.y, -maxima.z, -minima.z) * glm::mat4_cast(inverseRotation)); | ||
| 3089 | |||
| 3090 | // update the shadow view frustum | ||
| 3091 | // glm::vec3 shadowFrustumCenter = glm::vec3((minima.x + maxima.x) * 0.5f, (minima.y + maxima.y) * 0.5f, (minima.z + maxima.z) * 0.5f); | ||
| 3092 | glm::vec3 shadowFrustumCenter = rotation * ((minima + maxima) * 0.5f); | ||
| 3093 | _shadowViewFrustum.setPosition(shadowFrustumCenter); | ||
| 3094 | _shadowViewFrustum.setOrientation(rotation); | ||
| 3095 | _shadowViewFrustum.setProjection(glm::ortho(minima.x, maxima.x, minima.y, maxima.y, minima.z, maxima.z)); | ||
| 3096 | _shadowViewFrustum.calculate(); | ||
| 3097 | |||
| 3098 | glMatrixMode(GL_PROJECTION); | ||
| 3099 | glPushMatrix(); | ||
| 3100 | glLoadIdentity(); | ||
| 3101 | glOrtho(minima.x, maxima.x, minima.y, maxima.y, -maxima.z, -minima.z); | ||
| 3102 | |||
| 3103 | glm::mat4 projAgain; | ||
| 3104 | glGetFloatv(GL_PROJECTION_MATRIX, (GLfloat*)&projAgain); | ||
| 3105 | |||
| 3106 | |||
| 3107 | glMatrixMode(GL_MODELVIEW); | ||
| 3108 | glPushMatrix(); | ||
| 3109 | glLoadIdentity(); | ||
| 3110 | glm::vec3 axis = glm::axis(inverseRotation); | ||
| 3111 | glRotatef(glm::degrees(glm::angle(inverseRotation)), axis.x, axis.y, axis.z); | ||
| 3112 | |||
| 3113 | // store view matrix without translation, which we'll use for precision-sensitive objects | ||
| 3114 | updateUntranslatedViewMatrix(); | ||
| 3115 | |||
| 3116 | // Equivalent to what is happening with _untranslatedViewMatrix and the _viewMatrixTranslation | ||
| 3117 | // the viewTransofmr object is updatded with the correct values and saved, | ||
| 3118 | // this is what is used for rendering the Entities and avatars | ||
| 3119 | Transform viewTransform; | ||
| 3120 | viewTransform.setRotation(rotation); | ||
| 3121 | // viewTransform.postTranslate(shadowFrustumCenter); | ||
| 3122 | setViewTransform(viewTransform); | ||
| 3123 | |||
| 3124 | |||
| 3125 | glEnable(GL_POLYGON_OFFSET_FILL); | ||
| 3126 | glPolygonOffset(1.1f, 4.0f); // magic numbers courtesy http://www.eecs.berkeley.edu/~ravir/6160/papers/shadowmaps.ppt | ||
| 3127 | |||
| 3128 | { | ||
| 3129 | PerformanceTimer perfTimer("entities"); | ||
| 3130 | _entities.render(renderArgs); | ||
| 3131 | } | ||
| 3132 | |||
| 3133 | glDisable(GL_POLYGON_OFFSET_FILL); | ||
| 3134 | |||
| 3135 | glPopMatrix(); | ||
| 3136 | |||
| 3137 | glMatrixMode(GL_PROJECTION); | ||
| 3138 | glPopMatrix(); | ||
| 3139 | |||
| 3140 | glMatrixMode(GL_MODELVIEW); | ||
| 3141 | } | ||
| 3142 | |||
| 3143 | // fbo->release(); | ||
| 3144 | |||
| 3145 | glViewport(0, 0, _glWidget->getDeviceWidth(), _glWidget->getDeviceHeight()); | ||
| 3146 | activeRenderingThread = nullptr; | ||
| 3147 | } | ||
| 3148 | |||
| 3149 | const GLfloat WORLD_AMBIENT_COLOR[] = { 0.525f, 0.525f, 0.6f }; | ||
| 3150 | const GLfloat WORLD_DIFFUSE_COLOR[] = { 0.6f, 0.525f, 0.525f }; | ||
| 3151 | const GLfloat WORLD_SPECULAR_COLOR[] = { 0.08f, 0.08f, 0.08f, 1.0f }; | ||
| 3152 | |||
| 3153 | const glm::vec3 GLOBAL_LIGHT_COLOR = { 0.6f, 0.525f, 0.525f }; | ||
| 3154 | |||
| 3155 | void Application::setupWorldLight() { | ||
| 3156 | |||
| 3157 | // Setup 3D lights (after the camera transform, so that they are positioned in world space) | ||
| 3158 | glEnable(GL_COLOR_MATERIAL); | ||
| 3159 | glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); | ||
| 3160 | |||
| 3161 | glm::vec3 sunDirection = getSunDirection(); | ||
| 3162 | GLfloat light_position0[] = { sunDirection.x, sunDirection.y, sunDirection.z, 0.0 }; | ||
| 3163 | glLightfv(GL_LIGHT0, GL_POSITION, light_position0); | ||
| 3164 | glLightfv(GL_LIGHT0, GL_AMBIENT, WORLD_AMBIENT_COLOR); | ||
| 3165 | glLightfv(GL_LIGHT0, GL_DIFFUSE, WORLD_DIFFUSE_COLOR); | ||
| 3166 | glLightfv(GL_LIGHT0, GL_SPECULAR, WORLD_SPECULAR_COLOR); | ||
| 3167 | glMaterialfv(GL_FRONT, GL_SPECULAR, WORLD_SPECULAR_COLOR); | ||
| 3168 | glMateriali(GL_FRONT, GL_SHININESS, 96); | ||
| 3169 | |||
| 3170 | } | ||
| 3171 | |||
| 3172 | bool Application::shouldRenderMesh(float largestDimension, float distanceToCamera) { | 2945 | bool Application::shouldRenderMesh(float largestDimension, float distanceToCamera) { |
| 3173 | return DependencyManager::get<LODManager>()->shouldRenderMesh(largestDimension, distanceToCamera); | 2946 | return DependencyManager::get<LODManager>()->shouldRenderMesh(largestDimension, distanceToCamera); |
| 3174 | } | 2947 | } |
| @@ -3189,35 +2962,25 @@ PickRay Application::computePickRay(float x, float y) const { · 14 unmodified lines | |||
| 3189 | if (isHMDMode()) { | 2962 | if (isHMDMode()) { |
| 3190 | getApplicationCompositor().computeHmdPickRay(glm::vec2(x, y), result.origin, result.direction); | 2963 | getApplicationCompositor().computeHmdPickRay(glm::vec2(x, y), result.origin, result.direction); |
| 3191 | } else { | 2964 | } else { |
| 3192 | if (QThread::currentThread() == activeRenderingThread) { | 2965 | getViewFrustum()->computePickRay(x, y, result.origin, result.direction); |
| 3193 | getDisplayViewFrustum()->computePickRay(x, y, result.origin, result.direction); | ||
| 3194 | } else { | ||
| 3195 | getViewFrustum()->computePickRay(x, y, result.origin, result.direction); | ||
| 3196 | } | ||
| 3197 | } | 2966 | } |
| 3198 | return result; | 2967 | return result; |
| 3199 | } | 2968 | } |
| 3200 | 2969 | ||
| 3201 | QImage Application::renderAvatarBillboard(RenderArgs* renderArgs) { | 2970 | QImage Application::renderAvatarBillboard(RenderArgs* renderArgs) { |
| 3202 | auto primaryFramebuffer = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer(); | ||
| 3203 | glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFramebuffer)); | ||
| 3204 | |||
| 3205 | // clear the alpha channel so the background is transparent | ||
| 3206 | glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); | ||
| 3207 | glClearColor(0.0, 0.0, 0.0, 0.0); | ||
| 3208 | glClear(GL_COLOR_BUFFER_BIT); | ||
| 3209 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); | ||
| 3210 | 2971 | ||
| 3211 | const int BILLBOARD_SIZE = 64; | 2972 | const int BILLBOARD_SIZE = 64; |
| 3212 | // TODO: Pass a RenderArgs to renderAvatarBillboard | 2973 | |
| 3213 | renderRearViewMirror(renderArgs, QRect(0, _glWidget->getDeviceHeight() - BILLBOARD_SIZE, | 2974 | // Need to make sure the gl context is current here |
| 3214 | BILLBOARD_SIZE, BILLBOARD_SIZE), | 2975 | _glWidget->makeCurrent(); |
| 3215 | true); | 2976 | |
| 2977 | renderArgs->_renderMode = RenderArgs::DEFAULT_RENDER_MODE; | ||
| 2978 | renderRearViewMirror(renderArgs, QRect(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE), true); | ||
| 2979 | |||
| 2980 | auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor(); | ||
| 3216 | QImage image(BILLBOARD_SIZE, BILLBOARD_SIZE, QImage::Format_ARGB32); | 2981 | QImage image(BILLBOARD_SIZE, BILLBOARD_SIZE, QImage::Format_ARGB32); |
| 3217 | glReadPixels(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE, GL_BGRA, GL_UNSIGNED_BYTE, image.bits()); | 2982 | renderArgs->_context->downloadFramebuffer(primaryFbo, glm::ivec4(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE), image); |
| 3218 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | ||
| 3219 | 2983 | ||
| 3220 | glBindFramebuffer(GL_FRAMEBUFFER, 0); | ||
| 3221 | return image; | 2984 | return image; |
| 3222 | } | 2985 | } |
| 3223 | 2986 | ||
| @@ -3322,9 +3085,6 @@ namespace render { · 98 unmodified lines | |||
| 3322 | PerformanceTimer perfTimer("stars"); | 3085 | PerformanceTimer perfTimer("stars"); |
| 3323 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), | 3086 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), |
| 3324 | "Application::payloadRender<BackgroundRenderData>() ... stars..."); | 3087 | "Application::payloadRender<BackgroundRenderData>() ... stars..."); |
| 3325 | if (!background->_stars.isStarsLoaded()) { | ||
| 3326 | background->_stars.generate(STARFIELD_NUM_STARS, STARFIELD_SEED); | ||
| 3327 | } | ||
| 3328 | // should be the first rendering pass - w/o depth buffer / lighting | 3088 | // should be the first rendering pass - w/o depth buffer / lighting |
| 3329 | 3089 | ||
| 3330 | // compute starfield alpha based on distance from atmosphere | 3090 | // compute starfield alpha based on distance from atmosphere |
| @@ -3352,7 +3112,7 @@ namespace render { · 21 unmodified lines | |||
| 3352 | + APPROXIMATE_DISTANCE_FROM_HORIZON; | 3112 | + APPROXIMATE_DISTANCE_FROM_HORIZON; |
| 3353 | alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON); | 3113 | alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON); |
| 3354 | } | 3114 | } |
| 3355 | 3115 | ||
| 3356 | 3116 | ||
| 3357 | } else if (height < closestData.getAtmosphereOuterRadius()) { | 3117 | } else if (height < closestData.getAtmosphereOuterRadius()) { |
| 3358 | alpha = (height - closestData.getAtmosphereInnerRadius()) / | 3118 | alpha = (height - closestData.getAtmosphereInnerRadius()) / |
| @@ -3372,7 +3132,7 @@ namespace render { · 13 unmodified lines | |||
| 3372 | 3132 | ||
| 3373 | // finally render the starfield | 3133 | // finally render the starfield |
| 3374 | if (hasStars) { | 3134 | if (hasStars) { |
| 3375 | background->_stars.render(args->_viewFrustum->getFieldOfView(), args->_viewFrustum->getAspectRatio(), args->_viewFrustum->getNearClip(), alpha); | 3135 | background->_stars.render(args, alpha); |
| 3376 | } | 3136 | } |
| 3377 | 3137 | ||
| 3378 | // draw the sky dome | 3138 | // draw the sky dome |
| @@ -3387,16 +3147,12 @@ namespace render { · 8 unmodified lines | |||
| 3387 | } | 3147 | } |
| 3388 | } else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) { | 3148 | } else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) { |
| 3389 | PerformanceTimer perfTimer("skybox"); | 3149 | PerformanceTimer perfTimer("skybox"); |
| 3390 | 3150 | ||
| 3391 | skybox = skyStage->getSkybox(); | 3151 | skybox = skyStage->getSkybox(); |
| 3392 | if (skybox) { | 3152 | if (skybox) { |
| 3393 | model::Skybox::render(batch, *(Application::getInstance()->getDisplayViewFrustum()), *skybox); | 3153 | model::Skybox::render(batch, *(Application::getInstance()->getDisplayViewFrustum()), *skybox); |
| 3394 | } | 3154 | } |
| 3395 | } | 3155 | } |
| 3396 | // FIX ME - If I don't call this renderBatch() here, then the atmosphere and skybox don't render, but it | ||
| 3397 | // seems like these payloadRender() methods shouldn't be doing this. We need to investigate why the engine | ||
| 3398 | // isn't rendering our batch | ||
| 3399 | gpu::GLBackend::renderBatch(batch, true); | ||
| 3400 | } | 3156 | } |
| 3401 | } | 3157 | } |
| 3402 | 3158 | ||
| @@ -3416,76 +3172,22 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 13 unmodified lines | |||
| 3416 | // load the view frustum | 3172 | // load the view frustum |
| 3417 | loadViewFrustum(theCamera, _displayViewFrustum); | 3173 | loadViewFrustum(theCamera, _displayViewFrustum); |
| 3418 | 3174 | ||
| 3419 | // transform view according to theCamera | 3175 | // TODO fix shadows and make them use the GPU library |
| 3420 | // could be myCamera (if in normal mode) | ||
| 3421 | // or could be viewFrustumOffsetCamera if in offset mode | ||
| 3422 | |||
| 3423 | glm::quat rotation = theCamera.getRotation(); | ||
| 3424 | glm::vec3 axis = glm::axis(rotation); | ||
| 3425 | glRotatef(-glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); | ||
| 3426 | |||
| 3427 | // store view matrix without translation, which we'll use for precision-sensitive objects | ||
| 3428 | updateUntranslatedViewMatrix(-theCamera.getPosition()); | ||
| 3429 | |||
| 3430 | // Equivalent to what is happening with _untranslatedViewMatrix and the _viewMatrixTranslation | ||
| 3431 | // the viewTransofmr object is updatded with the correct values and saved, | ||
| 3432 | // this is what is used for rendering the Entities and avatars | ||
| 3433 | Transform viewTransform; | ||
| 3434 | viewTransform.setTranslation(theCamera.getPosition()); | ||
| 3435 | viewTransform.setRotation(rotation); | ||
| 3436 | if (renderArgs->_renderSide != RenderArgs::MONO) { | ||
| 3437 | glm::mat4 invView = glm::inverse(_untranslatedViewMatrix); | ||
| 3438 | |||
| 3439 | viewTransform.evalFromRawMatrix(invView); | ||
| 3440 | viewTransform.preTranslate(_viewMatrixTranslation); | ||
| 3441 | } | ||
| 3442 | |||
| 3443 | setViewTransform(viewTransform); | ||
| 3444 | |||
| 3445 | glTranslatef(_viewMatrixTranslation.x, _viewMatrixTranslation.y, _viewMatrixTranslation.z); | ||
| 3446 | |||
| 3447 | // Setup 3D lights (after the camera transform, so that they are positioned in world space) | ||
| 3448 | { | ||
| 3449 | PerformanceTimer perfTimer("lights"); | ||
| 3450 | setupWorldLight(); | ||
| 3451 | } | ||
| 3452 | |||
| 3453 | // setup shadow matrices (again, after the camera transform) | ||
| 3454 | int shadowMatrixCount = 0; | ||
| 3455 | if (Menu::getInstance()->isOptionChecked(MenuOption::SimpleShadows)) { | ||
| 3456 | shadowMatrixCount = 1; | ||
| 3457 | } else if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) { | ||
| 3458 | shadowMatrixCount = CASCADED_SHADOW_MATRIX_COUNT; | ||
| 3459 | } | ||
| 3460 | for (int i = shadowMatrixCount - 1; i >= 0; i--) { | ||
| 3461 | glActiveTexture(GL_TEXTURE0 + i); | ||
| 3462 | glTexGenfv(GL_S, GL_EYE_PLANE, (const GLfloat*)&_shadowMatrices[i][0]); | ||
| 3463 | glTexGenfv(GL_T, GL_EYE_PLANE, (const GLfloat*)&_shadowMatrices[i][1]); | ||
| 3464 | glTexGenfv(GL_R, GL_EYE_PLANE, (const GLfloat*)&_shadowMatrices[i][2]); | ||
| 3465 | } | ||
| 3466 | 3176 | ||
| 3467 | // The pending changes collecting the changes here | 3177 | // The pending changes collecting the changes here |
| 3468 | render::PendingChanges pendingChanges; | 3178 | render::PendingChanges pendingChanges; |
| 3469 | 3179 | ||
| 3470 | // Background rendering decision | 3180 | // Background rendering decision |
| 3471 | if (BackgroundRenderData::_item == 0) { | 3181 | if (BackgroundRenderData::_item == 0) { |
| 3472 | auto backgroundRenderData = BackgroundRenderData::Pointer(new BackgroundRenderData(&_environment)); | 3182 | auto backgroundRenderData = make_shared<BackgroundRenderData>(&_environment); |
| 3473 | auto backgroundRenderPayload = render::PayloadPointer(new BackgroundRenderData::Payload(backgroundRenderData)); | 3183 | auto backgroundRenderPayload = make_shared<BackgroundRenderData::Payload>(backgroundRenderData); |
| 3474 | BackgroundRenderData::_item = _main3DScene->allocateID(); | 3184 | BackgroundRenderData::_item = _main3DScene->allocateID(); |
| 3475 | pendingChanges.resetItem(WorldBoxRenderData::_item, backgroundRenderPayload); | 3185 | pendingChanges.resetItem(WorldBoxRenderData::_item, backgroundRenderPayload); |
| 3476 | } else { | 3186 | } else { |
| 3477 | 3187 | ||
| 3478 | } | 3188 | } |
| 3479 | 3189 | ||
| 3480 | if (Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) { | ||
| 3481 | glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | ||
| 3482 | } | ||
| 3483 | |||
| 3484 | glEnable(GL_LIGHTING); | ||
| 3485 | glEnable(GL_DEPTH_TEST); | ||
| 3486 | |||
| 3487 | // Assuming nothing get's rendered through that | 3190 | // Assuming nothing get's rendered through that |
| 3488 | |||
| 3489 | if (!selfAvatarOnly) { | 3191 | if (!selfAvatarOnly) { |
| 3490 | if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) { | 3192 | if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) { |
| 3491 | // render models... | 3193 | // render models... |
| @@ -3505,20 +3207,12 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 13 unmodified lines | |||
| 3505 | renderArgs->_debugFlags = renderDebugFlags; | 3207 | renderArgs->_debugFlags = renderDebugFlags; |
| 3506 | _entities.render(renderArgs); | 3208 | _entities.render(renderArgs); |
| 3507 | } | 3209 | } |
| 3508 | |||
| 3509 | // render the ambient occlusion effect if enabled | ||
| 3510 | if (Menu::getInstance()->isOptionChecked(MenuOption::AmbientOcclusion)) { | ||
| 3511 | PerformanceTimer perfTimer("ambientOcclusion"); | ||
| 3512 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), | ||
| 3513 | "Application::displaySide() ... AmbientOcclusion..."); | ||
| 3514 | DependencyManager::get<AmbientOcclusionEffect>()->render(); | ||
| 3515 | } | ||
| 3516 | } | 3210 | } |
| 3517 | 3211 | ||
| 3518 | // Make sure the WorldBox is in the scene | 3212 | // Make sure the WorldBox is in the scene |
| 3519 | if (WorldBoxRenderData::_item == 0) { | 3213 | if (WorldBoxRenderData::_item == 0) { |
| 3520 | auto worldBoxRenderData = WorldBoxRenderData::Pointer(new WorldBoxRenderData()); | 3214 | auto worldBoxRenderData = make_shared<WorldBoxRenderData>(); |
| 3521 | auto worldBoxRenderPayload = render::PayloadPointer(new WorldBoxRenderData::Payload(worldBoxRenderData)); | 3215 | auto worldBoxRenderPayload = make_shared<WorldBoxRenderData::Payload>(worldBoxRenderData); |
| 3522 | 3216 | ||
| 3523 | WorldBoxRenderData::_item = _main3DScene->allocateID(); | 3217 | WorldBoxRenderData::_item = _main3DScene->allocateID(); |
| 3524 | 3218 | ||
| @@ -3572,6 +3266,8 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 47 unmodified lines | |||
| 3572 | renderContext._drawItemStatus = sceneInterface->doEngineDisplayItemStatus(); | 3266 | renderContext._drawItemStatus = sceneInterface->doEngineDisplayItemStatus(); |
| 3573 | renderContext._drawHitEffect = sceneInterface->doEngineDisplayHitEffect(); | 3267 | renderContext._drawHitEffect = sceneInterface->doEngineDisplayHitEffect(); |
| 3574 | 3268 | ||
| 3269 | renderContext._occlusionStatus = Menu::getInstance()->isOptionChecked(MenuOption::DebugAmbientOcclusion); | ||
| 3270 | |||
| 3575 | renderArgs->_shouldRender = LODManager::shouldRender; | 3271 | renderArgs->_shouldRender = LODManager::shouldRender; |
| 3576 | 3272 | ||
| 3577 | renderContext.args = renderArgs; | 3273 | renderContext.args = renderArgs; |
| @@ -3580,7 +3276,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 2 unmodified lines | |||
| 3580 | 3276 | ||
| 3581 | // Before the deferred pass, let's try to use the render engine | 3277 | // Before the deferred pass, let's try to use the render engine |
| 3582 | _renderEngine->run(); | 3278 | _renderEngine->run(); |
| 3583 | 3279 | ||
| 3584 | auto engineRC = _renderEngine->getRenderContext(); | 3280 | auto engineRC = _renderEngine->getRenderContext(); |
| 3585 | sceneInterface->setEngineFeedOpaqueItems(engineRC->_numFeedOpaqueItems); | 3281 | sceneInterface->setEngineFeedOpaqueItems(engineRC->_numFeedOpaqueItems); |
| 3586 | sceneInterface->setEngineDrawnOpaqueItems(engineRC->_numDrawnOpaqueItems); | 3282 | sceneInterface->setEngineDrawnOpaqueItems(engineRC->_numDrawnOpaqueItems); |
| @@ -3591,10 +3287,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 4 unmodified lines | |||
| 3591 | sceneInterface->setEngineFeedOverlay3DItems(engineRC->_numFeedOverlay3DItems); | 3287 | sceneInterface->setEngineFeedOverlay3DItems(engineRC->_numFeedOverlay3DItems); |
| 3592 | sceneInterface->setEngineDrawnOverlay3DItems(engineRC->_numDrawnOverlay3DItems); | 3288 | sceneInterface->setEngineDrawnOverlay3DItems(engineRC->_numDrawnOverlay3DItems); |
| 3593 | } | 3289 | } |
| 3594 | //Render the sixense lasers | ||
| 3595 | if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers)) { | ||
| 3596 | _myAvatar->renderLaserPointers(*renderArgs->_batch); | ||
| 3597 | } | ||
| 3598 | 3290 | ||
| 3599 | if (!selfAvatarOnly) { | 3291 | if (!selfAvatarOnly) { |
| 3600 | // give external parties a change to hook in | 3292 | // give external parties a change to hook in |
| @@ -3604,37 +3296,9 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 3 unmodified lines | |||
| 3604 | } | 3296 | } |
| 3605 | } | 3297 | } |
| 3606 | 3298 | ||
| 3607 | if (Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) { | ||
| 3608 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | ||
| 3609 | } | ||
| 3610 | |||
| 3611 | activeRenderingThread = nullptr; | 3299 | activeRenderingThread = nullptr; |
| 3612 | } | 3300 | } |
| 3613 | 3301 | ||
| 3614 | void Application::updateUntranslatedViewMatrix(const glm::vec3& viewMatrixTranslation) { | ||
| 3615 | glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*)&_untranslatedViewMatrix); | ||
| 3616 | _viewMatrixTranslation = viewMatrixTranslation; | ||
| 3617 | } | ||
| 3618 | |||
| 3619 | void Application::setViewTransform(const Transform& view) { | ||
| 3620 | _viewTransform = view; | ||
| 3621 | } | ||
| 3622 | |||
| 3623 | void Application::loadTranslatedViewMatrix(const glm::vec3& translation) { | ||
| 3624 | glLoadMatrixf((const GLfloat*)&_untranslatedViewMatrix); | ||
| 3625 | glTranslatef(translation.x + _viewMatrixTranslation.x, translation.y + _viewMatrixTranslation.y, | ||
| 3626 | translation.z + _viewMatrixTranslation.z); | ||
| 3627 | } | ||
| 3628 | |||
| 3629 | void Application::getModelViewMatrix(glm::dmat4* modelViewMatrix) { | ||
| 3630 | (*modelViewMatrix) =_untranslatedViewMatrix; | ||
| 3631 | (*modelViewMatrix)[3] = _untranslatedViewMatrix * glm::vec4(_viewMatrixTranslation, 1); | ||
| 3632 | } | ||
| 3633 | |||
| 3634 | void Application::getProjectionMatrix(glm::dmat4* projectionMatrix) { | ||
| 3635 | *projectionMatrix = _projectionMatrix; | ||
| 3636 | } | ||
| 3637 | |||
| 3638 | void Application::computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal, | 3302 | void Application::computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal, |
| 3639 | float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const { | 3303 | float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const { |
| 3640 | 3304 | ||
| @@ -3685,9 +3349,9 @@ glm::vec2 Application::getScaledScreenPoint(glm::vec2 projectedPoint) { · 44 unmodified lines | |||
| 3685 | } | 3349 | } |
| 3686 | 3350 | ||
| 3687 | void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool billboard) { | 3351 | void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool billboard) { |
| 3352 | auto originalViewport = renderArgs->_viewport; | ||
| 3688 | // Grab current viewport to reset it at the end | 3353 | // Grab current viewport to reset it at the end |
| 3689 | int viewport[4]; | 3354 | |
| 3690 | glGetIntegerv(GL_VIEWPORT, viewport); | ||
| 3691 | float aspect = (float)region.width() / region.height(); | 3355 | float aspect = (float)region.width() / region.height(); |
| 3692 | float fov = MIRROR_FIELD_OF_VIEW; | 3356 | float fov = MIRROR_FIELD_OF_VIEW; |
| 3693 | 3357 | ||
| @@ -3718,43 +3382,30 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi · 24 unmodified lines | |||
| 3718 | // This was removed in commit 71e59cfa88c6563749594e25494102fe01db38e9 but could be further | 3382 | // This was removed in commit 71e59cfa88c6563749594e25494102fe01db38e9 but could be further |
| 3719 | // investigated in order to adapt the technique while fixing the head rendering issue, | 3383 | // investigated in order to adapt the technique while fixing the head rendering issue, |
| 3720 | // but the complexity of the hack suggests that a better approach | 3384 | // but the complexity of the hack suggests that a better approach |
| 3721 | _mirrorCamera.setPosition(_myAvatar->getHead()->getEyePosition() + | 3385 | _mirrorCamera.setPosition(_myAvatar->getDefaultEyePosition() + |
| 3722 | _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale()); | 3386 | _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale()); |
| 3723 | } | 3387 | } |
| 3724 | _mirrorCamera.setProjection(glm::perspective(glm::radians(fov), aspect, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP)); | 3388 | _mirrorCamera.setProjection(glm::perspective(glm::radians(fov), aspect, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP)); |
| 3725 | _mirrorCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); | 3389 | _mirrorCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f))); |
| 3726 | 3390 | ||
| 3391 | |||
| 3727 | // set the bounds of rear mirror view | 3392 | // set the bounds of rear mirror view |
| 3393 | gpu::Vec4i viewport; | ||
| 3728 | if (billboard) { | 3394 | if (billboard) { |
| 3729 | QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize(); | 3395 | viewport = gpu::Vec4i(0, 0, region.width(), region.height()); |
| 3730 | glViewport(region.x(), size.height() - region.y() - region.height(), region.width(), region.height()); | ||
| 3731 | glScissor(region.x(), size.height() - region.y() - region.height(), region.width(), region.height()); | ||
| 3732 | renderArgs->_viewport = glm::ivec4(region.x(), size.height() - region.y() - region.height(), region.width(), region.height()); | ||
| 3733 | } else { | 3396 | } else { |
| 3734 | // if not rendering the billboard, the region is in device independent coordinates; must convert to device | 3397 | // if not rendering the billboard, the region is in device independent coordinates; must convert to device |
| 3735 | QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize(); | ||
| 3736 | float ratio = (float)QApplication::desktop()->windowHandle()->devicePixelRatio() * getRenderResolutionScale(); | 3398 | float ratio = (float)QApplication::desktop()->windowHandle()->devicePixelRatio() * getRenderResolutionScale(); |
| 3737 | int x = region.x() * ratio, y = region.y() * ratio, width = region.width() * ratio, height = region.height() * ratio; | 3399 | int width = region.width() * ratio; |
| 3738 | glViewport(x, size.height() - y - height, width, height); | 3400 | int height = region.height() * ratio; |
| 3739 | glScissor(x, size.height() - y - height, width, height); | 3401 | viewport = gpu::Vec4i(0, 0, width, height); |
| 3740 | |||
| 3741 | renderArgs->_viewport = glm::ivec4(x, size.height() - y - height, width, height); | ||
| 3742 | } | 3402 | } |
| 3743 | bool updateViewFrustum = false; | 3403 | renderArgs->_viewport = viewport; |
| 3744 | updateProjectionMatrix(_mirrorCamera, updateViewFrustum); | ||
| 3745 | glEnable(GL_SCISSOR_TEST); | ||
| 3746 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||
| 3747 | 3404 | ||
| 3748 | // render rear mirror view | 3405 | // render rear mirror view |
| 3749 | glPushMatrix(); | ||
| 3750 | displaySide(renderArgs, _mirrorCamera, true, billboard); | 3406 | displaySide(renderArgs, _mirrorCamera, true, billboard); |
| 3751 | glPopMatrix(); | ||
| 3752 | 3407 | ||
| 3753 | // reset Viewport and projection matrix | 3408 | renderArgs->_viewport = originalViewport; |
| 3754 | renderArgs->_viewport = glm::ivec4(viewport[0], viewport[1], viewport[2], viewport[3]); | ||
| 3755 | glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); | ||
| 3756 | glDisable(GL_SCISSOR_TEST); | ||
| 3757 | updateProjectionMatrix(_myCamera, updateViewFrustum); | ||
| 3758 | } | 3409 | } |
| 3759 | 3410 | ||
| 3760 | void Application::resetSensors() { | 3411 | void Application::resetSensors() { |
| @@ -3841,11 +3492,24 @@ void Application::domainChanged(const QString& domainHostname) { · 80 unmodified lines | |||
| 3841 | _domainConnectionRefusals.clear(); | 3492 | _domainConnectionRefusals.clear(); |
| 3842 | } | 3493 | } |
| 3843 | 3494 | ||
| 3844 | void Application::domainConnectionDenied(const QString& reason) { | 3495 | void Application::handleDomainConnectionDeniedPacket(QSharedPointer<NLPacket> packet) { |
| 3496 | // Read deny reason from packet | ||
| 3497 | quint16 reasonSize; | ||
| 3498 | packet->readPrimitive(&reasonSize); | ||
| 3499 | QString reason = QString::fromUtf8(packet->getPayload() + packet->pos(), reasonSize); | ||
| 3500 | packet->seek(packet->pos() + reasonSize); | ||
| 3501 | |||
| 3502 | // output to the log so the user knows they got a denied connection request | ||
| 3503 | // and check and signal for an access token so that we can make sure they are logged in | ||
| 3504 | qCDebug(interfaceapp) << "The domain-server denied a connection request: " << reason; | ||
| 3505 | qCDebug(interfaceapp) << "You may need to re-log to generate a keypair so you can provide a username signature."; | ||
| 3506 | |||
| 3845 | if (!_domainConnectionRefusals.contains(reason)) { | 3507 | if (!_domainConnectionRefusals.contains(reason)) { |
| 3846 | _domainConnectionRefusals.append(reason); | 3508 | _domainConnectionRefusals.append(reason); |
| 3847 | emit domainConnectionRefused(reason); | 3509 | emit domainConnectionRefused(reason); |
| 3848 | } | 3510 | } |
| 3511 | |||
| 3512 | AccountManager::getInstance().checkAndSignalForAccessToken(); | ||
| 3849 | } | 3513 | } |
| 3850 | 3514 | ||
| 3851 | void Application::connectedToDomain(const QString& hostname) { | 3515 | void Application::connectedToDomain(const QString& hostname) { |
| @@ -3910,12 +3574,12 @@ void Application::nodeKilled(SharedNodePointer node) { · 58 unmodified lines | |||
| 3910 | DependencyManager::get<AvatarManager>()->clearOtherAvatars(); | 3574 | DependencyManager::get<AvatarManager>()->clearOtherAvatars(); |
| 3911 | } | 3575 | } |
| 3912 | } | 3576 | } |
| 3913 | 3577 | ||
| 3914 | void Application::trackIncomingOctreePacket(const QByteArray& packet, const SharedNodePointer& sendingNode, bool wasStatsPacket) { | 3578 | void Application::trackIncomingOctreePacket(NLPacket& packet, SharedNodePointer sendingNode, bool wasStatsPacket) { |
| 3915 | 3579 | ||
| 3916 | // Attempt to identify the sender from its address. | 3580 | // Attempt to identify the sender from its address. |
| 3917 | if (sendingNode) { | 3581 | if (sendingNode) { |
| 3918 | QUuid nodeUUID = sendingNode->getUUID(); | 3582 | const QUuid& nodeUUID = sendingNode->getUUID(); |
| 3919 | 3583 | ||
| 3920 | // now that we know the node ID, let's add these stats to the stats for that node... | 3584 | // now that we know the node ID, let's add these stats to the stats for that node... |
| 3921 | _octreeSceneStatsLock.lockForWrite(); | 3585 | _octreeSceneStatsLock.lockForWrite(); |
| @@ -3927,60 +3591,54 @@ void Application::trackIncomingOctreePacket(const QByteArray& packet, const Shar · 5 unmodified lines | |||
| 3927 | } | 3591 | } |
| 3928 | } | 3592 | } |
| 3929 | 3593 | ||
| 3930 | int Application::parseOctreeStats(const QByteArray& packet, const SharedNodePointer& sendingNode) { | 3594 | int Application::processOctreeStats(NLPacket& packet, SharedNodePointer sendingNode) { |
| 3931 | // But, also identify the sender, and keep track of the contained jurisdiction root for this server | 3595 | // But, also identify the sender, and keep track of the contained jurisdiction root for this server |
| 3932 | 3596 | ||
| 3933 | // parse the incoming stats datas stick it in a temporary object for now, while we | 3597 | // parse the incoming stats datas stick it in a temporary object for now, while we |
| 3934 | // determine which server it belongs to | 3598 | // determine which server it belongs to |
| 3935 | OctreeSceneStats temp; | 3599 | int statsMessageLength = 0; |
| 3936 | int statsMessageLength = temp.unpackFromMessage(reinterpret_cast<const unsigned char*>(packet.data()), packet.size()); | ||
| 3937 | 3600 | ||
| 3938 | // quick fix for crash... why would voxelServer be NULL? | 3601 | const QUuid& nodeUUID = sendingNode->getUUID(); |
| 3939 | if (sendingNode) { | 3602 | |
| 3940 | QUuid nodeUUID = sendingNode->getUUID(); | 3603 | // now that we know the node ID, let's add these stats to the stats for that node... |
| 3604 | _octreeSceneStatsLock.lockForWrite(); | ||
| 3605 | |||
| 3606 | OctreeSceneStats& octreeStats = _octreeServerSceneStats[nodeUUID]; | ||
| 3607 | statsMessageLength = octreeStats.unpackFromPacket(packet); | ||
| 3608 | |||
| 3609 | _octreeSceneStatsLock.unlock(); | ||
| 3941 | 3610 | ||
| 3942 | // now that we know the node ID, let's add these stats to the stats for that node... | 3611 | // see if this is the first we've heard of this node... |
| 3943 | _octreeSceneStatsLock.lockForWrite(); | 3612 | NodeToJurisdictionMap* jurisdiction = NULL; |
| 3944 | if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) { | 3613 | QString serverType; |
| 3945 | _octreeServerSceneStats[nodeUUID].unpackFromMessage(reinterpret_cast<const unsigned char*>(packet.data()), | 3614 | if (sendingNode->getType() == NodeType::EntityServer) { |
| 3946 | packet.size()); | 3615 | jurisdiction = &_entityServerJurisdictions; |
| 3947 | } else { | 3616 | serverType = "Entity"; |
| 3948 | _octreeServerSceneStats[nodeUUID] = temp; | 3617 | } |
| 3949 | } | ||
| 3950 | _octreeSceneStatsLock.unlock(); | ||
| 3951 | 3618 | ||
| 3619 | jurisdiction->lockForRead(); | ||
| 3620 | if (jurisdiction->find(nodeUUID) == jurisdiction->end()) { | ||
| 3621 | jurisdiction->unlock(); | ||
| 3622 | |||
| 3952 | VoxelPositionSize rootDetails; | 3623 | VoxelPositionSize rootDetails; |
| 3953 | voxelDetailsForCode(temp.getJurisdictionRoot(), rootDetails); | 3624 | voxelDetailsForCode(octreeStats.getJurisdictionRoot(), rootDetails); |
| 3954 | 3625 | ||
| 3955 | // see if this is the first we've heard of this node... | 3626 | qCDebug(interfaceapp, "stats from new %s server... [%f, %f, %f, %f]", |
| 3956 | NodeToJurisdictionMap* jurisdiction = NULL; | 3627 | qPrintable(serverType), |
| 3957 | QString serverType; | 3628 | (double)rootDetails.x, (double)rootDetails.y, (double)rootDetails.z, (double)rootDetails.s); |
| 3958 | if (sendingNode->getType() == NodeType::EntityServer) { | 3629 | } else { |
| 3959 | jurisdiction = &_entityServerJurisdictions; | ||
| 3960 | serverType = "Entity"; | ||
| 3961 | } | ||
| 3962 | |||
| 3963 | jurisdiction->lockForRead(); | ||
| 3964 | if (jurisdiction->find(nodeUUID) == jurisdiction->end()) { | ||
| 3965 | jurisdiction->unlock(); | ||
| 3966 | |||
| 3967 | qCDebug(interfaceapp, "stats from new %s server... [%f, %f, %f, %f]", | ||
| 3968 | qPrintable(serverType), | ||
| 3969 | (double)rootDetails.x, (double)rootDetails.y, (double)rootDetails.z, (double)rootDetails.s); | ||
| 3970 | |||
| 3971 | } else { | ||
| 3972 | jurisdiction->unlock(); | ||
| 3973 | } | ||
| 3974 | // store jurisdiction details for later use | ||
| 3975 | // This is bit of fiddling is because JurisdictionMap assumes it is the owner of the values used to construct it | ||
| 3976 | // but OctreeSceneStats thinks it's just returning a reference to its contents. So we need to make a copy of the | ||
| 3977 | // details from the OctreeSceneStats to construct the JurisdictionMap | ||
| 3978 | JurisdictionMap jurisdictionMap; | ||
| 3979 | jurisdictionMap.copyContents(temp.getJurisdictionRoot(), temp.getJurisdictionEndNodes()); | ||
| 3980 | jurisdiction->lockForWrite(); | ||
| 3981 | (*jurisdiction)[nodeUUID] = jurisdictionMap; | ||
| 3982 | jurisdiction->unlock(); | 3630 | jurisdiction->unlock(); |
| 3983 | } | 3631 | } |
| 3632 | // store jurisdiction details for later use | ||
| 3633 | // This is bit of fiddling is because JurisdictionMap assumes it is the owner of the values used to construct it | ||
| 3634 | // but OctreeSceneStats thinks it's just returning a reference to its contents. So we need to make a copy of the | ||
| 3635 | // details from the OctreeSceneStats to construct the JurisdictionMap | ||
| 3636 | JurisdictionMap jurisdictionMap; | ||
| 3637 | jurisdictionMap.copyContents(octreeStats.getJurisdictionRoot(), octreeStats.getJurisdictionEndNodes()); | ||
| 3638 | jurisdiction->lockForWrite(); | ||
| 3639 | (*jurisdiction)[nodeUUID] = jurisdictionMap; | ||
| 3640 | jurisdiction->unlock(); | ||
| 3641 | |||
| 3984 | return statsMessageLength; | 3642 | return statsMessageLength; |
| 3985 | } | 3643 | } |
| 3986 | 3644 | ||
| @@ -4120,10 +3778,13 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri · 133 unmodified lines | |||
| 4120 | 3778 | ||
| 4121 | // when the worker thread is started, call our engine's run.. | 3779 | // when the worker thread is started, call our engine's run.. |
| 4122 | connect(workerThread, &QThread::started, scriptEngine, &ScriptEngine::run); | 3780 | connect(workerThread, &QThread::started, scriptEngine, &ScriptEngine::run); |
| 4123 | 3781 | ||
| 4124 | // when the thread is terminated, add both scriptEngine and thread to the deleteLater queue | 3782 | // when the thread is terminated, add both scriptEngine and thread to the deleteLater queue |
| 4125 | connect(scriptEngine, SIGNAL(doneRunning()), scriptEngine, SLOT(deleteLater())); | 3783 | connect(scriptEngine, &ScriptEngine::doneRunning, scriptEngine, &ScriptEngine::deleteLater); |
| 4126 | connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater())); | 3784 | connect(workerThread, &QThread::finished, workerThread, &QThread::deleteLater); |
| 3785 | |||
| 3786 | // tell the thread to stop when the script engine is done | ||
| 3787 | connect(scriptEngine, &ScriptEngine::destroyed, workerThread, &QThread::quit); | ||
| 4127 | 3788 | ||
| 4128 | auto nodeList = DependencyManager::get<NodeList>(); | 3789 | auto nodeList = DependencyManager::get<NodeList>(); |
| 4129 | connect(nodeList.data(), &NodeList::nodeKilled, scriptEngine, &ScriptEngine::nodeKilled); | 3790 | connect(nodeList.data(), &NodeList::nodeKilled, scriptEngine, &ScriptEngine::nodeKilled); |
| @@ -4763,7 +4424,11 @@ void Application::friendsWindowClosed() { · 633 unmodified lines | |||
| 4763 | } | 4424 | } |
| 4764 | 4425 | ||
| 4765 | void Application::postLambdaEvent(std::function<void()> f) { | 4426 | void Application::postLambdaEvent(std::function<void()> f) { |
| 4766 | QCoreApplication::postEvent(this, new LambdaEvent(f)); | 4427 | if (this->thread() == QThread::currentThread()) { |
| 4428 | f(); | ||
| 4429 | } else { | ||
| 4430 | QCoreApplication::postEvent(this, new LambdaEvent(f)); | ||
| 4431 | } | ||
| 4767 | } | 4432 | } |
| 4768 | 4433 | ||
| 4769 | void Application::initPlugins() { | 4434 | void Application::initPlugins() { |
| @@ -4824,7 +4489,7 @@ mat4 Application::getEyeProjection(int eye) const { · 54 unmodified lines | |||
| 4824 | if (isHMDMode()) { | 4489 | if (isHMDMode()) { |
| 4825 | return OculusManager::getEyeProjection(eye); | 4490 | return OculusManager::getEyeProjection(eye); |
| 4826 | } | 4491 | } |
| 4827 | 4492 | ||
| 4828 | return _viewFrustum.getProjection(); | 4493 | return _viewFrustum.getProjection(); |
| 4829 | } | 4494 | } |
| 4830 | 4495 | ||