History

Merge branch 'master' into audioStatsDialog

bwent committed 11 years ago

Commit 70e3e7c2 parents 2c24251 029af53455 files · +15918 −12936Browse files

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

Unified · Split

interface/src/Application.cpp+276−261
@@ -66,6 +66,9 @@ · 65 unmodified lines
6666 #include <EntityScriptingInterface.h>
6767 #include <ErrorDialog.h>
6868 #include <GlowEffect.h>
69+#include <gpu/Batch.h>
70+#include <gpu/Context.h>
71+#include <gpu/GLBackend.h>
6972 #include <HFActionEvent.h>
7073 #include <HFBackEvent.h>
7174 #include <InfoView.h>
@@ -83,12 +86,15 @@ · 11 unmodified lines
8386 #include <PerfStat.h>
8487 #include <PhysicsEngine.h>
8588 #include <ProgramObject.h>
89+#include <RenderDeferredTask.h>
8690 #include <ResourceCache.h>
8791 #include <SceneScriptingInterface.h>
8892 #include <ScriptCache.h>
8993 #include <SettingHandle.h>
94+#include <SimpleAverage.h>
9095 #include <SoundCache.h>
9196 #include <TextRenderer.h>
97+#include <Tooltip.h>
9298 #include <UserActivityLogger.h>
9399 #include <UUID.h>
94100 #include <VrMenu.h>
@@ -106,10 +112,8 @@ · 11 unmodified lines
106112
107113 #include "avatar/AvatarManager.h"
108114
109−#include "audio/AudioToolBox.h"
110115 #include "audio/AudioScope.h"
111116
112−#include "devices/CameraToolBox.h"
113117 #include "devices/DdeFaceTracker.h"
114118 #include "devices/Faceshift.h"
115119 #include "devices/Leapmotion.h"
@@ -119,12 +123,6 @@ · 3 unmodified lines
119123 #include "devices/OculusManager.h"
120124 #include "devices/TV3DManager.h"
121125
122−#include "gpu/Batch.h"
123−#include "gpu/Context.h"
124−#include "gpu/GLBackend.h"
125−
126−#include "RenderDeferredTask.h"
127−
128126 #include "scripting/AccountScriptingInterface.h"
129127 #include "scripting/AudioDeviceScriptingInterface.h"
130128 #include "scripting/ClipboardScriptingInterface.h"
@@ -140,6 +138,7 @@ · 9 unmodified lines
140138 #include "SpeechRecognizer.h"
141139 #endif
142140
141+#include "ui/AvatarInputs.h"
143142 #include "ui/DataWebDialog.h"
144143 #include "ui/DialogsManager.h"
145144 #include "ui/LoginDialog.h"
@@ -179,6 +178,7 @@ using namespace std; · 33 unmodified lines
179178 // Starfield information
180179 static unsigned STARFIELD_NUM_STARS = 50000;
181180 static unsigned STARFIELD_SEED = 1;
181+static uint8_t THROTTLED_IDLE_TIMER_DELAY = 10;
182182
183183 const qint64 MAXIMUM_CACHE_SIZE = 10 * BYTES_PER_GIGABYTES; // 10GB
184184
@@ -279,8 +279,6 @@ bool setupEssentials(int& argc, char** argv) { · 94 unmodified lines
279279 auto animationCache = DependencyManager::set<AnimationCache>();
280280 auto ddeFaceTracker = DependencyManager::set<DdeFaceTracker>();
281281 auto modelBlender = DependencyManager::set<ModelBlender>();
282− auto audioToolBox = DependencyManager::set<AudioToolBox>();
283− auto cameraToolBox = DependencyManager::set<CameraToolBox>();
284282 auto avatarManager = DependencyManager::set<AvatarManager>();
285283 auto lodManager = DependencyManager::set<LODManager>();
286284 auto jsConsole = DependencyManager::set<StandAloneJSConsole>();
@@ -333,13 +331,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 46 unmodified lines
333331 _cursorVisible(true),
334332 _lastMouseMove(usecTimestampNow()),
335333 _lastMouseMoveWasSimulated(false),
336− _touchAvgX(0.0f),
337− _touchAvgY(0.0f),
338334 _isTouchPressed(false),
339335 _mousePressed(false),
340336 _enableProcessOctreeThread(true),
341337 _octreeProcessor(),
342− _nodeBoundsDisplay(this),
343338 _runningScriptsWidget(NULL),
344339 _runningScriptsWidgetWasVisible(false),
345340 _trayIcon(new QSystemTrayIcon(_window)),
@@ -396,6 +391,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 50 unmodified lines
396391 static_cast<NodeList*>(dependency)->deleteLater();
397392 });
398393
394+ // setup a timer for domain-server check ins
395+ QTimer* domainCheckInTimer = new QTimer(nodeList.data());
396+ connect(domainCheckInTimer, &QTimer::timeout, nodeList.data(), &NodeList::sendDomainServerCheckIn);
397+ domainCheckInTimer->start(DOMAIN_SERVER_CHECK_IN_MSECS);
398+
399399 // put the NodeList and datagram processing on the node thread
400400 nodeList->moveToThread(nodeThread);
401401
@@ -608,6 +608,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 206 unmodified lines
608608 _settingsTimer.setSingleShot(false);
609609 _settingsTimer.setInterval(SAVE_SETTINGS_INTERVAL);
610610 _settingsThread.start();
611+
612+ if (Menu::getInstance()->isOptionChecked(MenuOption::IndependentMode)) {
613+ Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, true);
614+ cameraMenuChanged();
615+ }
611616
612617 _trayIcon->show();
613618
@@ -694,6 +699,14 @@ void Application::cleanupBeforeQuit() { · 80 unmodified lines
694699 #endif
695700 }
696701
702+void Application::emptyLocalCache() {
703+ QNetworkDiskCache* cache = qobject_cast<QNetworkDiskCache*>(NetworkAccessManager::getInstance().cache());
704+ if (cache) {
705+ qDebug() << "DiskCacheEditor::clear(): Clearing disk cache.";
706+ cache->clear();
707+ }
708+}
709+
697710 Application::~Application() {
698711 EntityTree* tree = _entities.getTree();
699712 tree->lockForWrite();
@@ -829,6 +842,7 @@ void Application::initializeUi() { · 129 unmodified lines
829842 LoginDialog::registerType();
830843 MessageDialog::registerType();
831844 VrMenu::registerType();
845+ Tooltip::registerType();
832846 UpdateDialog::registerType();
833847
834848 auto offscreenUi = DependencyManager::get<OffscreenUi>();
@@ -842,7 +856,7 @@ void Application::initializeUi() { · 7 unmodified lines
842856 VrMenu::executeQueuedLambdas();
843857 offscreenUi->setMouseTranslator([this](const QPointF& p){
844858 if (OculusManager::isConnected()) {
845− glm::vec2 pos = _applicationOverlay.screenToOverlay(toGlm(p));
859+ glm::vec2 pos = _compositor.screenToOverlay(toGlm(p));
846860 return QPointF(pos.x, pos.y);
847861 }
848862 return QPointF(p);
@@ -875,6 +889,7 @@ void Application::paintGL() { · 26 unmodified lines
875889 OculusManager::beginFrameTiming();
876890 }
877891
892+
878893 PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings));
879894 bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
880895 PerformanceWarning warn(showWarnings, "Application::paintGL()");
@@ -887,8 +902,11 @@ void Application::paintGL() { · 6 unmodified lines
887902
888903 glEnable(GL_LINE_SMOOTH);
889904
890− Menu::getInstance()->setIsOptionChecked("First Person", _myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN);
891− Application::getInstance()->cameraMenuChanged();
905+ if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
906+ Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, _myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN);
907+ Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(_myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN));
908+ Application::getInstance()->cameraMenuChanged();
909+ }
892910
893911 if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {
894912 // Always use the default eye position, not the actual head eye position.
@@ -954,6 +972,8 @@ void Application::paintGL() { · 59 unmodified lines
954972 } else if (TV3DManager::isConnected()) {
955973 TV3DManager::display(&renderArgs, _myCamera);
956974 } else {
975+ PROFILE_RANGE(__FUNCTION__ "/mainRender");
976+
957977 DependencyManager::get<GlowEffect>()->prepare(&renderArgs);
958978
959979 // Viewport is assigned to the size of the framebuffer
@@ -967,27 +987,28 @@ void Application::paintGL() { · 7 unmodified lines
967987 glPopMatrix();
968988
969989 renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE;
970− if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
971− _rearMirrorTools->render(&renderArgs, true, _glWidget->mapFromGlobal(QCursor::pos()));
972− } else if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
973− renderRearViewMirror(&renderArgs, _mirrorViewRect);
990+ if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
991+ renderRearViewMirror(&renderArgs, _mirrorViewRect);
974992 }
975993
976994 renderArgs._renderMode = RenderArgs::NORMAL_RENDER_MODE;
977995
978996 auto finalFbo = DependencyManager::get<GlowEffect>()->render(&renderArgs);
979997
998+
980999 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
9811000 glBindFramebuffer(GL_READ_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(finalFbo));
9821001 glBlitFramebuffer(0, 0, _renderResolution.x, _renderResolution.y,
9831002 0, 0, _glWidget->getDeviceSize().width(), _glWidget->getDeviceSize().height(),
984− GL_COLOR_BUFFER_BIT, GL_NEAREST);
1003+ GL_COLOR_BUFFER_BIT, GL_LINEAR);
9851004 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
9861005
987− _applicationOverlay.displayOverlayTexture();
1006+ _compositor.displayOverlayTexture(&renderArgs);
9881007 }
9891008
1009+
9901010 if (!OculusManager::isConnected() || OculusManager::allowSwap()) {
1011+ PROFILE_RANGE(__FUNCTION__ "/bufferSwap");
9911012 _glWidget->swapBuffers();
9921013 }
9931014
@@ -1000,6 +1021,7 @@ void Application::paintGL() { · 6 unmodified lines
10001021
10011022 void Application::runTests() {
10021023 runTimingTests();
1024+ runUnitTests();
10031025 }
10041026
10051027 void Application::audioMuteToggled() {
@@ -1025,7 +1047,7 @@ void Application::showEditEntitiesHelp() { · 19 unmodified lines
10251047 InfoView::show(INFO_EDIT_ENTITIES_PATH);
10261048 }
10271049
1028−void Application::resetCamerasOnResizeGL(Camera& camera, const glm::uvec2& size) {
1050+void Application::resetCameras(Camera& camera, const glm::uvec2& size) {
10291051 if (OculusManager::isConnected()) {
10301052 OculusManager::configureCamera(camera);
10311053 } else if (TV3DManager::isConnected()) {
@@ -1036,6 +1058,7 @@ void Application::resetCamerasOnResizeGL(Camera& camera, const glm::uvec2& size) · 4 unmodified lines
10361058 }
10371059
10381060 void Application::resizeGL() {
1061+ PROFILE_RANGE(__FUNCTION__);
10391062 // Set the desired FBO texture size. If it hasn't changed, this does nothing.
10401063 // Otherwise, it must rebuild the FBOs
10411064 QSize renderSize;
@@ -1044,27 +1067,25 @@ void Application::resizeGL() { · 2 unmodified lines
10441067 } else {
10451068 renderSize = _glWidget->getDeviceSize() * getRenderResolutionScale();
10461069 }
1047− if (_renderResolution == toGlm(renderSize)) {
1048− return;
1049− }
10501070
1051− _renderResolution = toGlm(renderSize);
1052− DependencyManager::get<TextureCache>()->setFrameBufferSize(renderSize);
1053− resetCamerasOnResizeGL(_myCamera, _renderResolution);
1071+ if (_renderResolution != toGlm(renderSize)) {
1072+ _renderResolution = toGlm(renderSize);
1073+ DependencyManager::get<TextureCache>()->setFrameBufferSize(renderSize);
10541074
1055− glViewport(0, 0, _renderResolution.x, _renderResolution.y); // shouldn't this account for the menu???
1075+ glViewport(0, 0, _renderResolution.x, _renderResolution.y); // shouldn't this account for the menu???
1076+
1077+ updateProjectionMatrix();
1078+ glLoadIdentity();
1079+ }
10561080
1057− updateProjectionMatrix();
1058− glLoadIdentity();
1081+ resetCameras(_myCamera, _renderResolution);
10591082
10601083 auto offscreenUi = DependencyManager::get<OffscreenUi>();
1061− offscreenUi->resize(_glWidget->size());
1084+
1085+ auto canvasSize = _glWidget->size();
1086+ offscreenUi->resize(canvasSize);
10621087 _glWidget->makeCurrent();
10631088
1064− // update Stats width
1065− // let's set horizontal offset to give stats some margin to mirror
1066− int horizontalOffset = MIRROR_VIEW_WIDTH + MIRROR_VIEW_LEFT_PADDING * 2;
1067− Stats::getInstance()->resetWidth(_renderResolution.x, horizontalOffset);
10681089 }
10691090
10701091 void Application::updateProjectionMatrix() {
@@ -1170,7 +1191,6 @@ bool Application::event(QEvent* event) { · 99 unmodified lines
11701191 }
11711192
11721193 bool Application::eventFilter(QObject* object, QEvent* event) {
1173−
11741194 if (event->type() == QEvent::ShortcutOverride) {
11751195 if (DependencyManager::get<OffscreenUi>()->shouldSwallowShortcut(event)) {
11761196 event->accept();
@@ -1383,11 +1403,17 @@ void Application::keyPressEvent(QKeyEvent* event) { · 206 unmodified lines
13831403 if (isShifted) {
13841404 Menu::getInstance()->triggerOption(MenuOption::Mirror);
13851405 } else {
1386− Menu::getInstance()->triggerOption(MenuOption::FullscreenMirror);
1406+ Menu::getInstance()->setIsOptionChecked(MenuOption::FullscreenMirror, !Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror));
1407+ if (!Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
1408+ Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, true);
1409+ }
1410+ cameraMenuChanged();
13871411 }
13881412 break;
13891413 case Qt::Key_P:
1390− Menu::getInstance()->triggerOption(MenuOption::FirstPerson);
1414+ Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, !Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson));
1415+ Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson));
1416+ cameraMenuChanged();
13911417 break;
13921418 case Qt::Key_Slash:
13931419 Menu::getInstance()->triggerOption(MenuOption::Stats);
@@ -1508,6 +1534,7 @@ void Application::focusOutEvent(QFocusEvent* event) { · 114 unmodified lines
15081534 }
15091535
15101536 void Application::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) {
1537+ PROFILE_RANGE(__FUNCTION__);
15111538 // Used by application overlay to determine how to draw cursor(s)
15121539 _lastMouseMoveWasSimulated = deviceID > 0;
15131540 if (!_lastMouseMoveWasSimulated) {
@@ -1562,27 +1589,9 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) { · 48 unmodified lines
15621589 _keyboardMouseDevice.mousePressEvent(event);
15631590
15641591 if (event->button() == Qt::LeftButton) {
1565− _mouseDragStartedX = getTrueMouseX();
1566− _mouseDragStartedY = getTrueMouseY();
1592+ _mouseDragStarted = getTrueMouse();
15671593 _mousePressed = true;
15681594
1569− if (mouseOnScreen()) {
1570− if (DependencyManager::get<AudioToolBox>()->mousePressEvent(getMouseX(), getMouseY())) {
1571− // stop propagation
1572− return;
1573− }
1574−
1575− if (DependencyManager::get<CameraToolBox>()->mousePressEvent(getMouseX(), getMouseY())) {
1576− // stop propagation
1577− return;
1578− }
1579−
1580− if (_rearMirrorTools->mousePressEvent(getMouseX(), getMouseY())) {
1581− // stop propagation
1582− return;
1583− }
1584− }
1585−
15861595 // nobody handled this - make it an action event on the _window object
15871596 HFActionEvent actionEvent(HFActionEvent::startType(),
15881597 computePickRay(event->x(), event->y()));
@@ -1601,17 +1610,6 @@ void Application::mouseDoublePressEvent(QMouseEvent* event, unsigned int deviceI · 12 unmodified lines
16011610 }
16021611
16031612 _controllerScriptingInterface.emitMouseDoublePressEvent(event);
1604−
1605− if (activeWindow() == _window) {
1606− if (event->button() == Qt::LeftButton) {
1607− if (mouseOnScreen()) {
1608− if (DependencyManager::get<CameraToolBox>()->mouseDoublePressEvent(getMouseX(), getMouseY())) {
1609− // stop propagation
1610− return;
1611− }
1612− }
1613− }
1614− }
16151613 }
16161614
16171615 void Application::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) {
@@ -1633,13 +1631,6 @@ void Application::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) { · 15 unmodified lines
16331631 if (event->button() == Qt::LeftButton) {
16341632 _mousePressed = false;
16351633
1636− if (Menu::getInstance()->isOptionChecked(MenuOption::Stats) && mouseOnScreen()) {
1637− // let's set horizontal offset to give stats some margin to mirror
1638− int horizontalOffset = MIRROR_VIEW_WIDTH;
1639− Stats::getInstance()->checkClick(getMouseX(), getMouseY(),
1640− getMouseDragStartedX(), getMouseDragStartedY(), horizontalOffset);
1641− }
1642−
16431634 // fire an action end event
16441635 HFActionEvent actionEvent(HFActionEvent::endType(),
16451636 computePickRay(event->x(), event->y()));
@@ -1667,22 +1658,18 @@ void Application::touchUpdateEvent(QTouchEvent* event) { · 21 unmodified lines
16671658 bool validTouch = false;
16681659 if (activeWindow() == _window) {
16691660 const QList<QTouchEvent::TouchPoint>& tPoints = event->touchPoints();
1670− _touchAvgX = 0.0f;
1671− _touchAvgY = 0.0f;
1661+ _touchAvg = vec2();
16721662 int numTouches = tPoints.count();
16731663 if (numTouches > 1) {
16741664 for (int i = 0; i < numTouches; ++i) {
1675− _touchAvgX += (float)tPoints[i].pos().x();
1676− _touchAvgY += (float)tPoints[i].pos().y();
1665+ _touchAvg += toGlm(tPoints[i].pos());
16771666 }
1678− _touchAvgX /= (float)(numTouches);
1679− _touchAvgY /= (float)(numTouches);
1667+ _touchAvg /= (float)(numTouches);
16801668 validTouch = true;
16811669 }
16821670 }
16831671 if (!_isTouchPressed) {
1684− _touchDragStartedAvgX = _touchAvgX;
1685− _touchDragStartedAvgY = _touchAvgY;
1672+ _touchDragStartedAvg = _touchAvg;
16861673 }
16871674 _isTouchPressed = validTouch;
16881675 }
@@ -1718,8 +1705,7 @@ void Application::touchEndEvent(QTouchEvent* event) { · 29 unmodified lines
17181705 _keyboardMouseDevice.touchEndEvent(event);
17191706
17201707 // put any application specific touch behavior below here..
1721− _touchDragStartedAvgX = _touchAvgX;
1722− _touchDragStartedAvgY = _touchAvgY;
1708+ _touchDragStartedAvg = _touchAvg;
17231709 _isTouchPressed = false;
17241710
17251711 }
@@ -1804,14 +1790,28 @@ void Application::checkFPS() { · 78 unmodified lines
18041790 _frameCount = 0;
18051791 _datagramProcessor->resetCounters();
18061792 _timerStart.start();
1807−
1808− // ask the node list to check in with the domain server
1809− DependencyManager::get<NodeList>()->sendDomainServerCheckIn();
18101793 }
18111794
18121795 void Application::idle() {
1813− PerformanceTimer perfTimer("idle");
1796+ PROFILE_RANGE(__FUNCTION__);
1797+ static SimpleAverage<float> interIdleDurations;
1798+ static uint64_t lastIdleEnd{ 0 };
1799+
1800+ if (lastIdleEnd != 0) {
1801+ uint64_t now = usecTimestampNow();
1802+ interIdleDurations.update(now - lastIdleEnd);
1803+ static uint64_t lastReportTime = now;
1804+ if ((now - lastReportTime) >= (USECS_PER_SECOND)) {
1805+ static QString LOGLINE("Average inter-idle time: %1 us for %2 samples");
1806+ if (Menu::getInstance()->isOptionChecked(MenuOption::LogExtraTimings)) {
1807+ qCDebug(interfaceapp_timing) << LOGLINE.arg((int)interIdleDurations.getAverage()).arg(interIdleDurations.getCount());
1808+ }
1809+ interIdleDurations.reset();
1810+ lastReportTime = now;
1811+ }
1812+ }
18141813
1814+ PerformanceTimer perfTimer("idle");
18151815 if (_aboutToQuit) {
18161816 return; // bail early, nothing to do here.
18171817 }
@@ -1835,6 +1835,7 @@ void Application::idle() { · 17 unmodified lines
18351835 PerformanceTimer perfTimer("update");
18361836 PerformanceWarning warn(showWarnings, "Application::idle()... update()");
18371837 const float BIGGEST_DELTA_TIME_SECS = 0.25f;
1838+ PROFILE_RANGE(__FUNCTION__ "/idleUpdate");
18381839 update(glm::clamp((float)timeSinceLastUpdate / 1000.0f, 0.0f, BIGGEST_DELTA_TIME_SECS));
18391840 }
18401841 {
@@ -1854,13 +1855,15 @@ void Application::idle() { · 13 unmodified lines
18541855 _idleLoopStdev.reset();
18551856 }
18561857
1857− // After finishing all of the above work, restart the idle timer, allowing 2ms to process events.
1858− idleTimer->start(2);
18591858 }
1859+ // After finishing all of the above work, ensure the idle timer is set to the proper interval,
1860+ // depending on whether we're throttling or not
1861+ idleTimer->start(_glWidget->isThrottleRendering() ? THROTTLED_IDLE_TIMER_DELAY : 1);
18601862 }
18611863
18621864 // check for any requested background downloads.
18631865 emit checkBackgroundDownloads();
1866+ lastIdleEnd = usecTimestampNow();
18641867 }
18651868
18661869 void Application::setFullscreen(bool fullscreen) {
@@ -1868,9 +1871,9 @@ void Application::setFullscreen(bool fullscreen) { · 1 unmodified line
18681871 Menu::getInstance()->getActionForOption(MenuOption::Fullscreen)->setChecked(fullscreen);
18691872 }
18701873
1871−// The following code block is useful on platforms that can have a visible
1872−// app menu in a fullscreen window. However the OSX mechanism hides the
1873−// application menu for fullscreen apps, so the check is not required.
1874+ // The following code block is useful on platforms that can have a visible
1875+ // app menu in a fullscreen window. However the OSX mechanism hides the
1876+ // application menu for fullscreen apps, so the check is not required.
18741877 #ifndef Q_OS_MAC
18751878 if (Menu::getInstance()->isOptionChecked(MenuOption::EnableVRMode)) {
18761879 if (fullscreen) {
@@ -1944,11 +1947,6 @@ void Application::setEnableVRMode(bool enableVRMode) { · 67 unmodified lines
19441947 } else {
19451948 OculusManager::abandonCalibration();
19461949 OculusManager::disconnect();
1947−
1948− _mirrorCamera.setHmdPosition(glm::vec3());
1949− _mirrorCamera.setHmdRotation(glm::quat());
1950− _myCamera.setHmdPosition(glm::vec3());
1951− _myCamera.setHmdRotation(glm::quat());
19521950 }
19531951
19541952 resizeGL();
@@ -1960,44 +1958,34 @@ void Application::setLowVelocityFilter(bool lowVelocityFilter) { · 5 unmodified lines
19601958
19611959 bool Application::mouseOnScreen() const {
19621960 if (OculusManager::isConnected()) {
1963− return getMouseX() >= 0 && getMouseX() <= _glWidget->getDeviceWidth() &&
1964− getMouseY() >= 0 && getMouseY() <= _glWidget->getDeviceHeight();
1961+ ivec2 mouse = getMouse();
1962+ if (!glm::all(glm::greaterThanEqual(mouse, ivec2()))) {
1963+ return false;
1964+ }
1965+ ivec2 size = toGlm(_glWidget->getDeviceSize());
1966+ if (!glm::all(glm::lessThanEqual(mouse, size))) {
1967+ return false;
1968+ }
19651969 }
19661970 return true;
19671971 }
19681972
1969−int Application::getMouseX() const {
1970− if (OculusManager::isConnected()) {
1971− glm::vec2 pos = _applicationOverlay.screenToOverlay(glm::vec2(getTrueMouseX(), getTrueMouseY()));
1972− return pos.x;
1973− }
1974− return getTrueMouseX();
1975−}
1976−
1977−int Application::getMouseY() const {
1973+ivec2 Application::getMouse() const {
19781974 if (OculusManager::isConnected()) {
1979− glm::vec2 pos = _applicationOverlay.screenToOverlay(glm::vec2(getTrueMouseX(), getTrueMouseY()));
1980− return pos.y;
1975+ return _compositor.screenToOverlay(getTrueMouse());
19811976 }
1982− return getTrueMouseY();
1977+ return getTrueMouse();
19831978 }
19841979
1985−int Application::getMouseDragStartedX() const {
1980+ivec2 Application::getMouseDragStarted() const {
19861981 if (OculusManager::isConnected()) {
1987− glm::vec2 pos = _applicationOverlay.screenToOverlay(glm::vec2(getTrueMouseDragStartedX(),
1988− getTrueMouseDragStartedY()));
1989− return pos.x;
1982+ return _compositor.screenToOverlay(getTrueMouseDragStarted());
19901983 }
1991− return getTrueMouseDragStartedX();
1984+ return getTrueMouseDragStarted();
19921985 }
19931986
1994−int Application::getMouseDragStartedY() const {
1995− if (OculusManager::isConnected()) {
1996− glm::vec2 pos = _applicationOverlay.screenToOverlay(glm::vec2(getTrueMouseDragStartedX(),
1997− getTrueMouseDragStartedY()));
1998− return pos.y;
1999− }
2000− return getTrueMouseDragStartedY();
1987+ivec2 Application::getTrueMouseDragStarted() const {
1988+ return _mouseDragStarted;
20011989 }
20021990
20031991 FaceTracker* Application::getActiveFaceTracker() {
@@ -2242,19 +2230,13 @@ void Application::init() { · 238 unmodified lines
22422230 _entityClipboardRenderer.setViewFrustum(getViewFrustum());
22432231 _entityClipboardRenderer.setTree(&_entityClipboard);
22442232
2245− _rearMirrorTools = new RearMirrorTools(_mirrorViewRect);
2246−
2247− connect(_rearMirrorTools, SIGNAL(closeView()), SLOT(closeMirrorView()));
2248− connect(_rearMirrorTools, SIGNAL(restoreView()), SLOT(restoreMirrorView()));
2249− connect(_rearMirrorTools, SIGNAL(shrinkView()), SLOT(shrinkMirrorView()));
2250− connect(_rearMirrorTools, SIGNAL(resetView()), SLOT(resetSensors()));
2251−
22522233 // initialize the GlowEffect with our widget
22532234 bool glow = Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect);
22542235 DependencyManager::get<GlowEffect>()->init(glow);
22552236
22562237 // Make sure any new sounds are loaded as soon as know about them.
22572238 connect(tree, &EntityTree::newCollisionSoundURL, DependencyManager::get<SoundCache>().data(), &SoundCache::getSound);
2239+ connect(_myAvatar, &MyAvatar::newCollisionSoundURL, DependencyManager::get<SoundCache>().data(), &SoundCache::getSound);
22582240 }
22592241
22602242 void Application::closeMirrorView() {
@@ -2330,38 +2312,42 @@ void Application::updateMyAvatarLookAtPosition() { · 69 unmodified lines
23302312 bool isLookingAtSomeone = false;
23312313 glm::vec3 lookAtSpot;
23322314 if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
2333− // When I am in mirror mode, just look right at the camera (myself)
2315+ // When I am in mirror mode, just look right at the camera (myself); don't switch gaze points because when physically
2316+ // looking in a mirror one's eyes appear steady.
23342317 if (!OculusManager::isConnected()) {
23352318 lookAtSpot = _myCamera.getPosition();
23362319 } else {
2337− if (_myAvatar->isLookingAtLeftEye()) {
2338− lookAtSpot = OculusManager::getLeftEyePosition();
2339− } else {
2340− lookAtSpot = OculusManager::getRightEyePosition();
2341− }
2320+ lookAtSpot = _myCamera.getPosition() + OculusManager::getMidEyePosition();
23422321 }
2343−
23442322 } else {
23452323 AvatarSharedPointer lookingAt = _myAvatar->getLookAtTargetAvatar().lock();
23462324 if (lookingAt && _myAvatar != lookingAt.get()) {
2347− isLookingAtSomeone = true;
23482325 // If I am looking at someone else, look directly at one of their eyes
2349− if (tracker && !tracker->isMuted()) {
2350− // If a face tracker is active, look at the eye for the side my gaze is biased toward
2351− if (tracker->getEstimatedEyeYaw() > _myAvatar->getHead()->getFinalYaw()) {
2352− // Look at their right eye
2353− lookAtSpot = static_cast<Avatar*>(lookingAt.get())->getHead()->getRightEyePosition();
2354− } else {
2355− // Look at their left eye
2356− lookAtSpot = static_cast<Avatar*>(lookingAt.get())->getHead()->getLeftEyePosition();
2326+ isLookingAtSomeone = true;
2327+ Head* lookingAtHead = static_cast<Avatar*>(lookingAt.get())->getHead();
2328+
2329+ const float MAXIMUM_FACE_ANGLE = 65.0f * RADIANS_PER_DEGREE;
2330+ glm::vec3 lookingAtFaceOrientation = lookingAtHead->getFinalOrientationInWorldFrame() * IDENTITY_FRONT;
2331+ glm::vec3 fromLookingAtToMe = glm::normalize(_myAvatar->getHead()->getEyePosition()
2332+ - lookingAtHead->getEyePosition());
2333+ float faceAngle = glm::angle(lookingAtFaceOrientation, fromLookingAtToMe);
2334+
2335+ if (faceAngle < MAXIMUM_FACE_ANGLE) {
2336+ // Randomly look back and forth between look targets
2337+ switch (_myAvatar->getEyeContactTarget()) {
2338+ case LEFT_EYE:
2339+ lookAtSpot = lookingAtHead->getLeftEyePosition();
2340+ break;
2341+ case RIGHT_EYE:
2342+ lookAtSpot = lookingAtHead->getRightEyePosition();
2343+ break;
2344+ case MOUTH:
2345+ lookAtSpot = lookingAtHead->getMouthPosition();
2346+ break;
23572347 }
23582348 } else {
2359− // Need to add randomly looking back and forth between left and right eye for case with no tracker
2360− if (_myAvatar->isLookingAtLeftEye()) {
2361− lookAtSpot = static_cast<Avatar*>(lookingAt.get())->getHead()->getLeftEyePosition();
2362− } else {
2363− lookAtSpot = static_cast<Avatar*>(lookingAt.get())->getHead()->getRightEyePosition();
2364− }
2349+ // Just look at their head (mid point between eyes)
2350+ lookAtSpot = lookingAtHead->getEyePosition();
23652351 }
23662352 } else {
23672353 // I am not looking at anyone else, so just look forward
@@ -2369,14 +2355,13 @@ void Application::updateMyAvatarLookAtPosition() { · 1 unmodified line
23692355 (_myAvatar->getHead()->getFinalOrientationInWorldFrame() * glm::vec3(0.0f, 0.0f, -TREE_SCALE));
23702356 }
23712357 }
2372− //
2373− // Deflect the eyes a bit to match the detected Gaze from 3D camera if active
2374− //
2375− if (tracker && !tracker->isMuted()) {
2358+
2359+ // Deflect the eyes a bit to match the detected gaze from Faceshift if active.
2360+ // DDE doesn't track eyes.
2361+ if (tracker && typeid(*tracker) == typeid(Faceshift) && !tracker->isMuted()) {
23762362 float eyePitch = tracker->getEstimatedEyePitch();
23772363 float eyeYaw = tracker->getEstimatedEyeYaw();
23782364 const float GAZE_DEFLECTION_REDUCTION_DURING_EYE_CONTACT = 0.1f;
2379− // deflect using Faceshift gaze data
23802365 glm::vec3 origin = _myAvatar->getHead()->getEyePosition();
23812366 float pitchSign = (_myCamera.getMode() == CAMERA_MODE_MIRROR) ? -1.0f : 1.0f;
23822367 float deflection = DependencyManager::get<Faceshift>()->getEyeDeflection();
@@ -2413,16 +2398,29 @@ void Application::cameraMenuChanged() { · 30 unmodified lines
24132398 _myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
24142399 _myAvatar->setBoomLength(MyAvatar::ZOOM_MIN);
24152400 }
2416− } else {
2401+ } else if (Menu::getInstance()->isOptionChecked(MenuOption::ThirdPerson)) {
24172402 if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) {
24182403 _myCamera.setMode(CAMERA_MODE_THIRD_PERSON);
24192404 if (_myAvatar->getBoomLength() == MyAvatar::ZOOM_MIN) {
24202405 _myAvatar->setBoomLength(MyAvatar::ZOOM_DEFAULT);
24212406 }
24222407 }
2408+ } else if (Menu::getInstance()->isOptionChecked(MenuOption::IndependentMode)) {
2409+ if (_myCamera.getMode() != CAMERA_MODE_INDEPENDENT) {
2410+ _myCamera.setMode(CAMERA_MODE_INDEPENDENT);
2411+ }
24232412 }
24242413 }
24252414
2415+void Application::reloadResourceCaches() {
2416+ emptyLocalCache();
2417+
2418+ DependencyManager::get<AnimationCache>()->refreshAll();
2419+ DependencyManager::get<GeometryCache>()->refreshAll();
2420+ DependencyManager::get<SoundCache>()->refreshAll();
2421+ DependencyManager::get<TextureCache>()->refreshAll();
2422+}
2423+
24262424 void Application::rotationModeChanged() {
24272425 if (!Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) {
24282426 _myAvatar->setHeadPitch(0);
@@ -2519,18 +2517,22 @@ void Application::update(float deltaTime) { · 90 unmodified lines
25192517
25202518 // Transfer the user inputs to the driveKeys
25212519 _myAvatar->clearDriveKeys();
2522− _myAvatar->setDriveKeys(FWD, _userInputMapper.getActionState(UserInputMapper::LONGITUDINAL_FORWARD));
2523− _myAvatar->setDriveKeys(BACK, _userInputMapper.getActionState(UserInputMapper::LONGITUDINAL_BACKWARD));
2524− _myAvatar->setDriveKeys(UP, _userInputMapper.getActionState(UserInputMapper::VERTICAL_UP));
2525− _myAvatar->setDriveKeys(DOWN, _userInputMapper.getActionState(UserInputMapper::VERTICAL_DOWN));
2526− _myAvatar->setDriveKeys(LEFT, _userInputMapper.getActionState(UserInputMapper::LATERAL_LEFT));
2527− _myAvatar->setDriveKeys(RIGHT, _userInputMapper.getActionState(UserInputMapper::LATERAL_RIGHT));
2528− _myAvatar->setDriveKeys(ROT_UP, _userInputMapper.getActionState(UserInputMapper::PITCH_UP));
2529− _myAvatar->setDriveKeys(ROT_DOWN, _userInputMapper.getActionState(UserInputMapper::PITCH_DOWN));
2530− _myAvatar->setDriveKeys(ROT_LEFT, _userInputMapper.getActionState(UserInputMapper::YAW_LEFT));
2531− _myAvatar->setDriveKeys(ROT_RIGHT, _userInputMapper.getActionState(UserInputMapper::YAW_RIGHT));
2532− _myAvatar->setDriveKeys(BOOM_IN, _userInputMapper.getActionState(UserInputMapper::BOOM_IN));
2533− _myAvatar->setDriveKeys(BOOM_OUT, _userInputMapper.getActionState(UserInputMapper::BOOM_OUT));
2520+ if (_myCamera.getMode() != CAMERA_MODE_INDEPENDENT) {
2521+ if (!_controllerScriptingInterface.areActionsCaptured()) {
2522+ _myAvatar->setDriveKeys(FWD, _userInputMapper.getActionState(UserInputMapper::LONGITUDINAL_FORWARD));
2523+ _myAvatar->setDriveKeys(BACK, _userInputMapper.getActionState(UserInputMapper::LONGITUDINAL_BACKWARD));
2524+ _myAvatar->setDriveKeys(UP, _userInputMapper.getActionState(UserInputMapper::VERTICAL_UP));
2525+ _myAvatar->setDriveKeys(DOWN, _userInputMapper.getActionState(UserInputMapper::VERTICAL_DOWN));
2526+ _myAvatar->setDriveKeys(LEFT, _userInputMapper.getActionState(UserInputMapper::LATERAL_LEFT));
2527+ _myAvatar->setDriveKeys(RIGHT, _userInputMapper.getActionState(UserInputMapper::LATERAL_RIGHT));
2528+ _myAvatar->setDriveKeys(ROT_UP, _userInputMapper.getActionState(UserInputMapper::PITCH_UP));
2529+ _myAvatar->setDriveKeys(ROT_DOWN, _userInputMapper.getActionState(UserInputMapper::PITCH_DOWN));
2530+ _myAvatar->setDriveKeys(ROT_LEFT, _userInputMapper.getActionState(UserInputMapper::YAW_LEFT));
2531+ _myAvatar->setDriveKeys(ROT_RIGHT, _userInputMapper.getActionState(UserInputMapper::YAW_RIGHT));
2532+ }
2533+ _myAvatar->setDriveKeys(BOOM_IN, _userInputMapper.getActionState(UserInputMapper::BOOM_IN));
2534+ _myAvatar->setDriveKeys(BOOM_OUT, _userInputMapper.getActionState(UserInputMapper::BOOM_OUT));
2535+ }
25342536
25352537 updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process...
25362538
@@ -2547,24 +2549,45 @@ void Application::update(float deltaTime) { · 10 unmodified lines
25472549
25482550 _entitySimulation.lock();
25492551 _physicsEngine.deleteObjects(_entitySimulation.getObjectsToDelete());
2552+ _entitySimulation.unlock();
2553+
2554+ _entities.getTree()->lockForWrite();
2555+ _entitySimulation.lock();
25502556 _physicsEngine.addObjects(_entitySimulation.getObjectsToAdd());
2557+ _entitySimulation.unlock();
2558+ _entities.getTree()->unlock();
2559+
2560+ _entities.getTree()->lockForWrite();
2561+ _entitySimulation.lock();
25512562 _physicsEngine.changeObjects(_entitySimulation.getObjectsToChange());
2563+ _entitySimulation.unlock();
2564+ _entities.getTree()->unlock();
2565+
2566+ _entitySimulation.lock();
25522567 _entitySimulation.applyActionChanges();
25532568 _entitySimulation.unlock();
25542569
2570+
25552571 AvatarManager* avatarManager = DependencyManager::get<AvatarManager>().data();
25562572 _physicsEngine.deleteObjects(avatarManager->getObjectsToDelete());
25572573 _physicsEngine.addObjects(avatarManager->getObjectsToAdd());
25582574 _physicsEngine.changeObjects(avatarManager->getObjectsToChange());
25592575
2576+ _entities.getTree()->lockForWrite();
25602577 _physicsEngine.stepSimulation();
2578+ _entities.getTree()->unlock();
25612579
25622580 if (_physicsEngine.hasOutgoingChanges()) {
2581+ _entities.getTree()->lockForWrite();
25632582 _entitySimulation.lock();
25642583 _entitySimulation.handleOutgoingChanges(_physicsEngine.getOutgoingChanges(), _physicsEngine.getSessionID());
25652584 _entitySimulation.unlock();
2585+ _entities.getTree()->unlock();
25662586
2587+ _entities.getTree()->lockForWrite();
25672588 avatarManager->handleOutgoingChanges(_physicsEngine.getOutgoingChanges());
2589+ _entities.getTree()->unlock();
2590+
25682591 auto collisionEvents = _physicsEngine.getCollisionEvents();
25692592 avatarManager->handleCollisionEvents(collisionEvents);
25702593
@@ -2953,6 +2976,7 @@ QRect Application::getDesirableApplicationGeometry() { · 382 unmodified lines
29532976 // or the "myCamera".
29542977 //
29552978 void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) {
2979+ PROFILE_RANGE(__FUNCTION__);
29562980 // We will use these below, from either the camera or head vectors calculated above
29572981 viewFrustum.setProjection(camera.getProjection());
29582982
@@ -3154,7 +3178,7 @@ PickRay Application::computePickRay(float x, float y) const { · 195 unmodified lines
31543178 y /= size.y;
31553179 PickRay result;
31563180 if (isHMDMode()) {
3157− getApplicationOverlay().computeHmdPickRay(glm::vec2(x, y), result.origin, result.direction);
3181+ getApplicationCompositor().computeHmdPickRay(glm::vec2(x, y), result.origin, result.direction);
31583182 } else {
31593183 if (QThread::currentThread() == activeRenderingThread) {
31603184 getDisplayViewFrustum()->computePickRay(x, y, result.origin, result.direction);
@@ -3183,13 +3207,11 @@ QImage Application::renderAvatarBillboard(RenderArgs* renderArgs) { · 22 unmodified lines
31833207 renderRearViewMirror(renderArgs, QRect(0, _glWidget->getDeviceHeight() - BILLBOARD_SIZE,
31843208 BILLBOARD_SIZE, BILLBOARD_SIZE),
31853209 true);
3186−
31873210 QImage image(BILLBOARD_SIZE, BILLBOARD_SIZE, QImage::Format_ARGB32);
31883211 glReadPixels(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE, GL_BGRA, GL_UNSIGNED_BYTE, image.bits());
31893212 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
31903213
31913214 glBindFramebuffer(GL_FRAMEBUFFER, 0);
3192−
31933215 return image;
31943216 }
31953217
@@ -3311,7 +3333,7 @@ namespace render { · 115 unmodified lines
33113333 const float APPROXIMATE_DISTANCE_FROM_HORIZON = 0.1f;
33123334 const float DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON = 0.2f;
33133335
3314− glm::vec3 sunDirection = (args->_viewFrustum->getPosition()/*getAvatarPosition()*/ - closestData.getSunLocation())
3336+ glm::vec3 sunDirection = (args->_viewFrustum->getPosition()/*getAvatarPosition()*/ - closestData.getSunLocation())
33153337 / closestData.getAtmosphereOuterRadius();
33163338 float height = glm::distance(args->_viewFrustum->getPosition()/*theCamera.getPosition()*/, closestData.getAtmosphereCenter());
33173339 if (height < closestData.getAtmosphereInnerRadius()) {
@@ -3319,8 +3341,8 @@ namespace render { · 1 unmodified line
33193341 alpha = 0.0f;
33203342
33213343 if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) {
3322− float directionY = glm::clamp(sunDirection.y,
3323− -APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON)
3344+ float directionY = glm::clamp(sunDirection.y,
3345+ -APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON)
33243346 + APPROXIMATE_DISTANCE_FROM_HORIZON;
33253347 alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON);
33263348 }
@@ -3331,8 +3353,8 @@ namespace render { · 4 unmodified lines
33313353 (closestData.getAtmosphereOuterRadius() - closestData.getAtmosphereInnerRadius());
33323354
33333355 if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) {
3334− float directionY = glm::clamp(sunDirection.y,
3335− -APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON)
3356+ float directionY = glm::clamp(sunDirection.y,
3357+ -APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON)
33363358 + APPROXIMATE_DISTANCE_FROM_HORIZON;
33373359 alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON);
33383360 }
@@ -3374,6 +3396,11 @@ namespace render { · 35 unmodified lines
33743396
33753397
33763398 void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool selfAvatarOnly, bool billboard) {
3399+
3400+ // FIXME: This preRender call is temporary until we create a separate render::scene for the mirror rendering.
3401+ // Then we can move this logic into the Avatar::simulate call.
3402+ _myAvatar->preRender(renderArgs);
3403+
33773404 activeRenderingThread = QThread::currentThread();
33783405 PROFILE_RANGE(__FUNCTION__);
33793406 PerformanceTimer perfTimer("display");
@@ -3383,15 +3410,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 3 unmodified lines
33833410 // load the view frustum
33843411 loadViewFrustum(theCamera, _displayViewFrustum);
33853412
3386− // flip x if in mirror mode (also requires reversing winding order for backface culling)
3387− if (theCamera.getMode() == CAMERA_MODE_MIRROR) {
3388− glScalef(-1.0f, 1.0f, 1.0f);
3389− glFrontFace(GL_CW);
3390−
3391− } else {
3392− glFrontFace(GL_CCW);
3393− }
3394−
33953413 // transform view according to theCamera
33963414 // could be myCamera (if in normal mode)
33973415 // or could be viewFrustumOffsetCamera if in offset mode
@@ -3409,9 +3427,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 11 unmodified lines
34093427 Transform viewTransform;
34103428 viewTransform.setTranslation(theCamera.getPosition());
34113429 viewTransform.setRotation(rotation);
3412− if (theCamera.getMode() == CAMERA_MODE_MIRROR) {
3413− viewTransform.setScale(Transform::Vec3(-1.0f, 1.0f, 1.0f));
3414− }
34153430 if (renderArgs->_renderSide != RenderArgs::MONO) {
34163431 glm::mat4 invView = glm::inverse(_untranslatedViewMatrix);
34173432
@@ -3466,9 +3481,8 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 48 unmodified lines
34663481 // Assuming nothing get's rendered through that
34673482
34683483 if (!selfAvatarOnly) {
3469−
3470− // render models...
34713484 if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderEntities()) {
3485+ // render models...
34723486 PerformanceTimer perfTimer("entities");
34733487 PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
34743488 "Application::displaySide() ... entities...");
@@ -3476,11 +3490,11 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 1 unmodified line
34763490 RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE;
34773491
34783492 if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowHulls)) {
3479− renderDebugFlags = (RenderArgs::DebugFlags) (renderDebugFlags | (int) RenderArgs::RENDER_DEBUG_HULLS);
3493+ renderDebugFlags = (RenderArgs::DebugFlags) (renderDebugFlags | (int)RenderArgs::RENDER_DEBUG_HULLS);
34803494 }
34813495 if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowOwned)) {
34823496 renderDebugFlags =
3483− (RenderArgs::DebugFlags) (renderDebugFlags | (int) RenderArgs::RENDER_DEBUG_SIMULATION_OWNERSHIP);
3497+ (RenderArgs::DebugFlags) (renderDebugFlags | (int)RenderArgs::RENDER_DEBUG_SIMULATION_OWNERSHIP);
34843498 }
34853499 renderArgs->_debugFlags = renderDebugFlags;
34863500 _entities.render(renderArgs);
@@ -3505,8 +3519,8 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 18 unmodified lines
35053519 pendingChanges.resetItem(WorldBoxRenderData::_item, worldBoxRenderPayload);
35063520 } else {
35073521
3508− pendingChanges.updateItem<WorldBoxRenderData>(WorldBoxRenderData::_item,
3509− [](WorldBoxRenderData& payload) {
3522+ pendingChanges.updateItem<WorldBoxRenderData>(WorldBoxRenderData::_item,
3523+ [](WorldBoxRenderData& payload) {
35103524 payload._val++;
35113525 });
35123526 }
@@ -3525,7 +3539,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 12 unmodified lines
35253539 }
35263540
35273541 {
3528− PerformanceTimer perfTimer("SceneProcessPendingChanges");
3542+ PerformanceTimer perfTimer("SceneProcessPendingChanges");
35293543 _main3DScene->enqueuePendingChanges(pendingChanges);
35303544
35313545 _main3DScene->processPendingChangesQueue();
@@ -3549,6 +3563,8 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 17 unmodified lines
35493563 renderContext._maxDrawnTransparentItems = sceneInterface->getEngineMaxDrawnTransparentItems();
35503564 renderContext._maxDrawnOverlay3DItems = sceneInterface->getEngineMaxDrawnOverlay3DItems();
35513565
3566+ renderContext._drawItemStatus = sceneInterface->doEngineDisplayItemStatus();
3567+
35523568 renderArgs->_shouldRender = LODManager::shouldRender;
35533569
35543570 renderContext.args = renderArgs;
@@ -3570,29 +3586,10 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 15 unmodified lines
35703586 }
35713587 //Render the sixense lasers
35723588 if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers)) {
3573− _myAvatar->renderLaserPointers();
3589+ _myAvatar->renderLaserPointers(*renderArgs->_batch);
35743590 }
35753591
35763592 if (!selfAvatarOnly) {
3577− _nodeBoundsDisplay.draw();
3578−
3579− // render octree fades if they exist
3580− if (_octreeFades.size() > 0) {
3581− PerformanceTimer perfTimer("octreeFades");
3582− PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
3583− "Application::displaySide() ... octree fades...");
3584− _octreeFadesLock.lockForWrite();
3585− for(std::vector<OctreeFade>::iterator fade = _octreeFades.begin(); fade != _octreeFades.end();) {
3586− fade->render(renderArgs);
3587− if(fade->isDone()) {
3588− fade = _octreeFades.erase(fade);
3589− } else {
3590− ++fade;
3591− }
3592− }
3593− _octreeFadesLock.unlock();
3594− }
3595−
35963593 // give external parties a change to hook in
35973594 {
35983595 PerformanceTimer perfTimer("inWorldInterface");
@@ -3693,7 +3690,7 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi · 94 unmodified lines
36933690 _mirrorCamera.setPosition(_myAvatar->getPosition() +
36943691 _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * BILLBOARD_DISTANCE * _myAvatar->getScale());
36953692
3696− } else if (RearMirrorTools::rearViewZoomLevel.get() == BODY) {
3693+ } else if (!AvatarInputs::getInstance()->mirrorZoomed()) {
36973694 _mirrorCamera.setPosition(_myAvatar->getChestPosition() +
36983695 _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar->getScale());
36993696
@@ -3743,10 +3740,6 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi · 43 unmodified lines
37433740 displaySide(renderArgs, _mirrorCamera, true, billboard);
37443741 glPopMatrix();
37453742
3746− if (!billboard) {
3747− _rearMirrorTools->render(renderArgs, false, _glWidget->mapFromGlobal(QCursor::pos()));
3748− }
3749−
37503743 // reset Viewport and projection matrix
37513744 glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
37523745 glDisable(GL_SCISSOR_TEST);
@@ -3888,17 +3881,6 @@ void Application::nodeKilled(SharedNodePointer node) { · 135 unmodified lines
38883881 qCDebug(interfaceapp, "model server going away...... v[%f, %f, %f, %f]",
38893882 (double)rootDetails.x, (double)rootDetails.y, (double)rootDetails.z, (double)rootDetails.s);
38903883
3891− // Add the jurisditionDetails object to the list of "fade outs"
3892− if (!Menu::getInstance()->isOptionChecked(MenuOption::DontFadeOnOctreeServerChanges)) {
3893− OctreeFade fade(OctreeFade::FADE_OUT, NODE_KILLED_RED, NODE_KILLED_GREEN, NODE_KILLED_BLUE);
3894− fade.voxelDetails = rootDetails;
3895− const float slightly_smaller = 0.99f;
3896− fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller;
3897− _octreeFadesLock.lockForWrite();
3898− _octreeFades.push_back(fade);
3899− _octreeFadesLock.unlock();
3900− }
3901−
39023884 // If the model server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server
39033885 _entityServerJurisdictions.lockForWrite();
39043886 _entityServerJurisdictions.erase(_entityServerJurisdictions.find(nodeUUID));
@@ -3975,16 +3957,6 @@ int Application::parseOctreeStats(const QByteArray& packet, const SharedNodePoin · 70 unmodified lines
39753957 qPrintable(serverType),
39763958 (double)rootDetails.x, (double)rootDetails.y, (double)rootDetails.z, (double)rootDetails.s);
39773959
3978− // Add the jurisditionDetails object to the list of "fade outs"
3979− if (!Menu::getInstance()->isOptionChecked(MenuOption::DontFadeOnOctreeServerChanges)) {
3980− OctreeFade fade(OctreeFade::FADE_OUT, NODE_ADDED_RED, NODE_ADDED_GREEN, NODE_ADDED_BLUE);
3981− fade.voxelDetails = rootDetails;
3982− const float slightly_smaller = 0.99f;
3983− fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller;
3984− _octreeFadesLock.lockForWrite();
3985− _octreeFades.push_back(fade);
3986− _octreeFadesLock.unlock();
3987− }
39883960 } else {
39893961 jurisdiction->unlock();
39903962 }
@@ -4080,6 +4052,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri · 89 unmodified lines
40804052 connect(scriptEngine, SIGNAL(finished(const QString&)), this, SLOT(scriptFinished(const QString&)));
40814053
40824054 connect(scriptEngine, SIGNAL(loadScript(const QString&, bool)), this, SLOT(loadScript(const QString&, bool)));
4055+ connect(scriptEngine, SIGNAL(reloadScript(const QString&, bool)), this, SLOT(reloadScript(const QString&, bool)));
40834056
40844057 scriptEngine->registerGlobalObject("Overlays", &_overlays);
40854058 qScriptRegisterMetaType(scriptEngine, OverlayPropertyResultToScriptValue, OverlayPropertyResultFromScriptValue);
@@ -4295,7 +4268,7 @@ bool Application::askToLoadScript(const QString& scriptFilenameOrURL) { · 209 unmodified lines
42954268 }
42964269
42974270 ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUserLoaded,
4298− bool loadScriptFromEditor, bool activateMainWindow) {
4271+ bool loadScriptFromEditor, bool activateMainWindow, bool reload) {
42994272
43004273 if (isAboutToQuit()) {
43014274 return NULL;
@@ -4324,7 +4297,7 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser · 22 unmodified lines
43244297 connect(scriptEngine, &ScriptEngine::errorLoadingScript, this, &Application::handleScriptLoadError);
43254298
43264299 // get the script engine object to load the script at the designated script URL
4327− scriptEngine->loadURL(scriptUrl);
4300+ scriptEngine->loadURL(scriptUrl, reload);
43284301 }
43294302
43304303 // restore the main window's active state
@@ -4335,6 +4308,10 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser · 4 unmodified lines
43354308 return scriptEngine;
43364309 }
43374310
4311+void Application::reloadScript(const QString& scriptName, bool isUserLoaded) {
4312+ loadScript(scriptName, isUserLoaded, false, false, true);
4313+}
4314+
43384315 void Application::handleScriptEngineLoaded(const QString& scriptFilename) {
43394316 ScriptEngine* scriptEngine = qobject_cast<ScriptEngine*>(sender());
43404317
@@ -4362,14 +4339,25 @@ void Application::scriptFinished(const QString& scriptName) { · 21 unmodified lines
43624339 }
43634340
43644341 void Application::stopAllScripts(bool restart) {
4365− // stops all current running scripts
4342+ if (restart) {
4343+ // Delete all running scripts from cache so that they are re-downloaded when they are restarted
4344+ auto scriptCache = DependencyManager::get<ScriptCache>();
4345+ for (QHash<QString, ScriptEngine*>::const_iterator it = _scriptEnginesHash.constBegin();
4346+ it != _scriptEnginesHash.constEnd(); it++) {
4347+ if (!it.value()->isFinished()) {
4348+ scriptCache->deleteScript(it.key());
4349+ }
4350+ }
4351+ }
4352+
4353+ // Stop and possibly restart all currently running scripts
43664354 for (QHash<QString, ScriptEngine*>::const_iterator it = _scriptEnginesHash.constBegin();
43674355 it != _scriptEnginesHash.constEnd(); it++) {
43684356 if (it.value()->isFinished()) {
43694357 continue;
43704358 }
43714359 if (restart && it.value()->isUserLoaded()) {
4372− connect(it.value(), SIGNAL(finished(const QString&)), SLOT(loadScript(const QString&)));
4360+ connect(it.value(), SIGNAL(finished(const QString&)), SLOT(reloadScript(const QString&)));
43734361 }
43744362 it.value()->stop();
43754363 qCDebug(interfaceapp) << "stopping script..." << it.key();
@@ -4377,13 +4365,20 @@ void Application::stopAllScripts(bool restart) { · 1 unmodified line
43774365 // HACK: ATM scripts cannot set/get their animation priorities, so we clear priorities
43784366 // whenever a script stops in case it happened to have been setting joint rotations.
43794367 // TODO: expose animation priorities and provide a layered animation control system.
4368+ _myAvatar->clearJointAnimationPriorities();
43804369 _myAvatar->clearScriptableSettings();
43814370 }
43824371
4383−void Application::stopScript(const QString &scriptName) {
4372+void Application::stopScript(const QString &scriptName, bool restart) {
43844373 const QString& scriptURLString = QUrl(scriptName).toString();
43854374 if (_scriptEnginesHash.contains(scriptURLString)) {
4386− _scriptEnginesHash.value(scriptURLString)->stop();
4375+ ScriptEngine* scriptEngine = _scriptEnginesHash[scriptURLString];
4376+ if (restart) {
4377+ auto scriptCache = DependencyManager::get<ScriptCache>();
4378+ scriptCache->deleteScript(scriptName);
4379+ connect(scriptEngine, SIGNAL(finished(const QString&)), SLOT(reloadScript(const QString&)));
4380+ }
4381+ scriptEngine->stop();
43874382 qCDebug(interfaceapp) << "stopping script..." << scriptName;
43884383 // HACK: ATM scripts cannot set/get their animation priorities, so we clear priorities
43894384 // whenever a script stops in case it happened to have been setting joint rotations.
@@ -4399,6 +4394,10 @@ void Application::reloadAllScripts() { · 9 unmodified lines
43994394 stopAllScripts(true);
44004395 }
44014396
4397+void Application::reloadOneScript(const QString& scriptName) {
4398+ stopScript(scriptName, true);
4399+}
4400+
44024401 void Application::loadDefaultScripts() {
44034402 if (!_scriptEnginesHash.contains(DEFAULT_SCRIPTS_JS_URL)) {
44044403 loadScript(DEFAULT_SCRIPTS_JS_URL);
@@ -4753,11 +4752,9 @@ void Application::postLambdaEvent(std::function<void()> f) { · 348 unmodified lines
47534752 }
47544753
47554754 void Application::initPlugins() {
4756− OculusManager::init();
47574755 }
47584756
47594757 void Application::shutdownPlugins() {
4760− OculusManager::deinit();
47614758 }
47624759
47634760 glm::vec3 Application::getHeadPosition() const {
@@ -4777,12 +4774,8 @@ QSize Application::getDeviceSize() const { · 13 unmodified lines
47774774 return _glWidget->getDeviceSize();
47784775 }
47794776
4780−int Application::getTrueMouseX() const {
4781− return _glWidget->mapFromGlobal(QCursor::pos()).x();
4782−}
4783−
4784−int Application::getTrueMouseY() const {
4785− return _glWidget->mapFromGlobal(QCursor::pos()).y();
4777+ivec2 Application::getTrueMouse() const {
4778+ return toGlm(_glWidget->mapFromGlobal(QCursor::pos()));
47864779 }
47874780
47884781 bool Application::isThrottleRendering() const {
@@ -4812,3 +4805,25 @@ qreal Application::getDevicePixelRatio() { · 23 unmodified lines
48124805 return _window ? _window->windowHandle()->devicePixelRatio() : 1.0;
48134806 }
48144807
4808+mat4 Application::getEyeProjection(int eye) const {
4809+ if (isHMDMode()) {
4810+ return OculusManager::getEyeProjection(eye);
4811+ }
4812+
4813+ return _viewFrustum.getProjection();
4814+}
4815+
4816+mat4 Application::getEyePose(int eye) const {
4817+ if (isHMDMode()) {
4818+ return OculusManager::getEyePose(eye);
4819+ }
4820+
4821+ return mat4();
4822+}
4823+
4824+mat4 Application::getHeadPose() const {
4825+ if (isHMDMode()) {
4826+ return OculusManager::getHeadPose();
4827+ }
4828+ return mat4();
4829+}