History

fixed merge conflicts and refactored hit effect to catch up with refactored rendering engine

ericrius1 committed 11 years ago

Commit 697cb4c2 parents 469bace 6a5c298406 files · +11309 −11832Browse files

Showing the changes to interface/src/Application.cpp (1 of 406 files). Show all

Unified · Split

interface/src/Application.cpp+280−615
@@ -9,11 +9,9 @@ · 8 unmodified lines
9// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html9// 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
174using namespace std;169using namespace std;
175 170
176// Starfield information171// Starfield information
177static unsigned STARFIELD_NUM_STARS = 50000;
178static unsigned STARFIELD_SEED = 1;
179static uint8_t THROTTLED_IDLE_TIMER_DELAY = 10;172static uint8_t THROTTLED_IDLE_TIMER_DELAY = 10;
180 173
181const qint64 MAXIMUM_CACHE_SIZE = 10 * BYTES_PER_GIGABYTES; // 10GB174const 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 menu364 _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 running370 // 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 priority375 // 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 ins378 // 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 thread393 // 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 AccountManager459 // 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 surface534 // the GL surface
538 _glWidget->setCursor(Qt::BlankCursor);535 _glWidget->setCursor(Qt::BlankCursor);
539#endif536#endif
540 537
541 // enable mouse tracking; otherwise, we only get drag events538 // 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 estimator569 // 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#endif636#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
646void Application::aboutToQuit() {646void Application::aboutToQuit() {
@@ -653,8 +653,10 @@ void Application::aboutToQuit() { · 6 unmodified lines
653void Application::cleanupBeforeQuit() {653void Application::cleanupBeforeQuit() {
654 654
655 _entities.clear(); // this will allow entity scripts to properly shutdown655 _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 circuit657 // 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 scripts660 _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 scripts661 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 done747 // 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 #endif768 #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 renderArgs906 // NOTE: There is no batch associated with this renderArgs
900 // the ApplicationOverlay class assumes it's viewport is setup to be the device size907 // 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 position961 // 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 rotation967 //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 framebuffer977 // 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
1099void Application::updateProjectionMatrix() {
1100 updateProjectionMatrix(_myCamera);
1101}
1102
1103void 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
1117void 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
1124bool Application::importSVOFromURL(const QString& urlString) {1078bool 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
1788void Application::sendPingPackets() {1736void Application::sendPingPackets() {
1789 QByteArray pingPacket = DependencyManager::get<NodeList>()->constructPingPacket();1737
1790 controlledBroadcastToNodes(pingPacket, NodeSet()1738 auto nodeList = DependencyManager::get<NodeList>();
1791 << NodeType::EntityServer1739
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 stuff1754// 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 not1832 // 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
2153void Application::initDisplay() {2114void 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
2162void Application::init() {2117void 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 AvatarManager2125 // 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
2263const float HEAD_SPHERE_RADIUS = 0.1f;2217const float HEAD_SPHERE_RADIUS = 0.1f;
2264 2218
2265bool Application::isLookingAtMyAvatar(Avatar* avatar) {2219bool 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 eyes2282 // 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 set2681 // 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 node2688 // 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 header2696 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
2767void Application::queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions) {2709void 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 serverType2802 // 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 UUID2876 // 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 socket2880 // 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 builds2942// FIXME, preprocessor guard this check to occur only in DEBUG builds
3007static QThread * activeRenderingThread = nullptr;2943static QThread * activeRenderingThread = nullptr;
3008 2944
3009void 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
3149const GLfloat WORLD_AMBIENT_COLOR[] = { 0.525f, 0.525f, 0.6f };
3150const GLfloat WORLD_DIFFUSE_COLOR[] = { 0.6f, 0.525f, 0.525f };
3151const GLfloat WORLD_SPECULAR_COLOR[] = { 0.08f, 0.08f, 0.08f, 1.0f };
3152
3153const glm::vec3 GLOBAL_LIGHT_COLOR = { 0.6f, 0.525f, 0.525f };
3154
3155void 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
3172bool Application::shouldRenderMesh(float largestDimension, float distanceToCamera) {2945bool 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
3201QImage Application::renderAvatarBillboard(RenderArgs* renderArgs) {2970QImage 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 renderAvatarBillboard2973
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 / lighting3088 // should be the first rendering pass - w/o depth buffer / lighting
3329 3089
3330 // compute starfield alpha based on distance from atmosphere3090 // 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 starfield3133 // 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 dome3138 // 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 frustum3172 // load the view frustum
3417 loadViewFrustum(theCamera, _displayViewFrustum);3173 loadViewFrustum(theCamera, _displayViewFrustum);
3418 3174
3419 // transform view according to theCamera3175 // 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 here3177 // The pending changes collecting the changes here
3468 render::PendingChanges pendingChanges;3178 render::PendingChanges pendingChanges;
3469 3179
3470 // Background rendering decision3180 // 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 that3190 // 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 scene3212 // 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 engine3277 // 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 in3292 // 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
3614void Application::updateUntranslatedViewMatrix(const glm::vec3& viewMatrixTranslation) {
3615 glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*)&_untranslatedViewMatrix);
3616 _viewMatrixTranslation = viewMatrixTranslation;
3617}
3618
3619void Application::setViewTransform(const Transform& view) {
3620 _viewTransform = view;
3621}
3622
3623void 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
3629void Application::getModelViewMatrix(glm::dmat4* modelViewMatrix) {
3630 (*modelViewMatrix) =_untranslatedViewMatrix;
3631 (*modelViewMatrix)[3] = _untranslatedViewMatrix * glm::vec4(_viewMatrixTranslation, 1);
3632}
3633
3634void Application::getProjectionMatrix(glm::dmat4* projectionMatrix) {
3635 *projectionMatrix = _projectionMatrix;
3636}
3637
3638void Application::computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal,3302void 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
3687void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool billboard) {3351void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool billboard) {
3352 auto originalViewport = renderArgs->_viewport;
3688 // Grab current viewport to reset it at the end3353 // 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 further3382 // 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 approach3384 // 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 view3392 // 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 device3397 // 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 view3405 // 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 matrix3408 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
3760void Application::resetSensors() {3411void 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
3844void Application::domainConnectionDenied(const QString& reason) {3495void 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
3851void Application::connectedToDomain(const QString& hostname) {3515void 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
3914void Application::trackIncomingOctreePacket(const QByteArray& packet, const SharedNodePointer& sendingNode, bool wasStatsPacket) {3578void 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
3930int Application::parseOctreeStats(const QByteArray& packet, const SharedNodePointer& sendingNode) {3594int Application::processOctreeStats(NLPacket& packet, SharedNodePointer sendingNode) {
3931 // But, also identify the sender, and keep track of the contained jurisdiction root for this server3595 // 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 we3597 // parse the incoming stats datas stick it in a temporary object for now, while we
3934 // determine which server it belongs to3598 // 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 queue3782 // 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
4765void Application::postLambdaEvent(std::function<void()> f) {4426void 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
4769void Application::initPlugins() {4434void 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