History

Merge branch 'master' into render_cursor

Brad Davis committed 11 years ago

Commit c360dde2 parents b353421 f491a7a165 files · +6287 −2667Browse files

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

Unified · Split

interface/src/Application.cpp+437−349
@@ -117,8 +117,11 @@ · 116 unmodified lines
117117 #include "devices/TV3DManager.h"
118118
119119 #include "gpu/Batch.h"
120+#include "gpu/Context.h"
120121 #include "gpu/GLBackend.h"
121122
123+#include "RenderDeferredTask.h"
124+
122125 #include "scripting/AccountScriptingInterface.h"
123126 #include "scripting/AudioDeviceScriptingInterface.h"
124127 #include "scripting/ClipboardScriptingInterface.h"
@@ -143,6 +146,7 @@ · 18 unmodified lines
143146 #include "ui/Stats.h"
144147 #include "ui/AddressBarDialog.h"
145148
149+
146150 // ON WIndows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
147151 #if defined(Q_OS_WIN)
148152 extern "C" {
@@ -250,12 +254,12 @@ bool setupEssentials(int& argc, char** argv) { · 101 unmodified lines
250254 }
251255 // Set build version
252256 QCoreApplication::setApplicationVersion(BUILD_VERSION);
253−
257+
254258 DependencyManager::registerInheritance<LimitedNodeList, NodeList>();
255259 DependencyManager::registerInheritance<AvatarHashMap, AvatarManager>();
256260
257261 Setting::init();
258−
262+
259263 // Set dependencies
260264 auto addressManager = DependencyManager::set<AddressManager>();
261265 auto nodeList = DependencyManager::set<NodeList>(NodeType::Agent, listenPort);
@@ -289,6 +293,7 @@ bool setupEssentials(int& argc, char** argv) { · 27 unmodified lines
289293 auto discoverabilityManager = DependencyManager::set<DiscoverabilityManager>();
290294 auto sceneScriptingInterface = DependencyManager::set<SceneScriptingInterface>();
291295 auto offscreenUi = DependencyManager::set<OffscreenUi>();
296+ auto pathUtils = DependencyManager::set<PathUtils>();
292297
293298 return true;
294299 }
@@ -355,9 +360,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 60 unmodified lines
355360
356361 QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "styles/Inconsolata.otf");
357362 _window->setWindowTitle("Interface");
358−
363+
359364 Model::setAbstractViewStateInterface(this); // The model class will sometimes need to know view state details from us
360−
365+
361366 auto nodeList = DependencyManager::get<NodeList>();
362367
363368 _myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
@@ -369,7 +374,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 5 unmodified lines
369374 _bookmarks = new Bookmarks(); // Before setting up the menu
370375
371376 _runningScriptsWidget = new RunningScriptsWidget(_window);
372−
377+ _renderEngine->addTask(render::TaskPointer(new RenderDeferredTask()));
378+ _renderEngine->registerScene(_main3DScene);
379+
373380 // start the nodeThread so its event loop is running
374381 QThread* nodeThread = new QThread(this);
375382 nodeThread->setObjectName("Datagram Processor Thread");
@@ -377,14 +384,14 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 1 unmodified line
377384
378385 // make sure the node thread is given highest priority
379386 nodeThread->setPriority(QThread::TimeCriticalPriority);
380−
387+
381388 _datagramProcessor = new DatagramProcessor(nodeList.data());
382−
389+
383390 // have the NodeList use deleteLater from DM customDeleter
384391 nodeList->setCustomDeleter([](Dependency* dependency) {
385392 static_cast<NodeList*>(dependency)->deleteLater();
386393 });
387−
394+
388395 // put the NodeList and datagram processing on the node thread
389396 nodeList->moveToThread(nodeThread);
390397
@@ -392,7 +399,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 1 unmodified line
392399 // emit checkBackgroundDownloads to cause the GeometryCache to check it's queue for requested background
393400 // downloads.
394401 QSharedPointer<GeometryCache> geometryCacheP = DependencyManager::get<GeometryCache>();
395− ResourceCache *geometryCache = geometryCacheP.data();
402+ ResourceCache* geometryCache = geometryCacheP.data();
396403 connect(this, &Application::checkBackgroundDownloads, geometryCache, &ResourceCache::checkAsynchronousGets);
397404
398405 // connect the DataProcessor processDatagrams slot to the QUDPSocket readyRead() signal
@@ -401,20 +408,22 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 2 unmodified lines
401408 // put the audio processing on a separate thread
402409 QThread* audioThread = new QThread();
403410 audioThread->setObjectName("Audio Thread");
404−
411+
405412 auto audioIO = DependencyManager::get<AudioClient>();
406−
413+
407414 audioIO->setPositionGetter(getPositionForAudio);
408415 audioIO->setOrientationGetter(getOrientationForAudio);
409−
416+
410417 audioIO->moveToThread(audioThread);
411418 connect(audioThread, &QThread::started, audioIO.data(), &AudioClient::start);
412419 connect(audioIO.data(), &AudioClient::destroyed, audioThread, &QThread::quit);
413420 connect(audioThread, &QThread::finished, audioThread, &QThread::deleteLater);
414421 connect(audioIO.data(), &AudioClient::muteToggled, this, &Application::audioMuteToggled);
422+ connect(audioIO.data(), &AudioClient::receivedFirstPacket,
423+ &AudioScriptingInterface::getInstance(), &AudioScriptingInterface::receivedFirstPacket);
415424
416425 audioThread->start();
417−
426+
418427 const DomainHandler& domainHandler = nodeList->getDomainHandler();
419428
420429 connect(&domainHandler, SIGNAL(hostnameChanged(const QString&)), SLOT(domainChanged(const QString&)));
@@ -433,7 +442,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 12 unmodified lines
433442 auto discoverabilityManager = DependencyManager::get<DiscoverabilityManager>();
434443 connect(locationUpdateTimer, &QTimer::timeout, discoverabilityManager.data(), &DiscoverabilityManager::updateLocation);
435444 locationUpdateTimer->start(DATA_SERVER_LOCATION_CHANGE_UPDATE_MSECS);
436−
445+
437446 // if we get a domain change, immediately attempt update location in metaverse server
438447 connect(&nodeList->getDomainHandler(), &DomainHandler::connectedToDomain,
439448 discoverabilityManager.data(), &DiscoverabilityManager::updateLocation);
@@ -467,13 +476,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 27 unmodified lines
467476
468477 // once the event loop has started, check and signal for an access token
469478 QMetaObject::invokeMethod(&accountManager, "checkAndSignalForAccessToken", Qt::QueuedConnection);
470−
479+
471480 auto addressManager = DependencyManager::get<AddressManager>();
472−
481+
473482 // use our MyAvatar position and quat for address manager path
474483 addressManager->setPositionGetter(getPositionForPath);
475484 addressManager->setOrientationGetter(getOrientationForPath);
476−
485+
477486 connect(addressManager.data(), &AddressManager::hostChanged, this, &Application::updateWindowTitle);
478487 connect(this, &QCoreApplication::aboutToQuit, addressManager.data(), &AddressManager::storeCurrentAddress);
479488
@@ -505,7 +514,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 25 unmodified lines
505514 cache->setMaximumCacheSize(MAXIMUM_CACHE_SIZE);
506515 cache->setCacheDirectory(!cachePath.isEmpty() ? cachePath : "interfaceCache");
507516 networkAccessManager.setCache(cache);
508−
517+
509518 ResourceCache::setRequestLimit(3);
510519
511520 _window->setCentralWidget(_glWidget);
@@ -557,11 +566,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 45 unmodified lines
557566 connect(nodeList.data(), SIGNAL(dataReceived(const quint8, const int)),
558567 bandwidthRecorder.data(), SLOT(updateInboundData(const quint8, const int)));
559568
560− connect(&_myAvatar->getSkeletonModel(), &SkeletonModel::skeletonLoaded,
569+ connect(&_myAvatar->getSkeletonModel(), &SkeletonModel::skeletonLoaded,
561570 this, &Application::checkSkeleton, Qt::QueuedConnection);
562571
563572 // Setup the userInputMapper with the actions
564− // Setup the keyboardMouseDevice and the user input mapper with the default bindings
573+ // Setup the keyboardMouseDevice and the user input mapper with the default bindings
565574 _keyboardMouseDevice.registerToUserInputMapper(_userInputMapper);
566575 _keyboardMouseDevice.assignDefaultInputMapping(_userInputMapper);
567576
@@ -577,7 +586,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 9 unmodified lines
577586 // do this as late as possible so that all required subsystems are initialized
578587 loadScripts();
579588 }
580−
589+
581590 loadSettings();
582591 int SAVE_SETTINGS_INTERVAL = 10 * MSECS_PER_SECOND; // Let's save every seconds for now
583592 connect(&_settingsTimer, &QTimer::timeout, this, &Application::saveSettings);
@@ -587,12 +596,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 3 unmodified lines
587596 _settingsTimer.setSingleShot(false);
588597 _settingsTimer.setInterval(SAVE_SETTINGS_INTERVAL);
589598 _settingsThread.start();
590−
599+
591600 _trayIcon->show();
592−
601+
593602 // set the local loopback interface for local sounds from audio scripts
594603 AudioScriptingInterface::getInstance().setLocalAudioInterface(audioIO.data());
595−
604+
596605 #ifdef HAVE_RTMIDI
597606 // setup the MIDIManager
598607 MIDIManager& midiManagerInstance = MIDIManager::getInstance();
@@ -600,7 +609,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 1 unmodified line
600609 #endif
601610
602611 this->installEventFilter(this);
603− // The offscreen UI needs to intercept the mouse and keyboard
612+ // The offscreen UI needs to intercept the mouse and keyboard
604613 // events coming from the onscreen window
605614 _glWidget->installEventFilter(DependencyManager::get<OffscreenUi>().data());
606615
@@ -618,7 +627,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 11 unmodified lines
618627
619628 void Application::aboutToQuit() {
620629 emit beforeAboutToQuit();
621−
630+
622631 _aboutToQuit = true;
623632 cleanupBeforeQuit();
624633 }
@@ -630,7 +639,7 @@ void Application::cleanupBeforeQuit() { · 5 unmodified lines
630639 _datagramProcessor->shutdown(); // tell the datagram processor we're shutting down, so it can short circuit
631640 _entities.shutdown(); // tell the entities system we're shutting down, so it will stop running scripts
632641 ScriptEngine::stopAllScripts(this); // stop all currently running global scripts
633−
642+
634643 // first stop all timers directly or by invokeMethod
635644 // depending on what thread they run in
636645 locationUpdateTimer->stop();
@@ -657,11 +666,11 @@ void Application::cleanupBeforeQuit() { · 20 unmodified lines
657666
658667 // let the avatar mixer know we're out
659668 MyAvatar::sendKillAvatar();
660−
669+
661670 // stop the AudioClient
662671 QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(),
663672 "stop", Qt::BlockingQueuedConnection);
664−
673+
665674 // destroy the AudioClient so it and its thread have a chance to go down safely
666675 DependencyManager::destroy<AudioClient>();
667676
@@ -670,12 +679,12 @@ void Application::cleanupBeforeQuit() { · 2 unmodified lines
670679 #endif
671680 }
672681
673−Application::~Application() {
682+Application::~Application() {
674683 EntityTree* tree = _entities.getTree();
675684 tree->lockForWrite();
676685 _entities.getTree()->setSimulation(NULL);
677686 tree->unlock();
678−
687+
679688 _octreeProcessor.terminate();
680689 _entityEditSender.terminate();
681690
@@ -685,7 +694,7 @@ Application::~Application() { · 3 unmodified lines
685694 _myAvatar = NULL;
686695
687696 ModelEntityItem::cleanupLoadedAnimations();
688−
697+
689698 // stop the glWidget frame timer so it doesn't call paintGL
690699 _glWidget->stopFrameTimer();
691700
@@ -700,10 +709,10 @@ Application::~Application() { · 8 unmodified lines
700709 DependencyManager::destroy<GeometryCache>();
701710 DependencyManager::destroy<ScriptCache>();
702711 DependencyManager::destroy<SoundCache>();
703−
712+
704713 QThread* nodeThread = DependencyManager::get<NodeList>()->thread();
705714 DependencyManager::destroy<NodeList>();
706−
715+
707716 // ask the node thread to quit and wait until it is done
708717 nodeThread->quit();
709718 nodeThread->wait();
@@ -757,8 +766,8 @@ void Application::initializeGL() { · 47 unmodified lines
757766 initDisplay();
758767 qCDebug(interfaceapp, "Initialized Display.");
759768
760− // The UI can't be created until the primary OpenGL
761− // context is created, because it needs to share
769+ // The UI can't be created until the primary OpenGL
770+ // context is created, because it needs to share
762771 // texture resources
763772 initializeUi();
764773 qCDebug(interfaceapp, "Initialized Offscreen UI.");
@@ -837,6 +846,13 @@ void Application::initializeUi() { · 72 unmodified lines
837846 void Application::paintGL() {
838847 PROFILE_RANGE(__FUNCTION__);
839848 _glWidget->makeCurrent();
849+
850+ auto lodManager = DependencyManager::get<LODManager>();
851+ gpu::Context context(new gpu::GLBackend());
852+ RenderArgs renderArgs(&context, nullptr, getViewFrustum(), lodManager->getOctreeSizeScale(),
853+ lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE,
854+ RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE);
855+
840856 PerformanceTimer perfTimer("paintGL");
841857 //Need accurate frame timing for the oculus rift
842858 if (OculusManager::isConnected()) {
@@ -850,7 +866,7 @@ void Application::paintGL() { · 7 unmodified lines
850866
851867 {
852868 PerformanceTimer perfTimer("renderOverlay");
853− _applicationOverlay.renderOverlay();
869+ _applicationOverlay.renderOverlay(&renderArgs);
854870 }
855871
856872 glEnable(GL_LINE_SMOOTH);
@@ -899,22 +915,23 @@ void Application::paintGL() { · 42 unmodified lines
899915 loadViewFrustum(_myCamera, _viewFrustum);
900916
901917 if (getShadowsEnabled()) {
902− updateShadowMap();
918+ renderArgs._renderMode = RenderArgs::SHADOW_RENDER_MODE;
919+ updateShadowMap(&renderArgs);
903920 }
904921
922+ renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE;
923+
905924 if (OculusManager::isConnected()) {
906925 //When in mirror mode, use camera rotation. Otherwise, use body rotation
907926 if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
908− OculusManager::display(_glWidget, _myCamera.getRotation(), _myCamera.getPosition(), _myCamera);
927+ OculusManager::display(_glWidget, &renderArgs, _myCamera.getRotation(), _myCamera.getPosition(), _myCamera);
909928 } else {
910− OculusManager::display(_glWidget, _myAvatar->getWorldAlignedOrientation(), _myAvatar->getDefaultEyePosition(), _myCamera);
929+ OculusManager::display(_glWidget, &renderArgs, _myAvatar->getWorldAlignedOrientation(), _myAvatar->getDefaultEyePosition(), _myCamera);
911930 }
912931 } else if (TV3DManager::isConnected()) {
913−
914− TV3DManager::display(_myCamera);
915−
932+ TV3DManager::display(&renderArgs, _myCamera);
916933 } else {
917− DependencyManager::get<GlowEffect>()->prepare();
934+ DependencyManager::get<GlowEffect>()->prepare(&renderArgs);
918935
919936 // Viewport is assigned to the size of the framebuffer
920937 QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize();
@@ -923,16 +940,16 @@ void Application::paintGL() { · 2 unmodified lines
923940 glMatrixMode(GL_MODELVIEW);
924941 glPushMatrix();
925942 glLoadIdentity();
926− displaySide(_myCamera);
943+ displaySide(&renderArgs, _myCamera);
927944 glPopMatrix();
928945
929946 if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
930− _rearMirrorTools->render(true, _glWidget->mapFromGlobal(QCursor::pos()));
947+ _rearMirrorTools->render(&renderArgs, true, _glWidget->mapFromGlobal(QCursor::pos()));
931948 } else if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
932− renderRearViewMirror(_mirrorViewRect);
949+ renderRearViewMirror(&renderArgs, _mirrorViewRect);
933950 }
934951
935− auto finalFbo = DependencyManager::get<GlowEffect>()->render();
952+ auto finalFbo = DependencyManager::get<GlowEffect>()->render(&renderArgs);
936953
937954 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
938955 glBindFramebuffer(GL_READ_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(finalFbo));
@@ -946,12 +963,13 @@ void Application::paintGL() { · 7 unmodified lines
946963
947964 if (!OculusManager::isConnected() || OculusManager::allowSwap()) {
948965 _glWidget->swapBuffers();
949− }
966+ }
950967
951968 if (OculusManager::isConnected()) {
952969 OculusManager::endFrameTiming();
953970 }
954971 _frameCount++;
972+ Stats::getInstance()->setRenderDetails(renderArgs._details);
955973 }
956974
957975 void Application::runTests() {
@@ -1036,7 +1054,7 @@ void Application::updateProjectionMatrix(Camera& camera, bool updateViewFrustum) · 78 unmodified lines
10361054 // Tell our viewFrustum about this change, using the application camera
10371055 if (updateViewFrustum) {
10381056 loadViewFrustum(camera, _viewFrustum);
1039− }
1057+ }
10401058
10411059 glMatrixMode(GL_MODELVIEW);
10421060 }
@@ -1104,11 +1122,11 @@ bool Application::event(QEvent* event) { · 61 unmodified lines
11041122
11051123 // handle custom URL
11061124 if (event->type() == QEvent::FileOpen) {
1107−
1125+
11081126 QFileOpenEvent* fileEvent = static_cast<QFileOpenEvent*>(event);
11091127
11101128 QUrl url = fileEvent->url();
1111−
1129+
11121130 if (!url.isEmpty()) {
11131131 QString urlString = url.toString();
11141132 if (canAcceptURL(urlString)) {
@@ -1117,7 +1135,7 @@ bool Application::event(QEvent* event) { · 2 unmodified lines
11171135 }
11181136 return false;
11191137 }
1120−
1138+
11211139 if (HFActionEvent::types().contains(event->type())) {
11221140 _controllerScriptingInterface.handleMetaEvent(static_cast<HFMetaEvent*>(event));
11231141 }
@@ -1183,7 +1201,7 @@ void Application::keyPressEvent(QKeyEvent* event) { · 59 unmodified lines
11831201 Menu::getInstance()->triggerOption(MenuOption::AddressBar);
11841202 } else if (isShifted) {
11851203 Menu::getInstance()->triggerOption(MenuOption::LodTools);
1186− }
1204+ }
11871205 break;
11881206
11891207 case Qt::Key_F: {
@@ -1224,7 +1242,7 @@ void Application::keyPressEvent(QKeyEvent* event) { · 34 unmodified lines
12241242 case Qt::Key_Backslash:
12251243 Menu::getInstance()->triggerOption(MenuOption::Chat);
12261244 break;
1227−
1245+
12281246 case Qt::Key_Up:
12291247 if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
12301248 if (!isShifted) {
@@ -1353,18 +1371,18 @@ void Application::keyPressEvent(QKeyEvent* event) { · 122 unmodified lines
13531371 computePickRay(getTrueMouseX(), getTrueMouseY()));
13541372 sendEvent(this, &startActionEvent);
13551373 }
1356−
1374+
13571375 break;
13581376 }
13591377 case Qt::Key_Escape: {
13601378 OculusManager::abandonCalibration();
1361−
1379+
13621380 if (!event->isAutoRepeat()) {
13631381 // this starts the HFCancelEvent
13641382 HFBackEvent startBackEvent(HFBackEvent::startType());
13651383 sendEvent(this, &startBackEvent);
13661384 }
1367−
1385+
13681386 break;
13691387 }
13701388
@@ -1426,7 +1444,7 @@ void Application::keyReleaseEvent(QKeyEvent* event) { · 55 unmodified lines
14261444
14271445 void Application::focusOutEvent(QFocusEvent* event) {
14281446 _keyboardMouseDevice.focusOutEvent(event);
1429−
1447+
14301448 // synthesize events for keys currently pressed, since we may not get their release events
14311449 foreach (int key, _keysPressed) {
14321450 QKeyEvent event(QEvent::KeyRelease, key, Qt::NoModifier);
@@ -1441,12 +1459,12 @@ void Application::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) { · 8 unmodified lines
14411459 if (!_lastMouseMoveWasSimulated) {
14421460 _lastMouseMove = usecTimestampNow();
14431461 }
1444−
1462+
14451463 if (_aboutToQuit) {
14461464 return;
14471465 }
1448−
1449− if (Menu::getInstance()->isOptionChecked(MenuOption::Fullscreen)
1466+
1467+ if (Menu::getInstance()->isOptionChecked(MenuOption::Fullscreen)
14501468 && !Menu::getInstance()->isOptionChecked(MenuOption::EnableVRMode)) {
14511469 // Show/hide menu bar in fullscreen
14521470 if (event->globalY() > _menuBarHeight) {
@@ -1459,7 +1477,7 @@ void Application::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) { · 6 unmodified lines
14591477 }
14601478
14611479 _entities.mouseMoveEvent(event, deviceID);
1462−
1480+
14631481 _controllerScriptingInterface.emitMouseMoveEvent(event, deviceID); // send events to any registered scripts
14641482 // if one of our scripts have asked to capture this event, then stop processing it
14651483 if (_controllerScriptingInterface.isMouseCaptured()) {
@@ -1467,7 +1485,7 @@ void Application::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) { · 1 unmodified line
14671485 }
14681486
14691487 _keyboardMouseDevice.mouseMoveEvent(event, deviceID);
1470−
1488+
14711489 }
14721490
14731491 void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) {
@@ -1493,7 +1511,7 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) { · 19 unmodified lines
14931511 _mouseDragStartedX = getTrueMouseX();
14941512 _mouseDragStartedY = getTrueMouseY();
14951513 _mousePressed = true;
1496−
1514+
14971515 if (mouseOnScreen()) {
14981516 if (DependencyManager::get<AudioToolBox>()->mousePressEvent(getMouseX(), getMouseY())) {
14991517 // stop propagation
@@ -1510,7 +1528,7 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) { · 10 unmodified lines
15101528 return;
15111529 }
15121530 }
1513−
1531+
15141532 // nobody handled this - make it an action event on the _window object
15151533 HFActionEvent actionEvent(HFActionEvent::startType(),
15161534 computePickRay(event->x(), event->y()));
@@ -1558,14 +1576,14 @@ void Application::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) { · 41 unmodified lines
15581576
15591577 if (event->button() == Qt::LeftButton) {
15601578 _mousePressed = false;
1561−
1579+
15621580 if (Menu::getInstance()->isOptionChecked(MenuOption::Stats) && mouseOnScreen()) {
15631581 // let's set horizontal offset to give stats some margin to mirror
15641582 int horizontalOffset = MIRROR_VIEW_WIDTH;
15651583 Stats::getInstance()->checkClick(getMouseX(), getMouseY(),
15661584 getMouseDragStartedX(), getMouseDragStartedY(), horizontalOffset);
15671585 }
1568−
1586+
15691587 // fire an action end event
15701588 HFActionEvent actionEvent(HFActionEvent::endType(),
15711589 computePickRay(event->x(), event->y()));
@@ -1674,7 +1692,7 @@ void Application::dropEvent(QDropEvent *event) { · 102 unmodified lines
16741692 }
16751693 }
16761694 }
1677−
1695+
16781696 if (atLeastOneFileAccepted) {
16791697 event->acceptProposedAction();
16801698 }
@@ -1694,7 +1712,7 @@ void Application::dragEnterEvent(QDragEnterEvent* event) { · 13 unmodified lines
16941712 bool Application::acceptSnapshot(const QString& urlString) {
16951713 QUrl url(urlString);
16961714 QString snapshotPath = url.toLocalFile();
1697−
1715+
16981716 SnapshotMetaData* snapshotData = Snapshot::parseSnapshotData(snapshotPath);
16991717 if (snapshotData) {
17001718 if (!snapshotData->getURL().toString().isEmpty()) {
@@ -1704,7 +1722,7 @@ bool Application::acceptSnapshot(const QString& urlString) { · 3 unmodified lines
17041722 QMessageBox msgBox;
17051723 msgBox.setText("No location details were found in the file "
17061724 + snapshotPath + ", try dragging in an authentic Hifi snapshot.");
1707−
1725+
17081726 msgBox.setStandardButtons(QMessageBox::Ok);
17091727 msgBox.exec();
17101728 }
@@ -1737,7 +1755,7 @@ void Application::checkFPS() { · 26 unmodified lines
17371755
17381756 void Application::idle() {
17391757 PerformanceTimer perfTimer("idle");
1740−
1758+
17411759 if (_aboutToQuit) {
17421760 return; // bail early, nothing to do here.
17431761 }
@@ -1925,7 +1943,7 @@ int Application::getMouseDragStartedY() const { · 181 unmodified lines
19251943 FaceTracker* Application::getActiveFaceTracker() {
19261944 auto faceshift = DependencyManager::get<Faceshift>();
19271945 auto dde = DependencyManager::get<DdeFaceTracker>();
1928−
1946+
19291947 return (dde->isActive() ? static_cast<FaceTracker*>(dde.data()) :
19301948 (faceshift->isActive() ? static_cast<FaceTracker*>(faceshift.data()) : NULL));
19311949 }
@@ -2058,14 +2076,14 @@ void Application::saveSettings() { · 126 unmodified lines
20582076
20592077 bool Application::importEntities(const QString& urlOrFilename) {
20602078 _entityClipboard.eraseAllOctreeElements();
2061−
2079+
20622080 QUrl url(urlOrFilename);
2063−
2081+
20642082 // if the URL appears to be invalid or relative, then it is probably a local file
20652083 if (!url.isValid() || url.isRelative()) {
20662084 url = QUrl::fromLocalFile(urlOrFilename);
20672085 }
2068−
2086+
20692087 bool success = _entityClipboard.readFromURL(url.toString());
20702088 if (success) {
20712089 _entityClipboard.reaverageOctreeElements();
@@ -2089,7 +2107,7 @@ void Application::initDisplay() { · 17 unmodified lines
20892107 void Application::init() {
20902108 // Make sure Login state is up to date
20912109 DependencyManager::get<DialogsManager>()->toggleLoginDialog();
2092−
2110+
20932111 _environment.init();
20942112
20952113 DependencyManager::get<DeferredLightingEffect>()->init(this);
@@ -2117,7 +2135,7 @@ void Application::init() { · 21 unmodified lines
21172135
21182136 _timerStart.start();
21192137 _lastTimeUpdated.start();
2120−
2138+
21212139 // when --url in command line, teleport to location
21222140 const QString HIFI_URL_COMMAND_LINE_KEY = "--url";
21232141 int urlIndex = arguments().indexOf(HIFI_URL_COMMAND_LINE_KEY);
@@ -2125,11 +2143,11 @@ void Application::init() { · 1 unmodified line
21252143 if (urlIndex != -1) {
21262144 addressLookupString = arguments().value(urlIndex + 1);
21272145 }
2128−
2146+
21292147 DependencyManager::get<AddressManager>()->loadSettings(addressLookupString);
2130−
2148+
21312149 qCDebug(interfaceapp) << "Loaded settings";
2132−
2150+
21332151 #ifdef __APPLE__
21342152 if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseEnabled)) {
21352153 // on OS X we only setup sixense if the user wants it on - this allows running without the hid_init crash
@@ -2237,7 +2255,7 @@ void Application::updateMouseRay() { · 101 unmodified lines
22372255 PickRay pickRay = computePickRay(getTrueMouseX(), getTrueMouseY());
22382256 _mouseRayOrigin = pickRay.origin;
22392257 _mouseRayDirection = pickRay.direction;
2240−
2258+
22412259 // adjust for mirroring
22422260 if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
22432261 glm::vec3 mouseRayOffset = _mouseRayOrigin - _viewFrustum.getPosition();
@@ -2269,28 +2287,27 @@ void Application::updateMyAvatarLookAtPosition() { · 25 unmodified lines
22692287 lookAtSpot = OculusManager::getRightEyePosition();
22702288 }
22712289 }
2272−
2290+
22732291 } else {
2274− AvatarSharedPointer lookingAt = _myAvatar->getLookAtTargetAvatar().toStrongRef();
2275− if (lookingAt && _myAvatar != lookingAt.data()) {
2276−
2292+ AvatarSharedPointer lookingAt = _myAvatar->getLookAtTargetAvatar().lock();
2293+ if (lookingAt && _myAvatar != lookingAt.get()) {
22772294 isLookingAtSomeone = true;
22782295 // If I am looking at someone else, look directly at one of their eyes
22792296 if (tracker && !tracker->isMuted()) {
22802297 // If a face tracker is active, look at the eye for the side my gaze is biased toward
22812298 if (tracker->getEstimatedEyeYaw() > _myAvatar->getHead()->getFinalYaw()) {
22822299 // Look at their right eye
2283− lookAtSpot = static_cast<Avatar*>(lookingAt.data())->getHead()->getRightEyePosition();
2300+ lookAtSpot = static_cast<Avatar*>(lookingAt.get())->getHead()->getRightEyePosition();
22842301 } else {
22852302 // Look at their left eye
2286− lookAtSpot = static_cast<Avatar*>(lookingAt.data())->getHead()->getLeftEyePosition();
2303+ lookAtSpot = static_cast<Avatar*>(lookingAt.get())->getHead()->getLeftEyePosition();
22872304 }
22882305 } else {
22892306 // Need to add randomly looking back and forth between left and right eye for case with no tracker
22902307 if (_myAvatar->isLookingAtLeftEye()) {
2291− lookAtSpot = static_cast<Avatar*>(lookingAt.data())->getHead()->getLeftEyePosition();
2308+ lookAtSpot = static_cast<Avatar*>(lookingAt.get())->getHead()->getLeftEyePosition();
22922309 } else {
2293− lookAtSpot = static_cast<Avatar*>(lookingAt.data())->getHead()->getRightEyePosition();
2310+ lookAtSpot = static_cast<Avatar*>(lookingAt.get())->getHead()->getRightEyePosition();
22942311 }
22952312 }
22962313 } else {
@@ -2360,7 +2377,7 @@ void Application::updateDialogs(float deltaTime) { · 63 unmodified lines
23602377 bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
23612378 PerformanceWarning warn(showWarnings, "Application::updateDialogs()");
23622379 auto dialogsManager = DependencyManager::get<DialogsManager>();
2363−
2380+
23642381 // Update bandwidth dialog, if any
23652382 BandwidthDialog* bandwidthDialog = dialogsManager->getBandwidthDialog();
23662383 if (bandwidthDialog) {
@@ -2555,7 +2572,7 @@ void Application::update(float deltaTime) { · 188 unmodified lines
25552572 }
25562573 }
25572574
2558− // send packet containing downstream audio stats to the AudioMixer
2575+ // send packet containing downstream audio stats to the AudioMixer
25592576 {
25602577 quint64 sinceLastNack = now - _lastSendDownstreamAudioStats;
25612578 if (sinceLastNack > TOO_LONG_SINCE_LAST_SEND_DOWNSTREAM_AUDIO_STATS) {
@@ -2577,64 +2594,64 @@ int Application::sendNackPackets() { · 15 unmodified lines
25772594
25782595 // iterates thru all nodes in NodeList
25792596 auto nodeList = DependencyManager::get<NodeList>();
2580−
2597+
25812598 nodeList->eachNode([&](const SharedNodePointer& node){
2582−
2599+
25832600 if (node->getActiveSocket() && node->getType() == NodeType::EntityServer) {
2584−
2601+
25852602 QUuid nodeUUID = node->getUUID();
2586−
2603+
25872604 // if there are octree packets from this node that are waiting to be processed,
25882605 // don't send a NACK since the missing packets may be among those waiting packets.
25892606 if (_octreeProcessor.hasPacketsToProcessFrom(nodeUUID)) {
25902607 return;
25912608 }
2592−
2609+
25932610 _octreeSceneStatsLock.lockForRead();
2594−
2611+
25952612 // retreive octree scene stats of this node
25962613 if (_octreeServerSceneStats.find(nodeUUID) == _octreeServerSceneStats.end()) {
25972614 _octreeSceneStatsLock.unlock();
25982615 return;
25992616 }
2600−
2617+
26012618 // get sequence number stats of node, prune its missing set, and make a copy of the missing set
26022619 SequenceNumberStats& sequenceNumberStats = _octreeServerSceneStats[nodeUUID].getIncomingOctreeSequenceNumberStats();
26032620 sequenceNumberStats.pruneMissingSet();
26042621 const QSet<OCTREE_PACKET_SEQUENCE> missingSequenceNumbers = sequenceNumberStats.getMissingSet();
2605−
2622+
26062623 _octreeSceneStatsLock.unlock();
2607−
2624+
26082625 // construct nack packet(s) for this node
26092626 int numSequenceNumbersAvailable = missingSequenceNumbers.size();
26102627 QSet<OCTREE_PACKET_SEQUENCE>::const_iterator missingSequenceNumbersIterator = missingSequenceNumbers.constBegin();
26112628 while (numSequenceNumbersAvailable > 0) {
2612−
2629+
26132630 char* dataAt = packet;
26142631 int bytesRemaining = MAX_PACKET_SIZE;
2615−
2632+
26162633 // pack header
26172634 int numBytesPacketHeader = nodeList->populatePacketHeader(packet, PacketTypeOctreeDataNack);
26182635 dataAt += numBytesPacketHeader;
26192636 bytesRemaining -= numBytesPacketHeader;
2620−
2637+
26212638 // calculate and pack the number of sequence numbers
26222639 int numSequenceNumbersRoomFor = (bytesRemaining - sizeof(uint16_t)) / sizeof(OCTREE_PACKET_SEQUENCE);
26232640 uint16_t numSequenceNumbers = min(numSequenceNumbersAvailable, numSequenceNumbersRoomFor);
26242641 uint16_t* numSequenceNumbersAt = (uint16_t*)dataAt;
26252642 *numSequenceNumbersAt = numSequenceNumbers;
26262643 dataAt += sizeof(uint16_t);
2627−
2644+
26282645 // pack sequence numbers
26292646 for (int i = 0; i < numSequenceNumbers; i++) {
26302647 OCTREE_PACKET_SEQUENCE* sequenceNumberAt = (OCTREE_PACKET_SEQUENCE*)dataAt;
26312648 *sequenceNumberAt = *missingSequenceNumbersIterator;
26322649 dataAt += sizeof(OCTREE_PACKET_SEQUENCE);
2633−
2650+
26342651 missingSequenceNumbersIterator++;
26352652 }
26362653 numSequenceNumbersAvailable -= numSequenceNumbers;
2637−
2654+
26382655 // send it
26392656 nodeList->writeUnverifiedDatagram(packet, dataAt - packet, node);
26402657 packetsSent++;
@@ -2676,7 +2693,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node · 35 unmodified lines
26762693 int unknownJurisdictionServers = 0;
26772694
26782695 auto nodeList = DependencyManager::get<NodeList>();
2679−
2696+
26802697 nodeList->eachNode([&](const SharedNodePointer& node) {
26812698 // only send to the NodeTypes that are serverType
26822699 if (node->getActiveSocket() && node->getType() == serverType) {
@@ -2736,17 +2753,17 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node · 53 unmodified lines
27362753 if (wantExtraDebugging) {
27372754 qCDebug(interfaceapp, "perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer);
27382755 }
2739−
2756+
27402757 nodeList->eachNode([&](const SharedNodePointer& node){
27412758 // only send to the NodeTypes that are serverType
27422759 if (node->getActiveSocket() && node->getType() == serverType) {
2743−
2760+
27442761 // get the server bounds for this server
27452762 QUuid nodeUUID = node->getUUID();
2746−
2763+
27472764 bool inView = false;
27482765 bool unknownView = false;
2749−
2766+
27502767 // if we haven't heard from this voxel server, go ahead and send it a query, so we
27512768 // can get the jurisdiction...
27522769 if (jurisdictions.find(nodeUUID) == jurisdictions.end()) {
@@ -2756,9 +2773,9 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node · 3 unmodified lines
27562773 }
27572774 } else {
27582775 const JurisdictionMap& map = (jurisdictions)[nodeUUID];
2759−
2776+
27602777 unsigned char* rootCode = map.getRootOctalCode();
2761−
2778+
27622779 if (rootCode) {
27632780 VoxelPositionSize rootDetails;
27642781 voxelDetailsForCode(rootCode, rootDetails);
@@ -2768,7 +2785,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node · 3 unmodified lines
27682785 rootDetails.s * TREE_SCALE);
27692786
27702787
2771−
2788+
27722789 ViewFrustum::location serverFrustumLocation = _viewFrustum.cubeInFrustum(serverBounds);
27732790 if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
27742791 inView = true;
@@ -2781,7 +2798,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node · 6 unmodified lines
27812798 }
27822799 }
27832800 }
2784−
2801+
27852802 if (inView) {
27862803 _octreeQuery.setMaxQueryPacketsPerSecond(perServerPPS);
27872804 } else if (unknownView) {
@@ -2789,7 +2806,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node · 1 unmodified line
27892806 qCDebug(interfaceapp) << "no known jurisdiction for node " << *node << ", give it budget of "
27902807 << perUnknownServer << " to send us jurisdiction.";
27912808 }
2792−
2809+
27932810 // set the query's position/orientation to be degenerate in a manner that will get the scene quickly
27942811 // If there's only one server, then don't do this, and just let the normal voxel query pass through
27952812 // as expected... this way, we will actually get a valid scene if there is one to be seen
@@ -2816,12 +2833,12 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node · 20 unmodified lines
28162833
28172834 // insert packet type/version and node UUID
28182835 endOfQueryPacket += nodeList->populatePacketHeader(reinterpret_cast<char*>(endOfQueryPacket), packetType);
2819−
2836+
28202837 // encode the query data...
28212838 endOfQueryPacket += _octreeQuery.getBroadcastData(endOfQueryPacket);
2822−
2839+
28232840 int packetLength = endOfQueryPacket - queryPacket;
2824−
2841+
28252842 // make sure we still have an active socket
28262843 nodeList->writeUnverifiedDatagram(reinterpret_cast<const char*>(queryPacket), packetLength, node);
28272844 }
@@ -2838,7 +2855,7 @@ bool Application::isHMDMode() const { · 10 unmodified lines
28382855
28392856 QRect Application::getDesirableApplicationGeometry() {
28402857 QRect applicationGeometry = getWindow()->geometry();
2841−
2858+
28422859 // If our parent window is on the HMD, then don't use its geometry, instead use
28432860 // the "main screen" geometry.
28442861 HMDToolsDialog* hmdTools = DependencyManager::get<DialogsManager>()->getHMDToolsDialog();
@@ -2886,7 +2903,7 @@ glm::vec3 Application::getSunDirection() { · 41 unmodified lines
28862903 // FIXME, preprocessor guard this check to occur only in DEBUG builds
28872904 static QThread * activeRenderingThread = nullptr;
28882905
2889−void Application::updateShadowMap() {
2906+void Application::updateShadowMap(RenderArgs* renderArgs) {
28902907 activeRenderingThread = QThread::currentThread();
28912908
28922909 PerformanceTimer perfTimer("shadowMap");
@@ -2899,14 +2916,14 @@ void Application::updateShadowMap() { · 6 unmodified lines
28992916 glm::vec3 lightDirection = getSunDirection();
29002917 glm::quat rotation = rotationBetween(IDENTITY_FRONT, lightDirection);
29012918 glm::quat inverseRotation = glm::inverse(rotation);
2902−
2919+
29032920 const float SHADOW_MATRIX_DISTANCES[] = { 0.0f, 2.0f, 6.0f, 14.0f, 30.0f };
29042921 const glm::vec2 MAP_COORDS[] = { glm::vec2(0.0f, 0.0f), glm::vec2(0.5f, 0.0f),
29052922 glm::vec2(0.0f, 0.5f), glm::vec2(0.5f, 0.5f) };
2906−
2923+
29072924 float frustumScale = 1.0f / (_viewFrustum.getFarClip() - _viewFrustum.getNearClip());
29082925 loadViewFrustum(_myCamera, _viewFrustum);
2909−
2926+
29102927 int matrixCount = 1;
29112928 //int targetSize = fbo->width();
29122929 int sourceSize = shadowFramebuffer->getWidth();
@@ -2948,12 +2965,12 @@ void Application::updateShadowMap() { · 35 unmodified lines
29482965 _shadowDistances[i] = -glm::distance(_viewFrustum.getPosition(), center) - radius * RADIUS_SCALE;
29492966 }
29502967 center = inverseRotation * center;
2951−
2968+
29522969 // to reduce texture "shimmer," move in texel increments
29532970 float texelSize = (2.0f * radius) / targetSize;
29542971 center = glm::vec3(roundf(center.x / texelSize) * texelSize, roundf(center.y / texelSize) * texelSize,
29552972 roundf(center.z / texelSize) * texelSize);
2956−
2973+
29572974 glm::vec3 minima(center.x - radius, center.y - radius, center.z - radius);
29582975 glm::vec3 maxima(center.x + radius, center.y + radius, center.z + radius);
29592976
@@ -2992,7 +3009,7 @@ void Application::updateShadowMap() { · 32 unmodified lines
29923009
29933010 // store view matrix without translation, which we'll use for precision-sensitive objects
29943011 updateUntranslatedViewMatrix();
2995−
3012+
29963013 // Equivalent to what is happening with _untranslatedViewMatrix and the _viewMatrixTranslation
29973014 // the viewTransofmr object is updatded with the correct values and saved,
29983015 // this is what is used for rendering the Entities and avatars
@@ -3005,25 +3022,9 @@ void Application::updateShadowMap() { · 6 unmodified lines
30053022 glEnable(GL_POLYGON_OFFSET_FILL);
30063023 glPolygonOffset(1.1f, 4.0f); // magic numbers courtesy http://www.eecs.berkeley.edu/~ravir/6160/papers/shadowmaps.ppt
30073024
3008− {
3009− PerformanceTimer perfTimer("avatarManager");
3010− DependencyManager::get<AvatarManager>()->renderAvatars(RenderArgs::SHADOW_RENDER_MODE);
3011− }
3012−
30133025 {
30143026 PerformanceTimer perfTimer("entities");
3015− _entities.render(RenderArgs::SHADOW_RENDER_MODE);
3016− }
3017−
3018− // render JS/scriptable overlays
3019− {
3020− PerformanceTimer perfTimer("3dOverlays");
3021− _overlays.renderWorld(false, RenderArgs::SHADOW_RENDER_MODE);
3022− }
3023−
3024− {
3025− PerformanceTimer perfTimer("3dOverlaysFront");
3026− _overlays.renderWorld(true, RenderArgs::SHADOW_RENDER_MODE);
3027+ _entities.render(renderArgs);
30273028 }
30283029
30293030 glDisable(GL_POLYGON_OFFSET_FILL);
@@ -3035,9 +3036,9 @@ void Application::updateShadowMap() { · 5 unmodified lines
30353036
30363037 glMatrixMode(GL_MODELVIEW);
30373038 }
3038−
3039+
30393040 // fbo->release();
3040−
3041+
30413042 glViewport(0, 0, _glWidget->getDeviceWidth(), _glWidget->getDeviceHeight());
30423043 activeRenderingThread = nullptr;
30433044 }
@@ -3069,11 +3070,11 @@ bool Application::shouldRenderMesh(float largestDimension, float distanceToCamer · 25 unmodified lines
30693070 return DependencyManager::get<LODManager>()->shouldRenderMesh(largestDimension, distanceToCamera);
30703071 }
30713072
3072−float Application::getSizeScale() const {
3073+float Application::getSizeScale() const {
30733074 return DependencyManager::get<LODManager>()->getOctreeSizeScale();
30743075 }
30753076
3076−int Application::getBoundaryLevelAdjust() const {
3077+int Application::getBoundaryLevelAdjust() const {
30773078 return DependencyManager::get<LODManager>()->getBoundaryLevelAdjust();
30783079 }
30793080
@@ -3094,30 +3095,31 @@ PickRay Application::computePickRay(float x, float y) const { · 14 unmodified lines
30943095 return result;
30953096 }
30963097
3097−QImage Application::renderAvatarBillboard() {
3098+QImage Application::renderAvatarBillboard(RenderArgs* renderArgs) {
30983099 auto primaryFramebuffer = DependencyManager::get<TextureCache>()->getPrimaryFramebuffer();
30993100 glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFramebuffer));
3100−
3101+
31013102 // clear the alpha channel so the background is transparent
31023103 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
31033104 glClearColor(0.0, 0.0, 0.0, 0.0);
31043105 glClear(GL_COLOR_BUFFER_BIT);
31053106 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
3106−
3107+
31073108 // the "glow" here causes an alpha of one
3108− Glower glower;
3109−
3109+ Glower glower(renderArgs);
3110+
31103111 const int BILLBOARD_SIZE = 64;
3111− renderRearViewMirror(QRect(0, _glWidget->getDeviceHeight() - BILLBOARD_SIZE,
3112+ // TODO: Pass a RenderArgs to renderAvatarBillboard
3113+ renderRearViewMirror(renderArgs, QRect(0, _glWidget->getDeviceHeight() - BILLBOARD_SIZE,
31123114 BILLBOARD_SIZE, BILLBOARD_SIZE),
31133115 true);
3114−
3116+
31153117 QImage image(BILLBOARD_SIZE, BILLBOARD_SIZE, QImage::Format_ARGB32);
31163118 glReadPixels(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE, GL_BGRA, GL_UNSIGNED_BYTE, image.bits());
31173119 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3118−
3120+
31193121 glBindFramebuffer(GL_FRAMEBUFFER, 0);
3120−
3122+
31213123 return image;
31223124 }
31233125
@@ -3161,7 +3163,143 @@ const ViewFrustum* Application::getDisplayViewFrustum() const { · 37 unmodified lines
31613163 return &_displayViewFrustum;
31623164 }
31633165
3164−void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, bool billboard, RenderArgs::RenderSide renderSide) {
3166+// WorldBox Render Data & rendering functions
3167+
3168+class WorldBoxRenderData {
3169+public:
3170+ typedef render::Payload<WorldBoxRenderData> Payload;
3171+ typedef Payload::DataPointer Pointer;
3172+
3173+ int _val = 0;
3174+ static render::ItemID _item; // unique WorldBoxRenderData
3175+};
3176+
3177+render::ItemID WorldBoxRenderData::_item = 0;
3178+
3179+namespace render {
3180+ template <> const ItemKey payloadGetKey(const WorldBoxRenderData::Pointer& stuff) { return ItemKey::Builder::opaqueShape(); }
3181+ template <> const Item::Bound payloadGetBound(const WorldBoxRenderData::Pointer& stuff) { return Item::Bound(); }
3182+ template <> void payloadRender(const WorldBoxRenderData::Pointer& stuff, RenderArgs* args) {
3183+ if (args->_renderMode != RenderArgs::MIRROR_RENDER_MODE && Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {
3184+ PerformanceTimer perfTimer("worldBox");
3185+
3186+ auto& batch = *args->_batch;
3187+ DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch);
3188+ renderWorldBox(batch);
3189+ }
3190+ }
3191+}
3192+
3193+// Background Render Data & rendering functions
3194+class BackgroundRenderData {
3195+public:
3196+ typedef render::Payload<BackgroundRenderData> Payload;
3197+ typedef Payload::DataPointer Pointer;
3198+
3199+ Stars _stars;
3200+ Environment* _environment;
3201+
3202+ BackgroundRenderData(Environment* environment) : _environment(environment) {
3203+ }
3204+
3205+ static render::ItemID _item; // unique WorldBoxRenderData
3206+};
3207+
3208+render::ItemID BackgroundRenderData::_item = 0;
3209+
3210+namespace render {
3211+ template <> const ItemKey payloadGetKey(const BackgroundRenderData::Pointer& stuff) { return ItemKey::Builder::background(); }
3212+ template <> const Item::Bound payloadGetBound(const BackgroundRenderData::Pointer& stuff) { return Item::Bound(); }
3213+ template <> void payloadRender(const BackgroundRenderData::Pointer& background, RenderArgs* args) {
3214+
3215+ // Background rendering decision
3216+ auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
3217+ auto skybox = model::SkyboxPointer();
3218+ if (skyStage->getBackgroundMode() == model::SunSkyStage::NO_BACKGROUND) {
3219+ } else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_DOME) {
3220+ if (/*!selfAvatarOnly &&*/ Menu::getInstance()->isOptionChecked(MenuOption::Stars)) {
3221+ PerformanceTimer perfTimer("stars");
3222+ PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
3223+ "Application::payloadRender<BackgroundRenderData>() ... stars...");
3224+ if (!background->_stars.isStarsLoaded()) {
3225+ background->_stars.generate(STARFIELD_NUM_STARS, STARFIELD_SEED);
3226+ }
3227+ // should be the first rendering pass - w/o depth buffer / lighting
3228+
3229+ // compute starfield alpha based on distance from atmosphere
3230+ float alpha = 1.0f;
3231+ bool hasStars = true;
3232+
3233+ if (Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) {
3234+ // TODO: handle this correctly for zones
3235+ const EnvironmentData& closestData = background->_environment->getClosestData(args->_viewFrustum->getPosition()); // was theCamera instead of _viewFrustum
3236+
3237+ if (closestData.getHasStars()) {
3238+ const float APPROXIMATE_DISTANCE_FROM_HORIZON = 0.1f;
3239+ const float DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON = 0.2f;
3240+
3241+ glm::vec3 sunDirection = (args->_viewFrustum->getPosition()/*getAvatarPosition()*/ - closestData.getSunLocation())
3242+ / closestData.getAtmosphereOuterRadius();
3243+ float height = glm::distance(args->_viewFrustum->getPosition()/*theCamera.getPosition()*/, closestData.getAtmosphereCenter());
3244+ if (height < closestData.getAtmosphereInnerRadius()) {
3245+ // If we're inside the atmosphere, then determine if our keyLight is below the horizon
3246+ alpha = 0.0f;
3247+
3248+ if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) {
3249+ float directionY = glm::clamp(sunDirection.y,
3250+ -APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON)
3251+ + APPROXIMATE_DISTANCE_FROM_HORIZON;
3252+ alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON);
3253+ }
3254+
3255+
3256+ } else if (height < closestData.getAtmosphereOuterRadius()) {
3257+ alpha = (height - closestData.getAtmosphereInnerRadius()) /
3258+ (closestData.getAtmosphereOuterRadius() - closestData.getAtmosphereInnerRadius());
3259+
3260+ if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) {
3261+ float directionY = glm::clamp(sunDirection.y,
3262+ -APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON)
3263+ + APPROXIMATE_DISTANCE_FROM_HORIZON;
3264+ alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON);
3265+ }
3266+ }
3267+ } else {
3268+ hasStars = false;
3269+ }
3270+ }
3271+
3272+ // finally render the starfield
3273+ if (hasStars) {
3274+ background->_stars.render(args->_viewFrustum->getFieldOfView(), args->_viewFrustum->getAspectRatio(), args->_viewFrustum->getNearClip(), alpha);
3275+ }
3276+
3277+ // draw the sky dome
3278+ if (/*!selfAvatarOnly &&*/ Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) {
3279+ PerformanceTimer perfTimer("atmosphere");
3280+ PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
3281+ "Application::displaySide() ... atmosphere...");
3282+ background->_environment->renderAtmospheres(*(args->_viewFrustum));
3283+ }
3284+
3285+ }
3286+ } else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) {
3287+ PerformanceTimer perfTimer("skybox");
3288+
3289+ skybox = skyStage->getSkybox();
3290+ if (skybox) {
3291+ gpu::Batch batch;
3292+ model::Skybox::render(batch, *(Application::getInstance()->getDisplayViewFrustum()), *skybox);
3293+
3294+ gpu::GLBackend::renderBatch(batch, true);
3295+ glUseProgram(0);
3296+ }
3297+ }
3298+ }
3299+}
3300+
3301+
3302+void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool selfAvatarOnly, bool billboard) {
31653303 activeRenderingThread = QThread::currentThread();
31663304 PROFILE_RANGE(__FUNCTION__);
31673305 PerformanceTimer perfTimer("display");
@@ -3200,13 +3338,13 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, bool billb · 32 unmodified lines
32003338 if (theCamera.getMode() == CAMERA_MODE_MIRROR) {
32013339 viewTransform.setScale(Transform::Vec3(-1.0f, 1.0f, 1.0f));
32023340 }
3203− if (renderSide != RenderArgs::MONO) {
3341+ if (renderArgs->_renderSide != RenderArgs::MONO) {
32043342 glm::mat4 invView = glm::inverse(_untranslatedViewMatrix);
3205−
3343+
32063344 viewTransform.evalFromRawMatrix(invView);
32073345 viewTransform.preTranslate(_viewMatrixTranslation);
32083346 }
3209−
3347+
32103348 setViewTransform(viewTransform);
32113349
32123350 glTranslatef(_viewMatrixTranslation.x, _viewMatrixTranslation.y, _viewMatrixTranslation.z);
@@ -3231,86 +3369,17 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, bool billb · 18 unmodified lines
32313369 glTexGenfv(GL_R, GL_EYE_PLANE, (const GLfloat*)&_shadowMatrices[i][2]);
32323370 }
32333371
3234− // Background rendering decision
3235− auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
3236− auto skybox = model::SkyboxPointer();
3237− if (skyStage->getBackgroundMode() == model::SunSkyStage::NO_BACKGROUND) {
3238− } else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_DOME) {
3239− if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Stars)) {
3240− PerformanceTimer perfTimer("stars");
3241− PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
3242− "Application::displaySide() ... stars...");
3243− if (!_stars.isStarsLoaded()) {
3244− _stars.generate(STARFIELD_NUM_STARS, STARFIELD_SEED);
3245− }
3246− // should be the first rendering pass - w/o depth buffer / lighting
3247−
3248− // compute starfield alpha based on distance from atmosphere
3249− float alpha = 1.0f;
3250− bool hasStars = true;
3251−
3252− if (Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) {
3253− // TODO: handle this correctly for zones
3254− const EnvironmentData& closestData = _environment.getClosestData(theCamera.getPosition());
3255−
3256− if (closestData.getHasStars()) {
3257− const float APPROXIMATE_DISTANCE_FROM_HORIZON = 0.1f;
3258− const float DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON = 0.2f;
3259−
3260− glm::vec3 sunDirection = (getAvatarPosition() - closestData.getSunLocation())
3261− / closestData.getAtmosphereOuterRadius();
3262− float height = glm::distance(theCamera.getPosition(), closestData.getAtmosphereCenter());
3263− if (height < closestData.getAtmosphereInnerRadius()) {
3264− // If we're inside the atmosphere, then determine if our keyLight is below the horizon
3265− alpha = 0.0f;
3266−
3267− if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) {
3268− float directionY = glm::clamp(sunDirection.y,
3269− -APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON)
3270− + APPROXIMATE_DISTANCE_FROM_HORIZON;
3271− alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON);
3272− }
3273−
3274−
3275− } else if (height < closestData.getAtmosphereOuterRadius()) {
3276− alpha = (height - closestData.getAtmosphereInnerRadius()) /
3277− (closestData.getAtmosphereOuterRadius() - closestData.getAtmosphereInnerRadius());
3278−
3279− if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) {
3280− float directionY = glm::clamp(sunDirection.y,
3281− -APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON)
3282− + APPROXIMATE_DISTANCE_FROM_HORIZON;
3283− alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON);
3284− }
3285− }
3286− } else {
3287− hasStars = false;
3288− }
3289− }
3372+ // The pending changes collecting the changes here
3373+ render::PendingChanges pendingChanges;
32903374
3291− // finally render the starfield
3292− if (hasStars) {
3293− _stars.render(_displayViewFrustum.getFieldOfView(), _displayViewFrustum.getAspectRatio(), _displayViewFrustum.getNearClip(), alpha);
3294− }
3295−
3296− // draw the sky dome
3297− if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) {
3298− PerformanceTimer perfTimer("atmosphere");
3299− PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
3300− "Application::displaySide() ... atmosphere...");
3301− _environment.renderAtmospheres(theCamera);
3302− }
3375+ // Background rendering decision
3376+ if (BackgroundRenderData::_item == 0) {
3377+ auto backgroundRenderData = BackgroundRenderData::Pointer(new BackgroundRenderData(&_environment));
3378+ auto backgroundRenderPayload = render::PayloadPointer(new BackgroundRenderData::Payload(backgroundRenderData));
3379+ BackgroundRenderData::_item = _main3DScene->allocateID();
3380+ pendingChanges.resetItem(WorldBoxRenderData::_item, backgroundRenderPayload);
3381+ } else {
33033382
3304− }
3305− } else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) {
3306− skybox = skyStage->getSkybox();
3307− if (skybox) {
3308− gpu::Batch batch;
3309− model::Skybox::render(batch, _displayViewFrustum, *skybox);
3310−
3311− gpu::GLBackend::renderBatch(batch);
3312− glUseProgram(0);
3313− }
33143383 }
33153384
33163385 if (Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) {
@@ -3320,13 +3389,10 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, bool billb · 3 unmodified lines
33203389 glEnable(GL_LIGHTING);
33213390 glEnable(GL_DEPTH_TEST);
33223391
3323− DependencyManager::get<DeferredLightingEffect>()->prepare();
3392+ // Assuming nothing get's rendered through that
33243393
33253394 if (!selfAvatarOnly) {
3326− // draw a red sphere
3327− float originSphereRadius = 0.05f;
3328− DependencyManager::get<GeometryCache>()->renderSphere(originSphereRadius, 15, 15, glm::vec4(1.0f, 0.0f, 0.0f, 1.0f));
3329−
3395+
33303396 // render models...
33313397 if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) {
33323398 PerformanceTimer perfTimer("entities");
@@ -3346,18 +3412,9 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, bool billb · 13 unmodified lines
33463412 if (theCamera.getMode() == CAMERA_MODE_MIRROR) {
33473413 renderMode = RenderArgs::MIRROR_RENDER_MODE;
33483414 }
3349− _entities.render(renderMode, renderSide, renderDebugFlags);
3350−
3351− if (!Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) {
3352− // Restaure polygon mode
3353− glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
3354− }
3355− }
3356−
3357− // render JS/scriptable overlays
3358− {
3359− PerformanceTimer perfTimer("3dOverlays");
3360− _overlays.renderWorld(false);
3415+ renderArgs->_renderMode = renderMode;
3416+ renderArgs->_debugFlags = renderDebugFlags;
3417+ _entities.render(renderArgs);
33613418 }
33623419
33633420 // render the ambient occlusion effect if enabled
@@ -3368,13 +3425,21 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, bool billb · 4 unmodified lines
33683425 DependencyManager::get<AmbientOcclusionEffect>()->render();
33693426 }
33703427 }
3371−
3372− bool mirrorMode = (theCamera.getMode() == CAMERA_MODE_MIRROR);
3373−
3374− {
3375− PerformanceTimer perfTimer("avatars");
3376− DependencyManager::get<AvatarManager>()->renderAvatars(mirrorMode ? RenderArgs::MIRROR_RENDER_MODE : RenderArgs::NORMAL_RENDER_MODE,
3377− false, selfAvatarOnly);
3428+
3429+ // Make sure the WorldBox is in the scene
3430+ if (WorldBoxRenderData::_item == 0) {
3431+ auto worldBoxRenderData = WorldBoxRenderData::Pointer(new WorldBoxRenderData());
3432+ auto worldBoxRenderPayload = render::PayloadPointer(new WorldBoxRenderData::Payload(worldBoxRenderData));
3433+
3434+ WorldBoxRenderData::_item = _main3DScene->allocateID();
3435+
3436+ pendingChanges.resetItem(WorldBoxRenderData::_item, worldBoxRenderPayload);
3437+ } else {
3438+
3439+ pendingChanges.updateItem<WorldBoxRenderData>(WorldBoxRenderData::_item,
3440+ [](WorldBoxRenderData& payload) {
3441+ payload._val++;
3442+ });
33783443 }
33793444
33803445 if (!billboard) {
@@ -3382,19 +3447,55 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, bool billb · 1 unmodified line
33823447 auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
33833448 DependencyManager::get<DeferredLightingEffect>()->setGlobalLight(skyStage->getSunLight()->getDirection(), skyStage->getSunLight()->getColor(), skyStage->getSunLight()->getIntensity(), skyStage->getSunLight()->getAmbientIntensity());
33843449 DependencyManager::get<DeferredLightingEffect>()->setGlobalAtmosphere(skyStage->getAtmosphere());
3450+
3451+ auto skybox = model::SkyboxPointer();
3452+ if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) {
3453+ skybox = skyStage->getSkybox();
3454+ }
33853455 DependencyManager::get<DeferredLightingEffect>()->setGlobalSkybox(skybox);
3456+ }
33863457
3387− PROFILE_RANGE("DeferredLighting");
3388− PerformanceTimer perfTimer("lighting");
3389− DependencyManager::get<DeferredLightingEffect>()->render();
3458+ {
3459+ PerformanceTimer perfTimer("SceneProcessPendingChanges");
3460+ _main3DScene->enqueuePendingChanges(pendingChanges);
3461+
3462+ _main3DScene->processPendingChangesQueue();
33903463 }
33913464
3465+ // For now every frame pass the renderContext
33923466 {
3393− PerformanceTimer perfTimer("avatarsPostLighting");
3394− DependencyManager::get<AvatarManager>()->renderAvatars(mirrorMode ? RenderArgs::MIRROR_RENDER_MODE : RenderArgs::NORMAL_RENDER_MODE,
3395− true, selfAvatarOnly);
3467+ PerformanceTimer perfTimer("EngineRun");
3468+ render::RenderContext renderContext;
3469+
3470+ auto sceneInterface = DependencyManager::get<SceneScriptingInterface>();
3471+
3472+ renderContext._cullOpaque = sceneInterface->doEngineCullOpaque();
3473+ renderContext._sortOpaque = sceneInterface->doEngineSortOpaque();
3474+ renderContext._renderOpaque = sceneInterface->doEngineRenderOpaque();
3475+ renderContext._cullTransparent = sceneInterface->doEngineCullTransparent();
3476+ renderContext._sortTransparent = sceneInterface->doEngineSortTransparent();
3477+ renderContext._renderTransparent = sceneInterface->doEngineRenderTransparent();
3478+
3479+ renderContext._maxDrawnOpaqueItems = sceneInterface->getEngineMaxDrawnOpaqueItems();
3480+ renderContext._maxDrawnTransparentItems = sceneInterface->getEngineMaxDrawnTransparentItems();
3481+
3482+ renderArgs->_shouldRender = LODManager::shouldRender;
3483+
3484+ renderContext.args = renderArgs;
3485+ renderArgs->_viewFrustum = getDisplayViewFrustum();
3486+ _renderEngine->setRenderContext(renderContext);
3487+
3488+ // Before the deferred pass, let's try to use the render engine
3489+ _renderEngine->run();
3490+
3491+ auto engineRC = _renderEngine->getRenderContext();
3492+ sceneInterface->setEngineFeedOpaqueItems(engineRC->_numFeedOpaqueItems);
3493+ sceneInterface->setEngineDrawnOpaqueItems(engineRC->_numDrawnOpaqueItems);
3494+
3495+ sceneInterface->setEngineFeedTransparentItems(engineRC->_numFeedTransparentItems);
3496+ sceneInterface->setEngineDrawnTransparentItems(engineRC->_numDrawnTransparentItems);
3497+
33963498 }
3397−
33983499 //Render the sixense lasers
33993500 if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers)) {
34003501 _myAvatar->renderLaserPointers();
@@ -3402,12 +3503,6 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, bool billb · 1 unmodified line
34023503
34033504 if (!selfAvatarOnly) {
34043505 _nodeBoundsDisplay.draw();
3405−
3406− // Render the world box
3407− if (theCamera.getMode() != CAMERA_MODE_MIRROR && Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {
3408− PerformanceTimer perfTimer("worldBox");
3409− renderWorldBox();
3410− }
34113506
34123507 // render octree fades if they exist
34133508 if (_octreeFades.size() > 0) {
@@ -3416,7 +3511,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, bool billb · 2 unmodified lines
34163511 "Application::displaySide() ... octree fades...");
34173512 _octreeFadesLock.lockForWrite();
34183513 for(std::vector<OctreeFade>::iterator fade = _octreeFades.begin(); fade != _octreeFades.end();) {
3419− fade->render();
3514+ fade->render(renderArgs);
34203515 if(fade->isDone()) {
34213516 fade = _octreeFades.erase(fade);
34223517 } else {
@@ -3437,14 +3532,6 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, bool billb · 14 unmodified lines
34373532 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
34383533 }
34393534
3440− // Render 3D overlays that should be drawn in front
3441− {
3442− PerformanceTimer perfTimer("3dOverlaysFront");
3443− glClear(GL_DEPTH_BUFFER_BIT);
3444− Glower glower; // Sets alpha to 1.0
3445− _overlays.renderWorld(true);
3446− }
3447−
34483535 activeRenderingThread = nullptr;
34493536 }
34503537
@@ -3479,9 +3566,9 @@ void Application::computeOffAxisFrustum(float& left, float& right, float& bottom · 28 unmodified lines
34793566 _displayViewFrustum.computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
34803567 if (OculusManager::isConnected()) {
34813568 OculusManager::overrideOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
3482−
3569+
34833570 } else if (TV3DManager::isConnected()) {
3484− TV3DManager::overrideOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
3571+ TV3DManager::overrideOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
34853572 }
34863573 }
34873574
@@ -3491,8 +3578,8 @@ bool Application::getShadowsEnabled() { · 3 unmodified lines
34913578 menubar->isOptionChecked(MenuOption::CascadedShadows);
34923579 }
34933580
3494−bool Application::getCascadeShadowsEnabled() {
3495− return Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows);
3581+bool Application::getCascadeShadowsEnabled() {
3582+ return Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows);
34963583 }
34973584
34983585 glm::vec2 Application::getScaledScreenPoint(glm::vec2 projectedPoint) {
@@ -3521,7 +3608,7 @@ glm::vec2 Application::getScaledScreenPoint(glm::vec2 projectedPoint) { · 22 unmodified lines
35213608 return screenPoint;
35223609 }
35233610
3524−void Application::renderRearViewMirror(const QRect& region, bool billboard) {
3611+void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool billboard) {
35253612 // Grab current viewport to reset it at the end
35263613 int viewport[4];
35273614 glGetIntegerv(GL_VIEWPORT, viewport);
@@ -3539,22 +3626,22 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { · 11 unmodified lines
35393626 _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar->getScale());
35403627
35413628 } else { // HEAD zoom level
3542− // FIXME note that the positioing of the camera relative to the avatar can suffer limited
3543− // precision as the user's position moves further away from the origin. Thus at
3544− // /1e7,1e7,1e7 (well outside the buildable volume) the mirror camera veers and sways
3545− // wildly as you rotate your avatar because the floating point values are becoming
3546− // larger, squeezing out the available digits of precision you have available at the
3547− // human scale for camera positioning.
3548−
3549− // Previously there was a hack to correct this using the mechanism of repositioning
3550− // the avatar at the origin of the world for the purposes of rendering the mirror,
3551− // but it resulted in failing to render the avatar's head model in the mirror view
3552− // when in first person mode. Presumably this was because of some missed culling logic
3553− // that was not accounted for in the hack.
3554−
3555− // This was removed in commit 71e59cfa88c6563749594e25494102fe01db38e9 but could be further
3629+ // FIXME note that the positioing of the camera relative to the avatar can suffer limited
3630+ // precision as the user's position moves further away from the origin. Thus at
3631+ // /1e7,1e7,1e7 (well outside the buildable volume) the mirror camera veers and sways
3632+ // wildly as you rotate your avatar because the floating point values are becoming
3633+ // larger, squeezing out the available digits of precision you have available at the
3634+ // human scale for camera positioning.
3635+
3636+ // Previously there was a hack to correct this using the mechanism of repositioning
3637+ // the avatar at the origin of the world for the purposes of rendering the mirror,
3638+ // but it resulted in failing to render the avatar's head model in the mirror view
3639+ // when in first person mode. Presumably this was because of some missed culling logic
3640+ // that was not accounted for in the hack.
3641+
3642+ // This was removed in commit 71e59cfa88c6563749594e25494102fe01db38e9 but could be further
35563643 // investigated in order to adapt the technique while fixing the head rendering issue,
3557− // but the complexity of the hack suggests that a better approach
3644+ // but the complexity of the hack suggests that a better approach
35583645 _mirrorCamera.setPosition(_myAvatar->getHead()->getEyePosition() +
35593646 _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale());
35603647 }
@@ -3565,7 +3652,7 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { · 4 unmodified lines
35653652 if (billboard) {
35663653 QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize();
35673654 glViewport(region.x(), size.height() - region.y() - region.height(), region.width(), region.height());
3568− glScissor(region.x(), size.height() - region.y() - region.height(), region.width(), region.height());
3655+ glScissor(region.x(), size.height() - region.y() - region.height(), region.width(), region.height());
35693656 } else {
35703657 // if not rendering the billboard, the region is in device independent coordinates; must convert to device
35713658 QSize size = DependencyManager::get<TextureCache>()->getFrameBufferSize();
@@ -3581,11 +3668,11 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { · 9 unmodified lines
35813668
35823669 // render rear mirror view
35833670 glPushMatrix();
3584− displaySide(_mirrorCamera, true, billboard);
3671+ displaySide(renderArgs, _mirrorCamera, true, billboard);
35853672 glPopMatrix();
35863673
35873674 if (!billboard) {
3588− _rearMirrorTools->render(false, _glWidget->mapFromGlobal(QCursor::pos()));
3675+ _rearMirrorTools->render(renderArgs, false, _glWidget->mapFromGlobal(QCursor::pos()));
35893676 }
35903677
35913678 // reset Viewport and projection matrix
@@ -3606,7 +3693,7 @@ void Application::resetSensors() { · 14 unmodified lines
36063693 QWindow* mainWindow = _window->windowHandle();
36073694 QPoint windowCenter = mainWindow->geometry().center();
36083695 _glWidget->cursor().setPos(currentScreen, windowCenter);
3609−
3696+
36103697 _myAvatar->reset();
36113698
36123699 QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "reset", Qt::QueuedConnection);
@@ -3639,11 +3726,11 @@ void Application::updateWindowTitle(){ · 26 unmodified lines
36393726 QString connectionStatus = nodeList->getDomainHandler().isConnected() ? "" : " (NOT CONNECTED) ";
36403727 QString username = AccountManager::getInstance().getAccountInfo().getUsername();
36413728 QString currentPlaceName = DependencyManager::get<AddressManager>()->getHost();
3642−
3729+
36433730 if (currentPlaceName.isEmpty()) {
36443731 currentPlaceName = nodeList->getDomainHandler().getHostname();
36453732 }
3646−
3733+
36473734 QString title = QString() + (!username.isEmpty() ? username + " @ " : QString())
36483735 + currentPlaceName + connectionStatus + buildVersion;
36493736
@@ -3657,7 +3744,6 @@ void Application::updateWindowTitle(){ · 7 unmodified lines
36573744 void Application::clearDomainOctreeDetails() {
36583745 qCDebug(interfaceapp) << "Clearing domain octree details...";
36593746 // reset the environment so that we don't erroneously end up with multiple
3660− _environment.resetToDefault();
36613747
36623748 // reset our node to stats and node to jurisdiction maps... since these must be changing...
36633749 _entityServerJurisdictions.lockForWrite();
@@ -3689,7 +3775,7 @@ void Application::domainConnectionDenied(const QString& reason) { · 25 unmodified lines
36893775 void Application::connectedToDomain(const QString& hostname) {
36903776 AccountManager& accountManager = AccountManager::getInstance();
36913777 const QUuid& domainID = DependencyManager::get<NodeList>()->getDomainHandler().getUUID();
3692−
3778+
36933779 if (accountManager.isLoggedIn() && !domainID.isNull()) {
36943780 _notifiedPacketVersionMismatchThisDomain = false;
36953781 }
@@ -3873,7 +3959,7 @@ void Application::saveScripts() { · 177 unmodified lines
38733959 Settings settings;
38743960 settings.beginWriteArray(SETTINGS_KEY);
38753961 settings.remove("");
3876−
3962+
38773963 QStringList runningScripts = getRunningScripts();
38783964 int i = 0;
38793965 for (auto it = runningScripts.begin(); it != runningScripts.end(); ++it) {
@@ -3924,7 +4010,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri · 44 unmodified lines
39244010
39254011 scriptEngine->registerGlobalObject("Overlays", &_overlays);
39264012 qScriptRegisterMetaType(scriptEngine, OverlayPropertyResultToScriptValue, OverlayPropertyResultFromScriptValue);
3927− qScriptRegisterMetaType(scriptEngine, RayToOverlayIntersectionResultToScriptValue,
4013+ qScriptRegisterMetaType(scriptEngine, RayToOverlayIntersectionResultToScriptValue,
39284014 RayToOverlayIntersectionResultFromScriptValue);
39294015
39304016 QScriptValue windowValue = scriptEngine->registerGlobalObject("Window", DependencyManager::get<WindowScriptingInterface>().data());
@@ -3935,7 +4021,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri · 4 unmodified lines
39354021 LocationScriptingInterface::locationSetter);
39364022
39374023 scriptEngine->registerFunction("WebWindow", WebWindowClass::constructor, 1);
3938−
4024+
39394025 scriptEngine->registerGlobalObject("Menu", MenuScriptingInterface::getInstance());
39404026 scriptEngine->registerGlobalObject("Settings", SettingsScriptingInterface::getInstance());
39414027 scriptEngine->registerGlobalObject("AudioDevice", AudioDeviceScriptingInterface::getInstance());
@@ -3947,7 +4033,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri · 5 unmodified lines
39474033 qScriptRegisterMetaType(scriptEngine, DownloadInfoResultToScriptValue, DownloadInfoResultFromScriptValue);
39484034
39494035 scriptEngine->registerGlobalObject("AvatarManager", DependencyManager::get<AvatarManager>().data());
3950−
4036+
39514037 scriptEngine->registerGlobalObject("Joysticks", &JoystickScriptingInterface::getInstance());
39524038 qScriptRegisterMetaType(scriptEngine, joystickToScriptValue, joystickFromScriptValue);
39534039
@@ -3955,6 +4041,8 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri · 1 unmodified line
39554041
39564042 scriptEngine->registerGlobalObject("LODManager", DependencyManager::get<LODManager>().data());
39574043
4044+ scriptEngine->registerGlobalObject("Paths", DependencyManager::get<PathUtils>().data());
4045+
39584046 QScriptValue hmdInterface = scriptEngine->registerGlobalObject("HMD", &HMDScriptingInterface::getInstance());
39594047 scriptEngine->registerFunction(hmdInterface, "getHUDLookAtPosition2D", HMDScriptingInterface::getHUDLookAtPosition2D, 0);
39604048 scriptEngine->registerFunction(hmdInterface, "getHUDLookAtPosition3D", HMDScriptingInterface::getHUDLookAtPosition3D, 0);
@@ -4002,7 +4090,7 @@ void Application::initializeAcceptedFiles() { · 41 unmodified lines
40024090
40034091 bool Application::canAcceptURL(const QString& urlString) {
40044092 initializeAcceptedFiles();
4005−
4093+
40064094 QUrl url(urlString);
40074095 if (urlString.startsWith(HIFI_URL_SCHEME)) {
40084096 return true;
@@ -4020,7 +4108,7 @@ bool Application::canAcceptURL(const QString& urlString) { · 11 unmodified lines
40204108
40214109 bool Application::acceptURL(const QString& urlString) {
40224110 initializeAcceptedFiles();
4023−
4111+
40244112 if (urlString.startsWith(HIFI_URL_SCHEME)) {
40254113 // this is a hifi URL - have the AddressManager handle it
40264114 QMetaObject::invokeMethod(DependencyManager::get<AddressManager>().data(), "handleLookupString",
@@ -4058,19 +4146,19 @@ bool Application::askToSetAvatarUrl(const QString& url) { · 31 unmodified lines
40584146 msgBox.exec();
40594147 return false;
40604148 }
4061−
4149+
40624150 // Download the FST file, to attempt to determine its model type
40634151 QVariantHash fstMapping = FSTReader::downloadMapping(url);
4064−
4152+
40654153 FSTReader::ModelType modelType = FSTReader::predictModelType(fstMapping);
4066−
4154+
40674155 QMessageBox msgBox;
40684156 msgBox.setIcon(QMessageBox::Question);
40694157 msgBox.setWindowTitle("Set Avatar");
40704158 QPushButton* headButton = NULL;
40714159 QPushButton* bodyButton = NULL;
40724160 QPushButton* bodyAndHeadButton = NULL;
4073−
4161+
40744162 QString modelName = fstMapping["name"].toString();
40754163 QString message;
40764164 QString typeInfo;
@@ -4089,7 +4177,7 @@ bool Application::askToSetAvatarUrl(const QString& url) { · 12 unmodified lines
40894177 message = QString("Would you like to use '") + modelName + QString("' for your avatar?");
40904178 bodyAndHeadButton = msgBox.addButton(tr("Yes"), QMessageBox::ActionRole);
40914179 break;
4092−
4180+
40934181 default:
40944182 message = QString("Would you like to use '") + modelName + QString("' for some part of your avatar head?");
40954183 headButton = msgBox.addButton(tr("Use for Head"), QMessageBox::ActionRole);
@@ -4115,7 +4203,7 @@ bool Application::askToSetAvatarUrl(const QString& url) { · 19 unmodified lines
41154203 } else {
41164204 qCDebug(interfaceapp) << "Declined to use the avatar: " << url;
41174205 }
4118−
4206+
41194207 return true;
41204208 }
41214209
@@ -4140,7 +4228,7 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser · 18 unmodified lines
41404228 if (isAboutToQuit()) {
41414229 return NULL;
41424230 }
4143−
4231+
41444232 QUrl scriptUrl(scriptFilename);
41454233 const QString& scriptURLString = scriptUrl.toString();
41464234 if (_scriptEnginesHash.contains(scriptURLString) && loadScriptFromEditor
@@ -4151,18 +4239,18 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser · 4 unmodified lines
41514239
41524240 ScriptEngine* scriptEngine = new ScriptEngine(NO_SCRIPT, "", &_controllerScriptingInterface);
41534241 scriptEngine->setUserLoaded(isUserLoaded);
4154−
4242+
41554243 if (scriptFilename.isNull()) {
41564244 // this had better be the script editor (we should de-couple so somebody who thinks they are loading a script
41574245 // doesn't just get an empty script engine)
4158−
4246+
41594247 // we can complete setup now since there isn't a script we have to load
41604248 registerScriptEngineWithApplicationServices(scriptEngine);
41614249 } else {
41624250 // connect to the appropriate signals of this script engine
41634251 connect(scriptEngine, &ScriptEngine::scriptLoaded, this, &Application::handleScriptEngineLoaded);
41644252 connect(scriptEngine, &ScriptEngine::errorLoadingScript, this, &Application::handleScriptLoadError);
4165−
4253+
41664254 // get the script engine object to load the script at the designated script URL
41674255 scriptEngine->loadURL(scriptUrl);
41684256 }
@@ -4177,11 +4265,11 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser · 8 unmodified lines
41774265
41784266 void Application::handleScriptEngineLoaded(const QString& scriptFilename) {
41794267 ScriptEngine* scriptEngine = qobject_cast<ScriptEngine*>(sender());
4180−
4268+
41814269 _scriptEnginesHash.insertMulti(scriptFilename, scriptEngine);
41824270 _runningScriptsWidget->setRunningScripts(getRunningScripts());
41834271 UserActivityLogger::getInstance().loadedScript(scriptFilename);
4184−
4272+
41854273 // register our application services and set it off on its own thread
41864274 registerScriptEngineWithApplicationServices(scriptEngine);
41874275 }
@@ -4291,7 +4379,7 @@ void Application::updateMyAvatarTransform() { · 103 unmodified lines
42914379 glm::vec3 newOriginOffset = avatarPosition;
42924380 int halfExtent = (int)HALF_SIMULATION_EXTENT;
42934381 for (int i = 0; i < 3; ++i) {
4294− newOriginOffset[i] = (float)(glm::max(halfExtent,
4382+ newOriginOffset[i] = (float)(glm::max(halfExtent,
42954383 ((int)(avatarPosition[i] / SIMULATION_OFFSET_QUANTIZATION)) * (int)SIMULATION_OFFSET_QUANTIZATION));
42964384 }
42974385 // TODO: Andrew to replace this with method that actually moves existing object positions in PhysicsEngine
@@ -4305,23 +4393,23 @@ void Application::domainSettingsReceived(const QJsonObject& domainSettingsObject · 7 unmodified lines
43054393 const QString PER_VOXEL_COST_KEY = "per-voxel-credits";
43064394 const QString PER_METER_CUBED_COST_KEY = "per-meter-cubed-credits";
43074395 const QString VOXEL_WALLET_UUID = "voxel-wallet";
4308−
4396+
43094397 const QJsonObject& voxelObject = domainSettingsObject[VOXEL_SETTINGS_KEY].toObject();
4310−
4398+
43114399 qint64 satoshisPerVoxel = 0;
43124400 qint64 satoshisPerMeterCubed = 0;
43134401 QUuid voxelWalletUUID;
4314−
4402+
43154403 if (!domainSettingsObject.isEmpty()) {
43164404 float perVoxelCredits = (float) voxelObject[PER_VOXEL_COST_KEY].toDouble();
43174405 float perMeterCubedCredits = (float) voxelObject[PER_METER_CUBED_COST_KEY].toDouble();
4318−
4406+
43194407 satoshisPerVoxel = (qint64) floorf(perVoxelCredits * SATOSHIS_PER_CREDIT);
43204408 satoshisPerMeterCubed = (qint64) floorf(perMeterCubedCredits * SATOSHIS_PER_CREDIT);
4321−
4409+
43224410 voxelWalletUUID = QUuid(voxelObject[VOXEL_WALLET_UUID].toString());
43234411 }
4324−
4412+
43254413 qCDebug(interfaceapp) << "Octree edits costs are" << satoshisPerVoxel << "per octree cell and" << satoshisPerMeterCubed << "per meter cubed";
43264414 qCDebug(interfaceapp) << "Destination wallet UUID for edit payments is" << voxelWalletUUID;
43274415 }
@@ -4524,7 +4612,7 @@ bool Application::isVSyncOn() const { · 196 unmodified lines
45244612 } else {
45254613 return true;
45264614 }
4527− */
4615+ */
45284616 #endif
45294617 return true;
45304618 }
@@ -4622,14 +4710,14 @@ void Application::notifyPacketVersionMismatch() { · 91 unmodified lines
46224710 void Application::checkSkeleton() {
46234711 if (_myAvatar->getSkeletonModel().isActive() && !_myAvatar->getSkeletonModel().hasSkeleton()) {
46244712 qCDebug(interfaceapp) << "MyAvatar model has no skeleton";
4625−
4713+
46264714 QString message = "Your selected avatar body has no skeleton.\n\nThe default body will be loaded...";
46274715 QMessageBox msgBox;
46284716 msgBox.setText(message);
46294717 msgBox.setStandardButtons(QMessageBox::Ok);
46304718 msgBox.setIcon(QMessageBox::Warning);
46314719 msgBox.exec();
4632−
4720+
46334721 _myAvatar->useBodyURL(DEFAULT_BODY_MODEL_URL, "Default");
46344722 } else {
46354723 _physicsEngine.setCharacterController(_myAvatar->getCharacterController());
@@ -4642,7 +4730,7 @@ void Application::showFriendsWindow() { · 6 unmodified lines
46424730 const int FRIENDS_WINDOW_WIDTH = 290;
46434731 const int FRIENDS_WINDOW_HEIGHT = 500;
46444732 if (!_friendsWindow) {
4645− _friendsWindow = new WebWindowClass(FRIENDS_WINDOW_TITLE, FRIENDS_WINDOW_URL, FRIENDS_WINDOW_WIDTH,
4733+ _friendsWindow = new WebWindowClass(FRIENDS_WINDOW_TITLE, FRIENDS_WINDOW_URL, FRIENDS_WINDOW_WIDTH,
46464734 FRIENDS_WINDOW_HEIGHT, false);
46474735 connect(_friendsWindow, &WebWindowClass::closed, this, &Application::friendsWindowClosed);
46484736 }
@@ -4683,16 +4771,16 @@ QSize Application::getDeviceSize() const { · 34 unmodified lines
46834771 return _glWidget->getDeviceSize();
46844772 }
46854773
4686−int Application::getTrueMouseX() const {
4687− return _glWidget->mapFromGlobal(QCursor::pos()).x();
4774+int Application::getTrueMouseX() const {
4775+ return _glWidget->mapFromGlobal(QCursor::pos()).x();
46884776 }
46894777
4690−int Application::getTrueMouseY() const {
4691− return _glWidget->mapFromGlobal(QCursor::pos()).y();
4778+int Application::getTrueMouseY() const {
4779+ return _glWidget->mapFromGlobal(QCursor::pos()).y();
46924780 }
46934781
4694−bool Application::isThrottleRendering() const {
4695− return _glWidget->isThrottleRendering();
4782+bool Application::isThrottleRendering() const {
4783+ return _glWidget->isThrottleRendering();
46964784 }
46974785
46984786 PickRay Application::computePickRay() const {