Showing the changes to interface/src/Application.cpp (1 of 325 files). Show all
Unified · Split
| @@ -194,8 +194,13 @@ · 193 unmodified lines | ||
| 194 | 194 | #include <EntityScriptClient.h> |
| 195 | 195 | #include <ModelScriptingInterface.h> |
| 196 | 196 | |
| 197 | +#include <PickManager.h> | |
| 198 | +#include <PointerManager.h> | |
| 197 | 199 | #include <raypick/RayPickScriptingInterface.h> |
| 198 | 200 | #include <raypick/LaserPointerScriptingInterface.h> |
| 201 | +#include <raypick/PickScriptingInterface.h> | |
| 202 | +#include <raypick/PointerScriptingInterface.h> | |
| 203 | +#include <raypick/MouseRayPick.h> | |
| 199 | 204 | |
| 200 | 205 | #include <FadeEffect.h> |
| 201 | 206 | |
| @@ -203,6 +208,8 @@ · 1 unmodified line | ||
| 203 | 208 | #include "commerce/Wallet.h" |
| 204 | 209 | #include "commerce/QmlCommerce.h" |
| 205 | 210 | |
| 211 | +#include "webbrowser/WebBrowserSuggestionsEngine.h" | |
| 212 | + | |
| 206 | 213 | // On Windows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU |
| 207 | 214 | // FIXME seems to be broken. |
| 208 | 215 | #if defined(Q_OS_WIN) |
| @@ -618,6 +625,12 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { · 409 unmodified lines | ||
| 618 | 625 | DependencyManager::registerInheritance<SpatialParentFinder, InterfaceParentFinder>(); |
| 619 | 626 | |
| 620 | 627 | // Set dependencies |
| 628 | + DependencyManager::set<PickManager>(); | |
| 629 | + DependencyManager::set<PointerManager>(); | |
| 630 | + DependencyManager::set<LaserPointerScriptingInterface>(); | |
| 631 | + DependencyManager::set<RayPickScriptingInterface>(); | |
| 632 | + DependencyManager::set<PointerScriptingInterface>(); | |
| 633 | + DependencyManager::set<PickScriptingInterface>(); | |
| 621 | 634 | DependencyManager::set<Cursor::Manager>(); |
| 622 | 635 | DependencyManager::set<AccountManager>(std::bind(&Application::getUserAgent, qApp)); |
| 623 | 636 | DependencyManager::set<StatTracker>(); |
| @@ -698,9 +711,6 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { · 74 unmodified lines | ||
| 698 | 711 | |
| 699 | 712 | DependencyManager::set<FadeEffect>(); |
| 700 | 713 | |
| 701 | − DependencyManager::set<LaserPointerScriptingInterface>(); | |
| 702 | − DependencyManager::set<RayPickScriptingInterface>(); | |
| 703 | − | |
| 704 | 714 | return previousSessionCrashed; |
| 705 | 715 | } |
| 706 | 716 | |
| @@ -893,7 +903,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 186 unmodified lines | ||
| 893 | 903 | connect(audioIO.data(), &AudioClient::muteEnvironmentRequested, [](glm::vec3 position, float radius) { |
| 894 | 904 | auto audioClient = DependencyManager::get<AudioClient>(); |
| 895 | 905 | auto audioScriptingInterface = DependencyManager::get<AudioScriptingInterface>(); |
| 896 | − auto myAvatarPosition = DependencyManager::get<AvatarManager>()->getMyAvatar()->getPosition(); | |
| 906 | + auto myAvatarPosition = DependencyManager::get<AvatarManager>()->getMyAvatar()->getWorldPosition(); | |
| 897 | 907 | float distance = glm::distance(myAvatarPosition, position); |
| 898 | 908 | bool shouldMute = !audioClient->isMuted() && (distance < radius); |
| 899 | 909 | |
| @@ -966,8 +976,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 66 unmodified lines | ||
| 966 | 976 | auto addressManager = DependencyManager::get<AddressManager>(); |
| 967 | 977 | |
| 968 | 978 | // use our MyAvatar position and quat for address manager path |
| 969 | − addressManager->setPositionGetter([this]{ return getMyAvatar()->getPosition(); }); | |
| 970 | − addressManager->setOrientationGetter([this]{ return getMyAvatar()->getOrientation(); }); | |
| 979 | + addressManager->setPositionGetter([this]{ return getMyAvatar()->getWorldPosition(); }); | |
| 980 | + addressManager->setOrientationGetter([this]{ return getMyAvatar()->getWorldOrientation(); }); | |
| 971 | 981 | |
| 972 | 982 | connect(addressManager.data(), &AddressManager::hostChanged, this, &Application::updateWindowTitle); |
| 973 | 983 | connect(this, &QCoreApplication::aboutToQuit, addressManager.data(), &AddressManager::storeCurrentAddress); |
| @@ -1183,6 +1193,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 209 unmodified lines | ||
| 1183 | 1193 | _entityEditSender.setServerJurisdictions(&_entityServerJurisdictions); |
| 1184 | 1194 | _entityEditSender.setMyAvatar(myAvatar.get()); |
| 1185 | 1195 | |
| 1196 | + // The entity octree will have to know about MyAvatar for the parentJointName import | |
| 1197 | + getEntities()->getTree()->setMyAvatar(myAvatar); | |
| 1198 | + _entityClipboard->setMyAvatar(myAvatar); | |
| 1199 | + | |
| 1186 | 1200 | // For now we're going to set the PPS for outbound packets to be super high, this is |
| 1187 | 1201 | // probably not the right long term solution. But for now, we're going to do this to |
| 1188 | 1202 | // allow you to move an entity around in your hand |
| @@ -1464,13 +1478,15 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 275 unmodified lines | ||
| 1464 | 1478 | |
| 1465 | 1479 | // If the user clicks an an entity, we will check that it's an unlocked web entity, and if so, set the focus to it |
| 1466 | 1480 | auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); |
| 1467 | − connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickDownOnEntity, | |
| 1481 | + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, | |
| 1468 | 1482 | [this](const EntityItemID& entityItemID, const PointerEvent& event) { |
| 1469 | − if (getEntities()->wantsKeyboardFocus(entityItemID)) { | |
| 1470 | − setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); | |
| 1471 | − setKeyboardFocusEntity(entityItemID); | |
| 1472 | − } else { | |
| 1473 | − setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); | |
| 1483 | + if (event.shouldFocus()) { | |
| 1484 | + if (getEntities()->wantsKeyboardFocus(entityItemID)) { | |
| 1485 | + setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); | |
| 1486 | + setKeyboardFocusEntity(entityItemID); | |
| 1487 | + } else { | |
| 1488 | + setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); | |
| 1489 | + } | |
| 1474 | 1490 | } |
| 1475 | 1491 | }); |
| 1476 | 1492 | |
| @@ -1501,7 +1517,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 24 unmodified lines | ||
| 1501 | 1517 | static const QString FAST_STATS_ARG = "--fast-heartbeat"; |
| 1502 | 1518 | static int SEND_STATS_INTERVAL_MS = arguments().indexOf(FAST_STATS_ARG) != -1 ? 1000 : 10000; |
| 1503 | 1519 | |
| 1504 | − static glm::vec3 lastAvatarPosition = myAvatar->getPosition(); | |
| 1520 | + static glm::vec3 lastAvatarPosition = myAvatar->getWorldPosition(); | |
| 1505 | 1521 | static glm::mat4 lastHMDHeadPose = getHMDSensorPose(); |
| 1506 | 1522 | static controller::Pose lastLeftHandPose = myAvatar->getLeftHandPose(); |
| 1507 | 1523 | static controller::Pose lastRightHandPose = myAvatar->getRightHandPose(); |
| @@ -1629,7 +1645,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 121 unmodified lines | ||
| 1629 | 1645 | properties["bytes_downloaded"] = bytesDownloaded; |
| 1630 | 1646 | |
| 1631 | 1647 | auto myAvatar = getMyAvatar(); |
| 1632 | − glm::vec3 avatarPosition = myAvatar->getPosition(); | |
| 1648 | + glm::vec3 avatarPosition = myAvatar->getWorldPosition(); | |
| 1633 | 1649 | properties["avatar_has_moved"] = lastAvatarPosition != avatarPosition; |
| 1634 | 1650 | lastAvatarPosition = avatarPosition; |
| 1635 | 1651 | |
| @@ -1709,7 +1725,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 73 unmodified lines | ||
| 1709 | 1725 | checkNearbyAvatarsTimer->setInterval(CHECK_NEARBY_AVATARS_INTERVAL_MS); // 10 seconds, Qt::CoarseTimer ok |
| 1710 | 1726 | connect(checkNearbyAvatarsTimer, &QTimer::timeout, this, [this]() { |
| 1711 | 1727 | auto avatarManager = DependencyManager::get<AvatarManager>(); |
| 1712 | − int nearbyAvatars = avatarManager->numberOfAvatarsInRange(avatarManager->getMyAvatar()->getPosition(), | |
| 1728 | + int nearbyAvatars = avatarManager->numberOfAvatarsInRange(avatarManager->getMyAvatar()->getWorldPosition(), | |
| 1713 | 1729 | NEARBY_AVATAR_RADIUS_METERS) - 1; |
| 1714 | 1730 | if (nearbyAvatars != lastCountOfNearbyAvatars) { |
| 1715 | 1731 | lastCountOfNearbyAvatars = nearbyAvatars; |
| @@ -1798,25 +1814,35 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 82 unmodified lines | ||
| 1798 | 1814 | |
| 1799 | 1815 | connect(&_myCamera, &Camera::modeUpdated, this, &Application::cameraModeChanged); |
| 1800 | 1816 | |
| 1817 | + DependencyManager::get<PickManager>()->setShouldPickHUDOperator([&]() { return DependencyManager::get<HMDScriptingInterface>()->isHMDMode(); }); | |
| 1818 | + DependencyManager::get<PickManager>()->setCalculatePos2DFromHUDOperator([&](const glm::vec3& intersection) { | |
| 1819 | + const glm::vec2 MARGIN(25.0f); | |
| 1820 | + glm::vec2 maxPos = _controllerScriptingInterface->getViewportDimensions() - MARGIN; | |
| 1821 | + glm::vec2 pos2D = DependencyManager::get<HMDScriptingInterface>()->overlayFromWorldPoint(intersection); | |
| 1822 | + return glm::max(MARGIN, glm::min(pos2D, maxPos)); | |
| 1823 | + }); | |
| 1824 | + | |
| 1801 | 1825 | // Setup the mouse ray pick and related operators |
| 1802 | − DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickID(_rayPickManager.createRayPick( | |
| 1803 | − RayPickFilter(DependencyManager::get<RayPickScriptingInterface>()->PICK_ENTITIES() | DependencyManager::get<RayPickScriptingInterface>()->PICK_INCLUDE_NONCOLLIDABLE()), | |
| 1804 | − 0.0f, true)); | |
| 1805 | − DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickResultOperator([&](QUuid rayPickID) { | |
| 1826 | + DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickID(DependencyManager::get<PickManager>()->addPick(PickQuery::Ray, std::make_shared<MouseRayPick>( | |
| 1827 | + PickFilter(PickScriptingInterface::PICK_ENTITIES() | PickScriptingInterface::PICK_INCLUDE_NONCOLLIDABLE()), 0.0f, true))); | |
| 1828 | + DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickResultOperator([&](unsigned int rayPickID) { | |
| 1806 | 1829 | RayToEntityIntersectionResult entityResult; |
| 1807 | − RayPickResult result = _rayPickManager.getPrevRayPickResult(rayPickID); | |
| 1808 | − entityResult.intersects = result.type != DependencyManager::get<RayPickScriptingInterface>()->INTERSECTED_NONE(); | |
| 1809 | − if (entityResult.intersects) { | |
| 1810 | − entityResult.intersection = result.intersection; | |
| 1811 | − entityResult.distance = result.distance; | |
| 1812 | − entityResult.surfaceNormal = result.surfaceNormal; | |
| 1813 | − entityResult.entityID = result.objectID; | |
| 1814 | − entityResult.entity = DependencyManager::get<EntityTreeRenderer>()->getTree()->findEntityByID(entityResult.entityID); | |
| 1830 | + entityResult.intersects = false; | |
| 1831 | + auto pickResult = DependencyManager::get<PickManager>()->getPrevPickResultTyped<RayPickResult>(rayPickID); | |
| 1832 | + if (pickResult) { | |
| 1833 | + entityResult.intersects = pickResult->type != IntersectionType::NONE; | |
| 1834 | + if (entityResult.intersects) { | |
| 1835 | + entityResult.intersection = pickResult->intersection; | |
| 1836 | + entityResult.distance = pickResult->distance; | |
| 1837 | + entityResult.surfaceNormal = pickResult->surfaceNormal; | |
| 1838 | + entityResult.entityID = pickResult->objectID; | |
| 1839 | + entityResult.entity = DependencyManager::get<EntityTreeRenderer>()->getTree()->findEntityByID(entityResult.entityID); | |
| 1840 | + } | |
| 1815 | 1841 | } |
| 1816 | 1842 | return entityResult; |
| 1817 | 1843 | }); |
| 1818 | − DependencyManager::get<EntityTreeRenderer>()->setSetPrecisionPickingOperator([&](QUuid rayPickID, bool value) { | |
| 1819 | − _rayPickManager.setPrecisionPicking(rayPickID, value); | |
| 1844 | + DependencyManager::get<EntityTreeRenderer>()->setSetPrecisionPickingOperator([&](unsigned int rayPickID, bool value) { | |
| 1845 | + DependencyManager::get<PickManager>()->setPrecisionPicking(rayPickID, value); | |
| 1820 | 1846 | }); |
| 1821 | 1847 | |
| 1822 | 1848 | // Preload Tablet sounds |
| @@ -2258,6 +2284,7 @@ void Application::initializeUi() { · 435 unmodified lines | ||
| 2258 | 2284 | }, callback); |
| 2259 | 2285 | qmlRegisterType<ResourceImageItem>("Hifi", 1, 0, "ResourceImageItem"); |
| 2260 | 2286 | qmlRegisterType<Preference>("Hifi", 1, 0, "Preference"); |
| 2287 | + qmlRegisterType<WebBrowserSuggestionsEngine>("HifiWeb", 1, 0, "WebBrowserSuggestionsEngine"); | |
| 2261 | 2288 | |
| 2262 | 2289 | { |
| 2263 | 2290 | auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>(); |
| @@ -2436,7 +2463,7 @@ void Application::updateCamera(RenderArgs& renderArgs) { · 172 unmodified lines | ||
| 2436 | 2463 | auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); |
| 2437 | 2464 | _myCamera.setOrientation(glm::normalize(glmExtractRotation(hmdWorldMat))); |
| 2438 | 2465 | _myCamera.setPosition(extractTranslation(hmdWorldMat) + |
| 2439 | − myAvatar->getOrientation() * boomOffset); | |
| 2466 | + myAvatar->getWorldOrientation() * boomOffset); | |
| 2440 | 2467 | } |
| 2441 | 2468 | else { |
| 2442 | 2469 | _myCamera.setOrientation(myAvatar->getHead()->getOrientation()); |
| @@ -2446,13 +2473,13 @@ void Application::updateCamera(RenderArgs& renderArgs) { · 3 unmodified lines | ||
| 2446 | 2473 | } |
| 2447 | 2474 | else { |
| 2448 | 2475 | _myCamera.setPosition(myAvatar->getDefaultEyePosition() |
| 2449 | − + myAvatar->getOrientation() * boomOffset); | |
| 2476 | + + myAvatar->getWorldOrientation() * boomOffset); | |
| 2450 | 2477 | } |
| 2451 | 2478 | } |
| 2452 | 2479 | } |
| 2453 | 2480 | else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { |
| 2454 | 2481 | if (isHMDMode()) { |
| 2455 | − auto mirrorBodyOrientation = myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)); | |
| 2482 | + auto mirrorBodyOrientation = myAvatar->getWorldOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)); | |
| 2456 | 2483 | |
| 2457 | 2484 | glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); |
| 2458 | 2485 | // Mirror HMD yaw and roll |
| @@ -2475,11 +2502,11 @@ void Application::updateCamera(RenderArgs& renderArgs) { · 16 unmodified lines | ||
| 2475 | 2502 | + mirrorBodyOrientation * hmdOffset); |
| 2476 | 2503 | } |
| 2477 | 2504 | else { |
| 2478 | − _myCamera.setOrientation(myAvatar->getOrientation() | |
| 2505 | + _myCamera.setOrientation(myAvatar->getWorldOrientation() | |
| 2479 | 2506 | * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); |
| 2480 | 2507 | _myCamera.setPosition(myAvatar->getDefaultEyePosition() |
| 2481 | 2508 | + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) |
| 2482 | − + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * | |
| 2509 | + + (myAvatar->getWorldOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * | |
| 2483 | 2510 | glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); |
| 2484 | 2511 | } |
| 2485 | 2512 | renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; |
| @@ -2489,13 +2516,13 @@ void Application::updateCamera(RenderArgs& renderArgs) { · 3 unmodified lines | ||
| 2489 | 2516 | if (cameraEntity != nullptr) { |
| 2490 | 2517 | if (isHMDMode()) { |
| 2491 | 2518 | glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); |
| 2492 | − _myCamera.setOrientation(cameraEntity->getRotation() * hmdRotation); | |
| 2519 | + _myCamera.setOrientation(cameraEntity->getWorldOrientation() * hmdRotation); | |
| 2493 | 2520 | glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); |
| 2494 | − _myCamera.setPosition(cameraEntity->getPosition() + (hmdRotation * hmdOffset)); | |
| 2521 | + _myCamera.setPosition(cameraEntity->getWorldPosition() + (hmdRotation * hmdOffset)); | |
| 2495 | 2522 | } |
| 2496 | 2523 | else { |
| 2497 | − _myCamera.setOrientation(cameraEntity->getRotation()); | |
| 2498 | − _myCamera.setPosition(cameraEntity->getPosition()); | |
| 2524 | + _myCamera.setOrientation(cameraEntity->getWorldOrientation()); | |
| 2525 | + _myCamera.setPosition(cameraEntity->getWorldPosition()); | |
| 2499 | 2526 | } |
| 2500 | 2527 | } |
| 2501 | 2528 | } |
| @@ -3311,7 +3338,7 @@ void Application::mouseMoveEvent(QMouseEvent* event) { · 809 unmodified lines | ||
| 3311 | 3338 | |
| 3312 | 3339 | auto offscreenUi = DependencyManager::get<OffscreenUi>(); |
| 3313 | 3340 | auto eventPosition = compositor.getMouseEventPosition(event); |
| 3314 | − QPointF transformedPos = offscreenUi->mapToVirtualScreen(eventPosition, _glWidget); | |
| 3341 | + QPointF transformedPos = offscreenUi->mapToVirtualScreen(eventPosition); | |
| 3315 | 3342 | auto button = event->button(); |
| 3316 | 3343 | auto buttons = event->buttons(); |
| 3317 | 3344 | // Determine if the ReticleClick Action is 1 and if so, fake include the LeftMouseButton |
| @@ -3357,7 +3384,7 @@ void Application::mousePressEvent(QMouseEvent* event) { · 39 unmodified lines | ||
| 3357 | 3384 | offscreenUi->unfocusWindows(); |
| 3358 | 3385 | |
| 3359 | 3386 | auto eventPosition = getApplicationCompositor().getMouseEventPosition(event); |
| 3360 | − QPointF transformedPos = offscreenUi->mapToVirtualScreen(eventPosition, _glWidget); | |
| 3387 | + QPointF transformedPos = offscreenUi->mapToVirtualScreen(eventPosition); | |
| 3361 | 3388 | QMouseEvent mappedEvent(event->type(), |
| 3362 | 3389 | transformedPos, |
| 3363 | 3390 | event->screenPos(), event->button(), |
| @@ -3387,7 +3414,7 @@ void Application::mousePressEvent(QMouseEvent* event) { · 23 unmodified lines | ||
| 3387 | 3414 | void Application::mouseDoublePressEvent(QMouseEvent* event) { |
| 3388 | 3415 | auto offscreenUi = DependencyManager::get<OffscreenUi>(); |
| 3389 | 3416 | auto eventPosition = getApplicationCompositor().getMouseEventPosition(event); |
| 3390 | − QPointF transformedPos = offscreenUi->mapToVirtualScreen(eventPosition, _glWidget); | |
| 3417 | + QPointF transformedPos = offscreenUi->mapToVirtualScreen(eventPosition); | |
| 3391 | 3418 | QMouseEvent mappedEvent(event->type(), |
| 3392 | 3419 | transformedPos, |
| 3393 | 3420 | event->screenPos(), event->button(), |
| @@ -3413,7 +3440,7 @@ void Application::mouseReleaseEvent(QMouseEvent* event) { · 19 unmodified lines | ||
| 3413 | 3440 | |
| 3414 | 3441 | auto offscreenUi = DependencyManager::get<OffscreenUi>(); |
| 3415 | 3442 | auto eventPosition = getApplicationCompositor().getMouseEventPosition(event); |
| 3416 | − QPointF transformedPos = offscreenUi->mapToVirtualScreen(eventPosition, _glWidget); | |
| 3443 | + QPointF transformedPos = offscreenUi->mapToVirtualScreen(eventPosition); | |
| 3417 | 3444 | QMouseEvent mappedEvent(event->type(), |
| 3418 | 3445 | transformedPos, |
| 3419 | 3446 | event->screenPos(), event->button(), |
| @@ -3906,16 +3933,16 @@ void Application::idle() { · 486 unmodified lines | ||
| 3906 | 3933 | if (!_keyboardFocusedEntity.get().isInvalidID()) { |
| 3907 | 3934 | auto entity = getEntities()->getTree()->findEntityByID(_keyboardFocusedEntity.get()); |
| 3908 | 3935 | if (entity && _keyboardFocusHighlight) { |
| 3909 | − _keyboardFocusHighlight->setRotation(entity->getRotation()); | |
| 3910 | − _keyboardFocusHighlight->setPosition(entity->getPosition()); | |
| 3936 | + _keyboardFocusHighlight->setWorldOrientation(entity->getWorldOrientation()); | |
| 3937 | + _keyboardFocusHighlight->setWorldPosition(entity->getWorldPosition()); | |
| 3911 | 3938 | } |
| 3912 | 3939 | } else { |
| 3913 | 3940 | // Only Web overlays can have focus. |
| 3914 | 3941 | auto overlay = |
| 3915 | 3942 | std::dynamic_pointer_cast<Web3DOverlay>(getOverlays().getOverlay(_keyboardFocusedOverlay.get())); |
| 3916 | 3943 | if (overlay && _keyboardFocusHighlight) { |
| 3917 | − _keyboardFocusHighlight->setRotation(overlay->getRotation()); | |
| 3918 | − _keyboardFocusHighlight->setPosition(overlay->getPosition()); | |
| 3944 | + _keyboardFocusHighlight->setWorldOrientation(overlay->getWorldOrientation()); | |
| 3945 | + _keyboardFocusHighlight->setWorldPosition(overlay->getWorldPosition()); | |
| 3919 | 3946 | } |
| 3920 | 3947 | } |
| 3921 | 3948 | } |
| @@ -4031,6 +4058,7 @@ bool Application::exportEntities(const QString& filename, · 109 unmodified lines | ||
| 4031 | 4058 | |
| 4032 | 4059 | auto entityTree = getEntities()->getTree(); |
| 4033 | 4060 | auto exportTree = std::make_shared<EntityTree>(); |
| 4061 | + exportTree->setMyAvatar(getMyAvatar()); | |
| 4034 | 4062 | exportTree->createRootElement(); |
| 4035 | 4063 | glm::vec3 root(TREE_SCALE, TREE_SCALE, TREE_SCALE); |
| 4036 | 4064 | bool success = true; |
| @@ -4049,7 +4077,7 @@ bool Application::exportEntities(const QString& filename, · 12 unmodified lines | ||
| 4049 | 4077 | !entityIDs.contains(parentID) || |
| 4050 | 4078 | !entityTree->findEntityByEntityItemID(parentID))) { |
| 4051 | 4079 | // If parent wasn't selected, we want absolute position, which isn't in properties. |
| 4052 | − auto position = entityItem->getPosition(); | |
| 4080 | + auto position = entityItem->getWorldPosition(); | |
| 4053 | 4081 | root.x = glm::min(root.x, position.x); |
| 4054 | 4082 | root.y = glm::min(root.y, position.y); |
| 4055 | 4083 | root.z = glm::min(root.z, position.z); |
| @@ -4252,7 +4280,7 @@ void Application::init() { · 196 unmodified lines | ||
| 4252 | 4280 | return 0.0f; |
| 4253 | 4281 | } |
| 4254 | 4282 | |
| 4255 | − auto distance = glm::distance(getMyAvatar()->getPosition(), item.getPosition()); | |
| 4283 | + auto distance = glm::distance(getMyAvatar()->getWorldPosition(), item.getWorldPosition()); | |
| 4256 | 4284 | return atan2(maxSize, distance); |
| 4257 | 4285 | }); |
| 4258 | 4286 | |
| @@ -4329,7 +4357,7 @@ void Application::updateMyAvatarLookAtPosition() { · 70 unmodified lines | ||
| 4329 | 4357 | // TODO -- this code is probably wrong, getHeadPose() returns something in sensor frame, not avatar |
| 4330 | 4358 | glm::mat4 headPose = getActiveDisplayPlugin()->getHeadPose(); |
| 4331 | 4359 | glm::quat hmdRotation = glm::quat_cast(headPose); |
| 4332 | − lookAtSpot = _myCamera.getPosition() + myAvatar->getOrientation() * (hmdRotation * lookAtPosition); | |
| 4360 | + lookAtSpot = _myCamera.getPosition() + myAvatar->getWorldOrientation() * (hmdRotation * lookAtPosition); | |
| 4333 | 4361 | } else { |
| 4334 | 4362 | lookAtSpot = myAvatar->getHead()->getEyePosition() |
| 4335 | 4363 | + (myAvatar->getHead()->getFinalOrientationInWorldFrame() * lookAtPosition); |
| @@ -4558,8 +4586,8 @@ void Application::setKeyboardFocusHighlight(const glm::vec3& position, const glm · 222 unmodified lines | ||
| 4558 | 4586 | } |
| 4559 | 4587 | |
| 4560 | 4588 | // Position focus |
| 4561 | − _keyboardFocusHighlight->setRotation(rotation); | |
| 4562 | − _keyboardFocusHighlight->setPosition(position); | |
| 4589 | + _keyboardFocusHighlight->setWorldOrientation(rotation); | |
| 4590 | + _keyboardFocusHighlight->setWorldPosition(position); | |
| 4563 | 4591 | _keyboardFocusHighlight->setDimensions(dimensions); |
| 4564 | 4592 | _keyboardFocusHighlight->setVisible(true); |
| 4565 | 4593 | } |
| @@ -4596,7 +4624,7 @@ void Application::setKeyboardFocusEntity(const EntityItemID& entityItemID) { · 30 unmodified lines | ||
| 4596 | 4624 | } |
| 4597 | 4625 | _lastAcceptedKeyPress = usecTimestampNow(); |
| 4598 | 4626 | |
| 4599 | − setKeyboardFocusHighlight(entity->getPosition(), entity->getRotation(), | |
| 4627 | + setKeyboardFocusHighlight(entity->getWorldPosition(), entity->getWorldOrientation(), | |
| 4600 | 4628 | entity->getDimensions() * FOCUS_HIGHLIGHT_EXPANSION_FACTOR); |
| 4601 | 4629 | } |
| 4602 | 4630 | } |
| @@ -4633,7 +4661,7 @@ void Application::setKeyboardFocusOverlay(const OverlayID& overlayID) { · 30 unmodified lines | ||
| 4633 | 4661 | if (overlay->getProperty("showKeyboardFocusHighlight").toBool()) { |
| 4634 | 4662 | auto size = overlay->getSize() * FOCUS_HIGHLIGHT_EXPANSION_FACTOR; |
| 4635 | 4663 | const float OVERLAY_DEPTH = 0.0105f; |
| 4636 | − setKeyboardFocusHighlight(overlay->getPosition(), overlay->getRotation(), glm::vec3(size.x, size.y, OVERLAY_DEPTH)); | |
| 4664 | + setKeyboardFocusHighlight(overlay->getWorldPosition(), overlay->getWorldOrientation(), glm::vec3(size.x, size.y, OVERLAY_DEPTH)); | |
| 4637 | 4665 | } else if (_keyboardFocusHighlight) { |
| 4638 | 4666 | _keyboardFocusHighlight->setVisible(false); |
| 4639 | 4667 | } |
| @@ -4725,7 +4753,7 @@ void Application::update(float deltaTime) { · 85 unmodified lines | ||
| 4725 | 4753 | |
| 4726 | 4754 | controller::InputCalibrationData calibrationData = { |
| 4727 | 4755 | myAvatar->getSensorToWorldMatrix(), |
| 4728 | − createMatFromQuatAndPos(myAvatar->getOrientation(), myAvatar->getPosition()), | |
| 4756 | + createMatFromQuatAndPos(myAvatar->getWorldOrientation(), myAvatar->getWorldPosition()), | |
| 4729 | 4757 | myAvatar->getHMDSensorMatrix(), |
| 4730 | 4758 | myAvatar->getCenterEyeCalibrationMat(), |
| 4731 | 4759 | myAvatar->getHeadCalibrationMat(), |
| @@ -4835,7 +4863,7 @@ void Application::update(float deltaTime) { · 103 unmodified lines | ||
| 4835 | 4863 | }; |
| 4836 | 4864 | |
| 4837 | 4865 | // copy controller poses from userInputMapper to myAvatar. |
| 4838 | − glm::mat4 myAvatarMatrix = createMatFromQuatAndPos(myAvatar->getOrientation(), myAvatar->getPosition()); | |
| 4866 | + glm::mat4 myAvatarMatrix = createMatFromQuatAndPos(myAvatar->getWorldOrientation(), myAvatar->getWorldPosition()); | |
| 4839 | 4867 | glm::mat4 worldToSensorMatrix = glm::inverse(myAvatar->getSensorToWorldMatrix()); |
| 4840 | 4868 | glm::mat4 avatarToSensorMatrix = worldToSensorMatrix * myAvatarMatrix; |
| 4841 | 4869 | for (auto& action : avatarControllerActions) { |
| @@ -4975,13 +5003,13 @@ void Application::update(float deltaTime) { · 133 unmodified lines | ||
| 4975 | 5003 | |
| 4976 | 5004 | // TODO: break these out into distinct perfTimers when they prove interesting |
| 4977 | 5005 | { |
| 4978 | − PROFILE_RANGE(app, "RayPickManager"); | |
| 4979 | − _rayPickManager.update(); | |
| 5006 | + PROFILE_RANGE(app, "PickManager"); | |
| 5007 | + DependencyManager::get<PickManager>()->update(); | |
| 4980 | 5008 | } |
| 4981 | 5009 | |
| 4982 | 5010 | { |
| 4983 | − PROFILE_RANGE(app, "LaserPointerManager"); | |
| 4984 | − _laserPointerManager.update(); | |
| 5011 | + PROFILE_RANGE(app, "PointerManager"); | |
| 5012 | + DependencyManager::get<PointerManager>()->update(); | |
| 4985 | 5013 | } |
| 4986 | 5014 | |
| 4987 | 5015 | { |
| @@ -5451,7 +5479,7 @@ std::shared_ptr<MyAvatar> Application::getMyAvatar() const { · 463 unmodified lines | ||
| 5451 | 5479 | } |
| 5452 | 5480 | |
| 5453 | 5481 | glm::vec3 Application::getAvatarPosition() const { |
| 5454 | − return getMyAvatar()->getPosition(); | |
| 5482 | + return getMyAvatar()->getWorldPosition(); | |
| 5455 | 5483 | } |
| 5456 | 5484 | |
| 5457 | 5485 | void Application::copyViewFrustum(ViewFrustum& viewOut) const { |
| @@ -5535,6 +5563,8 @@ void Application::clearDomainOctreeDetails() { · 77 unmodified lines | ||
| 5535 | 5563 | DependencyManager::get<ModelCache>()->clearUnusedResources(); |
| 5536 | 5564 | DependencyManager::get<SoundCache>()->clearUnusedResources(); |
| 5537 | 5565 | DependencyManager::get<TextureCache>()->clearUnusedResources(); |
| 5566 | + | |
| 5567 | + getMyAvatar()->setAvatarEntityDataChanged(true); | |
| 5538 | 5568 | } |
| 5539 | 5569 | |
| 5540 | 5570 | void Application::clearDomainAvatars() { |
| @@ -5664,7 +5694,7 @@ bool Application::nearbyEntitiesAreReadyForPhysics() { · 123 unmodified lines | ||
| 5664 | 5694 | // whose bounding boxes cannot be computed (it is too loose for our purposes here). Instead we manufacture |
| 5665 | 5695 | // custom filters and use the general-purpose EntityTree::findEntities(filter, ...) |
| 5666 | 5696 | QVector<EntityItemPointer> entities; |
| 5667 | − AABox avatarBox(getMyAvatar()->getPosition() - glm::vec3(PHYSICS_READY_RANGE), glm::vec3(2 * PHYSICS_READY_RANGE)); | |
| 5697 | + AABox avatarBox(getMyAvatar()->getWorldPosition() - glm::vec3(PHYSICS_READY_RANGE), glm::vec3(2 * PHYSICS_READY_RANGE)); | |
| 5668 | 5698 | // create two functions that use avatarBox (entityScan and elementScan), the second calls the first |
| 5669 | 5699 | std::function<bool (EntityItemPointer&)> entityScan = [=](EntityItemPointer& entity) { |
| 5670 | 5700 | if (entity->shouldBePhysical()) { |
| @@ -5866,6 +5896,8 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe · 195 unmodified lines | ||
| 5866 | 5896 | |
| 5867 | 5897 | scriptEngine->registerGlobalObject("RayPick", DependencyManager::get<RayPickScriptingInterface>().data()); |
| 5868 | 5898 | scriptEngine->registerGlobalObject("LaserPointers", DependencyManager::get<LaserPointerScriptingInterface>().data()); |
| 5899 | + scriptEngine->registerGlobalObject("Picks", DependencyManager::get<PickScriptingInterface>().data()); | |
| 5900 | + scriptEngine->registerGlobalObject("Pointers", DependencyManager::get<PointerScriptingInterface>().data()); | |
| 5869 | 5901 | |
| 5870 | 5902 | // Caches |
| 5871 | 5903 | scriptEngine->registerGlobalObject("AnimationCache", DependencyManager::get<AnimationCache>().data()); |
| @@ -5923,6 +5955,8 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe · 51 unmodified lines | ||
| 5923 | 5955 | |
| 5924 | 5956 | qScriptRegisterMetaType(scriptEngine.data(), OverlayIDtoScriptValue, OverlayIDfromScriptValue); |
| 5925 | 5957 | |
| 5958 | + DependencyManager::get<PickScriptingInterface>()->registerMetaTypes(scriptEngine.data()); | |
| 5959 | + | |
| 5926 | 5960 | // connect this script engines printedMessage signal to the global ScriptEngines these various messages |
| 5927 | 5961 | connect(scriptEngine.data(), &ScriptEngine::printedMessage, |
| 5928 | 5962 | DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onPrintedMessage); |
| @@ -6164,46 +6198,60 @@ bool Application::askToReplaceDomainContent(const QString& url) { · 235 unmodified lines | ||
| 6164 | 6198 | "and restoring content, visit the documentation page at: ", MAX_CHARACTERS_PER_LINE) + |
| 6165 | 6199 | "\nhttps://docs.highfidelity.com/create-and-explore/start-working-in-your-sandbox/restoring-sandbox-content"; |
| 6166 | 6200 | |
| 6167 | − bool agreeToReplaceContent = false; // assume false | |
| 6168 | − agreeToReplaceContent = QMessageBox::Yes == OffscreenUi::question("Are you sure you want to replace this domain's content set?", | |
| 6169 | − infoText, QMessageBox::Yes | QMessageBox::No, QMessageBox::No); | |
| 6170 | − | |
| 6171 | − if (agreeToReplaceContent) { | |
| 6172 | − // Given confirmation, send request to domain server to replace content | |
| 6173 | − qCDebug(interfaceapp) << "Attempting to replace domain content: " << url; | |
| 6174 | − QByteArray urlData(url.toUtf8()); | |
| 6175 | − auto limitedNodeList = DependencyManager::get<LimitedNodeList>(); | |
| 6176 | − limitedNodeList->eachMatchingNode([](const SharedNodePointer& node) { | |
| 6177 | − return node->getType() == NodeType::EntityServer && node->getActiveSocket(); | |
| 6178 | − }, [&urlData, limitedNodeList](const SharedNodePointer& octreeNode) { | |
| 6179 | − auto octreeFilePacket = NLPacket::create(PacketType::OctreeFileReplacementFromUrl, urlData.size(), true); | |
| 6180 | − octreeFilePacket->write(urlData); | |
| 6181 | − limitedNodeList->sendPacket(std::move(octreeFilePacket), *octreeNode); | |
| 6182 | − }); | |
| 6183 | − auto addressManager = DependencyManager::get<AddressManager>(); | |
| 6184 | − addressManager->handleLookupString(DOMAIN_SPAWNING_POINT); | |
| 6185 | − QString newHomeAddress = addressManager->getHost() + DOMAIN_SPAWNING_POINT; | |
| 6186 | − qCDebug(interfaceapp) << "Setting new home bookmark to: " << newHomeAddress; | |
| 6187 | − DependencyManager::get<LocationBookmarks>()->setHomeLocationToAddress(newHomeAddress); | |
| 6188 | − methodDetails = "SuccessfulRequestToReplaceContent"; | |
| 6189 | − } else { | |
| 6190 | − methodDetails = "UserDeclinedToReplaceContent"; | |
| 6191 | − } | |
| 6201 | + ModalDialogListener* dig = OffscreenUi::asyncQuestion("Are you sure you want to replace this domain's content set?", | |
| 6202 | + infoText, QMessageBox::Yes | QMessageBox::No, QMessageBox::No); | |
| 6203 | + | |
| 6204 | + QObject::connect(dig, &ModalDialogListener::response, this, [=] (QVariant answer) { | |
| 6205 | + QString details; | |
| 6206 | + if (static_cast<QMessageBox::StandardButton>(answer.toInt()) == QMessageBox::Yes) { | |
| 6207 | + // Given confirmation, send request to domain server to replace content | |
| 6208 | + qCDebug(interfaceapp) << "Attempting to replace domain content: " << url; | |
| 6209 | + QByteArray urlData(url.toUtf8()); | |
| 6210 | + auto limitedNodeList = DependencyManager::get<LimitedNodeList>(); | |
| 6211 | + limitedNodeList->eachMatchingNode([](const SharedNodePointer& node) { | |
| 6212 | + return node->getType() == NodeType::EntityServer && node->getActiveSocket(); | |
| 6213 | + }, [&urlData, limitedNodeList](const SharedNodePointer& octreeNode) { | |
| 6214 | + auto octreeFilePacket = NLPacket::create(PacketType::OctreeFileReplacementFromUrl, urlData.size(), true); | |
| 6215 | + octreeFilePacket->write(urlData); | |
| 6216 | + limitedNodeList->sendPacket(std::move(octreeFilePacket), *octreeNode); | |
| 6217 | + }); | |
| 6218 | + auto addressManager = DependencyManager::get<AddressManager>(); | |
| 6219 | + addressManager->handleLookupString(DOMAIN_SPAWNING_POINT); | |
| 6220 | + QString newHomeAddress = addressManager->getHost() + DOMAIN_SPAWNING_POINT; | |
| 6221 | + qCDebug(interfaceapp) << "Setting new home bookmark to: " << newHomeAddress; | |
| 6222 | + DependencyManager::get<LocationBookmarks>()->setHomeLocationToAddress(newHomeAddress); | |
| 6223 | + details = "SuccessfulRequestToReplaceContent"; | |
| 6224 | + } else { | |
| 6225 | + details = "UserDeclinedToReplaceContent"; | |
| 6226 | + } | |
| 6227 | + QJsonObject messageProperties = { | |
| 6228 | + { "status", details }, | |
| 6229 | + { "content_set_url", url } | |
| 6230 | + }; | |
| 6231 | + UserActivityLogger::getInstance().logAction("replace_domain_content", messageProperties); | |
| 6232 | + QObject::disconnect(dig, &ModalDialogListener::response, this, nullptr); | |
| 6233 | + }); | |
| 6192 | 6234 | } else { |
| 6193 | 6235 | methodDetails = "ContentSetDidNotOriginateFromMarketplace"; |
| 6236 | + QJsonObject messageProperties = { | |
| 6237 | + { "status", methodDetails }, | |
| 6238 | + { "content_set_url", url } | |
| 6239 | + }; | |
| 6240 | + UserActivityLogger::getInstance().logAction("replace_domain_content", messageProperties); | |
| 6194 | 6241 | } |
| 6195 | 6242 | } else { |
| 6196 | 6243 | methodDetails = "UserDoesNotHavePermissionToReplaceContent"; |
| 6197 | 6244 | static const QString warningMessage = simpleWordWrap("The domain owner must enable 'Replace Content' " |
| 6198 | 6245 | "permissions for you in this domain's server settings before you can continue.", MAX_CHARACTERS_PER_LINE); |
| 6199 | − OffscreenUi::warning("You do not have permissions to replace domain content", warningMessage, | |
| 6246 | + OffscreenUi::asyncWarning("You do not have permissions to replace domain content", warningMessage, | |
| 6200 | 6247 | QMessageBox::Ok, QMessageBox::Ok); |
| 6248 | + | |
| 6249 | + QJsonObject messageProperties = { | |
| 6250 | + { "status", methodDetails }, | |
| 6251 | + { "content_set_url", url } | |
| 6252 | + }; | |
| 6253 | + UserActivityLogger::getInstance().logAction("replace_domain_content", messageProperties); | |
| 6201 | 6254 | } |
| 6202 | − QJsonObject messageProperties = { | |
| 6203 | − { "status", methodDetails }, | |
| 6204 | − { "content_set_url", url } | |
| 6205 | − }; | |
| 6206 | − UserActivityLogger::getInstance().logAction("replace_domain_content", messageProperties); | |
| 6207 | 6255 | return true; |
| 6208 | 6256 | } |
| 6209 | 6257 | |
| @@ -6363,20 +6411,14 @@ void Application::addAssetToWorldUnzipFailure(QString filePath) { · 153 unmodified lines | ||
| 6363 | 6411 | addAssetToWorldError(filename, "Couldn't unzip file " + filename + "."); |
| 6364 | 6412 | } |
| 6365 | 6413 | |
| 6366 | −void Application::addAssetToWorld(QString filePath, QString zipFile, bool isZip, bool isBlocks) { | |
| 6414 | +void Application::addAssetToWorld(QString path, QString zipFile, bool isZip, bool isBlocks) { | |
| 6367 | 6415 | // Automatically upload and add asset to world as an alternative manual process initiated by showAssetServerWidget(). |
| 6368 | 6416 | QString mapping; |
| 6369 | − QString path = filePath; | |
| 6370 | 6417 | QString filename = filenameFromPath(path); |
| 6371 | − if (isZip) { | |
| 6372 | − QString assetFolder = zipFile.section("/", -1); | |
| 6373 | − assetFolder.remove(".zip"); | |
| 6374 | − mapping = "/" + assetFolder + "/" + filename; | |
| 6375 | − } else if (isBlocks) { | |
| 6376 | − qCDebug(interfaceapp) << "Path to asset folder: " << zipFile; | |
| 6377 | − QString assetFolder = zipFile.section('/', -1); | |
| 6378 | − assetFolder.remove(".zip?noDownload=false"); | |
| 6379 | − mapping = "/" + assetFolder + "/" + filename; | |
| 6418 | + if (isZip || isBlocks) { | |
| 6419 | + QString assetName = zipFile.section("/", -1).remove(QRegExp("[.]zip(.*)$")); | |
| 6420 | + QString assetFolder = path.section("model_repo/", -1); | |
| 6421 | + mapping = "/" + assetName + "/" + assetFolder; | |
| 6380 | 6422 | } else { |
| 6381 | 6423 | mapping = "/" + filename; |
| 6382 | 6424 | } |
| @@ -6482,9 +6524,9 @@ void Application::addAssetToWorldAddEntity(QString filePath, QString mapping) { · 99 unmodified lines | ||
| 6482 | 6524 | properties.setShapeType(SHAPE_TYPE_SIMPLE_COMPOUND); |
| 6483 | 6525 | properties.setCollisionless(true); // Temporarily set so that doesn't collide with avatar. |
| 6484 | 6526 | properties.setVisible(false); // Temporarily set so that don't see at large unresized dimensions. |
| 6485 | − glm::vec3 positionOffset = getMyAvatar()->getOrientation() * (getMyAvatar()->getSensorToWorldScale() * glm::vec3(0.0f, 0.0f, -2.0f)); | |
| 6486 | − properties.setPosition(getMyAvatar()->getPosition() + positionOffset); | |
| 6487 | − properties.setRotation(getMyAvatar()->getOrientation()); | |
| 6527 | + glm::vec3 positionOffset = getMyAvatar()->getWorldOrientation() * (getMyAvatar()->getSensorToWorldScale() * glm::vec3(0.0f, 0.0f, -2.0f)); | |
| 6528 | + properties.setPosition(getMyAvatar()->getWorldPosition() + positionOffset); | |
| 6529 | + properties.setRotation(getMyAvatar()->getWorldOrientation()); | |
| 6488 | 6530 | properties.setGravity(glm::vec3(0.0f, 0.0f, 0.0f)); |
| 6489 | 6531 | auto entityID = DependencyManager::get<EntityScriptingInterface>()->addEntity(properties); |
| 6490 | 6532 | |
| @@ -6762,8 +6804,10 @@ void Application::handleUnzip(QString zipFile, QStringList unzipFile, bool autoA · 271 unmodified lines | ||
| 6762 | 6804 | if (autoAdd) { |
| 6763 | 6805 | if (!unzipFile.isEmpty()) { |
| 6764 | 6806 | for (int i = 0; i < unzipFile.length(); i++) { |
| 6765 | − qCDebug(interfaceapp) << "Preparing file for asset server: " << unzipFile.at(i); | |
| 6766 | − addAssetToWorld(unzipFile.at(i), zipFile, isZip, isBlocks); | |
| 6807 | + if (QFileInfo(unzipFile.at(i)).isFile()) { | |
| 6808 | + qCDebug(interfaceapp) << "Preparing file for asset server: " << unzipFile.at(i); | |
| 6809 | + addAssetToWorld(unzipFile.at(i), zipFile, isZip, isBlocks); | |
| 6810 | + } | |
| 6767 | 6811 | } |
| 6768 | 6812 | } else { |
| 6769 | 6813 | addAssetToWorldUnzipFailure(zipFile); |
| @@ -7066,11 +7110,11 @@ QRect Application::getRecommendedHUDRect() const { · 296 unmodified lines | ||
| 7066 | 7110 | return result; |
| 7067 | 7111 | } |
| 7068 | 7112 | |
| 7069 | −QSize Application::getDeviceSize() const { | |
| 7113 | +glm::vec2 Application::getDeviceSize() const { | |
| 7070 | 7114 | static const int MIN_SIZE = 1; |
| 7071 | − QSize result(MIN_SIZE, MIN_SIZE); | |
| 7115 | + glm::vec2 result(MIN_SIZE); | |
| 7072 | 7116 | if (_displayPlugin) { |
| 7073 | − result = fromGlm(getActiveDisplayPlugin()->getRecommendedRenderSize()); | |
| 7117 | + result = getActiveDisplayPlugin()->getRecommendedRenderSize(); | |
| 7074 | 7118 | } |
| 7075 | 7119 | return result; |
| 7076 | 7120 | } |
| @@ -7089,10 +7133,6 @@ bool Application::hasFocus() const { · 12 unmodified lines | ||
| 7089 | 7133 | return (QApplication::activeWindow() != nullptr); |
| 7090 | 7134 | } |
| 7091 | 7135 | |
| 7092 | −glm::vec2 Application::getViewportDimensions() const { | |
| 7093 | − return toGlm(getDeviceSize()); | |
| 7094 | −} | |
| 7095 | − | |
| 7096 | 7136 | void Application::setMaxOctreePacketsPerSecond(int maxOctreePPS) { |
| 7097 | 7137 | if (maxOctreePPS != _maxOctreePPS) { |
| 7098 | 7138 | _maxOctreePPS = maxOctreePPS; |
| @@ -7121,6 +7161,7 @@ DisplayPluginPointer Application::getActiveDisplayPlugin() const { · 22 unmodified lines | ||
| 7121 | 7161 | return _displayPlugin; |
| 7122 | 7162 | } |
| 7123 | 7163 | |
| 7164 | +static const char* EXCLUSION_GROUP_KEY = "exclusionGroup"; | |
| 7124 | 7165 | |
| 7125 | 7166 | static void addDisplayPluginToMenu(DisplayPluginPointer displayPlugin, bool active = false) { |
| 7126 | 7167 | auto menu = Menu::getInstance(); |
| @@ -7156,6 +7197,8 @@ static void addDisplayPluginToMenu(DisplayPluginPointer displayPlugin, bool acti · 29 unmodified lines | ||
| 7156 | 7197 | action->setCheckable(true); |
| 7157 | 7198 | action->setChecked(active); |
| 7158 | 7199 | displayPluginGroup->addAction(action); |
| 7200 | + | |
| 7201 | + action->setProperty(EXCLUSION_GROUP_KEY, QVariant::fromValue(displayPluginGroup)); | |
| 7159 | 7202 | Q_ASSERT(menu->menuItemExists(MenuOption::OutputMenu, name)); |
| 7160 | 7203 | } |
| 7161 | 7204 | |