History

Merge branch 'master' into feat/domain-setup

Liv Erickson committed 9 years ago

Commit da700712 parents be860d6 4acccb6184 files · +5287 −1611Browse files

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

Unified · Split

interface/src/Application.cpp+172−82
@@ -61,6 +61,7 @@ · 60 unmodified lines
6161 #include <AssetClient.h>
6262 #include <AssetUpload.h>
6363 #include <AutoUpdater.h>
64+#include <Midi.h>
6465 #include <AudioInjectorManager.h>
6566 #include <AvatarBookmarks.h>
6667 #include <CursorManager.h>
@@ -69,7 +70,7 @@ · 2 unmodified lines
6970 #include <EntityScriptClient.h>
7071 #include <EntityScriptServerLogClient.h>
7172 #include <EntityScriptingInterface.h>
72−#include <HoverOverlayInterface.h>
73+#include "ui/overlays/ContextOverlayInterface.h"
7374 #include <ErrorDialog.h>
7475 #include <FileScriptingInterface.h>
7576 #include <Finally.h>
@@ -230,6 +231,7 @@ static const QString FBX_EXTENSION = ".fbx"; · 154 unmodified lines
230231 static const QString OBJ_EXTENSION = ".obj";
231232 static const QString AVA_JSON_EXTENSION = ".ava.json";
232233 static const QString WEB_VIEW_TAG = "noDownload=true";
234+static const QString ZIP_EXTENSION = ".zip";
233235
234236 static const float MIRROR_FULLSCREEN_DISTANCE = 0.389f;
235237
@@ -264,7 +266,8 @@ const QHash<QString, Application::AcceptURLMethod> Application::_acceptedExtensi · 28 unmodified lines
264266 { JSON_EXTENSION, &Application::importJSONFromURL },
265267 { JS_EXTENSION, &Application::askToLoadScript },
266268 { FST_EXTENSION, &Application::askToSetAvatarUrl },
267− { JSON_GZ_EXTENSION, &Application::askToReplaceDomainContent }
269+ { JSON_GZ_EXTENSION, &Application::askToReplaceDomainContent },
270+ { ZIP_EXTENSION, &Application::importFromZIP }
268271 };
269272
270273 class DeadlockWatchdogThread : public QThread {
@@ -403,6 +406,10 @@ public: · 132 unmodified lines
403406 return true;
404407 }
405408 }
409+
410+ if (message->message == WM_DEVICECHANGE) {
411+ Midi::USBchanged(); // re-scan the MIDI bus
412+ }
406413 }
407414 return false;
408415 }
@@ -573,6 +580,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { · 164 unmodified lines
573580 DependencyManager::set<SceneScriptingInterface>();
574581 DependencyManager::set<OffscreenUi>();
575582 DependencyManager::set<AutoUpdater>();
583+ DependencyManager::set<Midi>();
576584 DependencyManager::set<PathUtils>();
577585 DependencyManager::set<InterfaceDynamicFactory>();
578586 DependencyManager::set<AudioInjectorManager>();
@@ -595,7 +603,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { · 16 unmodified lines
595603 DependencyManager::set<Snapshot>();
596604 DependencyManager::set<CloseEventSender>();
597605 DependencyManager::set<ResourceManager>();
598− DependencyManager::set<HoverOverlayInterface>();
606+ DependencyManager::set<ContextOverlayInterface>();
599607
600608 return previousSessionCrashed;
601609 }
@@ -624,6 +632,7 @@ const float DEFAULT_DESKTOP_TABLET_SCALE_PERCENT = 75.0f; · 22 unmodified lines
624632 const bool DEFAULT_DESKTOP_TABLET_BECOMES_TOOLBAR = true;
625633 const bool DEFAULT_HMD_TABLET_BECOMES_TOOLBAR = false;
626634 const bool DEFAULT_PREFER_AVATAR_FINGER_OVER_STYLUS = false;
635+const QString DEFAULT_CURSOR_NAME = "DEFAULT";
627636
628637 Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bool runningMarkerExisted) :
629638 QApplication(argc, argv),
@@ -643,6 +652,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 13 unmodified lines
643652 _hmdTabletBecomesToolbarSetting("hmdTabletBecomesToolbar", DEFAULT_HMD_TABLET_BECOMES_TOOLBAR),
644653 _preferAvatarFingerOverStylusSetting("preferAvatarFingerOverStylus", DEFAULT_PREFER_AVATAR_FINGER_OVER_STYLUS),
645654 _constrainToolbarPosition("toolbar/constrainToolbarToCenterX", true),
655+ _preferredCursor("preferredCursor", DEFAULT_CURSOR_NAME),
646656 _scaleMirror(1.0f),
647657 _rotateMirror(0.0f),
648658 _raiseMirror(0.0f),
@@ -938,14 +948,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 289 unmodified lines
938948 _glWidget->setFocusPolicy(Qt::StrongFocus);
939949 _glWidget->setFocus();
940950
941−#ifdef Q_OS_MAC
942− auto cursorTarget = _window; // OSX doesn't seem to provide for hiding the cursor only on the GL widget
943−#else
944− // On windows and linux, hiding the top level cursor also means it's invisible when hovering over the
945− // window menu, which is a pain, so only hide it for the GL surface
946− auto cursorTarget = _glWidget;
947−#endif
948− cursorTarget->setCursor(Qt::BlankCursor);
951+ showCursor(Cursor::Manager::lookupIcon(_preferredCursor.get()));
949952
950953 // enable mouse tracking; otherwise, we only get drag events
951954 _glWidget->setMouseTracking(true);
@@ -1329,12 +1332,16 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 377 unmodified lines
13291332 // Keyboard focus handling for Web overlays.
13301333 auto overlays = &(qApp->getOverlays());
13311334
1332− connect(overlays, &Overlays::mousePressOnOverlay, [=](OverlayID overlayID, const PointerEvent& event) {
1333− setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
1334− setKeyboardFocusOverlay(overlayID);
1335+ connect(overlays, &Overlays::mousePressOnOverlay, [=](const OverlayID& overlayID, const PointerEvent& event) {
1336+ auto thisOverlay = std::dynamic_pointer_cast<Web3DOverlay>(overlays->getOverlay(overlayID));
1337+ // Only Web overlays can have keyboard focus.
1338+ if (thisOverlay) {
1339+ setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
1340+ setKeyboardFocusOverlay(overlayID);
1341+ }
13351342 });
13361343
1337− connect(overlays, &Overlays::overlayDeleted, [=](OverlayID overlayID) {
1344+ connect(overlays, &Overlays::overlayDeleted, [=](const OverlayID& overlayID) {
13381345 if (overlayID == _keyboardFocusedOverlay.get()) {
13391346 setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID);
13401347 }
@@ -1349,6 +1356,21 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 8 unmodified lines
13491356 setKeyboardFocusEntity(UNKNOWN_ENTITY_ID);
13501357 });
13511358
1359+ connect(overlays,
1360+ SIGNAL(mousePressOnOverlay(const OverlayID&, const PointerEvent&)),
1361+ DependencyManager::get<ContextOverlayInterface>().data(),
1362+ SLOT(contextOverlays_mousePressOnOverlay(const OverlayID&, const PointerEvent&)));
1363+
1364+ connect(overlays,
1365+ SIGNAL(hoverEnterOverlay(const OverlayID&, const PointerEvent&)),
1366+ DependencyManager::get<ContextOverlayInterface>().data(),
1367+ SLOT(contextOverlays_hoverEnterOverlay(const OverlayID&, const PointerEvent&)));
1368+
1369+ connect(overlays,
1370+ SIGNAL(hoverLeaveOverlay(const OverlayID&, const PointerEvent&)),
1371+ DependencyManager::get<ContextOverlayInterface>().data(),
1372+ SLOT(contextOverlays_hoverLeaveOverlay(const OverlayID&, const PointerEvent&)));
1373+
13521374 // Add periodic checks to send user activity data
13531375 static int CHECK_NEARBY_AVATARS_INTERVAL_MS = 10000;
13541376 static int NEARBY_AVATAR_RADIUS_METERS = 10;
@@ -1475,7 +1497,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 120 unmodified lines
14751497 properties["atp_mapping_requests"] = atpMappingRequests;
14761498
14771499 properties["throttled"] = _displayPlugin ? _displayPlugin->isThrottled() : false;
1478−
1500+
14791501 QJsonObject bytesDownloaded;
14801502 bytesDownloaded["atp"] = statTracker->getStat(STAT_ATP_RESOURCE_TOTAL_BYTES).toInt();
14811503 bytesDownloaded["http"] = statTracker->getStat(STAT_HTTP_RESOURCE_TOTAL_BYTES).toInt();
@@ -1743,9 +1765,16 @@ void Application::checkChangeCursor() { · 261 unmodified lines
17431765 }
17441766 }
17451767
1746−void Application::showCursor(const QCursor& cursor) {
1768+void Application::showCursor(const Cursor::Icon& cursor) {
17471769 QMutexLocker locker(&_changeCursorLock);
1748− _desiredCursor = cursor;
1770+
1771+ auto managedCursor = Cursor::Manager::instance().getCursor();
1772+ auto curIcon = managedCursor->getIcon();
1773+ if (curIcon != cursor) {
1774+ managedCursor->setIcon(cursor);
1775+ curIcon = cursor;
1776+ }
1777+ _desiredCursor = cursor == Cursor::Icon::SYSTEM ? Qt::ArrowCursor : Qt::BlankCursor;
17491778 _cursorNeedsChanging = true;
17501779 }
17511780
@@ -2120,7 +2149,6 @@ void Application::initializeUi() { · 368 unmodified lines
21202149 surfaceContext->setContextProperty("AvatarManager", DependencyManager::get<AvatarManager>().data());
21212150 surfaceContext->setContextProperty("UndoStack", &_undoStackScriptingInterface);
21222151 surfaceContext->setContextProperty("LODManager", DependencyManager::get<LODManager>().data());
2123− surfaceContext->setContextProperty("Paths", DependencyManager::get<PathUtils>().data());
21242152 surfaceContext->setContextProperty("HMD", DependencyManager::get<HMDScriptingInterface>().data());
21252153 surfaceContext->setContextProperty("Scene", DependencyManager::get<SceneScriptingInterface>().data());
21262154 surfaceContext->setContextProperty("Render", _renderEngine->getConfiguration().get());
@@ -2131,7 +2159,7 @@ void Application::initializeUi() { · 4 unmodified lines
21312159 surfaceContext->setContextProperty("ApplicationCompositor", &getApplicationCompositor());
21322160
21332161 surfaceContext->setContextProperty("AvatarInputs", AvatarInputs::getInstance());
2134− surfaceContext->setContextProperty("HoverOverlay", DependencyManager::get<HoverOverlayInterface>().data());
2162+ surfaceContext->setContextProperty("ContextOverlay", DependencyManager::get<ContextOverlayInterface>().data());
21352163
21362164 if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {
21372165 surfaceContext->setContextProperty("Steam", new SteamScriptingInterface(engine, steamClient.get()));
@@ -2167,9 +2195,11 @@ void Application::initializeUi() { · 29 unmodified lines
21672195 _window->setMenuBar(new Menu());
21682196
21692197 auto compositorHelper = DependencyManager::get<CompositorHelper>();
2170− connect(compositorHelper.data(), &CompositorHelper::allowMouseCaptureChanged, [=] {
2198+ connect(compositorHelper.data(), &CompositorHelper::allowMouseCaptureChanged, this, [=] {
21712199 if (isHMDMode()) {
2172− showCursor(compositorHelper->getAllowMouseCapture() ? Qt::BlankCursor : Qt::ArrowCursor);
2200+ showCursor(compositorHelper->getAllowMouseCapture() ?
2201+ Cursor::Manager::lookupIcon(_preferredCursor.get()) :
2202+ Cursor::Icon::SYSTEM);
21732203 }
21742204 });
21752205
@@ -2235,7 +2265,7 @@ void Application::paintGL() { · 59 unmodified lines
22352265 QMutexLocker viewLocker(&_viewMutex);
22362266 _viewFrustum.calculate();
22372267 }
2238− renderArgs = RenderArgs(_gpuContext, getEntities(), lodManager->getOctreeSizeScale(),
2268+ renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(),
22392269 lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE,
22402270 RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE);
22412271 {
@@ -2321,7 +2351,7 @@ void Application::paintGL() { · 79 unmodified lines
23212351 }
23222352 } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
23232353 if (isHMDMode()) {
2324− auto mirrorBodyOrientation = myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f));
2354+ auto mirrorBodyOrientation = myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f));
23252355
23262356 glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix());
23272357 // Mirror HMD yaw and roll
@@ -2343,7 +2373,7 @@ void Application::paintGL() { · 15 unmodified lines
23432373 + mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror
23442374 + mirrorBodyOrientation * hmdOffset);
23452375 } else {
2346− _myCamera.setOrientation(myAvatar->getWorldAlignedOrientation()
2376+ _myCamera.setOrientation(myAvatar->getOrientation()
23472377 * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)));
23482378 _myCamera.setPosition(myAvatar->getDefaultEyePosition()
23492379 + glm::vec3(0, _raiseMirror * myAvatar->getUniformScale(), 0)
@@ -2511,6 +2541,12 @@ void Application::setPreferAvatarFingerOverStylus(bool value) { · 161 unmodified lines
25112541 _preferAvatarFingerOverStylusSetting.set(value);
25122542 }
25132543
2544+void Application::setPreferredCursor(const QString& cursorName) {
2545+ qCDebug(interfaceapp) << "setPreferredCursor" << cursorName;
2546+ _preferredCursor.set(cursorName.isEmpty() ? DEFAULT_CURSOR_NAME : cursorName);
2547+ showCursor(Cursor::Manager::lookupIcon(_preferredCursor.get()));
2548+}
2549+
25142550 void Application::setSettingConstrainToolbarPosition(bool setting) {
25152551 _constrainToolbarPosition.set(setting);
25162552 DependencyManager::get<OffscreenUi>()->setConstrainToolbarToCenterX(setting);
@@ -2744,6 +2780,20 @@ bool Application::importSVOFromURL(const QString& urlString) { · 227 unmodified lines
27442780 return true;
27452781 }
27462782
2783+void Application::onPresent(quint32 frameCount) {
2784+ if (shouldPaint()) {
2785+ postEvent(this, new QEvent(static_cast<QEvent::Type>(Idle)), Qt::HighEventPriority);
2786+ postEvent(this, new QEvent(static_cast<QEvent::Type>(Paint)), Qt::HighEventPriority);
2787+ }
2788+}
2789+
2790+bool Application::importFromZIP(const QString& filePath) {
2791+ qDebug() << "A zip file has been dropped in: " << filePath;
2792+ QUrl empty;
2793+ qApp->getFileDownloadInterface()->runUnzip(filePath, empty, true, true);
2794+ return true;
2795+}
2796+
27472797 bool _renderRequested { false };
27482798
27492799 bool Application::event(QEvent* event) {
@@ -2760,23 +2810,9 @@ bool Application::event(QEvent* event) { · 10 unmodified lines
27602810 // Explicit idle keeps the idle running at a lower interval, but without any rendering
27612811 // see (windowMinimizedChanged)
27622812 case Event::Idle:
2763− {
2764− float nsecsElapsed = (float)_lastTimeUpdated.nsecsElapsed();
2765− _lastTimeUpdated.start();
2766− idle(nsecsElapsed);
2767− }
2768− return true;
2769−
2770− case Event::Present:
2771− if (!_renderRequested) {
2772− float nsecsElapsed = (float)_lastTimeUpdated.nsecsElapsed();
2773− if (shouldPaint(nsecsElapsed)) {
2774− _renderRequested = true;
2775− _lastTimeUpdated.start();
2776− idle(nsecsElapsed);
2777− postEvent(this, new QEvent(static_cast<QEvent::Type>(Paint)), Qt::HighEventPriority);
2778− }
2779− }
2813+ idle();
2814+ // Clear the event queue of pending idle calls
2815+ removePostedEvents(this, Idle);
27802816 return true;
27812817
27822818 case Event::Paint:
@@ -2784,9 +2820,8 @@ bool Application::event(QEvent* event) { · 1 unmodified line
27842820 // or AvatarInputs will mysteriously move to the bottom-right
27852821 AvatarInputs::getInstance()->update();
27862822 paintGL();
2787− // wait for the next present event before starting idle / paint again
2788− removePostedEvents(this, Present);
2789− _renderRequested = false;
2823+ // Clear the event queue of pending paint calls
2824+ removePostedEvents(this, Paint);
27902825 return true;
27912826
27922827 default:
@@ -3026,7 +3061,9 @@ void Application::keyPressEvent(QKeyEvent* event) { · 233 unmodified lines
30263061 break;
30273062
30283063 case Qt::Key_F: {
3029− _physicsEngine->dumpNextStats();
3064+ if (isOption) {
3065+ _physicsEngine->dumpNextStats();
3066+ }
30303067 break;
30313068 }
30323069
@@ -3070,9 +3107,13 @@ void Application::keyPressEvent(QKeyEvent* event) { · 37 unmodified lines
30703107 auto cursor = Cursor::Manager::instance().getCursor();
30713108 auto curIcon = cursor->getIcon();
30723109 if (curIcon == Cursor::Icon::DEFAULT) {
3073− cursor->setIcon(Cursor::Icon::LINK);
3110+ showCursor(Cursor::Icon::RETICLE);
3111+ } else if (curIcon == Cursor::Icon::RETICLE) {
3112+ showCursor(Cursor::Icon::SYSTEM);
3113+ } else if (curIcon == Cursor::Icon::SYSTEM) {
3114+ showCursor(Cursor::Icon::LINK);
30743115 } else {
3075− cursor->setIcon(Cursor::Icon::DEFAULT);
3116+ showCursor(Cursor::Icon::DEFAULT);
30763117 }
30773118 } else {
30783119 resetSensors(true);
@@ -3599,7 +3640,7 @@ bool Application::acceptSnapshot(const QString& urlString) { · 520 unmodified lines
35993640
36003641 static uint32_t _renderedFrameIndex { INVALID_FRAME };
36013642
3602−bool Application::shouldPaint(float nsecsElapsed) {
3643+bool Application::shouldPaint() {
36033644 if (_aboutToQuit) {
36043645 return false;
36053646 }
@@ -3619,11 +3660,9 @@ bool Application::shouldPaint(float nsecsElapsed) { · 13 unmodified lines
36193660 (float)paintDelaySamples / paintDelayUsecs << "us";
36203661 }
36213662 #endif
3622−
3623− float msecondsSinceLastUpdate = nsecsElapsed / NSECS_PER_USEC / USECS_PER_MSEC;
3624−
3663+
36253664 // Throttle if requested
3626− if (displayPlugin->isThrottled() && (msecondsSinceLastUpdate < THROTTLED_SIM_FRAME_PERIOD_MS)) {
3665+ if (displayPlugin->isThrottled() && (_lastTimeUpdated.elapsed() < THROTTLED_SIM_FRAME_PERIOD_MS)) {
36273666 return false;
36283667 }
36293668
@@ -3840,7 +3879,7 @@ void setupCpuMonitorThread() { · 210 unmodified lines
38403879 #endif
38413880
38423881
3843−void Application::idle(float nsecsElapsed) {
3882+void Application::idle() {
38443883 PerformanceTimer perfTimer("idle");
38453884
38463885 // Update the deadlock watchdog
@@ -3897,7 +3936,8 @@ void Application::idle(float nsecsElapsed) { · 50 unmodified lines
38973936 steamClient->runCallbacks();
38983937 }
38993938
3900− float secondsSinceLastUpdate = nsecsElapsed / NSECS_PER_MSEC / MSECS_PER_SECOND;
3939+ float secondsSinceLastUpdate = (float)_lastTimeUpdated.nsecsElapsed() / NSECS_PER_MSEC / MSECS_PER_SECOND;
3940+ _lastTimeUpdated.start();
39013941
39023942 // If the offscreen Ui has something active that is NOT the root, then assume it has keyboard focus.
39033943 if (_keyboardDeviceHasFocus && offscreenUi && offscreenUi->getWindow()->activeFocusItem() != offscreenUi->getRootItem()) {
@@ -4131,6 +4171,7 @@ void Application::loadSettings() { · 227 unmodified lines
41314171 //DependencyManager::get<LODManager>()->setAutomaticLODAdjust(false);
41324172
41334173 Menu::getInstance()->loadSettings();
4174+
41344175 // If there is a preferred plugin, we probably messed it up with the menu settings, so fix it.
41354176 auto pluginManager = PluginManager::getInstance();
41364177 auto plugins = pluginManager->getPreferredDisplayPlugins();
@@ -4144,24 +4185,44 @@ void Application::loadSettings() { · 7 unmodified lines
41444185 break;
41454186 }
41464187 }
4147− } else {
4188+ }
4189+
4190+ Setting::Handle<bool> firstRun { Settings::firstRun, true };
4191+ bool isFirstPerson = false;
4192+ if (firstRun.get()) {
41484193 // If this is our first run, and no preferred devices were set, default to
41494194 // an HMD device if available.
4150− Setting::Handle<bool> firstRun { Settings::firstRun, true };
4151− if (firstRun.get()) {
4152− auto displayPlugins = pluginManager->getDisplayPlugins();
4153− for (auto& plugin : displayPlugins) {
4154− if (plugin->isHmd()) {
4155− if (auto action = menu->getActionForOption(plugin->getName())) {
4156− action->setChecked(true);
4157− action->trigger();
4158− break;
4159− }
4195+ auto displayPlugins = pluginManager->getDisplayPlugins();
4196+ for (auto& plugin : displayPlugins) {
4197+ if (plugin->isHmd()) {
4198+ if (auto action = menu->getActionForOption(plugin->getName())) {
4199+ action->setChecked(true);
4200+ action->trigger();
4201+ break;
41604202 }
41614203 }
41624204 }
4205+
4206+ isFirstPerson = (qApp->isHMDMode());
4207+ } else {
4208+ // if this is not the first run, the camera will be initialized differently depending on user settings
4209+
4210+ if (qApp->isHMDMode()) {
4211+ // if the HMD is active, use first-person camera, unless the appropriate setting is checked
4212+ isFirstPerson = menu->isOptionChecked(MenuOption::FirstPersonHMD);
4213+ } else {
4214+ // if HMD is not active, only use first person if the menu option is checked
4215+ isFirstPerson = menu->isOptionChecked(MenuOption::FirstPerson);
4216+ }
41634217 }
41644218
4219+ // finish initializing the camera, based on everything we checked above. Third person camera will be used if no settings
4220+ // dictated that we should be in first person
4221+ Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, isFirstPerson);
4222+ Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !isFirstPerson);
4223+ _myCamera.setMode((isFirstPerson) ? CAMERA_MODE_FIRST_PERSON : CAMERA_MODE_THIRD_PERSON);
4224+ cameraMenuChanged();
4225+
41654226 auto inputs = pluginManager->getInputPlugins();
41664227 for (auto plugin : inputs) {
41674228 if (!plugin->isActive()) {
@@ -4210,7 +4271,6 @@ void Application::init() { · 42 unmodified lines
42104271 DependencyManager::get<DeferredLightingEffect>()->init();
42114272
42124273 DependencyManager::get<AvatarManager>()->init();
4213− _myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
42144274
42154275 _timerStart.start();
42164276 _lastTimeUpdated.start();
@@ -4466,27 +4526,29 @@ void Application::cameraModeChanged() { · 249 unmodified lines
44664526
44674527
44684528 void Application::cameraMenuChanged() {
4469− if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
4529+ auto menu = Menu::getInstance();
4530+ if (menu->isOptionChecked(MenuOption::FullscreenMirror)) {
44704531 if (_myCamera.getMode() != CAMERA_MODE_MIRROR) {
44714532 _myCamera.setMode(CAMERA_MODE_MIRROR);
4533+ getMyAvatar()->reset(false, false, false); // to reset any active MyAvatar::FollowHelpers
44724534 }
4473− } else if (Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson)) {
4535+ } else if (menu->isOptionChecked(MenuOption::FirstPerson)) {
44744536 if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) {
44754537 _myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
44764538 getMyAvatar()->setBoomLength(MyAvatar::ZOOM_MIN);
44774539 }
4478− } else if (Menu::getInstance()->isOptionChecked(MenuOption::ThirdPerson)) {
4540+ } else if (menu->isOptionChecked(MenuOption::ThirdPerson)) {
44794541 if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) {
44804542 _myCamera.setMode(CAMERA_MODE_THIRD_PERSON);
44814543 if (getMyAvatar()->getBoomLength() == MyAvatar::ZOOM_MIN) {
44824544 getMyAvatar()->setBoomLength(MyAvatar::ZOOM_DEFAULT);
44834545 }
44844546 }
4485− } else if (Menu::getInstance()->isOptionChecked(MenuOption::IndependentMode)) {
4547+ } else if (menu->isOptionChecked(MenuOption::IndependentMode)) {
44864548 if (_myCamera.getMode() != CAMERA_MODE_INDEPENDENT) {
44874549 _myCamera.setMode(CAMERA_MODE_INDEPENDENT);
44884550 }
4489− } else if (Menu::getInstance()->isOptionChecked(MenuOption::CameraEntityMode)) {
4551+ } else if (menu->isOptionChecked(MenuOption::CameraEntityMode)) {
44904552 if (_myCamera.getMode() != CAMERA_MODE_ENTITY) {
44914553 _myCamera.setMode(CAMERA_MODE_ENTITY);
44924554 }
@@ -5380,6 +5442,17 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se · 887 unmodified lines
53805442 }
53815443 renderArgs->_debugFlags = renderDebugFlags;
53825444 //ViveControllerManager::getInstance().updateRendering(renderArgs, _main3DScene, transaction);
5445+
5446+ RenderArgs::OutlineFlags renderOutlineFlags = RenderArgs::RENDER_OUTLINE_NONE;
5447+ auto contextOverlayInterface = DependencyManager::get<ContextOverlayInterface>();
5448+ if (contextOverlayInterface->getEnabled()) {
5449+ if (DependencyManager::get<ContextOverlayInterface>()->getIsInMarketplaceInspectionMode()) {
5450+ renderOutlineFlags = RenderArgs::RENDER_OUTLINE_MARKETPLACE_MODE;
5451+ } else {
5452+ renderOutlineFlags = RenderArgs::RENDER_OUTLINE_WIREFRAMES;
5453+ }
5454+ }
5455+ renderArgs->_outlineFlags = renderOutlineFlags;
53835456 }
53845457 }
53855458
@@ -5844,7 +5917,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri · 458 unmodified lines
58445917 auto entityScriptServerLog = DependencyManager::get<EntityScriptServerLogClient>();
58455918 scriptEngine->registerGlobalObject("EntityScriptServerLog", entityScriptServerLog.data());
58465919 scriptEngine->registerGlobalObject("AvatarInputs", AvatarInputs::getInstance());
5847− scriptEngine->registerGlobalObject("HoverOverlay", DependencyManager::get<HoverOverlayInterface>().data());
5920+ scriptEngine->registerGlobalObject("ContextOverlay", DependencyManager::get<ContextOverlayInterface>().data());
58485921
58495922 qScriptRegisterMetaType(scriptEngine, OverlayIDtoScriptValue, OverlayIDfromScriptValue);
58505923
@@ -6199,7 +6272,7 @@ void Application::addAssetToWorldFromURLRequestFinished() { · 348 unmodified lines
61996272 if (tempFile.open(QIODevice::WriteOnly)) {
62006273 tempFile.write(request->getData());
62016274 addAssetToWorldInfoClear(filename); // Remove message from list; next one added will have a different key.
6202− qApp->getFileDownloadInterface()->runUnzip(downloadPath, url, true);
6275+ qApp->getFileDownloadInterface()->runUnzip(downloadPath, url, true, false);
62036276 } else {
62046277 QString errorInfo = "Couldn't open temporary file for download";
62056278 qWarning(interfaceapp) << errorInfo;
@@ -6229,12 +6302,18 @@ void Application::addAssetToWorldUnzipFailure(QString filePath) { · 23 unmodified lines
62296302 addAssetToWorldError(filename, "Couldn't unzip file " + filename + ".");
62306303 }
62316304
6232−void Application::addAssetToWorld(QString filePath) {
6305+void Application::addAssetToWorld(QString filePath, QString zipFile, bool isZip) {
62336306 // Automatically upload and add asset to world as an alternative manual process initiated by showAssetServerWidget().
6234−
6235− QString path = QUrl(filePath).toLocalFile();
6307+ QString mapping;
6308+ QString path = filePath;
62366309 QString filename = filenameFromPath(path);
6237− QString mapping = "/" + filename;
6310+ if (isZip) {
6311+ QString assetFolder = zipFile.section("/", -1);
6312+ assetFolder.remove(".zip");
6313+ mapping = "/" + assetFolder + "/" + filename;
6314+ } else {
6315+ mapping = "/" + filename;
6316+ }
62386317
62396318 // Test repeated because possibly different code paths.
62406319 if (!DependencyManager::get<NodeList>()->getThisNodeCanWriteAssets()) {
@@ -6315,7 +6394,13 @@ void Application::addAssetToWorldSetMapping(QString filePath, QString mapping, Q · 74 unmodified lines
63156394 qWarning(interfaceapp) << "Error downloading model: " + errorInfo;
63166395 addAssetToWorldError(filenameFromPath(filePath), errorInfo);
63176396 } else {
6318− addAssetToWorldAddEntity(filePath, mapping);
6397+ // to prevent files that aren't models from being loaded into world automatically
6398+ if (filePath.endsWith(".obj") || filePath.endsWith(".fbx")) {
6399+ addAssetToWorldAddEntity(filePath, mapping);
6400+ } else {
6401+ qCDebug(interfaceapp) << "Zipped contents are not supported entity files";
6402+ addAssetToWorldInfoDone(filenameFromPath(filePath));
6403+ }
63196404 }
63206405 request->deleteLater();
63216406 });
@@ -6605,15 +6690,18 @@ void Application::onAssetToWorldMessageBoxClosed() { · 283 unmodified lines
66056690 }
66066691
66076692
6608−void Application::handleUnzip(QString zipFile, QString unzipFile, bool autoAdd) {
6693+void Application::handleUnzip(QString zipFile, QStringList unzipFile, bool autoAdd, bool isZip) {
66096694 if (autoAdd) {
66106695 if (!unzipFile.isEmpty()) {
6611− addAssetToWorld(unzipFile);
6696+ for (int i = 0; i < unzipFile.length(); i++) {
6697+ qCDebug(interfaceapp) << "Preparing file for asset server: " << unzipFile.at(i);
6698+ addAssetToWorld(unzipFile.at(i), zipFile, isZip);
6699+ }
66126700 } else {
66136701 addAssetToWorldUnzipFailure(zipFile);
66146702 }
66156703 } else {
6616− showAssetServerWidget(unzipFile);
6704+ showAssetServerWidget(unzipFile.first());
66176705 }
66186706 }
66196707
@@ -7076,6 +7164,7 @@ void Application::updateDisplayMode() { · 456 unmodified lines
70767164
70777165 auto oldDisplayPlugin = _displayPlugin;
70787166 if (_displayPlugin) {
7167+ disconnect(_displayPluginPresentConnection);
70797168 _displayPlugin->deactivate();
70807169 }
70817170
@@ -7116,6 +7205,7 @@ void Application::updateDisplayMode() { · 34 unmodified lines
71167205 _offscreenContext->makeCurrent();
71177206 getApplicationCompositor().setDisplayPlugin(newDisplayPlugin);
71187207 _displayPlugin = newDisplayPlugin;
7208+ _displayPluginPresentConnection = connect(_displayPlugin.get(), &DisplayPlugin::presented, this, &Application::onPresent);
71197209 offscreenUi->getDesktop()->setProperty("repositionLocked", wasRepositionLocked);
71207210 }
71217211