History

Merge remote-tracking branch 'samuel/scriptableMaterials' into Leopoly_Phase1_010_graphics-scripting-merge

humbletim committed 8 years ago

Commit 72fca7e2 parents be8d79f 4c6169e498 files · +18323 −41125Browse files

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

Unified · Split

interface/src/Application.cpp+218−98
@@ -319,7 +319,7 @@ static QTimer pingTimer; · 318 unmodified lines
319static bool DISABLE_WATCHDOG = true;319static bool DISABLE_WATCHDOG = true;
320#else320#else
321static const QString DISABLE_WATCHDOG_FLAG{ "HIFI_DISABLE_WATCHDOG" };321static const QString DISABLE_WATCHDOG_FLAG{ "HIFI_DISABLE_WATCHDOG" };
322static bool DISABLE_WATCHDOG = QProcessEnvironment::systemEnvironment().contains(DISABLE_WATCHDOG_FLAG);322static bool DISABLE_WATCHDOG = nsightActive() || QProcessEnvironment::systemEnvironment().contains(DISABLE_WATCHDOG_FLAG);
323#endif323#endif
324 324
325#if defined(USE_GLES)325#if defined(USE_GLES)
@@ -336,15 +336,17 @@ static const int MAX_CONCURRENT_RESOURCE_DOWNLOADS = 16; · 10 unmodified lines
336// we will never drop below the 'min' value336// we will never drop below the 'min' value
337static const int MIN_PROCESSING_THREAD_POOL_SIZE = 1;337static const int MIN_PROCESSING_THREAD_POOL_SIZE = 1;
338 338
339static const QString SNAPSHOT_EXTENSION = ".jpg";339static const QString SNAPSHOT_EXTENSION = ".jpg";
340static const QString SVO_EXTENSION = ".svo";340static const QString JPG_EXTENSION = ".jpg";
341static const QString PNG_EXTENSION = ".png";
342static const QString SVO_EXTENSION = ".svo";
341static const QString SVO_JSON_EXTENSION = ".svo.json";343static const QString SVO_JSON_EXTENSION = ".svo.json";
342static const QString JSON_GZ_EXTENSION = ".json.gz";344static const QString JSON_GZ_EXTENSION = ".json.gz";
343static const QString JSON_EXTENSION = ".json";345static const QString JSON_EXTENSION = ".json";
344static const QString JS_EXTENSION = ".js";346static const QString JS_EXTENSION = ".js";
345static const QString FST_EXTENSION = ".fst";347static const QString FST_EXTENSION = ".fst";
346static const QString FBX_EXTENSION = ".fbx";348static const QString FBX_EXTENSION = ".fbx";
347static const QString OBJ_EXTENSION = ".obj";349static const QString OBJ_EXTENSION = ".obj";
348static const QString AVA_JSON_EXTENSION = ".ava.json";350static const QString AVA_JSON_EXTENSION = ".ava.json";
349static const QString WEB_VIEW_TAG = "noDownload=true";351static const QString WEB_VIEW_TAG = "noDownload=true";
350static const QString ZIP_EXTENSION = ".zip";352static const QString ZIP_EXTENSION = ".zip";
@@ -383,7 +385,9 @@ const QHash<QString, Application::AcceptURLMethod> Application::_acceptedExtensi · 32 unmodified lines
383 { JS_EXTENSION, &Application::askToLoadScript },385 { JS_EXTENSION, &Application::askToLoadScript },
384 { FST_EXTENSION, &Application::askToSetAvatarUrl },386 { FST_EXTENSION, &Application::askToSetAvatarUrl },
385 { JSON_GZ_EXTENSION, &Application::askToReplaceDomainContent },387 { JSON_GZ_EXTENSION, &Application::askToReplaceDomainContent },
386 { ZIP_EXTENSION, &Application::importFromZIP }388 { ZIP_EXTENSION, &Application::importFromZIP },
389 { JPG_EXTENSION, &Application::importImage },
390 { PNG_EXTENSION, &Application::importImage }
387};391};
388 392
389class DeadlockWatchdogThread : public QThread {393class DeadlockWatchdogThread : public QThread {
@@ -416,20 +420,26 @@ public: · 26 unmodified lines
416 *crashTrigger = 0xDEAD10CC;420 *crashTrigger = 0xDEAD10CC;
417 }421 }
418 422
423 static void withPause(const std::function<void()>& lambda) {
424 pause();
425 lambda();
426 resume();
427 }
419 static void pause() {428 static void pause() {
420 _paused = true;429 _paused = true;
421 }430 }
422 431
423 static void resume() {432 static void resume() {
424 _paused = false;433 // Update the heartbeat BEFORE resuming the checks
425 updateHeartbeat();434 updateHeartbeat();
435 _paused = false;
426 }436 }
427 437
428 void run() override {438 void run() override {
429 while (!_quit) {439 while (!_quit) {
430 QThread::sleep(HEARTBEAT_UPDATE_INTERVAL_SECS);440 QThread::sleep(HEARTBEAT_UPDATE_INTERVAL_SECS);
431 // Don't do heartbeat detection under nsight441 // Don't do heartbeat detection under nsight
432 if (nsightActive() || _paused) {442 if (_paused) {
433 continue;443 continue;
434 }444 }
435 uint64_t lastHeartbeat = _heartbeat; // sample atomic _heartbeat, because we could context switch away and have it updated on us445 uint64_t lastHeartbeat = _heartbeat; // sample atomic _heartbeat, because we could context switch away and have it updated on us
@@ -863,6 +873,8 @@ std::shared_ptr<Cube3DOverlay> _keyboardFocusHighlight{ nullptr }; · 427 unmodified lines
863OverlayID _keyboardFocusHighlightID{ UNKNOWN_OVERLAY_ID };873OverlayID _keyboardFocusHighlightID{ UNKNOWN_OVERLAY_ID };
864 874
865 875
876OffscreenGLCanvas* _qmlShareContext { nullptr };
877
866// FIXME hack access to the internal share context for the Chromium helper878// FIXME hack access to the internal share context for the Chromium helper
867// Normally we'd want to use QWebEngine::initialize(), but we can't because879// Normally we'd want to use QWebEngine::initialize(), but we can't because
868// our primary context is a QGLWidget, which can't easily be initialized to share880// our primary context is a QGLWidget, which can't easily be initialized to share
@@ -1112,7 +1124,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 243 unmodified lines
1112 connect(nodeList.data(), &NodeList::packetVersionMismatch, this, &Application::notifyPacketVersionMismatch);1124 connect(nodeList.data(), &NodeList::packetVersionMismatch, this, &Application::notifyPacketVersionMismatch);
1113 1125
1114 // you might think we could just do this in NodeList but we only want this connection for Interface1126 // you might think we could just do this in NodeList but we only want this connection for Interface
1115 connect(nodeList.data(), &NodeList::limitOfSilentDomainCheckInsReached, nodeList.data(), &NodeList::reset);1127 connect(&nodeList->getDomainHandler(), SIGNAL(limitOfSilentDomainCheckInsReached()),
1128 nodeList.data(), SLOT(reset()));
1116 1129
1117 auto dialogsManager = DependencyManager::get<DialogsManager>();1130 auto dialogsManager = DependencyManager::get<DialogsManager>();
1118 connect(accountManager.data(), &AccountManager::authRequired, dialogsManager.data(), &DialogsManager::showLoginDialog);1131 connect(accountManager.data(), &AccountManager::authRequired, dialogsManager.data(), &DialogsManager::showLoginDialog);
@@ -1646,6 +1659,73 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 527 unmodified lines
1646 }1659 }
1647 });1660 });
1648 1661
1662 EntityTree::setAddMaterialToEntityOperator([&](const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName) {
1663 // try to find the renderable
1664 auto renderable = getEntities()->renderableForEntityId(entityID);
1665 if (renderable) {
1666 renderable->addMaterial(material, parentMaterialName);
1667 }
1668
1669 // even if we don't find it, try to find the entity
1670 auto entity = getEntities()->getEntity(entityID);
1671 if (entity) {
1672 entity->addMaterial(material, parentMaterialName);
1673 return true;
1674 }
1675 return false;
1676 });
1677 EntityTree::setRemoveMaterialFromEntityOperator([&](const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName) {
1678 // try to find the renderable
1679 auto renderable = getEntities()->renderableForEntityId(entityID);
1680 if (renderable) {
1681 renderable->removeMaterial(material, parentMaterialName);
1682 }
1683
1684 // even if we don't find it, try to find the entity
1685 auto entity = getEntities()->getEntity(entityID);
1686 if (entity) {
1687 entity->removeMaterial(material, parentMaterialName);
1688 return true;
1689 }
1690 return false;
1691 });
1692
1693 EntityTree::setAddMaterialToAvatarOperator([](const QUuid& avatarID, graphics::MaterialLayer material, const std::string& parentMaterialName) {
1694 auto avatarManager = DependencyManager::get<AvatarManager>();
1695 auto avatar = avatarManager->getAvatarBySessionID(avatarID);
1696 if (avatar) {
1697 avatar->addMaterial(material, parentMaterialName);
1698 return true;
1699 }
1700 return false;
1701 });
1702 EntityTree::setRemoveMaterialFromAvatarOperator([](const QUuid& avatarID, graphics::MaterialPointer material, const std::string& parentMaterialName) {
1703 auto avatarManager = DependencyManager::get<AvatarManager>();
1704 auto avatar = avatarManager->getAvatarBySessionID(avatarID);
1705 if (avatar) {
1706 avatar->removeMaterial(material, parentMaterialName);
1707 return true;
1708 }
1709 return false;
1710 });
1711
1712 EntityTree::setAddMaterialToOverlayOperator([&](const QUuid& overlayID, graphics::MaterialLayer material, const std::string& parentMaterialName) {
1713 auto overlay = _overlays.getOverlay(overlayID);
1714 if (overlay) {
1715 overlay->addMaterial(material, parentMaterialName);
1716 return true;
1717 }
1718 return false;
1719 });
1720 EntityTree::setRemoveMaterialFromOverlayOperator([&](const QUuid& overlayID, graphics::MaterialPointer material, const std::string& parentMaterialName) {
1721 auto overlay = _overlays.getOverlay(overlayID);
1722 if (overlay) {
1723 overlay->removeMaterial(material, parentMaterialName);
1724 return true;
1725 }
1726 return false;
1727 });
1728
1649 // Keyboard focus handling for Web overlays.1729 // Keyboard focus handling for Web overlays.
1650 auto overlays = &(qApp->getOverlays());1730 auto overlays = &(qApp->getOverlays());
1651 connect(overlays, &Overlays::overlayDeleted, [=](const OverlayID& overlayID) {1731 connect(overlays, &Overlays::overlayDeleted, [=](const OverlayID& overlayID) {
@@ -2324,18 +2404,37 @@ void Application::initializeGL() { · 672 unmodified lines
2324 _isGLInitialized = true;2404 _isGLInitialized = true;
2325 }2405 }
2326 2406
2407 // Build a shared canvas / context for the Chromium processes
2327 _glWidget->makeCurrent();2408 _glWidget->makeCurrent();
2328 2409
2329#if !defined(DISABLE_QML)2410#if !defined(DISABLE_QML)
2411 // Chromium rendering uses some GL functions that prevent nSight from capturing
2412 // frames, so we only create the shared context if nsight is NOT active.
2330 if (!nsightActive()) {2413 if (!nsightActive()) {
2331 _chromiumShareContext = new OffscreenGLCanvas();2414 _chromiumShareContext = new OffscreenGLCanvas();
2332 _chromiumShareContext->setObjectName("ChromiumShareContext");2415 _chromiumShareContext->setObjectName("ChromiumShareContext");
2333 _chromiumShareContext->create(_glWidget->qglContext());2416 _chromiumShareContext->create(_glWidget->qglContext());
2334 _chromiumShareContext->makeCurrent();2417 _chromiumShareContext->makeCurrent();
2418 if (!_chromiumShareContext->makeCurrent()) {
2419 qCWarning(interfaceapp, "Unable to make chromium shared context current");
2420 }
2335 qt_gl_set_global_share_context(_chromiumShareContext->getContext());2421 qt_gl_set_global_share_context(_chromiumShareContext->getContext());
2422 } else {
2423 qCWarning(interfaceapp) << "nSIGHT detected, disabling chrome rendering";
2336 }2424 }
2337#endif2425#endif
2338 2426
2427 // Build a shared canvas / context for the QML rendering
2428 _glWidget->makeCurrent();
2429 _qmlShareContext = new OffscreenGLCanvas();
2430 _qmlShareContext->setObjectName("QmlShareContext");
2431 _qmlShareContext->create(_glWidget->qglContext());
2432 if (!_qmlShareContext->makeCurrent()) {
2433 qCWarning(interfaceapp, "Unable to make QML shared context current");
2434 }
2435 OffscreenQmlSurface::setSharedContext(_qmlShareContext->getContext());
2436 _qmlShareContext->doneCurrent();
2437
2339 _glWidget->makeCurrent();2438 _glWidget->makeCurrent();
2340 gpu::Context::init<gpu::gl::GLBackend>();2439 gpu::Context::init<gpu::gl::GLBackend>();
2341 qApp->setProperty(hifi::properties::gl::MAKE_PROGRAM_CALLBACK,2440 qApp->setProperty(hifi::properties::gl::MAKE_PROGRAM_CALLBACK,
@@ -2348,29 +2447,22 @@ void Application::initializeGL() { · 6 unmodified lines
2348 initDisplay();2447 initDisplay();
2349 qCDebug(interfaceapp, "Initialized Display.");2448 qCDebug(interfaceapp, "Initialized Display.");
2350 2449
2351#ifdef Q_OS_OSX2450 // FIXME: on low end systems os the shaders take up to 1 minute to compile, so we pause the deadlock watchdog thread.
2352 // FIXME: on mac os the shaders take up to 1 minute to compile, so we pause the deadlock watchdog thread.2451 DeadlockWatchdogThread::withPause([&] {
2353 DeadlockWatchdogThread::pause();2452 // Set up the render engine
2354#endif2453 render::CullFunctor cullFunctor = LODManager::shouldRender;
2355 2454 static const QString RENDER_FORWARD = "HIFI_RENDER_FORWARD";
2356 // Set up the render engine2455 _renderEngine->addJob<UpdateSceneTask>("UpdateScene");
2357 render::CullFunctor cullFunctor = LODManager::shouldRender;
2358 static const QString RENDER_FORWARD = "HIFI_RENDER_FORWARD";
2359 _renderEngine->addJob<UpdateSceneTask>("UpdateScene");
2360#ifndef Q_OS_ANDROID2456#ifndef Q_OS_ANDROID
2361 _renderEngine->addJob<SecondaryCameraRenderTask>("SecondaryCameraJob", cullFunctor, !DISABLE_DEFERRED);2457 _renderEngine->addJob<SecondaryCameraRenderTask>("SecondaryCameraJob", cullFunctor, !DISABLE_DEFERRED);
2362#endif2458#endif
2363 _renderEngine->addJob<RenderViewTask>("RenderMainView", cullFunctor, !DISABLE_DEFERRED);2459 _renderEngine->addJob<RenderViewTask>("RenderMainView", cullFunctor, !DISABLE_DEFERRED, render::ItemKey::TAG_BITS_0, render::ItemKey::TAG_BITS_0);
2460 _renderEngine->load();
2461 _renderEngine->registerScene(_main3DScene);
2364 2462
2365#ifdef Q_OS_OSX2463 // Now that OpenGL is initialized, we are sure we have a valid context and can create the various pipeline shaders with success.
2366 DeadlockWatchdogThread::resume();2464 DependencyManager::get<GeometryCache>()->initializeShapePipelines();
2367#endif2465 });
2368
2369 _renderEngine->load();
2370 _renderEngine->registerScene(_main3DScene);
2371
2372 // Now that OpenGL is initialized, we are sure we have a valid context and can create the various pipeline shaders with success.
2373 DependencyManager::get<GeometryCache>()->initializeShapePipelines();
2374 2466
2375 _offscreenContext = new OffscreenGLCanvas();2467 _offscreenContext = new OffscreenGLCanvas();
2376 _offscreenContext->setObjectName("MainThreadContext");2468 _offscreenContext->setObjectName("MainThreadContext");
@@ -2378,20 +2470,24 @@ void Application::initializeGL() { · 1 unmodified line
2378 if (!_offscreenContext->makeCurrent()) {2470 if (!_offscreenContext->makeCurrent()) {
2379 qFatal("Unable to make offscreen context current");2471 qFatal("Unable to make offscreen context current");
2380 }2472 }
2473 _offscreenContext->doneCurrent();
2474 _offscreenContext->setThreadContext();
2475 _renderEventHandler = new RenderEventHandler(_glWidget->qglContext());
2381 2476
2382 // The UI can't be created until the primary OpenGL2477 // The UI can't be created until the primary OpenGL
2383 // context is created, because it needs to share2478 // context is created, because it needs to share
2384 // texture resources2479 // texture resources
2385 // Needs to happen AFTER the render engine initialization to access its configuration2480 // Needs to happen AFTER the render engine initialization to access its configuration
2481 if (!_offscreenContext->makeCurrent()) {
2482 qFatal("Unable to make offscreen context current");
2483 }
2484
2386 initializeUi();2485 initializeUi();
2387 qCDebug(interfaceapp, "Initialized Offscreen UI.");2486 qCDebug(interfaceapp, "Initialized Offscreen UI.");
2388 _glWidget->makeCurrent();
2389
2390
2391 // call Menu getInstance static method to set up the menu
2392 // Needs to happen AFTER the QML UI initialization
2393 _window->setMenuBar(Menu::getInstance());
2394 2487
2488 if (!_offscreenContext->makeCurrent()) {
2489 qFatal("Unable to make offscreen context current");
2490 }
2395 init();2491 init();
2396 qCDebug(interfaceapp, "init() complete.");2492 qCDebug(interfaceapp, "init() complete.");
2397 2493
@@ -2402,7 +2498,6 @@ void Application::initializeGL() { · 4 unmodified lines
2402 2498
2403 _idleLoopStdev.reset();2499 _idleLoopStdev.reset();
2404 2500
2405 _renderEventHandler = new RenderEventHandler(_glWidget->qglContext());
2406 2501
2407 // Restore the primary GL content for the main thread2502 // Restore the primary GL content for the main thread
2408 if (!_offscreenContext->makeCurrent()) {2503 if (!_offscreenContext->makeCurrent()) {
@@ -2468,27 +2563,70 @@ void Application::initializeUi() { · 59 unmodified lines
2468 auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();2563 auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
2469 tabletScriptingInterface->getTablet(SYSTEM_TABLET);2564 tabletScriptingInterface->getTablet(SYSTEM_TABLET);
2470 }2565 }
2471 auto offscreenUi = DependencyManager::get<OffscreenUi>();
2472 offscreenUi->create();
2473 2566
2474 auto surfaceContext = offscreenUi->getSurfaceContext();2567 auto offscreenUi = DependencyManager::get<OffscreenUi>();
2568 connect(offscreenUi.data(), &hifi::qml::OffscreenSurface::rootContextCreated,
2569 this, &Application::onDesktopRootContextCreated);
2570 connect(offscreenUi.data(), &hifi::qml::OffscreenSurface::rootItemCreated,
2571 this, &Application::onDesktopRootItemCreated);
2475 2572
2476 offscreenUi->setProxyWindow(_window->windowHandle());2573 offscreenUi->setProxyWindow(_window->windowHandle());
2477 // OffscreenUi is a subclass of OffscreenQmlSurface specifically designed to2574 // OffscreenUi is a subclass of OffscreenQmlSurface specifically designed to
2478 // support the window management and scripting proxies for VR use2575 // support the window management and scripting proxies for VR use
2479 offscreenUi->createDesktop(PathUtils::qmlUrl("hifi/Desktop.qml"));2576 DeadlockWatchdogThread::withPause([&] {
2577 offscreenUi->createDesktop(PathUtils::qmlUrl("hifi/Desktop.qml"));
2578 });
2480 // FIXME either expose so that dialogs can set this themselves or2579 // FIXME either expose so that dialogs can set this themselves or
2481 // do better detection in the offscreen UI of what has focus2580 // do better detection in the offscreen UI of what has focus
2482 offscreenUi->setNavigationFocused(false);2581 offscreenUi->setNavigationFocused(false);
2483 2582
2484 auto engine = surfaceContext->engine();2583 setupPreferences();
2485 connect(engine, &QQmlEngine::quit, [] {2584
2486 qApp->quit();2585 _glWidget->installEventFilter(offscreenUi.data());
2586 offscreenUi->setMouseTranslator([=](const QPointF& pt) {
2587 QPointF result = pt;
2588 auto displayPlugin = getActiveDisplayPlugin();
2589 if (displayPlugin->isHmd()) {
2590 getApplicationCompositor().handleRealMouseMoveEvent(false);
2591 auto resultVec = getApplicationCompositor().getReticlePosition();
2592 result = QPointF(resultVec.x, resultVec.y);
2593 }
2594 return result.toPoint();
2595 });
2596 offscreenUi->resume();
2597 connect(_window, &MainWindow::windowGeometryChanged, [this](const QRect& r){
2598 resizeGL();
2487 });2599 });
2488 2600
2601 // This will set up the input plugins UI
2602 _activeInputPlugins.clear();
2603 foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) {
2604 if (KeyboardMouseDevice::NAME == inputPlugin->getName()) {
2605 _keyboardMouseDevice = std::dynamic_pointer_cast<KeyboardMouseDevice>(inputPlugin);
2606 }
2607 if (TouchscreenDevice::NAME == inputPlugin->getName()) {
2608 _touchscreenDevice = std::dynamic_pointer_cast<TouchscreenDevice>(inputPlugin);
2609 }
2610 }
2611
2612 auto compositorHelper = DependencyManager::get<CompositorHelper>();
2613 connect(compositorHelper.data(), &CompositorHelper::allowMouseCaptureChanged, this, [=] {
2614 if (isHMDMode()) {
2615 showCursor(compositorHelper->getAllowMouseCapture() ?
2616 Cursor::Manager::lookupIcon(_preferredCursor.get()) :
2617 Cursor::Icon::SYSTEM);
2618 }
2619 });
2620
2621 // Pre-create a couple of Web3D overlays to speed up tablet UI
2622 auto offscreenSurfaceCache = DependencyManager::get<OffscreenQmlSurfaceCache>();
2623 offscreenSurfaceCache->reserve(TabletScriptingInterface::QML, 1);
2624 offscreenSurfaceCache->reserve(Web3DOverlay::QML, 2);
2625}
2489 2626
2490 setupPreferences();
2491 2627
2628void Application::onDesktopRootContextCreated(QQmlContext* surfaceContext) {
2629 auto engine = surfaceContext->engine();
2492 // in Qt 5.10.0 there is already an "Audio" object in the QML context2630 // in Qt 5.10.0 there is already an "Audio" object in the QML context
2493 // though I failed to find it (from QtMultimedia??). So.. let it be "AudioScriptingInterface"2631 // though I failed to find it (from QtMultimedia??). So.. let it be "AudioScriptingInterface"
2494 surfaceContext->setContextProperty("AudioScriptingInterface", DependencyManager::get<AudioScriptingInterface>().data());2632 surfaceContext->setContextProperty("AudioScriptingInterface", DependencyManager::get<AudioScriptingInterface>().data());
@@ -2570,48 +2708,12 @@ void Application::initializeUi() { · 75 unmodified lines
2570 surfaceContext->setContextProperty("Steam", new SteamScriptingInterface(engine, steamClient.get()));2708 surfaceContext->setContextProperty("Steam", new SteamScriptingInterface(engine, steamClient.get()));
2571 }2709 }
2572 2710
2573
2574 _glWidget->installEventFilter(offscreenUi.data());
2575 offscreenUi->setMouseTranslator([=](const QPointF& pt) {
2576 QPointF result = pt;
2577 auto displayPlugin = getActiveDisplayPlugin();
2578 if (displayPlugin->isHmd()) {
2579 getApplicationCompositor().handleRealMouseMoveEvent(false);
2580 auto resultVec = getApplicationCompositor().getReticlePosition();
2581 result = QPointF(resultVec.x, resultVec.y);
2582 }
2583 return result.toPoint();
2584 });
2585 offscreenUi->resume();
2586 connect(_window, &MainWindow::windowGeometryChanged, [this](const QRect& r){
2587 resizeGL();
2588 });
2589
2590 // This will set up the input plugins UI
2591 _activeInputPlugins.clear();
2592 foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) {
2593 if (KeyboardMouseDevice::NAME == inputPlugin->getName()) {
2594 _keyboardMouseDevice = std::dynamic_pointer_cast<KeyboardMouseDevice>(inputPlugin);
2595 }
2596 if (TouchscreenDevice::NAME == inputPlugin->getName()) {
2597 _touchscreenDevice = std::dynamic_pointer_cast<TouchscreenDevice>(inputPlugin);
2598 }
2599 }
2600 _window->setMenuBar(new Menu());2711 _window->setMenuBar(new Menu());
2712}
2601 2713
2602 auto compositorHelper = DependencyManager::get<CompositorHelper>();2714void Application::onDesktopRootItemCreated(QQuickItem* rootItem) {
2603 connect(compositorHelper.data(), &CompositorHelper::allowMouseCaptureChanged, this, [=] {2715 Stats::show();
2604 if (isHMDMode()) {2716 AvatarInputs::show();
2605 showCursor(compositorHelper->getAllowMouseCapture() ?
2606 Cursor::Manager::lookupIcon(_preferredCursor.get()) :
2607 Cursor::Icon::SYSTEM);
2608 }
2609 });
2610
2611 // Pre-create a couple of Web3D overlays to speed up tablet UI
2612 auto offscreenSurfaceCache = DependencyManager::get<OffscreenQmlSurfaceCache>();
2613 offscreenSurfaceCache->reserve(TabletScriptingInterface::QML, 1);
2614 offscreenSurfaceCache->reserve(Web3DOverlay::QML, 2);
2615}2717}
2616 2718
2617void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) {2719void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) {
@@ -2850,6 +2952,8 @@ void Application::resizeGL() { · 232 unmodified lines
2850 QMutexLocker viewLocker(&_viewMutex);2952 QMutexLocker viewLocker(&_viewMutex);
2851 _myCamera.loadViewFrustum(_viewFrustum);2953 _myCamera.loadViewFrustum(_viewFrustum);
2852 }2954 }
2955
2956 DependencyManager::get<OffscreenUi>()->resize(fromGlm(displayPlugin->getRecommendedUiSize()));
2853}2957}
2854 2958
2855void Application::handleSandboxStatus(QNetworkReply* reply) {2959void Application::handleSandboxStatus(QNetworkReply* reply) {
@@ -2965,6 +3069,14 @@ bool Application::importFromZIP(const QString& filePath) { · 109 unmodified lines
2965 return true;3069 return true;
2966}3070}
2967 3071
3072bool Application::importImage(const QString& urlString) {
3073 qCDebug(interfaceapp) << "An image file has been dropped in";
3074 QString filepath(urlString);
3075 filepath.remove("file:///");
3076 addAssetToWorld(filepath, "", false, false);
3077 return true;
3078}
3079
2968// thread-safe3080// thread-safe
2969void Application::onPresent(quint32 frameCount) {3081void Application::onPresent(quint32 frameCount) {
2970 bool expected = false;3082 bool expected = false;
@@ -4058,7 +4170,7 @@ void Application::idle() { · 1087 unmodified lines
4058 // Bit of a hack since there's no device pixel ratio change event I can find.4170 // Bit of a hack since there's no device pixel ratio change event I can find.
4059 if (offscreenUi->size() != fromGlm(uiSize)) {4171 if (offscreenUi->size() != fromGlm(uiSize)) {
4060 qCDebug(interfaceapp) << "Device pixel ratio changed, triggering resize to " << uiSize;4172 qCDebug(interfaceapp) << "Device pixel ratio changed, triggering resize to " << uiSize;
4061 offscreenUi->resize(fromGlm(uiSize), true);4173 offscreenUi->resize(fromGlm(uiSize));
4062 _offscreenContext->makeCurrent();4174 _offscreenContext->makeCurrent();
4063 }4175 }
4064 }4176 }
@@ -6560,7 +6672,8 @@ void Application::addAssetToWorldSetMapping(QString filePath, QString mapping, Q · 2495 unmodified lines
6560 addAssetToWorldError(filenameFromPath(filePath), errorInfo);6672 addAssetToWorldError(filenameFromPath(filePath), errorInfo);
6561 } else {6673 } else {
6562 // to prevent files that aren't models from being loaded into world automatically6674 // to prevent files that aren't models from being loaded into world automatically
6563 if (filePath.endsWith(".obj") || filePath.endsWith(".fbx")) {6675 if (filePath.endsWith(OBJ_EXTENSION) || filePath.endsWith(FBX_EXTENSION) ||
6676 filePath.endsWith(JPG_EXTENSION) || filePath.endsWith(PNG_EXTENSION)) {
6564 addAssetToWorldAddEntity(filePath, mapping);6677 addAssetToWorldAddEntity(filePath, mapping);
6565 } else {6678 } else {
6566 qCDebug(interfaceapp) << "Zipped contents are not supported entity files";6679 qCDebug(interfaceapp) << "Zipped contents are not supported entity files";
@@ -6577,8 +6690,17 @@ void Application::addAssetToWorldAddEntity(QString filePath, QString mapping) { · 10 unmodified lines
6577 EntityItemProperties properties;6690 EntityItemProperties properties;
6578 properties.setType(EntityTypes::Model);6691 properties.setType(EntityTypes::Model);
6579 properties.setName(mapping.right(mapping.length() - 1));6692 properties.setName(mapping.right(mapping.length() - 1));
6580 properties.setModelURL("atp:" + mapping);6693 if (filePath.endsWith(PNG_EXTENSION) || filePath.endsWith(JPG_EXTENSION)) {
6581 properties.setShapeType(SHAPE_TYPE_SIMPLE_COMPOUND);6694 QJsonObject textures {
6695 {"tex.picture", QString("atp:" + mapping) }
6696 };
6697 properties.setModelURL("https://hifi-content.s3.amazonaws.com/DomainContent/production/default-image-model.fbx");
6698 properties.setTextures(QJsonDocument(textures).toJson(QJsonDocument::Compact));
6699 properties.setShapeType(SHAPE_TYPE_BOX);
6700 } else {
6701 properties.setModelURL("atp:" + mapping);
6702 properties.setShapeType(SHAPE_TYPE_SIMPLE_COMPOUND);
6703 }
6582 properties.setCollisionless(true); // Temporarily set so that doesn't collide with avatar.6704 properties.setCollisionless(true); // Temporarily set so that doesn't collide with avatar.
6583 properties.setVisible(false); // Temporarily set so that don't see at large unresized dimensions.6705 properties.setVisible(false); // Temporarily set so that don't see at large unresized dimensions.
6584 glm::vec3 positionOffset = getMyAvatar()->getWorldOrientation() * (getMyAvatar()->getSensorToWorldScale() * glm::vec3(0.0f, 0.0f, -2.0f));6706 glm::vec3 positionOffset = getMyAvatar()->getWorldOrientation() * (getMyAvatar()->getSensorToWorldScale() * glm::vec3(0.0f, 0.0f, -2.0f));
@@ -7002,10 +7124,10 @@ void Application::loadAvatarBrowser() const { · 417 unmodified lines
7002 DependencyManager::get<HMDScriptingInterface>()->openTablet();7124 DependencyManager::get<HMDScriptingInterface>()->openTablet();
7003}7125}
7004 7126
7005void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRatio) {7127void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRatio, const QString& filename) {
7006 postLambdaEvent([notify, includeAnimated, aspectRatio, this] {7128 postLambdaEvent([notify, includeAnimated, aspectRatio, filename, this] {
7007 // Get a screenshot and save it7129 // Get a screenshot and save it
7008 QString path = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio));7130 QString path = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getScreenshot(aspectRatio), filename);
7009 // If we're not doing an animated snapshot as well...7131 // If we're not doing an animated snapshot as well...
7010 if (!includeAnimated) {7132 if (!includeAnimated) {
7011 // Tell the dependency manager that the capture of the still snapshot has taken place.7133 // Tell the dependency manager that the capture of the still snapshot has taken place.
@@ -7017,9 +7139,9 @@ void Application::takeSnapshot(bool notify, bool includeAnimated, float aspectRa · 5 unmodified lines
7017 });7139 });
7018}7140}
7019 7141
7020void Application::takeSecondaryCameraSnapshot() {7142void Application::takeSecondaryCameraSnapshot(const QString& filename) {
7021 postLambdaEvent([this] {7143 postLambdaEvent([filename, this] {
7022 QString snapshotPath = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getSecondaryCameraScreenshot());7144 QString snapshotPath = Snapshot::saveSnapshot(getActiveDisplayPlugin()->getSecondaryCameraScreenshot(), filename);
7023 emit DependencyManager::get<WindowScriptingInterface>()->stillSnapshotTaken(snapshotPath, true);7145 emit DependencyManager::get<WindowScriptingInterface>()->stillSnapshotTaken(snapshotPath, true);
7024 });7146 });
7025}7147}
@@ -7393,9 +7515,7 @@ void Application::updateDisplayMode() { · 367 unmodified lines
7393 action->setChecked(true);7515 action->setChecked(true);
7394 }7516 }
7395 7517
7396 _offscreenContext->makeCurrent();
7397 offscreenUi->resize(fromGlm(newDisplayPlugin->getRecommendedUiSize()));7518 offscreenUi->resize(fromGlm(newDisplayPlugin->getRecommendedUiSize()));
7398 _offscreenContext->makeCurrent();
7399 getApplicationCompositor().setDisplayPlugin(newDisplayPlugin);7519 getApplicationCompositor().setDisplayPlugin(newDisplayPlugin);
7400 _displayPlugin = newDisplayPlugin;7520 _displayPlugin = newDisplayPlugin;
7401 connect(_displayPlugin.get(), &DisplayPlugin::presented, this, &Application::onPresent, Qt::DirectConnection);7521 connect(_displayPlugin.get(), &DisplayPlugin::presented, this, &Application::onPresent, Qt::DirectConnection);