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
99 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
1010 //
1111
12−#include <sstream>
12+#include "Application.h"
1313
14−#include <stdlib.h>
15−#include <cmath>
16−#include <math.h>
14+#include <sstream>
1715
1816 #include <glm/glm.hpp>
1917 #include <glm/gtx/component_wise.hpp>
@@ -21,9 +19,6 @@ · 1 unmodified line
2119 #include <glm/gtx/vector_angle.hpp>
2220 #include <glm/gtc/type_ptr.hpp>
2321
24−// include this before QGLWidget, which includes an earlier version of OpenGL
25−#include "InterfaceConfig.h"
26−
2722 #include <QAbstractNativeEventFilter>
2823 #include <QActionGroup>
2924 #include <QColorDialog>
@@ -58,13 +53,13 @@ · 28 unmodified lines
5853 #include <AccountManager.h>
5954 #include <AddressManager.h>
6055 #include <CursorManager.h>
61−#include <AmbientOcclusionEffect.h>
6256 #include <AudioInjector.h>
6357 #include <AutoUpdater.h>
6458 #include <DeferredLightingEffect.h>
6559 #include <DependencyManager.h>
6660 #include <EntityScriptingInterface.h>
6761 #include <ErrorDialog.h>
62+#include <FramebufferCache.h>
6863 #include <gpu/Batch.h>
6964 #include <gpu/Context.h>
7065 #include <gpu/GLBackend.h>
@@ -80,11 +75,10 @@ · 9 unmodified lines
8075 #include <ObjectMotionState.h>
8176 #include <OctalCode.h>
8277 #include <OctreeSceneStats.h>
83−#include <PacketHeaders.h>
78+#include <udt/PacketHeaders.h>
8479 #include <PathUtils.h>
8580 #include <PerfStat.h>
8681 #include <PhysicsEngine.h>
87−#include <ProgramObject.h>
8882 #include <RenderDeferredTask.h>
8983 #include <ResourceCache.h>
9084 #include <SceneScriptingInterface.h>
@@ -92,14 +86,15 @@ · 1 unmodified line
9286 #include <SettingHandle.h>
9387 #include <SimpleAverage.h>
9488 #include <SoundCache.h>
89+#include <TextureCache.h>
9590 #include <Tooltip.h>
9691 #include <UserActivityLogger.h>
9792 #include <UUID.h>
9893 #include <VrMenu.h>
9994
100−#include "Application.h"
10195 #include "AudioClient.h"
10296 #include "DiscoverabilityManager.h"
97+#include "GLCanvas.h"
10398 #include "InterfaceVersion.h"
10499 #include "LODManager.h"
105100 #include "Menu.h"
@@ -174,8 +169,6 @@ public: · 68 unmodified lines
174169 using namespace std;
175170
176171 // Starfield information
177−static unsigned STARFIELD_NUM_STARS = 50000;
178−static unsigned STARFIELD_SEED = 1;
179172 static uint8_t THROTTLED_IDLE_TIMER_DELAY = 10;
180173
181174 const qint64 MAXIMUM_CACHE_SIZE = 10 * BYTES_PER_GIGABYTES; // 10GB
@@ -271,8 +264,9 @@ bool setupEssentials(int& argc, char** argv) { · 89 unmodified lines
271264 auto audio = DependencyManager::set<AudioClient>();
272265 auto audioScope = DependencyManager::set<AudioScope>();
273266 auto deferredLightingEffect = DependencyManager::set<DeferredLightingEffect>();
274− auto ambientOcclusionEffect = DependencyManager::set<AmbientOcclusionEffect>();
275267 auto textureCache = DependencyManager::set<TextureCache>();
268+ auto framebufferCache = DependencyManager::set<FramebufferCache>();
269+
276270 auto animationCache = DependencyManager::set<AnimationCache>();
277271 auto ddeFaceTracker = DependencyManager::set<DdeFaceTracker>();
278272 auto modelBlender = DependencyManager::set<ModelBlender>();
@@ -303,7 +297,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 24 unmodified lines
303297 _window(new MainWindow(desktop())),
304298 _toolWindow(NULL),
305299 _friendsWindow(NULL),
306− _datagramProcessor(),
307300 _undoStack(),
308301 _undoStackScriptingInterface(&_undoStack),
309302 _frameCount(0),
@@ -321,7 +314,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 11 unmodified lines
321314 _previousScriptLocation("LastScriptLocation"),
322315 _scriptsLocationHandle("scriptsLocation"),
323316 _fieldOfView("fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES),
324− _viewTransform(),
325317 _scaleMirror(1.0f),
326318 _rotateMirror(0.0f),
327319 _raiseMirror(0.0f),
@@ -338,9 +330,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 10 unmodified lines
338330 _lastNackTime(usecTimestampNow()),
339331 _lastSendDownstreamAudioStats(usecTimestampNow()),
340332 _isVSyncOn(true),
341− _isThrottleFPSEnabled(false),
333+ _isThrottleFPSEnabled(true),
342334 _aboutToQuit(false),
343335 _notifiedPacketVersionMismatchThisDomain(false),
336+ _glWidget(new GLCanvas()),
344337 _domainConnectionRefusals(QList<QString>()),
345338 _maxOctreePPS(maxOctreePacketsPerSecond.get()),
346339 _lastFaceTrackerUpdate(0),
@@ -371,24 +364,17 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 24 unmodified lines
371364 _bookmarks = new Bookmarks(); // Before setting up the menu
372365
373366 _runningScriptsWidget = new RunningScriptsWidget(_window);
374− _renderEngine->addTask(render::TaskPointer(new RenderDeferredTask()));
367+ _renderEngine->addTask(make_shared<RenderDeferredTask>());
375368 _renderEngine->registerScene(_main3DScene);
376−
369+
377370 // start the nodeThread so its event loop is running
378371 QThread* nodeThread = new QThread(this);
379− nodeThread->setObjectName("Datagram Processor Thread");
372+ nodeThread->setObjectName("NodeList Thread");
380373 nodeThread->start();
381374
382375 // make sure the node thread is given highest priority
383376 nodeThread->setPriority(QThread::TimeCriticalPriority);
384377
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−
392378 // setup a timer for domain-server check ins
393379 QTimer* domainCheckInTimer = new QTimer(nodeList.data());
394380 connect(domainCheckInTimer, &QTimer::timeout, nodeList.data(), &NodeList::sendDomainServerCheckIn);
@@ -404,9 +390,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 9 unmodified lines
404390 ResourceCache* geometryCache = geometryCacheP.data();
405391 connect(this, &Application::checkBackgroundDownloads, geometryCache, &ResourceCache::checkAsynchronousGets);
406392
407− // connect the DataProcessor processDatagrams slot to the QUDPSocket readyRead() signal
408− connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, _datagramProcessor, &DatagramProcessor::processDatagrams);
409−
410393 // put the audio processing on a separate thread
411394 QThread* audioThread = new QThread();
412395 audioThread->setObjectName("Audio Thread");
@@ -417,14 +400,27 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 4 unmodified lines
417400 audioIO->setOrientationGetter(getOrientationForAudio);
418401
419402 audioIO->moveToThread(audioThread);
403+
404+ auto& audioScriptingInterface = AudioScriptingInterface::getInstance();
405+
420406 connect(audioThread, &QThread::started, audioIO.data(), &AudioClient::start);
421407 connect(audioIO.data(), &AudioClient::destroyed, audioThread, &QThread::quit);
422408 connect(audioThread, &QThread::finished, audioThread, &QThread::deleteLater);
423409 connect(audioIO.data(), &AudioClient::muteToggled, this, &Application::audioMuteToggled);
424− connect(audioIO.data(), &AudioClient::receivedFirstPacket,
425− &AudioScriptingInterface::getInstance(), &AudioScriptingInterface::receivedFirstPacket);
426− connect(audioIO.data(), &AudioClient::disconnected,
427− &AudioScriptingInterface::getInstance(), &AudioScriptingInterface::disconnected);
410+ connect(audioIO.data(), &AudioClient::mutedByMixer, &audioScriptingInterface, &AudioScriptingInterface::mutedByMixer);
411+ connect(audioIO.data(), &AudioClient::receivedFirstPacket, &audioScriptingInterface, &AudioScriptingInterface::receivedFirstPacket);
412+ connect(audioIO.data(), &AudioClient::disconnected, &audioScriptingInterface, &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+ });
428424
429425 audioThread->start();
430426
@@ -457,7 +453,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 26 unmodified lines
457453 connect(nodeList.data(), &NodeList::uuidChanged, _myAvatar, &MyAvatar::setSessionUUID);
458454 connect(nodeList.data(), &NodeList::uuidChanged, this, &Application::setSessionUUID);
459455 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);
461458
462459 // connect to appropriate slots on AccountManager
463460 AccountManager& accountManager = AccountManager::getInstance();
@@ -537,7 +534,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 73 unmodified lines
537534 // the GL surface
538535 _glWidget->setCursor(Qt::BlankCursor);
539536 #endif
540−
537+
541538 // enable mouse tracking; otherwise, we only get drag events
542539 _glWidget->setMouseTracking(true);
543540
@@ -571,10 +568,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 27 unmodified lines
571568
572569 // hook up bandwidth estimator
573570 QSharedPointer<BandwidthRecorder> bandwidthRecorder = DependencyManager::get<BandwidthRecorder>();
574− connect(nodeList.data(), SIGNAL(dataSent(const quint8, const int)),
575− bandwidthRecorder.data(), SLOT(updateOutboundData(const quint8, const int)));
576− connect(nodeList.data(), SIGNAL(dataReceived(const quint8, const int)),
577− bandwidthRecorder.data(), SLOT(updateInboundData(const quint8, const int)));
571+ connect(nodeList.data(), &LimitedNodeList::dataSent,
572+ bandwidthRecorder.data(), &BandwidthRecorder::updateOutboundData);
573+ connect(&nodeList->getPacketReceiver(), &PacketReceiver::dataReceived,
574+ bandwidthRecorder.data(), &BandwidthRecorder::updateInboundData);
578575
579576 connect(&_myAvatar->getSkeletonModel(), &SkeletonModel::skeletonLoaded,
580577 this, &Application::checkSkeleton, Qt::QueuedConnection);
@@ -606,7 +603,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 25 unmodified lines
606603 _settingsTimer.setSingleShot(false);
607604 _settingsTimer.setInterval(SAVE_SETTINGS_INTERVAL);
608605 _settingsThread.start();
609−
606+
610607 if (Menu::getInstance()->isOptionChecked(MenuOption::IndependentMode)) {
611608 Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, true);
612609 cameraMenuChanged();
@@ -637,10 +634,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 24 unmodified lines
637634 ddeTracker->init();
638635 connect(ddeTracker.data(), &FaceTracker::muteToggled, this, &Application::faceTrackerMuteToggled);
639636 #endif
640−
637+
641638 auto applicationUpdater = DependencyManager::get<AutoUpdater>();
642639 connect(applicationUpdater.data(), &AutoUpdater::newVersionIsAvailable, dialogsManager.data(), &DialogsManager::showUpdateDialog);
643640 applicationUpdater->checkForUpdate();
641+
642+ auto& packetReceiver = nodeList->getPacketReceiver();
643+ packetReceiver.registerListener(PacketType::DomainConnectionDenied, this, "handleDomainConnectionDeniedPacket");
644644 }
645645
646646 void Application::aboutToQuit() {
@@ -653,8 +653,10 @@ void Application::aboutToQuit() { · 6 unmodified lines
653653 void Application::cleanupBeforeQuit() {
654654
655655 _entities.clear(); // this will allow entity scripts to properly shutdown
656−
657− _datagramProcessor->shutdown(); // tell the datagram processor we're shutting down, so it can short circuit
656+
657+ // tell the packet receiver we're shutting down, so it can drop packets
658+ DependencyManager::get<NodeList>()->getPacketReceiver().setShouldDropPackets(true);
659+
658660 _entities.shutdown(); // tell the entities system we're shutting down, so it will stop running scripts
659661 ScriptEngine::stopAllScripts(this); // stop all currently running global scripts
660662
@@ -731,12 +733,15 @@ Application::~Application() { · 70 unmodified lines
731733 DependencyManager::destroy<OffscreenUi>();
732734 DependencyManager::destroy<AvatarManager>();
733735 DependencyManager::destroy<AnimationCache>();
736+ DependencyManager::destroy<FramebufferCache>();
734737 DependencyManager::destroy<TextureCache>();
735738 DependencyManager::destroy<GeometryCache>();
736739 DependencyManager::destroy<ScriptCache>();
737740 DependencyManager::destroy<SoundCache>();
738741
739742 QThread* nodeThread = DependencyManager::get<NodeList>()->thread();
743+
744+ // remove the NodeList from the DependencyManager
740745 DependencyManager::destroy<NodeList>();
741746
742747 // ask the node thread to quit and wait until it is done
@@ -762,32 +767,8 @@ void Application::initializeGL() { · 19 unmodified lines
762767 }
763768 #endif
764769
765− qCDebug(interfaceapp) << "GL Version: " << QString((const char*) glGetString(GL_VERSION));
766− qCDebug(interfaceapp) << "GL Shader Language Version: " << QString((const char*) glGetString(GL_SHADING_LANGUAGE_VERSION));
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
770+ // Where the gpuContext is created and where the TRUE Backend is created and assigned
771+ _gpuContext = std::make_shared<gpu::Context>(new gpu::GLBackend());
791772
792773 initDisplay();
793774 qCDebug(interfaceapp, "Initialized Display.");
@@ -876,8 +857,9 @@ void Application::paintGL() { · 82 unmodified lines
876857 _glWidget->makeCurrent();
877858
878859 auto lodManager = DependencyManager::get<LODManager>();
879− gpu::Context context(new gpu::GLBackend());
880− RenderArgs renderArgs(&context, nullptr, getViewFrustum(), lodManager->getOctreeSizeScale(),
860+
861+
862+ RenderArgs renderArgs(_gpuContext, nullptr, getViewFrustum(), lodManager->getOctreeSizeScale(),
881863 lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE,
882864 RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE);
883865
@@ -887,30 +869,56 @@ void Application::paintGL() { · 3 unmodified lines
887869 OculusManager::beginFrameTiming();
888870 }
889871
890−
872+
891873 PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings));
892874 bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
893875 PerformanceWarning warn(showWarnings, "Application::paintGL()");
894876 resizeGL();
895877
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+
896903 {
897904 PerformanceTimer perfTimer("renderOverlay");
898905
899906 // NOTE: There is no batch associated with this renderArgs
900907 // the ApplicationOverlay class assumes it's viewport is setup to be the device size
901908 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());
903910 _applicationOverlay.renderOverlay(&renderArgs);
904911 }
905912
906− glEnable(GL_LINE_SMOOTH);
907−
908913 if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
909914 Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, _myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN);
910915 Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(_myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN));
911916 Application::getInstance()->cameraMenuChanged();
912917 }
913918
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+
914922 if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {
915923 // Always use the default eye position, not the actual head eye position.
916924 // Using the latter will cause the camera to wobble with idle animations,
@@ -947,6 +955,7 @@ void Application::paintGL() { · 30 unmodified lines
947955 glm::vec3(0, _raiseMirror * _myAvatar->getScale(), 0) +
948956 (_myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) *
949957 glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror);
958+ renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE;
950959 }
951960
952961 // Update camera position
@@ -954,17 +963,6 @@ void Application::paintGL() { · 1 unmodified line
954963 _myCamera.update(1.0f / _fps);
955964 }
956965
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−
968966 if (OculusManager::isConnected()) {
969967 //When in mirror mode, use camera rotation. Otherwise, use body rotation
970968 if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
@@ -976,45 +974,28 @@ void Application::paintGL() { · 5 unmodified lines
976974 TV3DManager::display(&renderArgs, _myCamera);
977975 } else {
978976 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−
985977 // Viewport is assigned to the size of the framebuffer
986− QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize();
987− glViewport(0, 0, size.width(), size.height());
978+ QSize size = DependencyManager::get<FramebufferCache>()->getFrameBufferSize();
988979 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();
995980
996− renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE;
997− if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
998− renderRearViewMirror(&renderArgs, _mirrorViewRect);
999− }
1000981
1001− renderArgs._renderMode = RenderArgs::NORMAL_RENDER_MODE;
982+ displaySide(&renderArgs, _myCamera);
1002983
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()));
1004990
1005− glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1006− glBindFramebuffer(GL_READ_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(finalFbo));
1007− glBlitFramebuffer(0, 0, _renderResolution.x, _renderResolution.y,
1008− 0, 0, _glWidget->getDeviceSize().width(), _glWidget->getDeviceSize().height(),
1009− GL_COLOR_BUFFER_BIT, GL_LINEAR);
1010− glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1011−
1012− glBindTexture(GL_TEXTURE_2D, 0); // ???
991+ batch.setFramebuffer(nullptr);
992+
993+ renderArgs._context->render(batch);
994+ }
1013995
1014996 _compositor.displayOverlayTexture(&renderArgs);
1015997 }
1016−
1017−
998+
1018999 if (!OculusManager::isConnected() || OculusManager::allowSwap()) {
10191000 PROFILE_RANGE(__FUNCTION__ "/bufferSwap");
10201001 _glWidget->swapBuffers();
@@ -1024,6 +1005,7 @@ void Application::paintGL() { · 3 unmodified lines
10241005 OculusManager::endFrameTiming();
10251006 }
10261007 _frameCount++;
1008+ _numFramesSinceLastResize++;
10271009 Stats::getInstance()->setRenderDetails(renderArgs._details);
10281010 }
10291011
@@ -1077,13 +1059,11 @@ void Application::resizeGL() { · 47 unmodified lines
10771059 }
10781060
10791061 if (_renderResolution != toGlm(renderSize)) {
1062+ _numFramesSinceLastResize = 0;
10801063 _renderResolution = toGlm(renderSize);
1081− DependencyManager::get<TextureCache>()->setFrameBufferSize(renderSize);
1082−
1083− glViewport(0, 0, _renderResolution.x, _renderResolution.y); // shouldn't this account for the menu???
1064+ DependencyManager::get<FramebufferCache>()->setFrameBufferSize(renderSize);
10841065
1085− updateProjectionMatrix();
1086− glLoadIdentity();
1066+ loadViewFrustum(_myCamera, _viewFrustum);
10871067 }
10881068
10891069 resetCameras(_myCamera, _renderResolution);
@@ -1093,32 +1073,6 @@ void Application::resizeGL() { · 3 unmodified lines
10931073 auto canvasSize = _glWidget->size();
10941074 offscreenUi->resize(canvasSize);
10951075 _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− }
11221076 }
11231077
11241078 bool Application::importSVOFromURL(const QString& urlString) {
@@ -1267,12 +1221,6 @@ void Application::keyPressEvent(QKeyEvent* event) { · 142 unmodified lines
12671221 Menu::getInstance()->triggerOption(MenuOption::Stars);
12681222 break;
12691223
1270− case Qt::Key_W:
1271− if (isOption && !isShifted && !isMeta) {
1272− Menu::getInstance()->triggerOption(MenuOption::Wireframe);
1273− }
1274− break;
1275−
12761224 case Qt::Key_S:
12771225 if (isShifted && isMeta && !isOption) {
12781226 Menu::getInstance()->triggerOption(MenuOption::SuppressShortTimings);
@@ -1786,10 +1734,21 @@ bool Application::acceptSnapshot(const QString& urlString) { · 507 unmodified lines
17861734 }
17871735
17881736 void Application::sendPingPackets() {
1789− QByteArray pingPacket = DependencyManager::get<NodeList>()->constructPingPacket();
1790− controlledBroadcastToNodes(pingPacket, NodeSet()
1791− << NodeType::EntityServer
1792− << NodeType::AudioMixer << NodeType::AvatarMixer);
1737+
1738+ auto nodeList = DependencyManager::get<NodeList>();
1739+
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+ });
17931752 }
17941753
17951754 // Every second, check the frame rates and other stuff
@@ -1802,7 +1761,6 @@ void Application::checkFPS() { · 6 unmodified lines
18021761
18031762 _fps = (float)_frameCount / diffTime;
18041763 _frameCount = 0;
1805− _datagramProcessor->resetCounters();
18061764 _timerStart.start();
18071765 }
18081766
@@ -1868,11 +1826,15 @@ void Application::idle() { · 59 unmodified lines
18681826 _idleLoopMeasuredJitter = _idleLoopStdev.getStDev();
18691827 _idleLoopStdev.reset();
18701828 }
1871−
18721829 }
1830+
18731831 // 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
1875− idleTimer->start(_glWidget->isThrottleRendering() ? THROTTLED_IDLE_TIMER_DELAY : 1);
1832+ // depending on whether we're throttling or not.
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);
18761838 }
18771839
18781840 // check for any requested background downloads.
@@ -1955,7 +1917,6 @@ void Application::setEnableVRMode(bool enableVRMode) { · 76 unmodified lines
19551917 OculusManager::connect(_glWidget->context()->contextHandle());
19561918 _glWidget->setFocus();
19571919 _glWidget->makeCurrent();
1958− glClear(GL_COLOR_BUFFER_BIT);
19591920 }
19601921 OculusManager::recalibrate();
19611922 } else {
@@ -2151,12 +2112,6 @@ QVector<EntityItemID> Application::pasteEntities(float x, float y, float z) { · 189 unmodified lines
21512112 }
21522113
21532114 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);
21602115 }
21612116
21622117 void Application::init() {
@@ -2166,7 +2121,6 @@ void Application::init() { · 3 unmodified lines
21662121 _environment.init();
21672122
21682123 DependencyManager::get<DeferredLightingEffect>()->init(this);
2169− DependencyManager::get<AmbientOcclusionEffect>()->init(this);
21702124
21712125 // TODO: move _myAvatar out of Application. Move relevant code to MyAvataar or AvatarManager
21722126 DependencyManager::get<AvatarManager>()->init();
@@ -2262,8 +2216,8 @@ void Application::shrinkMirrorView() { · 89 unmodified lines
22622216
22632217 const float HEAD_SPHERE_RADIUS = 0.1f;
22642218
2265−bool Application::isLookingAtMyAvatar(Avatar* avatar) {
2266− glm::vec3 theirLookAt = avatar->getHead()->getLookAtPosition();
2219+bool Application::isLookingAtMyAvatar(AvatarSharedPointer avatar) {
2220+ glm::vec3 theirLookAt = dynamic_pointer_cast<Avatar>(avatar)->getHead()->getLookAtPosition();
22672221 glm::vec3 myEyePosition = _myAvatar->getHead()->getEyePosition();
22682222 if (pointInSphere(theirLookAt, myEyePosition, HEAD_SPHERE_RADIUS * _myAvatar->getScale())) {
22692223 return true;
@@ -2327,7 +2281,7 @@ void Application::updateMyAvatarLookAtPosition() { · 57 unmodified lines
23272281 if (lookingAt && _myAvatar != lookingAt.get()) {
23282282 // If I am looking at someone else, look directly at one of their eyes
23292283 isLookingAtSomeone = true;
2330− Head* lookingAtHead = static_cast<Avatar*>(lookingAt.get())->getHead();
2284+ auto lookingAtHead = static_pointer_cast<Avatar>(lookingAt)->getHead();
23312285
23322286 const float MAXIMUM_FACE_ANGLE = 65.0f * RADIANS_PER_DEGREE;
23332287 glm::vec3 lookingAtFaceOrientation = lookingAtHead->getFinalOrientationInWorldFrame() * IDENTITY_FRONT;
@@ -2357,23 +2311,21 @@ void Application::updateMyAvatarLookAtPosition() { · 23 unmodified lines
23572311 lookAtSpot = _myAvatar->getHead()->getEyePosition() +
23582312 (_myAvatar->getHead()->getFinalOrientationInWorldFrame() * glm::vec3(0.0f, 0.0f, -TREE_SCALE));
23592313 }
2360− }
23612314
2362− // Deflect the eyes a bit to match the detected gaze from Faceshift if active.
2363− // DDE doesn't track eyes.
2364− if (tracker && typeid(*tracker) == typeid(Faceshift) && !tracker->isMuted()) {
2365− float eyePitch = tracker->getEstimatedEyePitch();
2366− float eyeYaw = tracker->getEstimatedEyeYaw();
2367− const float GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT = 0.1f;
2368− glm::vec3 origin = _myAvatar->getHead()->getEyePosition();
2369− float pitchSign = (_myCamera.getMode() == CAMERA_MODE_MIRROR) ? -1.0f : 1.0f;
2370− float deflection = DependencyManager::get<Faceshift>()->getEyeDeflection();
2371− if (isLookingAtSomeone) {
2372− deflection *= GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT;
2373− }
2374− lookAtSpot = origin + _myCamera.getRotation() * glm::quat(glm::radians(glm::vec3(
2375− eyePitch * pitchSign * deflection, eyeYaw * deflection, 0.0f))) *
2315+ // Deflect the eyes a bit to match the detected gaze from the face tracker if active.
2316+ if (tracker && !tracker->isMuted()) {
2317+ float eyePitch = tracker->getEstimatedEyePitch();
2318+ float eyeYaw = tracker->getEstimatedEyeYaw();
2319+ const float GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT = 0.1f;
2320+ glm::vec3 origin = _myAvatar->getHead()->getEyePosition();
2321+ float deflection = tracker->getEyeDeflection();
2322+ if (isLookingAtSomeone) {
2323+ deflection *= GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT;
2324+ }
2325+ lookAtSpot = origin + _myCamera.getRotation() * glm::quat(glm::radians(glm::vec3(
2326+ eyePitch * deflection, eyeYaw * deflection, 0.0f))) *
23762327 glm::inverse(_myCamera.getRotation()) * (lookAtSpot - origin);
2328+ }
23772329 }
23782330
23792331 _myAvatar->getHead()->setLookAtPosition(lookAtSpot);
@@ -2534,10 +2486,18 @@ void Application::update(float deltaTime) { · 154 unmodified lines
25342486 _myAvatar->setDriveKeys(DOWN, _userInputMapper.getActionState(UserInputMapper::VERTICAL_DOWN));
25352487 _myAvatar->setDriveKeys(LEFT, _userInputMapper.getActionState(UserInputMapper::LATERAL_LEFT));
25362488 _myAvatar->setDriveKeys(RIGHT, _userInputMapper.getActionState(UserInputMapper::LATERAL_RIGHT));
2537− _myAvatar->setDriveKeys(ROT_UP, _userInputMapper.getActionState(UserInputMapper::PITCH_UP));
2538− _myAvatar->setDriveKeys(ROT_DOWN, _userInputMapper.getActionState(UserInputMapper::PITCH_DOWN));
2539− _myAvatar->setDriveKeys(ROT_LEFT, _userInputMapper.getActionState(UserInputMapper::YAW_LEFT));
2540− _myAvatar->setDriveKeys(ROT_RIGHT, _userInputMapper.getActionState(UserInputMapper::YAW_RIGHT));
2489+ if (deltaTime > FLT_EPSILON) {
2490+ // For rotations what we really want are meausures of "angles per second" (in order to prevent
2491+ // fps-dependent spin rates) so we need to scale the units of the controller contribution.
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+ }
25412501 }
25422502 _myAvatar->setDriveKeys(BOOM_IN, _userInputMapper.getActionState(UserInputMapper::BOOM_IN));
25432503 _myAvatar->setDriveKeys(BOOM_OUT, _userInputMapper.getActionState(UserInputMapper::BOOM_OUT));
@@ -2658,7 +2618,7 @@ void Application::update(float deltaTime) { · 114 unmodified lines
26582618 _lastQueriedTime = now;
26592619
26602620 if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) {
2661− queryOctree(NodeType::EntityServer, PacketTypeEntityQuery, _entityServerJurisdictions);
2621+ queryOctree(NodeType::EntityServer, PacketType::EntityQuery, _entityServerJurisdictions);
26622622 }
26632623 _lastQueriedViewFrustum = _viewFrustum;
26642624 }
@@ -2691,16 +2651,17 @@ int Application::sendNackPackets() { · 26 unmodified lines
26912651 return 0;
26922652 }
26932653
2694− int packetsSent = 0;
2695− char packet[MAX_PACKET_SIZE];
2696−
2697− // iterates thru all nodes in NodeList
2654+ // iterates through all nodes in NodeList
26982655 auto nodeList = DependencyManager::get<NodeList>();
26992656
2657+ int packetsSent = 0;
2658+
27002659 nodeList->eachNode([&](const SharedNodePointer& node){
27012660
27022661 if (node->getActiveSocket() && node->getType() == NodeType::EntityServer) {
27032662
2663+ NLPacketList nackPacketList(PacketType::OctreeDataNack);
2664+
27042665 QUuid nodeUUID = node->getUUID();
27052666
27062667 // if there are octree packets from this node that are waiting to be processed,
@@ -2716,55 +2677,36 @@ int Application::sendNackPackets() { · 9 unmodified lines
27162677 _octreeSceneStatsLock.unlock();
27172678 return;
27182679 }
2719−
2680+
27202681 // get sequence number stats of node, prune its missing set, and make a copy of the missing set
27212682 SequenceNumberStats& sequenceNumberStats = _octreeServerSceneStats[nodeUUID].getIncomingOctreeSequenceNumberStats();
27222683 sequenceNumberStats.pruneMissingSet();
27232684 const QSet<OCTREE_PACKET_SEQUENCE> missingSequenceNumbers = sequenceNumberStats.getMissingSet();
2724−
2685+
27252686 _octreeSceneStatsLock.unlock();
2726−
2687+
27272688 // construct nack packet(s) for this node
2728− int numSequenceNumbersAvailable = missingSequenceNumbers.size();
2729− QSet<OCTREE_PACKET_SEQUENCE>::const_iterator missingSequenceNumbersIterator = missingSequenceNumbers.constBegin();
2730− while (numSequenceNumbersAvailable > 0) {
2731−
2732− char* dataAt = packet;
2733− int bytesRemaining = MAX_PACKET_SIZE;
2734−
2735− // pack header
2736− int numBytesPacketHeader = nodeList->populatePacketHeader(packet, PacketTypeOctreeDataNack);
2737− dataAt += numBytesPacketHeader;
2738− bytesRemaining -= numBytesPacketHeader;
2739−
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++;
2689+ auto it = missingSequenceNumbers.constBegin();
2690+ while (it != missingSequenceNumbers.constEnd()) {
2691+ OCTREE_PACKET_SEQUENCE missingNumber = *it;
2692+ nackPacketList.writePrimitive(missingNumber);
2693+ ++it;
2694+ }
2695+
2696+ if (nackPacketList.getNumPackets()) {
2697+ packetsSent += nackPacketList.getNumPackets();
2698+
2699+ // send the packet list
2700+ nodeList->sendPacketList(nackPacketList, *node);
27602701 }
27612702 }
27622703 });
27632704
2705+
27642706 return packetsSent;
27652707 }
27662708
2767−void Application::queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions) {
2709+void Application::queryOctree(NodeType_t serverType, PacketType::Value packetType, NodeToJurisdictionMap& jurisdictions) {
27682710
27692711 //qCDebug(interfaceapp) << ">>> inside... queryOctree()... _viewFrustum.getFieldOfView()=" << _viewFrustum.getFieldOfView();
27702712 bool wantExtraDebugging = getLogger()->extraDebugging();
@@ -2787,9 +2729,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node · 16 unmodified lines
27872729 _octreeQuery.setOctreeSizeScale(lodManager->getOctreeSizeScale());
27882730 _octreeQuery.setBoundaryLevelAdjust(lodManager->getBoundaryLevelAdjust());
27892731
2790− unsigned char queryPacket[MAX_PACKET_SIZE];
2791−
2792− // Iterate all of the nodes, and get a count of how many voxel servers we have...
2732+ // Iterate all of the nodes, and get a count of how many octree servers we have...
27932733 int totalServers = 0;
27942734 int inViewServers = 0;
27952735 int unknownJurisdictionServers = 0;
@@ -2856,6 +2796,8 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node · 60 unmodified lines
28562796 qCDebug(interfaceapp, "perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer);
28572797 }
28582798
2799+ auto queryPacket = NLPacket::create(packetType);
2800+
28592801 nodeList->eachNode([&](const SharedNodePointer& node){
28602802 // only send to the NodeTypes that are serverType
28612803 if (node->getActiveSocket() && node->getType() == serverType) {
@@ -2930,19 +2872,13 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node · 68 unmodified lines
29302872 } else {
29312873 _octreeQuery.setMaxQueryPacketsPerSecond(0);
29322874 }
2933− // set up the packet for sending...
2934− unsigned char* endOfQueryPacket = queryPacket;
29352875
2936− // insert packet type/version and node UUID
2937− endOfQueryPacket += nodeList->populatePacketHeader(reinterpret_cast<char*>(endOfQueryPacket), packetType);
2938−
2939− // encode the query data...
2940− endOfQueryPacket += _octreeQuery.getBroadcastData(endOfQueryPacket);
2941−
2942− int packetLength = endOfQueryPacket - queryPacket;
2876+ // encode the query data
2877+ int packetSize = _octreeQuery.getBroadcastData(reinterpret_cast<unsigned char*>(queryPacket->getPayload()));
2878+ queryPacket->setPayloadSize(packetSize);
29432879
29442880 // make sure we still have an active socket
2945− nodeList->writeUnverifiedDatagram(reinterpret_cast<const char*>(queryPacket), packetLength, node);
2881+ nodeList->sendUnreliablePacket(*queryPacket, *node);
29462882 }
29472883 });
29482884 }
@@ -3006,169 +2942,6 @@ glm::vec3 Application::getSunDirection() { · 57 unmodified lines
30062942 // FIXME, preprocessor guard this check to occur only in DEBUG builds
30072943 static QThread * activeRenderingThread = nullptr;
30082944
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−
31722945 bool Application::shouldRenderMesh(float largestDimension, float distanceToCamera) {
31732946 return DependencyManager::get<LODManager>()->shouldRenderMesh(largestDimension, distanceToCamera);
31742947 }
@@ -3189,35 +2962,25 @@ PickRay Application::computePickRay(float x, float y) const { · 14 unmodified lines
31892962 if (isHMDMode()) {
31902963 getApplicationCompositor().computeHmdPickRay(glm::vec2(x, y), result.origin, result.direction);
31912964 } else {
3192− if (QThread::currentThread() == activeRenderingThread) {
3193− getDisplayViewFrustum()->computePickRay(x, y, result.origin, result.direction);
3194− } else {
3195− getViewFrustum()->computePickRay(x, y, result.origin, result.direction);
3196− }
2965+ getViewFrustum()->computePickRay(x, y, result.origin, result.direction);
31972966 }
31982967 return result;
31992968 }
32002969
32012970 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);
32102971
32112972 const int BILLBOARD_SIZE = 64;
3212− // TODO: Pass a RenderArgs to renderAvatarBillboard
3213− renderRearViewMirror(renderArgs, QRect(0, _glWidget->getDeviceHeight() - BILLBOARD_SIZE,
3214− BILLBOARD_SIZE, BILLBOARD_SIZE),
3215− true);
2973+
2974+ // Need to make sure the gl context is current here
2975+ _glWidget->makeCurrent();
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();
32162981 QImage image(BILLBOARD_SIZE, BILLBOARD_SIZE, QImage::Format_ARGB32);
3217− glReadPixels(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE, GL_BGRA, GL_UNSIGNED_BYTE, image.bits());
3218− glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2982+ renderArgs->_context->downloadFramebuffer(primaryFbo, glm::ivec4(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE), image);
32192983
3220− glBindFramebuffer(GL_FRAMEBUFFER, 0);
32212984 return image;
32222985 }
32232986
@@ -3322,9 +3085,6 @@ namespace render { · 98 unmodified lines
33223085 PerformanceTimer perfTimer("stars");
33233086 PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
33243087 "Application::payloadRender<BackgroundRenderData>() ... stars...");
3325− if (!background->_stars.isStarsLoaded()) {
3326− background->_stars.generate(STARFIELD_NUM_STARS, STARFIELD_SEED);
3327− }
33283088 // should be the first rendering pass - w/o depth buffer / lighting
33293089
33303090 // compute starfield alpha based on distance from atmosphere
@@ -3352,7 +3112,7 @@ namespace render { · 21 unmodified lines
33523112 + APPROXIMATE_DISTANCE_FROM_HORIZON;
33533113 alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON);
33543114 }
3355−
3115+
33563116
33573117 } else if (height < closestData.getAtmosphereOuterRadius()) {
33583118 alpha = (height - closestData.getAtmosphereInnerRadius()) /
@@ -3372,7 +3132,7 @@ namespace render { · 13 unmodified lines
33723132
33733133 // finally render the starfield
33743134 if (hasStars) {
3375− background->_stars.render(args->_viewFrustum->getFieldOfView(), args->_viewFrustum->getAspectRatio(), args->_viewFrustum->getNearClip(), alpha);
3135+ background->_stars.render(args, alpha);
33763136 }
33773137
33783138 // draw the sky dome
@@ -3387,16 +3147,12 @@ namespace render { · 8 unmodified lines
33873147 }
33883148 } else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) {
33893149 PerformanceTimer perfTimer("skybox");
3390−
3150+
33913151 skybox = skyStage->getSkybox();
33923152 if (skybox) {
33933153 model::Skybox::render(batch, *(Application::getInstance()->getDisplayViewFrustum()), *skybox);
33943154 }
33953155 }
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);
34003156 }
34013157 }
34023158
@@ -3416,76 +3172,22 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 13 unmodified lines
34163172 // load the view frustum
34173173 loadViewFrustum(theCamera, _displayViewFrustum);
34183174
3419− // transform view according to theCamera
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− }
3175+ // TODO fix shadows and make them use the GPU library
34663176
34673177 // The pending changes collecting the changes here
34683178 render::PendingChanges pendingChanges;
34693179
34703180 // Background rendering decision
34713181 if (BackgroundRenderData::_item == 0) {
3472− auto backgroundRenderData = BackgroundRenderData::Pointer(new BackgroundRenderData(&_environment));
3473− auto backgroundRenderPayload = render::PayloadPointer(new BackgroundRenderData::Payload(backgroundRenderData));
3182+ auto backgroundRenderData = make_shared<BackgroundRenderData>(&_environment);
3183+ auto backgroundRenderPayload = make_shared<BackgroundRenderData::Payload>(backgroundRenderData);
34743184 BackgroundRenderData::_item = _main3DScene->allocateID();
34753185 pendingChanges.resetItem(WorldBoxRenderData::_item, backgroundRenderPayload);
34763186 } else {
34773187
34783188 }
34793189
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−
34873190 // Assuming nothing get's rendered through that
3488−
34893191 if (!selfAvatarOnly) {
34903192 if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) {
34913193 // render models...
@@ -3505,20 +3207,12 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 13 unmodified lines
35053207 renderArgs->_debugFlags = renderDebugFlags;
35063208 _entities.render(renderArgs);
35073209 }
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− }
35163210 }
35173211
35183212 // Make sure the WorldBox is in the scene
35193213 if (WorldBoxRenderData::_item == 0) {
3520− auto worldBoxRenderData = WorldBoxRenderData::Pointer(new WorldBoxRenderData());
3521− auto worldBoxRenderPayload = render::PayloadPointer(new WorldBoxRenderData::Payload(worldBoxRenderData));
3214+ auto worldBoxRenderData = make_shared<WorldBoxRenderData>();
3215+ auto worldBoxRenderPayload = make_shared<WorldBoxRenderData::Payload>(worldBoxRenderData);
35223216
35233217 WorldBoxRenderData::_item = _main3DScene->allocateID();
35243218
@@ -3572,6 +3266,8 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 47 unmodified lines
35723266 renderContext._drawItemStatus = sceneInterface->doEngineDisplayItemStatus();
35733267 renderContext._drawHitEffect = sceneInterface->doEngineDisplayHitEffect();
35743268
3269+ renderContext._occlusionStatus = Menu::getInstance()->isOptionChecked(MenuOption::DebugAmbientOcclusion);
3270+
35753271 renderArgs->_shouldRender = LODManager::shouldRender;
35763272
35773273 renderContext.args = renderArgs;
@@ -3580,7 +3276,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 2 unmodified lines
35803276
35813277 // Before the deferred pass, let's try to use the render engine
35823278 _renderEngine->run();
3583−
3279+
35843280 auto engineRC = _renderEngine->getRenderContext();
35853281 sceneInterface->setEngineFeedOpaqueItems(engineRC->_numFeedOpaqueItems);
35863282 sceneInterface->setEngineDrawnOpaqueItems(engineRC->_numDrawnOpaqueItems);
@@ -3591,10 +3287,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 4 unmodified lines
35913287 sceneInterface->setEngineFeedOverlay3DItems(engineRC->_numFeedOverlay3DItems);
35923288 sceneInterface->setEngineDrawnOverlay3DItems(engineRC->_numDrawnOverlay3DItems);
35933289 }
3594− //Render the sixense lasers
3595− if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers)) {
3596− _myAvatar->renderLaserPointers(*renderArgs->_batch);
3597− }
35983290
35993291 if (!selfAvatarOnly) {
36003292 // give external parties a change to hook in
@@ -3604,37 +3296,9 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 3 unmodified lines
36043296 }
36053297 }
36063298
3607− if (Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) {
3608− glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
3609− }
3610−
36113299 activeRenderingThread = nullptr;
36123300 }
36133301
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−
36383302 void Application::computeOffAxisFrustum(float& left, float& right, float& bottom, float& top, float& nearVal,
36393303 float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const {
36403304
@@ -3685,9 +3349,9 @@ glm::vec2 Application::getScaledScreenPoint(glm::vec2 projectedPoint) { · 44 unmodified lines
36853349 }
36863350
36873351 void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool billboard) {
3352+ auto originalViewport = renderArgs->_viewport;
36883353 // Grab current viewport to reset it at the end
3689− int viewport[4];
3690− glGetIntegerv(GL_VIEWPORT, viewport);
3354+
36913355 float aspect = (float)region.width() / region.height();
36923356 float fov = MIRROR_FIELD_OF_VIEW;
36933357
@@ -3718,43 +3382,30 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi · 24 unmodified lines
37183382 // This was removed in commit 71e59cfa88c6563749594e25494102fe01db38e9 but could be further
37193383 // investigated in order to adapt the technique while fixing the head rendering issue,
37203384 // but the complexity of the hack suggests that a better approach
3721− _mirrorCamera.setPosition(_myAvatar->getHead()->getEyePosition() +
3385+ _mirrorCamera.setPosition(_myAvatar->getDefaultEyePosition() +
37223386 _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale());
37233387 }
37243388 _mirrorCamera.setProjection(glm::perspective(glm::radians(fov), aspect, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP));
37253389 _mirrorCamera.setRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f)));
37263390
3391+
37273392 // set the bounds of rear mirror view
3393+ gpu::Vec4i viewport;
37283394 if (billboard) {
3729− QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize();
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());
3395+ viewport = gpu::Vec4i(0, 0, region.width(), region.height());
37333396 } else {
37343397 // if not rendering the billboard, the region is in device independent coordinates; must convert to device
3735− QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize();
37363398 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;
3738− glViewport(x, size.height() - y - height, width, height);
3739− glScissor(x, size.height() - y - height, width, height);
3740−
3741− renderArgs->_viewport = glm::ivec4(x, size.height() - y - height, width, height);
3399+ int width = region.width() * ratio;
3400+ int height = region.height() * ratio;
3401+ viewport = gpu::Vec4i(0, 0, width, height);
37423402 }
3743− bool updateViewFrustum = false;
3744− updateProjectionMatrix(_mirrorCamera, updateViewFrustum);
3745− glEnable(GL_SCISSOR_TEST);
3746− glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
3403+ renderArgs->_viewport = viewport;
37473404
37483405 // render rear mirror view
3749− glPushMatrix();
37503406 displaySide(renderArgs, _mirrorCamera, true, billboard);
3751− glPopMatrix();
37523407
3753− // reset Viewport and projection matrix
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);
3408+ renderArgs->_viewport = originalViewport;
37583409 }
37593410
37603411 void Application::resetSensors() {
@@ -3841,11 +3492,24 @@ void Application::domainChanged(const QString& domainHostname) { · 80 unmodified lines
38413492 _domainConnectionRefusals.clear();
38423493 }
38433494
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+
38453507 if (!_domainConnectionRefusals.contains(reason)) {
38463508 _domainConnectionRefusals.append(reason);
38473509 emit domainConnectionRefused(reason);
38483510 }
3511+
3512+ AccountManager::getInstance().checkAndSignalForAccessToken();
38493513 }
38503514
38513515 void Application::connectedToDomain(const QString& hostname) {
@@ -3910,12 +3574,12 @@ void Application::nodeKilled(SharedNodePointer node) { · 58 unmodified lines
39103574 DependencyManager::get<AvatarManager>()->clearOtherAvatars();
39113575 }
39123576 }
3913−
3914−void Application::trackIncomingOctreePacket(const QByteArray& packet, const SharedNodePointer& sendingNode, bool wasStatsPacket) {
3577+
3578+void Application::trackIncomingOctreePacket(NLPacket& packet, SharedNodePointer sendingNode, bool wasStatsPacket) {
39153579
39163580 // Attempt to identify the sender from its address.
39173581 if (sendingNode) {
3918− QUuid nodeUUID = sendingNode->getUUID();
3582+ const QUuid& nodeUUID = sendingNode->getUUID();
39193583
39203584 // now that we know the node ID, let's add these stats to the stats for that node...
39213585 _octreeSceneStatsLock.lockForWrite();
@@ -3927,60 +3591,54 @@ void Application::trackIncomingOctreePacket(const QByteArray& packet, const Shar · 5 unmodified lines
39273591 }
39283592 }
39293593
3930−int Application::parseOctreeStats(const QByteArray& packet, const SharedNodePointer& sendingNode) {
3594+int Application::processOctreeStats(NLPacket& packet, SharedNodePointer sendingNode) {
39313595 // But, also identify the sender, and keep track of the contained jurisdiction root for this server
39323596
39333597 // parse the incoming stats datas stick it in a temporary object for now, while we
39343598 // determine which server it belongs to
3935− OctreeSceneStats temp;
3936− int statsMessageLength = temp.unpackFromMessage(reinterpret_cast<const unsigned char*>(packet.data()), packet.size());
3599+ int statsMessageLength = 0;
39373600
3938− // quick fix for crash... why would voxelServer be NULL?
3939− if (sendingNode) {
3940− QUuid nodeUUID = sendingNode->getUUID();
3601+ const QUuid& nodeUUID = sendingNode->getUUID();
3602+
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();
39413610
3942− // now that we know the node ID, let's add these stats to the stats for that node...
3943− _octreeSceneStatsLock.lockForWrite();
3944− if (_octreeServerSceneStats.find(nodeUUID) != _octreeServerSceneStats.end()) {
3945− _octreeServerSceneStats[nodeUUID].unpackFromMessage(reinterpret_cast<const unsigned char*>(packet.data()),
3946− packet.size());
3947− } else {
3948− _octreeServerSceneStats[nodeUUID] = temp;
3949− }
3950− _octreeSceneStatsLock.unlock();
3611+ // see if this is the first we've heard of this node...
3612+ NodeToJurisdictionMap* jurisdiction = NULL;
3613+ QString serverType;
3614+ if (sendingNode->getType() == NodeType::EntityServer) {
3615+ jurisdiction = &_entityServerJurisdictions;
3616+ serverType = "Entity";
3617+ }
39513618
3619+ jurisdiction->lockForRead();
3620+ if (jurisdiction->find(nodeUUID) == jurisdiction->end()) {
3621+ jurisdiction->unlock();
3622+
39523623 VoxelPositionSize rootDetails;
3953− voxelDetailsForCode(temp.getJurisdictionRoot(), rootDetails);
3624+ voxelDetailsForCode(octreeStats.getJurisdictionRoot(), rootDetails);
39543625
3955− // see if this is the first we've heard of this node...
3956− NodeToJurisdictionMap* jurisdiction = NULL;
3957− QString serverType;
3958− if (sendingNode->getType() == NodeType::EntityServer) {
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;
3626+ qCDebug(interfaceapp, "stats from new %s server... [%f, %f, %f, %f]",
3627+ qPrintable(serverType),
3628+ (double)rootDetails.x, (double)rootDetails.y, (double)rootDetails.z, (double)rootDetails.s);
3629+ } else {
39823630 jurisdiction->unlock();
39833631 }
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+
39843642 return statsMessageLength;
39853643 }
39863644
@@ -4120,10 +3778,13 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri · 133 unmodified lines
41203778
41213779 // when the worker thread is started, call our engine's run..
41223780 connect(workerThread, &QThread::started, scriptEngine, &ScriptEngine::run);
4123−
3781+
41243782 // when the thread is terminated, add both scriptEngine and thread to the deleteLater queue
4125− connect(scriptEngine, SIGNAL(doneRunning()), scriptEngine, SLOT(deleteLater()));
4126− connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater()));
3783+ connect(scriptEngine, &ScriptEngine::doneRunning, scriptEngine, &ScriptEngine::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);
41273788
41283789 auto nodeList = DependencyManager::get<NodeList>();
41293790 connect(nodeList.data(), &NodeList::nodeKilled, scriptEngine, &ScriptEngine::nodeKilled);
@@ -4763,7 +4424,11 @@ void Application::friendsWindowClosed() { · 633 unmodified lines
47634424 }
47644425
47654426 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+ }
47674432 }
47684433
47694434 void Application::initPlugins() {
@@ -4824,7 +4489,7 @@ mat4 Application::getEyeProjection(int eye) const { · 54 unmodified lines
48244489 if (isHMDMode()) {
48254490 return OculusManager::getEyeProjection(eye);
48264491 }
4827−
4492+
48284493 return _viewFrustum.getProjection();
48294494 }
48304495