Showing the changes to interface/src/Application.cpp (1 of 603 files). Show all
Unified · Split
| @@ -120,6 +120,7 @@ · 119 unmodified lines | ||
| 120 | 120 | #include <SceneScriptingInterface.h> |
| 121 | 121 | #include <ScriptEngines.h> |
| 122 | 122 | #include <ScriptCache.h> |
| 123 | +#include <ShapeEntityItem.h> | |
| 123 | 124 | #include <SoundCache.h> |
| 124 | 125 | #include <ui/TabletScriptingInterface.h> |
| 125 | 126 | #include <ui/ToolbarScriptingInterface.h> |
| @@ -192,8 +193,13 @@ · 66 unmodified lines | ||
| 192 | 193 | #include <EntityScriptClient.h> |
| 193 | 194 | #include <ModelScriptingInterface.h> |
| 194 | 195 | |
| 196 | +#include <PickManager.h> | |
| 197 | +#include <PointerManager.h> | |
| 195 | 198 | #include <raypick/RayPickScriptingInterface.h> |
| 196 | 199 | #include <raypick/LaserPointerScriptingInterface.h> |
| 200 | +#include <raypick/PickScriptingInterface.h> | |
| 201 | +#include <raypick/PointerScriptingInterface.h> | |
| 202 | +#include <raypick/MouseRayPick.h> | |
| 197 | 203 | |
| 198 | 204 | #include <FadeEffect.h> |
| 199 | 205 | |
| @@ -201,6 +207,8 @@ · 1 unmodified line | ||
| 201 | 207 | #include "commerce/Wallet.h" |
| 202 | 208 | #include "commerce/QmlCommerce.h" |
| 203 | 209 | |
| 210 | +#include "webbrowser/WebBrowserSuggestionsEngine.h" | |
| 211 | + | |
| 204 | 212 | // On Windows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU |
| 205 | 213 | // FIXME seems to be broken. |
| 206 | 214 | #if defined(Q_OS_WIN) |
| @@ -616,6 +624,12 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { · 409 unmodified lines | ||
| 616 | 624 | DependencyManager::registerInheritance<SpatialParentFinder, InterfaceParentFinder>(); |
| 617 | 625 | |
| 618 | 626 | // Set dependencies |
| 627 | + DependencyManager::set<PickManager>(); | |
| 628 | + DependencyManager::set<PointerManager>(); | |
| 629 | + DependencyManager::set<LaserPointerScriptingInterface>(); | |
| 630 | + DependencyManager::set<RayPickScriptingInterface>(); | |
| 631 | + DependencyManager::set<PointerScriptingInterface>(); | |
| 632 | + DependencyManager::set<PickScriptingInterface>(); | |
| 619 | 633 | DependencyManager::set<Cursor::Manager>(); |
| 620 | 634 | DependencyManager::set<AccountManager>(std::bind(&Application::getUserAgent, qApp)); |
| 621 | 635 | DependencyManager::set<StatTracker>(); |
| @@ -690,16 +704,12 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { · 68 unmodified lines | ||
| 690 | 704 | DependencyManager::set<CloseEventSender>(); |
| 691 | 705 | DependencyManager::set<ResourceManager>(); |
| 692 | 706 | DependencyManager::set<SelectionScriptingInterface>(); |
| 693 | − DependencyManager::set<ContextOverlayInterface>(); | |
| 694 | 707 | DependencyManager::set<Ledger>(); |
| 695 | 708 | DependencyManager::set<Wallet>(); |
| 696 | 709 | DependencyManager::set<WalletScriptingInterface>(); |
| 697 | 710 | |
| 698 | 711 | DependencyManager::set<FadeEffect>(); |
| 699 | 712 | |
| 700 | − DependencyManager::set<LaserPointerScriptingInterface>(); | |
| 701 | − DependencyManager::set<RayPickScriptingInterface>(); | |
| 702 | − | |
| 703 | 713 | return previousSessionCrashed; |
| 704 | 714 | } |
| 705 | 715 | |
| @@ -758,7 +768,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 52 unmodified lines | ||
| 758 | 768 | _notifiedPacketVersionMismatchThisDomain(false), |
| 759 | 769 | _maxOctreePPS(maxOctreePacketsPerSecond.get()), |
| 760 | 770 | _lastFaceTrackerUpdate(0), |
| 761 | − _snapshotSound(nullptr) | |
| 771 | + _snapshotSound(nullptr), | |
| 772 | + _sampleSound(nullptr) | |
| 773 | + | |
| 762 | 774 | { |
| 763 | 775 | auto steamClient = PluginManager::getInstance()->getSteamClientPlugin(); |
| 764 | 776 | setProperty(hifi::properties::STEAM, (steamClient && steamClient->isRunning())); |
| @@ -803,7 +815,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 38 unmodified lines | ||
| 803 | 815 | installNativeEventFilter(&MyNativeEventFilter::getInstance()); |
| 804 | 816 | #endif |
| 805 | 817 | |
| 806 | − | |
| 807 | 818 | _logger = new FileLogger(this); |
| 808 | 819 | qInstallMessageHandler(messageHandler); |
| 809 | 820 | |
| @@ -891,7 +902,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 81 unmodified lines | ||
| 891 | 902 | connect(audioIO.data(), &AudioClient::muteEnvironmentRequested, [](glm::vec3 position, float radius) { |
| 892 | 903 | auto audioClient = DependencyManager::get<AudioClient>(); |
| 893 | 904 | auto audioScriptingInterface = DependencyManager::get<AudioScriptingInterface>(); |
| 894 | − auto myAvatarPosition = DependencyManager::get<AvatarManager>()->getMyAvatar()->getPosition(); | |
| 905 | + auto myAvatarPosition = DependencyManager::get<AvatarManager>()->getMyAvatar()->getWorldPosition(); | |
| 895 | 906 | float distance = glm::distance(myAvatarPosition, position); |
| 896 | 907 | bool shouldMute = !audioClient->isMuted() && (distance < radius); |
| 897 | 908 | |
| @@ -964,8 +975,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 66 unmodified lines | ||
| 964 | 975 | auto addressManager = DependencyManager::get<AddressManager>(); |
| 965 | 976 | |
| 966 | 977 | // use our MyAvatar position and quat for address manager path |
| 967 | − addressManager->setPositionGetter([this]{ return getMyAvatar()->getPosition(); }); | |
| 968 | − addressManager->setOrientationGetter([this]{ return getMyAvatar()->getOrientation(); }); | |
| 978 | + addressManager->setPositionGetter([this]{ return getMyAvatar()->getWorldPosition(); }); | |
| 979 | + addressManager->setOrientationGetter([this]{ return getMyAvatar()->getWorldOrientation(); }); | |
| 969 | 980 | |
| 970 | 981 | connect(addressManager.data(), &AddressManager::hostChanged, this, &Application::updateWindowTitle); |
| 971 | 982 | connect(this, &QCoreApplication::aboutToQuit, addressManager.data(), &AddressManager::storeCurrentAddress); |
| @@ -980,6 +991,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 8 unmodified lines | ||
| 980 | 991 | connect(myAvatar.get(), &MyAvatar::positionGoneTo, |
| 981 | 992 | DependencyManager::get<AddressManager>().data(), &AddressManager::storeCurrentAddress); |
| 982 | 993 | |
| 994 | + // Inititalize sample before registering | |
| 995 | + QFileInfo infSample = QFileInfo(PathUtils::resourcesPath() + "sounds/sample.wav"); | |
| 996 | + _sampleSound = DependencyManager::get<SoundCache>()->getSound(QUrl::fromLocalFile(infSample.absoluteFilePath())); | |
| 997 | + | |
| 983 | 998 | auto scriptEngines = DependencyManager::get<ScriptEngines>().data(); |
| 984 | 999 | scriptEngines->registerScriptInitializer([this](ScriptEnginePointer engine){ |
| 985 | 1000 | registerScriptEngineWithApplicationServices(engine); |
| @@ -1012,6 +1027,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 26 unmodified lines | ||
| 1012 | 1027 | |
| 1013 | 1028 | // connect to the packet sent signal of the _entityEditSender |
| 1014 | 1029 | connect(&_entityEditSender, &EntityEditPacketSender::packetSent, this, &Application::packetSent); |
| 1030 | + connect(&_entityEditSender, &EntityEditPacketSender::addingEntityWithCertificate, this, &Application::addingEntityWithCertificate); | |
| 1015 | 1031 | |
| 1016 | 1032 | const char** constArgv = const_cast<const char**>(argv); |
| 1017 | 1033 | QString concurrentDownloadsStr = getCmdOption(argc, constArgv, "--concurrent-downloads"); |
| @@ -1176,12 +1192,19 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 158 unmodified lines | ||
| 1176 | 1192 | _entityEditSender.setServerJurisdictions(&_entityServerJurisdictions); |
| 1177 | 1193 | _entityEditSender.setMyAvatar(myAvatar.get()); |
| 1178 | 1194 | |
| 1195 | + // The entity octree will have to know about MyAvatar for the parentJointName import | |
| 1196 | + getEntities()->getTree()->setMyAvatar(myAvatar); | |
| 1197 | + _entityClipboard->setMyAvatar(myAvatar); | |
| 1198 | + | |
| 1179 | 1199 | // For now we're going to set the PPS for outbound packets to be super high, this is |
| 1180 | 1200 | // probably not the right long term solution. But for now, we're going to do this to |
| 1181 | 1201 | // allow you to move an entity around in your hand |
| 1182 | 1202 | _entityEditSender.setPacketsPerSecond(3000); // super high!! |
| 1183 | 1203 | |
| 1204 | + // Overlays need to exist before we set the ContextOverlayInterface dependency | |
| 1184 | 1205 | _overlays.init(); // do this before scripts load |
| 1206 | + DependencyManager::set<ContextOverlayInterface>(); | |
| 1207 | + | |
| 1185 | 1208 | // Make sure we don't time out during slow operations at startup |
| 1186 | 1209 | updateHeartbeat(); |
| 1187 | 1210 | |
| @@ -1382,7 +1405,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 194 unmodified lines | ||
| 1382 | 1405 | // Make sure we don't time out during slow operations at startup |
| 1383 | 1406 | updateHeartbeat(); |
| 1384 | 1407 | |
| 1385 | − | |
| 1386 | 1408 | QTimer* settingsTimer = new QTimer(); |
| 1387 | 1409 | moveToNewNamedThread(settingsTimer, "Settings Thread", [this, settingsTimer]{ |
| 1388 | 1410 | connect(qApp, &Application::beforeAboutToQuit, [this, settingsTimer]{ |
| @@ -1455,13 +1477,15 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 66 unmodified lines | ||
| 1455 | 1477 | |
| 1456 | 1478 | // 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 |
| 1457 | 1479 | auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); |
| 1458 | − connect(entityScriptingInterface.data(), &EntityScriptingInterface::clickDownOnEntity, | |
| 1480 | + connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, | |
| 1459 | 1481 | [this](const EntityItemID& entityItemID, const PointerEvent& event) { |
| 1460 | − if (getEntities()->wantsKeyboardFocus(entityItemID)) { | |
| 1461 | − setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); | |
| 1462 | − setKeyboardFocusEntity(entityItemID); | |
| 1463 | − } else { | |
| 1464 | − setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); | |
| 1482 | + if (event.shouldFocus()) { | |
| 1483 | + if (getEntities()->wantsKeyboardFocus(entityItemID)) { | |
| 1484 | + setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); | |
| 1485 | + setKeyboardFocusEntity(entityItemID); | |
| 1486 | + } else { | |
| 1487 | + setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); | |
| 1488 | + } | |
| 1465 | 1489 | } |
| 1466 | 1490 | }); |
| 1467 | 1491 | |
| @@ -1471,53 +1495,19 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 3 unmodified lines | ||
| 1471 | 1495 | } |
| 1472 | 1496 | }); |
| 1473 | 1497 | |
| 1474 | − // If the user clicks somewhere where there is NO entity at all, we will release focus | |
| 1475 | − connect(getEntities().data(), &EntityTreeRenderer::mousePressOffEntity, [=]() { | |
| 1476 | − setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); | |
| 1477 | − }); | |
| 1478 | − | |
| 1479 | 1498 | // Keyboard focus handling for Web overlays. |
| 1480 | 1499 | auto overlays = &(qApp->getOverlays()); |
| 1481 | − | |
| 1482 | − connect(overlays, &Overlays::mousePressOnOverlay, [=](const OverlayID& overlayID, const PointerEvent& event) { | |
| 1483 | − auto thisOverlay = std::dynamic_pointer_cast<Web3DOverlay>(overlays->getOverlay(overlayID)); | |
| 1484 | − // Only Web overlays can have keyboard focus. | |
| 1485 | − if (thisOverlay) { | |
| 1486 | − setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); | |
| 1487 | − setKeyboardFocusOverlay(overlayID); | |
| 1488 | − } | |
| 1489 | − }); | |
| 1490 | − | |
| 1491 | 1500 | connect(overlays, &Overlays::overlayDeleted, [=](const OverlayID& overlayID) { |
| 1492 | 1501 | if (overlayID == _keyboardFocusedOverlay.get()) { |
| 1493 | 1502 | setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); |
| 1494 | 1503 | } |
| 1495 | 1504 | }); |
| 1496 | 1505 | |
| 1497 | − connect(overlays, &Overlays::mousePressOffOverlay, [=]() { | |
| 1498 | − setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); | |
| 1499 | − }); | |
| 1500 | − | |
| 1501 | 1506 | connect(this, &Application::aboutToQuit, [=]() { |
| 1502 | 1507 | setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); |
| 1503 | 1508 | setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); |
| 1504 | 1509 | }); |
| 1505 | 1510 | |
| 1506 | − connect(overlays, | |
| 1507 | − SIGNAL(mousePressOnOverlay(const OverlayID&, const PointerEvent&)), | |
| 1508 | − DependencyManager::get<ContextOverlayInterface>().data(), | |
| 1509 | − SLOT(contextOverlays_mousePressOnOverlay(const OverlayID&, const PointerEvent&))); | |
| 1510 | − | |
| 1511 | − connect(overlays, | |
| 1512 | − SIGNAL(hoverEnterOverlay(const OverlayID&, const PointerEvent&)), | |
| 1513 | − DependencyManager::get<ContextOverlayInterface>().data(), | |
| 1514 | − SLOT(contextOverlays_hoverEnterOverlay(const OverlayID&, const PointerEvent&))); | |
| 1515 | − | |
| 1516 | − connect(overlays, | |
| 1517 | − SIGNAL(hoverLeaveOverlay(const OverlayID&, const PointerEvent&)), | |
| 1518 | − DependencyManager::get<ContextOverlayInterface>().data(), | |
| 1519 | − SLOT(contextOverlays_hoverLeaveOverlay(const OverlayID&, const PointerEvent&))); | |
| 1520 | − | |
| 1521 | 1511 | // Add periodic checks to send user activity data |
| 1522 | 1512 | static int CHECK_NEARBY_AVATARS_INTERVAL_MS = 10000; |
| 1523 | 1513 | static int NEARBY_AVATAR_RADIUS_METERS = 10; |
| @@ -1526,7 +1516,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 2 unmodified lines | ||
| 1526 | 1516 | static const QString FAST_STATS_ARG = "--fast-heartbeat"; |
| 1527 | 1517 | static int SEND_STATS_INTERVAL_MS = arguments().indexOf(FAST_STATS_ARG) != -1 ? 1000 : 10000; |
| 1528 | 1518 | |
| 1529 | − static glm::vec3 lastAvatarPosition = myAvatar->getPosition(); | |
| 1519 | + static glm::vec3 lastAvatarPosition = myAvatar->getWorldPosition(); | |
| 1530 | 1520 | static glm::mat4 lastHMDHeadPose = getHMDSensorPose(); |
| 1531 | 1521 | static controller::Pose lastLeftHandPose = myAvatar->getLeftHandPose(); |
| 1532 | 1522 | static controller::Pose lastRightHandPose = myAvatar->getRightHandPose(); |
| @@ -1654,7 +1644,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 121 unmodified lines | ||
| 1654 | 1644 | properties["bytes_downloaded"] = bytesDownloaded; |
| 1655 | 1645 | |
| 1656 | 1646 | auto myAvatar = getMyAvatar(); |
| 1657 | − glm::vec3 avatarPosition = myAvatar->getPosition(); | |
| 1647 | + glm::vec3 avatarPosition = myAvatar->getWorldPosition(); | |
| 1658 | 1648 | properties["avatar_has_moved"] = lastAvatarPosition != avatarPosition; |
| 1659 | 1649 | lastAvatarPosition = avatarPosition; |
| 1660 | 1650 | |
| @@ -1724,8 +1714,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 63 unmodified lines | ||
| 1724 | 1714 | lastLeftHandPose = leftHandPose; |
| 1725 | 1715 | lastRightHandPose = rightHandPose; |
| 1726 | 1716 | |
| 1727 | − properties["local_socket_changes"] = DependencyManager::get<StatTracker>()->getStat(LOCAL_SOCKET_CHANGE_STAT).toInt(); | |
| 1728 | − | |
| 1729 | 1717 | UserActivityLogger::getInstance().logAction("stats", properties); |
| 1730 | 1718 | }); |
| 1731 | 1719 | sendStatsTimer->start(); |
| @@ -1736,7 +1724,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 4 unmodified lines | ||
| 1736 | 1724 | checkNearbyAvatarsTimer->setInterval(CHECK_NEARBY_AVATARS_INTERVAL_MS); // 10 seconds, Qt::CoarseTimer ok |
| 1737 | 1725 | connect(checkNearbyAvatarsTimer, &QTimer::timeout, this, [this]() { |
| 1738 | 1726 | auto avatarManager = DependencyManager::get<AvatarManager>(); |
| 1739 | − int nearbyAvatars = avatarManager->numberOfAvatarsInRange(avatarManager->getMyAvatar()->getPosition(), | |
| 1727 | + int nearbyAvatars = avatarManager->numberOfAvatarsInRange(avatarManager->getMyAvatar()->getWorldPosition(), | |
| 1740 | 1728 | NEARBY_AVATAR_RADIUS_METERS) - 1; |
| 1741 | 1729 | if (nearbyAvatars != lastCountOfNearbyAvatars) { |
| 1742 | 1730 | lastCountOfNearbyAvatars = nearbyAvatars; |
| @@ -1786,9 +1774,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 43 unmodified lines | ||
| 1786 | 1774 | return entityServerNode && !isPhysicsEnabled(); |
| 1787 | 1775 | }); |
| 1788 | 1776 | |
| 1789 | − QFileInfo inf = QFileInfo(PathUtils::resourcesPath() + "sounds/snap.wav"); | |
| 1790 | − _snapshotSound = DependencyManager::get<SoundCache>()->getSound(QUrl::fromLocalFile(inf.absoluteFilePath())); | |
| 1791 | − | |
| 1777 | + QFileInfo infSnap = QFileInfo(PathUtils::resourcesPath() + "sounds/snap.wav"); | |
| 1778 | + _snapshotSound = DependencyManager::get<SoundCache>()->getSound(QUrl::fromLocalFile(infSnap.absoluteFilePath())); | |
| 1779 | + | |
| 1792 | 1780 | QVariant testProperty = property(hifi::properties::TEST); |
| 1793 | 1781 | qDebug() << testProperty; |
| 1794 | 1782 | if (testProperty.isValid()) { |
| @@ -1825,30 +1813,43 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 30 unmodified lines | ||
| 1825 | 1813 | |
| 1826 | 1814 | connect(&_myCamera, &Camera::modeUpdated, this, &Application::cameraModeChanged); |
| 1827 | 1815 | |
| 1816 | + DependencyManager::get<PickManager>()->setShouldPickHUDOperator([&]() { return DependencyManager::get<HMDScriptingInterface>()->isHMDMode(); }); | |
| 1817 | + DependencyManager::get<PickManager>()->setCalculatePos2DFromHUDOperator([&](const glm::vec3& intersection) { | |
| 1818 | + const glm::vec2 MARGIN(25.0f); | |
| 1819 | + glm::vec2 maxPos = _controllerScriptingInterface->getViewportDimensions() - MARGIN; | |
| 1820 | + glm::vec2 pos2D = DependencyManager::get<HMDScriptingInterface>()->overlayFromWorldPoint(intersection); | |
| 1821 | + return glm::max(MARGIN, glm::min(pos2D, maxPos)); | |
| 1822 | + }); | |
| 1823 | + | |
| 1828 | 1824 | // Setup the mouse ray pick and related operators |
| 1829 | − DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickID(_rayPickManager.createRayPick( | |
| 1830 | − RayPickFilter(DependencyManager::get<RayPickScriptingInterface>()->PICK_ENTITIES() | DependencyManager::get<RayPickScriptingInterface>()->PICK_INCLUDE_NONCOLLIDABLE()), | |
| 1831 | − 0.0f, true)); | |
| 1832 | − DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickResultOperator([&](QUuid rayPickID) { | |
| 1825 | + DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickID(DependencyManager::get<PickManager>()->addPick(PickQuery::Ray, std::make_shared<MouseRayPick>( | |
| 1826 | + PickFilter(PickScriptingInterface::PICK_ENTITIES() | PickScriptingInterface::PICK_INCLUDE_NONCOLLIDABLE()), 0.0f, true))); | |
| 1827 | + DependencyManager::get<EntityTreeRenderer>()->setMouseRayPickResultOperator([&](unsigned int rayPickID) { | |
| 1833 | 1828 | RayToEntityIntersectionResult entityResult; |
| 1834 | − RayPickResult result = _rayPickManager.getPrevRayPickResult(rayPickID); | |
| 1835 | − entityResult.intersects = result.type != DependencyManager::get<RayPickScriptingInterface>()->INTERSECTED_NONE(); | |
| 1836 | − if (entityResult.intersects) { | |
| 1837 | − entityResult.intersection = result.intersection; | |
| 1838 | − entityResult.distance = result.distance; | |
| 1839 | − entityResult.surfaceNormal = result.surfaceNormal; | |
| 1840 | − entityResult.entityID = result.objectID; | |
| 1841 | − entityResult.entity = DependencyManager::get<EntityTreeRenderer>()->getTree()->findEntityByID(entityResult.entityID); | |
| 1829 | + entityResult.intersects = false; | |
| 1830 | + auto pickResult = DependencyManager::get<PickManager>()->getPrevPickResultTyped<RayPickResult>(rayPickID); | |
| 1831 | + if (pickResult) { | |
| 1832 | + entityResult.intersects = pickResult->type != IntersectionType::NONE; | |
| 1833 | + if (entityResult.intersects) { | |
| 1834 | + entityResult.intersection = pickResult->intersection; | |
| 1835 | + entityResult.distance = pickResult->distance; | |
| 1836 | + entityResult.surfaceNormal = pickResult->surfaceNormal; | |
| 1837 | + entityResult.entityID = pickResult->objectID; | |
| 1838 | + entityResult.entity = DependencyManager::get<EntityTreeRenderer>()->getTree()->findEntityByID(entityResult.entityID); | |
| 1839 | + } | |
| 1842 | 1840 | } |
| 1843 | 1841 | return entityResult; |
| 1844 | 1842 | }); |
| 1845 | − DependencyManager::get<EntityTreeRenderer>()->setSetPrecisionPickingOperator([&](QUuid rayPickID, bool value) { | |
| 1846 | − _rayPickManager.setPrecisionPicking(rayPickID, value); | |
| 1843 | + DependencyManager::get<EntityTreeRenderer>()->setSetPrecisionPickingOperator([&](unsigned int rayPickID, bool value) { | |
| 1844 | + DependencyManager::get<PickManager>()->setPrecisionPicking(rayPickID, value); | |
| 1847 | 1845 | }); |
| 1848 | 1846 | |
| 1849 | 1847 | // Preload Tablet sounds |
| 1850 | 1848 | DependencyManager::get<TabletScriptingInterface>()->preloadSounds(); |
| 1851 | 1849 | |
| 1850 | + _pendingIdleEvent = false; | |
| 1851 | + _pendingRenderEvent = false; | |
| 1852 | + | |
| 1852 | 1853 | qCDebug(interfaceapp) << "Metaverse session ID is" << uuidStringWithoutCurlyBraces(accountManager->getSessionID()); |
| 1853 | 1854 | } |
| 1854 | 1855 | |
| @@ -2247,6 +2248,7 @@ void Application::initializeUi() { · 392 unmodified lines | ||
| 2247 | 2248 | QmlCommerce::registerType(); |
| 2248 | 2249 | qmlRegisterType<ResourceImageItem>("Hifi", 1, 0, "ResourceImageItem"); |
| 2249 | 2250 | qmlRegisterType<Preference>("Hifi", 1, 0, "Preference"); |
| 2251 | + qmlRegisterType<WebBrowserSuggestionsEngine>("HifiWeb", 1, 0, "WebBrowserSuggestionsEngine"); | |
| 2250 | 2252 | |
| 2251 | 2253 | auto offscreenUi = DependencyManager::get<OffscreenUi>(); |
| 2252 | 2254 | offscreenUi->create(); |
| @@ -2425,7 +2427,7 @@ void Application::updateCamera(RenderArgs& renderArgs) { · 172 unmodified lines | ||
| 2425 | 2427 | auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); |
| 2426 | 2428 | _myCamera.setOrientation(glm::normalize(glmExtractRotation(hmdWorldMat))); |
| 2427 | 2429 | _myCamera.setPosition(extractTranslation(hmdWorldMat) + |
| 2428 | − myAvatar->getOrientation() * boomOffset); | |
| 2430 | + myAvatar->getWorldOrientation() * boomOffset); | |
| 2429 | 2431 | } |
| 2430 | 2432 | else { |
| 2431 | 2433 | _myCamera.setOrientation(myAvatar->getHead()->getOrientation()); |
| @@ -2435,13 +2437,13 @@ void Application::updateCamera(RenderArgs& renderArgs) { · 3 unmodified lines | ||
| 2435 | 2437 | } |
| 2436 | 2438 | else { |
| 2437 | 2439 | _myCamera.setPosition(myAvatar->getDefaultEyePosition() |
| 2438 | − + myAvatar->getOrientation() * boomOffset); | |
| 2440 | + + myAvatar->getWorldOrientation() * boomOffset); | |
| 2439 | 2441 | } |
| 2440 | 2442 | } |
| 2441 | 2443 | } |
| 2442 | 2444 | else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { |
| 2443 | 2445 | if (isHMDMode()) { |
| 2444 | − auto mirrorBodyOrientation = myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)); | |
| 2446 | + auto mirrorBodyOrientation = myAvatar->getWorldOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)); | |
| 2445 | 2447 | |
| 2446 | 2448 | glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); |
| 2447 | 2449 | // Mirror HMD yaw and roll |
| @@ -2464,11 +2466,11 @@ void Application::updateCamera(RenderArgs& renderArgs) { · 16 unmodified lines | ||
| 2464 | 2466 | + mirrorBodyOrientation * hmdOffset); |
| 2465 | 2467 | } |
| 2466 | 2468 | else { |
| 2467 | − _myCamera.setOrientation(myAvatar->getOrientation() | |
| 2469 | + _myCamera.setOrientation(myAvatar->getWorldOrientation() | |
| 2468 | 2470 | * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); |
| 2469 | 2471 | _myCamera.setPosition(myAvatar->getDefaultEyePosition() |
| 2470 | 2472 | + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) |
| 2471 | − + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * | |
| 2473 | + + (myAvatar->getWorldOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * | |
| 2472 | 2474 | glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); |
| 2473 | 2475 | } |
| 2474 | 2476 | renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; |
| @@ -2478,13 +2480,13 @@ void Application::updateCamera(RenderArgs& renderArgs) { · 3 unmodified lines | ||
| 2478 | 2480 | if (cameraEntity != nullptr) { |
| 2479 | 2481 | if (isHMDMode()) { |
| 2480 | 2482 | glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); |
| 2481 | − _myCamera.setOrientation(cameraEntity->getRotation() * hmdRotation); | |
| 2483 | + _myCamera.setOrientation(cameraEntity->getWorldOrientation() * hmdRotation); | |
| 2482 | 2484 | glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); |
| 2483 | − _myCamera.setPosition(cameraEntity->getPosition() + (hmdRotation * hmdOffset)); | |
| 2485 | + _myCamera.setPosition(cameraEntity->getWorldPosition() + (hmdRotation * hmdOffset)); | |
| 2484 | 2486 | } |
| 2485 | 2487 | else { |
| 2486 | − _myCamera.setOrientation(cameraEntity->getRotation()); | |
| 2487 | − _myCamera.setPosition(cameraEntity->getPosition()); | |
| 2488 | + _myCamera.setOrientation(cameraEntity->getWorldOrientation()); | |
| 2489 | + _myCamera.setPosition(cameraEntity->getWorldPosition()); | |
| 2488 | 2490 | } |
| 2489 | 2491 | } |
| 2490 | 2492 | } |
| @@ -2717,7 +2719,7 @@ bool Application::importFromZIP(const QString& filePath) { · 226 unmodified lines | ||
| 2717 | 2719 | qDebug() << "A zip file has been dropped in: " << filePath; |
| 2718 | 2720 | QUrl empty; |
| 2719 | 2721 | // handle Blocks download from Marketplace |
| 2720 | − if (filePath.contains("vr.google.com/downloads")) { | |
| 2722 | + if (filePath.contains("poly.google.com/downloads")) { | |
| 2721 | 2723 | addAssetToWorldFromURL(filePath); |
| 2722 | 2724 | } else { |
| 2723 | 2725 | qApp->getFileDownloadInterface()->runUnzip(filePath, empty, true, true, false); |
| @@ -3300,7 +3302,7 @@ void Application::mouseMoveEvent(QMouseEvent* event) { · 576 unmodified lines | ||
| 3300 | 3302 | |
| 3301 | 3303 | auto offscreenUi = DependencyManager::get<OffscreenUi>(); |
| 3302 | 3304 | auto eventPosition = compositor.getMouseEventPosition(event); |
| 3303 | − QPointF transformedPos = offscreenUi->mapToVirtualScreen(eventPosition, _glWidget); | |
| 3305 | + QPointF transformedPos = offscreenUi->mapToVirtualScreen(eventPosition); | |
| 3304 | 3306 | auto button = event->button(); |
| 3305 | 3307 | auto buttons = event->buttons(); |
| 3306 | 3308 | // Determine if the ReticleClick Action is 1 and if so, fake include the LeftMouseButton |
| @@ -3346,7 +3348,7 @@ void Application::mousePressEvent(QMouseEvent* event) { · 39 unmodified lines | ||
| 3346 | 3348 | offscreenUi->unfocusWindows(); |
| 3347 | 3349 | |
| 3348 | 3350 | auto eventPosition = getApplicationCompositor().getMouseEventPosition(event); |
| 3349 | − QPointF transformedPos = offscreenUi->mapToVirtualScreen(eventPosition, _glWidget); | |
| 3351 | + QPointF transformedPos = offscreenUi->mapToVirtualScreen(eventPosition); | |
| 3350 | 3352 | QMouseEvent mappedEvent(event->type(), |
| 3351 | 3353 | transformedPos, |
| 3352 | 3354 | event->screenPos(), event->button(), |
| @@ -3376,7 +3378,7 @@ void Application::mousePressEvent(QMouseEvent* event) { · 23 unmodified lines | ||
| 3376 | 3378 | void Application::mouseDoublePressEvent(QMouseEvent* event) { |
| 3377 | 3379 | auto offscreenUi = DependencyManager::get<OffscreenUi>(); |
| 3378 | 3380 | auto eventPosition = getApplicationCompositor().getMouseEventPosition(event); |
| 3379 | − QPointF transformedPos = offscreenUi->mapToVirtualScreen(eventPosition, _glWidget); | |
| 3381 | + QPointF transformedPos = offscreenUi->mapToVirtualScreen(eventPosition); | |
| 3380 | 3382 | QMouseEvent mappedEvent(event->type(), |
| 3381 | 3383 | transformedPos, |
| 3382 | 3384 | event->screenPos(), event->button(), |
| @@ -3402,7 +3404,7 @@ void Application::mouseReleaseEvent(QMouseEvent* event) { · 19 unmodified lines | ||
| 3402 | 3404 | |
| 3403 | 3405 | auto offscreenUi = DependencyManager::get<OffscreenUi>(); |
| 3404 | 3406 | auto eventPosition = getApplicationCompositor().getMouseEventPosition(event); |
| 3405 | − QPointF transformedPos = offscreenUi->mapToVirtualScreen(eventPosition, _glWidget); | |
| 3407 | + QPointF transformedPos = offscreenUi->mapToVirtualScreen(eventPosition); | |
| 3406 | 3408 | QMouseEvent mappedEvent(event->type(), |
| 3407 | 3409 | transformedPos, |
| 3408 | 3410 | event->screenPos(), event->button(), |
| @@ -3895,16 +3897,16 @@ void Application::idle() { · 486 unmodified lines | ||
| 3895 | 3897 | if (!_keyboardFocusedEntity.get().isInvalidID()) { |
| 3896 | 3898 | auto entity = getEntities()->getTree()->findEntityByID(_keyboardFocusedEntity.get()); |
| 3897 | 3899 | if (entity && _keyboardFocusHighlight) { |
| 3898 | − _keyboardFocusHighlight->setRotation(entity->getRotation()); | |
| 3899 | − _keyboardFocusHighlight->setPosition(entity->getPosition()); | |
| 3900 | + _keyboardFocusHighlight->setWorldOrientation(entity->getWorldOrientation()); | |
| 3901 | + _keyboardFocusHighlight->setWorldPosition(entity->getWorldPosition()); | |
| 3900 | 3902 | } |
| 3901 | 3903 | } else { |
| 3902 | 3904 | // Only Web overlays can have focus. |
| 3903 | 3905 | auto overlay = |
| 3904 | 3906 | std::dynamic_pointer_cast<Web3DOverlay>(getOverlays().getOverlay(_keyboardFocusedOverlay.get())); |
| 3905 | 3907 | if (overlay && _keyboardFocusHighlight) { |
| 3906 | − _keyboardFocusHighlight->setRotation(overlay->getRotation()); | |
| 3907 | − _keyboardFocusHighlight->setPosition(overlay->getPosition()); | |
| 3908 | + _keyboardFocusHighlight->setWorldOrientation(overlay->getWorldOrientation()); | |
| 3909 | + _keyboardFocusHighlight->setWorldPosition(overlay->getWorldPosition()); | |
| 3908 | 3910 | } |
| 3909 | 3911 | } |
| 3910 | 3912 | } |
| @@ -4020,6 +4022,7 @@ bool Application::exportEntities(const QString& filename, · 109 unmodified lines | ||
| 4020 | 4022 | |
| 4021 | 4023 | auto entityTree = getEntities()->getTree(); |
| 4022 | 4024 | auto exportTree = std::make_shared<EntityTree>(); |
| 4025 | + exportTree->setMyAvatar(getMyAvatar()); | |
| 4023 | 4026 | exportTree->createRootElement(); |
| 4024 | 4027 | glm::vec3 root(TREE_SCALE, TREE_SCALE, TREE_SCALE); |
| 4025 | 4028 | bool success = true; |
| @@ -4038,7 +4041,7 @@ bool Application::exportEntities(const QString& filename, · 12 unmodified lines | ||
| 4038 | 4041 | !entityIDs.contains(parentID) || |
| 4039 | 4042 | !entityTree->findEntityByEntityItemID(parentID))) { |
| 4040 | 4043 | // If parent wasn't selected, we want absolute position, which isn't in properties. |
| 4041 | − auto position = entityItem->getPosition(); | |
| 4044 | + auto position = entityItem->getWorldPosition(); | |
| 4042 | 4045 | root.x = glm::min(root.x, position.x); |
| 4043 | 4046 | root.y = glm::min(root.y, position.y); |
| 4044 | 4047 | root.z = glm::min(root.z, position.z); |
| @@ -4201,6 +4204,7 @@ void Application::initDisplay() { · 156 unmodified lines | ||
| 4201 | 4204 | } |
| 4202 | 4205 | |
| 4203 | 4206 | void Application::init() { |
| 4207 | + | |
| 4204 | 4208 | // Make sure Login state is up to date |
| 4205 | 4209 | DependencyManager::get<DialogsManager>()->toggleLoginDialog(); |
| 4206 | 4210 | |
| @@ -4227,6 +4231,10 @@ void Application::init() { · 20 unmodified lines | ||
| 4227 | 4231 | // fire off an immediate domain-server check in now that settings are loaded |
| 4228 | 4232 | DependencyManager::get<NodeList>()->sendDomainServerCheckIn(); |
| 4229 | 4233 | |
| 4234 | + // This allows collision to be set up properly for shape entities supported by GeometryCache. | |
| 4235 | + // This is before entity setup to ensure that it's ready for whenever instance collision is initialized. | |
| 4236 | + ShapeEntityItem::setShapeInfoCalulator(ShapeEntityItem::ShapeInfoCalculator(&shapeInfoCalculator)); | |
| 4237 | + | |
| 4230 | 4238 | getEntities()->init(); |
| 4231 | 4239 | getEntities()->setEntityLoadingPriorityFunction([this](const EntityItem& item) { |
| 4232 | 4240 | auto dims = item.getDimensions(); |
| @@ -4236,7 +4244,7 @@ void Application::init() { · 3 unmodified lines | ||
| 4236 | 4244 | return 0.0f; |
| 4237 | 4245 | } |
| 4238 | 4246 | |
| 4239 | − auto distance = glm::distance(getMyAvatar()->getPosition(), item.getPosition()); | |
| 4247 | + auto distance = glm::distance(getMyAvatar()->getWorldPosition(), item.getWorldPosition()); | |
| 4240 | 4248 | return atan2(maxSize, distance); |
| 4241 | 4249 | }); |
| 4242 | 4250 | |
| @@ -4313,7 +4321,7 @@ void Application::updateMyAvatarLookAtPosition() { · 70 unmodified lines | ||
| 4313 | 4321 | // TODO -- this code is probably wrong, getHeadPose() returns something in sensor frame, not avatar |
| 4314 | 4322 | glm::mat4 headPose = getActiveDisplayPlugin()->getHeadPose(); |
| 4315 | 4323 | glm::quat hmdRotation = glm::quat_cast(headPose); |
| 4316 | − lookAtSpot = _myCamera.getPosition() + myAvatar->getOrientation() * (hmdRotation * lookAtPosition); | |
| 4324 | + lookAtSpot = _myCamera.getPosition() + myAvatar->getWorldOrientation() * (hmdRotation * lookAtPosition); | |
| 4317 | 4325 | } else { |
| 4318 | 4326 | lookAtSpot = myAvatar->getHead()->getEyePosition() |
| 4319 | 4327 | + (myAvatar->getHead()->getFinalOrientationInWorldFrame() * lookAtPosition); |
| @@ -4460,7 +4468,7 @@ void Application::cameraModeChanged() { · 140 unmodified lines | ||
| 4460 | 4468 | void Application::cameraMenuChanged() { |
| 4461 | 4469 | auto menu = Menu::getInstance(); |
| 4462 | 4470 | if (menu->isOptionChecked(MenuOption::FullscreenMirror)) { |
| 4463 | − if (_myCamera.getMode() != CAMERA_MODE_MIRROR) { | |
| 4471 | + if (!isHMDMode() && _myCamera.getMode() != CAMERA_MODE_MIRROR) { | |
| 4464 | 4472 | _myCamera.setMode(CAMERA_MODE_MIRROR); |
| 4465 | 4473 | getMyAvatar()->reset(false, false, false); // to reset any active MyAvatar::FollowHelpers |
| 4466 | 4474 | } |
| @@ -4500,8 +4508,11 @@ void Application::resetPhysicsReadyInformation() { · 33 unmodified lines | ||
| 4500 | 4508 | |
| 4501 | 4509 | void Application::reloadResourceCaches() { |
| 4502 | 4510 | resetPhysicsReadyInformation(); |
| 4511 | + | |
| 4503 | 4512 | // Query the octree to refresh everything in view |
| 4504 | 4513 | _lastQueriedTime = 0; |
| 4514 | + _octreeQuery.incrementConnectionID(); | |
| 4515 | + | |
| 4505 | 4516 | queryOctree(NodeType::EntityServer, PacketType::EntityQuery, _entityServerJurisdictions); |
| 4506 | 4517 | |
| 4507 | 4518 | DependencyManager::get<AssetClient>()->clearCache(); |
| @@ -4539,8 +4550,8 @@ void Application::setKeyboardFocusHighlight(const glm::vec3& position, const glm · 31 unmodified lines | ||
| 4539 | 4550 | } |
| 4540 | 4551 | |
| 4541 | 4552 | // Position focus |
| 4542 | − _keyboardFocusHighlight->setRotation(rotation); | |
| 4543 | − _keyboardFocusHighlight->setPosition(position); | |
| 4553 | + _keyboardFocusHighlight->setWorldOrientation(rotation); | |
| 4554 | + _keyboardFocusHighlight->setWorldPosition(position); | |
| 4544 | 4555 | _keyboardFocusHighlight->setDimensions(dimensions); |
| 4545 | 4556 | _keyboardFocusHighlight->setVisible(true); |
| 4546 | 4557 | } |
| @@ -4549,14 +4560,9 @@ QUuid Application::getKeyboardFocusEntity() const { · 2 unmodified lines | ||
| 4549 | 4560 | return _keyboardFocusedEntity.get(); |
| 4550 | 4561 | } |
| 4551 | 4562 | |
| 4552 | −void Application::setKeyboardFocusEntity(QUuid id) { | |
| 4553 | − EntityItemID entityItemID(id); | |
| 4554 | − setKeyboardFocusEntity(entityItemID); | |
| 4555 | −} | |
| 4556 | − | |
| 4557 | 4563 | static const float FOCUS_HIGHLIGHT_EXPANSION_FACTOR = 1.05f; |
| 4558 | 4564 | |
| 4559 | −void Application::setKeyboardFocusEntity(EntityItemID entityItemID) { | |
| 4565 | +void Application::setKeyboardFocusEntity(const EntityItemID& entityItemID) { | |
| 4560 | 4566 | if (_keyboardFocusedEntity.get() != entityItemID) { |
| 4561 | 4567 | _keyboardFocusedEntity.set(entityItemID); |
| 4562 | 4568 | |
| @@ -4582,7 +4588,7 @@ void Application::setKeyboardFocusEntity(EntityItemID entityItemID) { · 19 unmodified lines | ||
| 4582 | 4588 | } |
| 4583 | 4589 | _lastAcceptedKeyPress = usecTimestampNow(); |
| 4584 | 4590 | |
| 4585 | − setKeyboardFocusHighlight(entity->getPosition(), entity->getRotation(), | |
| 4591 | + setKeyboardFocusHighlight(entity->getWorldPosition(), entity->getWorldOrientation(), | |
| 4586 | 4592 | entity->getDimensions() * FOCUS_HIGHLIGHT_EXPANSION_FACTOR); |
| 4587 | 4593 | } |
| 4588 | 4594 | } |
| @@ -4593,7 +4599,7 @@ OverlayID Application::getKeyboardFocusOverlay() { · 4 unmodified lines | ||
| 4593 | 4599 | return _keyboardFocusedOverlay.get(); |
| 4594 | 4600 | } |
| 4595 | 4601 | |
| 4596 | −void Application::setKeyboardFocusOverlay(OverlayID overlayID) { | |
| 4602 | +void Application::setKeyboardFocusOverlay(const OverlayID& overlayID) { | |
| 4597 | 4603 | if (overlayID != _keyboardFocusedOverlay.get()) { |
| 4598 | 4604 | _keyboardFocusedOverlay.set(overlayID); |
| 4599 | 4605 | |
| @@ -4619,7 +4625,7 @@ void Application::setKeyboardFocusOverlay(OverlayID overlayID) { · 19 unmodified lines | ||
| 4619 | 4625 | if (overlay->getProperty("showKeyboardFocusHighlight").toBool()) { |
| 4620 | 4626 | auto size = overlay->getSize() * FOCUS_HIGHLIGHT_EXPANSION_FACTOR; |
| 4621 | 4627 | const float OVERLAY_DEPTH = 0.0105f; |
| 4622 | − setKeyboardFocusHighlight(overlay->getPosition(), overlay->getRotation(), glm::vec3(size.x, size.y, OVERLAY_DEPTH)); | |
| 4628 | + setKeyboardFocusHighlight(overlay->getWorldPosition(), overlay->getWorldOrientation(), glm::vec3(size.x, size.y, OVERLAY_DEPTH)); | |
| 4623 | 4629 | } else if (_keyboardFocusHighlight) { |
| 4624 | 4630 | _keyboardFocusHighlight->setVisible(false); |
| 4625 | 4631 | } |
| @@ -4711,7 +4717,7 @@ void Application::update(float deltaTime) { · 85 unmodified lines | ||
| 4711 | 4717 | |
| 4712 | 4718 | controller::InputCalibrationData calibrationData = { |
| 4713 | 4719 | myAvatar->getSensorToWorldMatrix(), |
| 4714 | − createMatFromQuatAndPos(myAvatar->getOrientation(), myAvatar->getPosition()), | |
| 4720 | + createMatFromQuatAndPos(myAvatar->getWorldOrientation(), myAvatar->getWorldPosition()), | |
| 4715 | 4721 | myAvatar->getHMDSensorMatrix(), |
| 4716 | 4722 | myAvatar->getCenterEyeCalibrationMat(), |
| 4717 | 4723 | myAvatar->getHeadCalibrationMat(), |
| @@ -4821,7 +4827,7 @@ void Application::update(float deltaTime) { · 103 unmodified lines | ||
| 4821 | 4827 | }; |
| 4822 | 4828 | |
| 4823 | 4829 | // copy controller poses from userInputMapper to myAvatar. |
| 4824 | − glm::mat4 myAvatarMatrix = createMatFromQuatAndPos(myAvatar->getOrientation(), myAvatar->getPosition()); | |
| 4830 | + glm::mat4 myAvatarMatrix = createMatFromQuatAndPos(myAvatar->getWorldOrientation(), myAvatar->getWorldPosition()); | |
| 4825 | 4831 | glm::mat4 worldToSensorMatrix = glm::inverse(myAvatar->getSensorToWorldMatrix()); |
| 4826 | 4832 | glm::mat4 avatarToSensorMatrix = worldToSensorMatrix * myAvatarMatrix; |
| 4827 | 4833 | for (auto& action : avatarControllerActions) { |
| @@ -4961,13 +4967,13 @@ void Application::update(float deltaTime) { · 133 unmodified lines | ||
| 4961 | 4967 | |
| 4962 | 4968 | // TODO: break these out into distinct perfTimers when they prove interesting |
| 4963 | 4969 | { |
| 4964 | − PROFILE_RANGE(app, "RayPickManager"); | |
| 4965 | − _rayPickManager.update(); | |
| 4970 | + PROFILE_RANGE(app, "PickManager"); | |
| 4971 | + DependencyManager::get<PickManager>()->update(); | |
| 4966 | 4972 | } |
| 4967 | 4973 | |
| 4968 | 4974 | { |
| 4969 | − PROFILE_RANGE(app, "LaserPointerManager"); | |
| 4970 | − _laserPointerManager.update(); | |
| 4975 | + PROFILE_RANGE(app, "PointerManager"); | |
| 4976 | + DependencyManager::get<PointerManager>()->update(); | |
| 4971 | 4977 | } |
| 4972 | 4978 | |
| 4973 | 4979 | { |
| @@ -5089,6 +5095,7 @@ void Application::update(float deltaTime) { · 115 unmodified lines | ||
| 5089 | 5095 | } |
| 5090 | 5096 | |
| 5091 | 5097 | this->updateCamera(appRenderArgs._renderArgs); |
| 5098 | + appRenderArgs._eyeToWorld = _myCamera.getTransform(); | |
| 5092 | 5099 | appRenderArgs._isStereo = false; |
| 5093 | 5100 | |
| 5094 | 5101 | { |
| @@ -5436,7 +5443,7 @@ std::shared_ptr<MyAvatar> Application::getMyAvatar() const { · 341 unmodified lines | ||
| 5436 | 5443 | } |
| 5437 | 5444 | |
| 5438 | 5445 | glm::vec3 Application::getAvatarPosition() const { |
| 5439 | − return getMyAvatar()->getPosition(); | |
| 5446 | + return getMyAvatar()->getWorldPosition(); | |
| 5440 | 5447 | } |
| 5441 | 5448 | |
| 5442 | 5449 | void Application::copyViewFrustum(ViewFrustum& viewOut) const { |
| @@ -5520,6 +5527,8 @@ void Application::clearDomainOctreeDetails() { · 77 unmodified lines | ||
| 5520 | 5527 | DependencyManager::get<ModelCache>()->clearUnusedResources(); |
| 5521 | 5528 | DependencyManager::get<SoundCache>()->clearUnusedResources(); |
| 5522 | 5529 | DependencyManager::get<TextureCache>()->clearUnusedResources(); |
| 5530 | + | |
| 5531 | + getMyAvatar()->setAvatarEntityDataChanged(true); | |
| 5523 | 5532 | } |
| 5524 | 5533 | |
| 5525 | 5534 | void Application::clearDomainAvatars() { |
| @@ -5566,6 +5575,7 @@ void Application::nodeActivated(SharedNodePointer node) { · 40 unmodified lines | ||
| 5566 | 5575 | // so we will do a proper query during update |
| 5567 | 5576 | if (node->getType() == NodeType::EntityServer) { |
| 5568 | 5577 | _lastQueriedTime = 0; |
| 5578 | + _octreeQuery.incrementConnectionID(); | |
| 5569 | 5579 | } |
| 5570 | 5580 | |
| 5571 | 5581 | if (node->getType() == NodeType::AudioMixer) { |
| @@ -5648,7 +5658,7 @@ bool Application::nearbyEntitiesAreReadyForPhysics() { · 76 unmodified lines | ||
| 5648 | 5658 | // whose bounding boxes cannot be computed (it is too loose for our purposes here). Instead we manufacture |
| 5649 | 5659 | // custom filters and use the general-purpose EntityTree::findEntities(filter, ...) |
| 5650 | 5660 | QVector<EntityItemPointer> entities; |
| 5651 | − AABox avatarBox(getMyAvatar()->getPosition() - glm::vec3(PHYSICS_READY_RANGE), glm::vec3(2 * PHYSICS_READY_RANGE)); | |
| 5661 | + AABox avatarBox(getMyAvatar()->getWorldPosition() - glm::vec3(PHYSICS_READY_RANGE), glm::vec3(2 * PHYSICS_READY_RANGE)); | |
| 5652 | 5662 | // create two functions that use avatarBox (entityScan and elementScan), the second calls the first |
| 5653 | 5663 | std::function<bool (EntityItemPointer&)> entityScan = [=](EntityItemPointer& entity) { |
| 5654 | 5664 | if (entity->shouldBePhysical()) { |
| @@ -5763,6 +5773,11 @@ int Application::processOctreeStats(ReceivedMessage& message, SharedNodePointer · 108 unmodified lines | ||
| 5763 | 5773 | void Application::packetSent(quint64 length) { |
| 5764 | 5774 | } |
| 5765 | 5775 | |
| 5776 | +void Application::addingEntityWithCertificate(const QString& certificateID, const QString& placeName) { | |
| 5777 | + auto ledger = DependencyManager::get<Ledger>(); | |
| 5778 | + ledger->updateLocation(certificateID, placeName); | |
| 5779 | +} | |
| 5780 | + | |
| 5766 | 5781 | void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointer scriptEngine) { |
| 5767 | 5782 | |
| 5768 | 5783 | scriptEngine->setEmitScriptUpdatesFunction([this]() { |
| @@ -5845,6 +5860,8 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe · 76 unmodified lines | ||
| 5845 | 5860 | |
| 5846 | 5861 | scriptEngine->registerGlobalObject("RayPick", DependencyManager::get<RayPickScriptingInterface>().data()); |
| 5847 | 5862 | scriptEngine->registerGlobalObject("LaserPointers", DependencyManager::get<LaserPointerScriptingInterface>().data()); |
| 5863 | + scriptEngine->registerGlobalObject("Picks", DependencyManager::get<PickScriptingInterface>().data()); | |
| 5864 | + scriptEngine->registerGlobalObject("Pointers", DependencyManager::get<PointerScriptingInterface>().data()); | |
| 5848 | 5865 | |
| 5849 | 5866 | // Caches |
| 5850 | 5867 | scriptEngine->registerGlobalObject("AnimationCache", DependencyManager::get<AnimationCache>().data()); |
| @@ -5902,6 +5919,8 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe · 51 unmodified lines | ||
| 5902 | 5919 | |
| 5903 | 5920 | qScriptRegisterMetaType(scriptEngine.data(), OverlayIDtoScriptValue, OverlayIDfromScriptValue); |
| 5904 | 5921 | |
| 5922 | + DependencyManager::get<PickScriptingInterface>()->registerMetaTypes(scriptEngine.data()); | |
| 5923 | + | |
| 5905 | 5924 | // connect this script engines printedMessage signal to the global ScriptEngines these various messages |
| 5906 | 5925 | connect(scriptEngine.data(), &ScriptEngine::printedMessage, |
| 5907 | 5926 | DependencyManager::get<ScriptEngines>().data(), &ScriptEngines::onPrintedMessage); |
| @@ -6143,46 +6162,60 @@ bool Application::askToReplaceDomainContent(const QString& url) { · 235 unmodified lines | ||
| 6143 | 6162 | "and restoring content, visit the documentation page at: ", MAX_CHARACTERS_PER_LINE) + |
| 6144 | 6163 | "\nhttps://docs.highfidelity.com/create-and-explore/start-working-in-your-sandbox/restoring-sandbox-content"; |
| 6145 | 6164 | |
| 6146 | − bool agreeToReplaceContent = false; // assume false | |
| 6147 | − agreeToReplaceContent = QMessageBox::Yes == OffscreenUi::question("Are you sure you want to replace this domain's content set?", | |
| 6148 | − infoText, QMessageBox::Yes | QMessageBox::No, QMessageBox::No); | |
| 6149 | − | |
| 6150 | − if (agreeToReplaceContent) { | |
| 6151 | − // Given confirmation, send request to domain server to replace content | |
| 6152 | − qCDebug(interfaceapp) << "Attempting to replace domain content: " << url; | |
| 6153 | − QByteArray urlData(url.toUtf8()); | |
| 6154 | − auto limitedNodeList = DependencyManager::get<LimitedNodeList>(); | |
| 6155 | − limitedNodeList->eachMatchingNode([](const SharedNodePointer& node) { | |
| 6156 | − return node->getType() == NodeType::EntityServer && node->getActiveSocket(); | |
| 6157 | − }, [&urlData, limitedNodeList](const SharedNodePointer& octreeNode) { | |
| 6158 | − auto octreeFilePacket = NLPacket::create(PacketType::OctreeFileReplacementFromUrl, urlData.size(), true); | |
| 6159 | − octreeFilePacket->write(urlData); | |
| 6160 | − limitedNodeList->sendPacket(std::move(octreeFilePacket), *octreeNode); | |
| 6161 | − }); | |
| 6162 | − auto addressManager = DependencyManager::get<AddressManager>(); | |
| 6163 | − addressManager->handleLookupString(DOMAIN_SPAWNING_POINT); | |
| 6164 | − QString newHomeAddress = addressManager->getHost() + DOMAIN_SPAWNING_POINT; | |
| 6165 | − qCDebug(interfaceapp) << "Setting new home bookmark to: " << newHomeAddress; | |
| 6166 | − DependencyManager::get<LocationBookmarks>()->setHomeLocationToAddress(newHomeAddress); | |
| 6167 | − methodDetails = "SuccessfulRequestToReplaceContent"; | |
| 6168 | − } else { | |
| 6169 | − methodDetails = "UserDeclinedToReplaceContent"; | |
| 6170 | − } | |
| 6165 | + ModalDialogListener* dig = OffscreenUi::asyncQuestion("Are you sure you want to replace this domain's content set?", | |
| 6166 | + infoText, QMessageBox::Yes | QMessageBox::No, QMessageBox::No); | |
| 6167 | + | |
| 6168 | + QObject::connect(dig, &ModalDialogListener::response, this, [=] (QVariant answer) { | |
| 6169 | + QString details; | |
| 6170 | + if (static_cast<QMessageBox::StandardButton>(answer.toInt()) == QMessageBox::Yes) { | |
| 6171 | + // Given confirmation, send request to domain server to replace content | |
| 6172 | + qCDebug(interfaceapp) << "Attempting to replace domain content: " << url; | |
| 6173 | + QByteArray urlData(url.toUtf8()); | |
| 6174 | + auto limitedNodeList = DependencyManager::get<LimitedNodeList>(); | |
| 6175 | + limitedNodeList->eachMatchingNode([](const SharedNodePointer& node) { | |
| 6176 | + return node->getType() == NodeType::EntityServer && node->getActiveSocket(); | |
| 6177 | + }, [&urlData, limitedNodeList](const SharedNodePointer& octreeNode) { | |
| 6178 | + auto octreeFilePacket = NLPacket::create(PacketType::OctreeFileReplacementFromUrl, urlData.size(), true); | |
| 6179 | + octreeFilePacket->write(urlData); | |
| 6180 | + limitedNodeList->sendPacket(std::move(octreeFilePacket), *octreeNode); | |
| 6181 | + }); | |
| 6182 | + auto addressManager = DependencyManager::get<AddressManager>(); | |
| 6183 | + addressManager->handleLookupString(DOMAIN_SPAWNING_POINT); | |
| 6184 | + QString newHomeAddress = addressManager->getHost() + DOMAIN_SPAWNING_POINT; | |
| 6185 | + qCDebug(interfaceapp) << "Setting new home bookmark to: " << newHomeAddress; | |
| 6186 | + DependencyManager::get<LocationBookmarks>()->setHomeLocationToAddress(newHomeAddress); | |
| 6187 | + details = "SuccessfulRequestToReplaceContent"; | |
| 6188 | + } else { | |
| 6189 | + details = "UserDeclinedToReplaceContent"; | |
| 6190 | + } | |
| 6191 | + QJsonObject messageProperties = { | |
| 6192 | + { "status", details }, | |
| 6193 | + { "content_set_url", url } | |
| 6194 | + }; | |
| 6195 | + UserActivityLogger::getInstance().logAction("replace_domain_content", messageProperties); | |
| 6196 | + QObject::disconnect(dig, &ModalDialogListener::response, this, nullptr); | |
| 6197 | + }); | |
| 6171 | 6198 | } else { |
| 6172 | 6199 | methodDetails = "ContentSetDidNotOriginateFromMarketplace"; |
| 6200 | + QJsonObject messageProperties = { | |
| 6201 | + { "status", methodDetails }, | |
| 6202 | + { "content_set_url", url } | |
| 6203 | + }; | |
| 6204 | + UserActivityLogger::getInstance().logAction("replace_domain_content", messageProperties); | |
| 6173 | 6205 | } |
| 6174 | 6206 | } else { |
| 6175 | 6207 | methodDetails = "UserDoesNotHavePermissionToReplaceContent"; |
| 6176 | 6208 | static const QString warningMessage = simpleWordWrap("The domain owner must enable 'Replace Content' " |
| 6177 | 6209 | "permissions for you in this domain's server settings before you can continue.", MAX_CHARACTERS_PER_LINE); |
| 6178 | − OffscreenUi::warning("You do not have permissions to replace domain content", warningMessage, | |
| 6210 | + OffscreenUi::asyncWarning("You do not have permissions to replace domain content", warningMessage, | |
| 6179 | 6211 | QMessageBox::Ok, QMessageBox::Ok); |
| 6212 | + | |
| 6213 | + QJsonObject messageProperties = { | |
| 6214 | + { "status", methodDetails }, | |
| 6215 | + { "content_set_url", url } | |
| 6216 | + }; | |
| 6217 | + UserActivityLogger::getInstance().logAction("replace_domain_content", messageProperties); | |
| 6180 | 6218 | } |
| 6181 | − QJsonObject messageProperties = { | |
| 6182 | − { "status", methodDetails }, | |
| 6183 | − { "content_set_url", url } | |
| 6184 | − }; | |
| 6185 | − UserActivityLogger::getInstance().logAction("replace_domain_content", messageProperties); | |
| 6186 | 6219 | return true; |
| 6187 | 6220 | } |
| 6188 | 6221 | |
| @@ -6253,7 +6286,7 @@ void Application::addAssetToWorldFromURL(QString url) { · 64 unmodified lines | ||
| 6253 | 6286 | if (url.contains("filename")) { |
| 6254 | 6287 | filename = url.section("filename=", 1, 1); // Filename is in "?filename=" parameter at end of URL. |
| 6255 | 6288 | } |
| 6256 | − if (url.contains("vr.google.com/downloads")) { | |
| 6289 | + if (url.contains("poly.google.com/downloads")) { | |
| 6257 | 6290 | filename = url.section('/', -1); |
| 6258 | 6291 | if (url.contains("noDownload")) { |
| 6259 | 6292 | filename.remove(".zip?noDownload=false"); |
| @@ -6288,7 +6321,7 @@ void Application::addAssetToWorldFromURLRequestFinished() { · 28 unmodified lines | ||
| 6288 | 6321 | if (url.contains("filename")) { |
| 6289 | 6322 | filename = url.section("filename=", 1, 1); // Filename is in "?filename=" parameter at end of URL. |
| 6290 | 6323 | } |
| 6291 | − if (url.contains("vr.google.com/downloads")) { | |
| 6324 | + if (url.contains("poly.google.com/downloads")) { | |
| 6292 | 6325 | filename = url.section('/', -1); |
| 6293 | 6326 | if (url.contains("noDownload")) { |
| 6294 | 6327 | filename.remove(".zip?noDownload=false"); |
| @@ -6342,20 +6375,14 @@ void Application::addAssetToWorldUnzipFailure(QString filePath) { · 47 unmodified lines | ||
| 6342 | 6375 | addAssetToWorldError(filename, "Couldn't unzip file " + filename + "."); |
| 6343 | 6376 | } |
| 6344 | 6377 | |
| 6345 | −void Application::addAssetToWorld(QString filePath, QString zipFile, bool isZip, bool isBlocks) { | |
| 6378 | +void Application::addAssetToWorld(QString path, QString zipFile, bool isZip, bool isBlocks) { | |
| 6346 | 6379 | // Automatically upload and add asset to world as an alternative manual process initiated by showAssetServerWidget(). |
| 6347 | 6380 | QString mapping; |
| 6348 | − QString path = filePath; | |
| 6349 | 6381 | QString filename = filenameFromPath(path); |
| 6350 | − if (isZip) { | |
| 6351 | − QString assetFolder = zipFile.section("/", -1); | |
| 6352 | − assetFolder.remove(".zip"); | |
| 6353 | − mapping = "/" + assetFolder + "/" + filename; | |
| 6354 | − } else if (isBlocks) { | |
| 6355 | − qCDebug(interfaceapp) << "Path to asset folder: " << zipFile; | |
| 6356 | − QString assetFolder = zipFile.section('/', -1); | |
| 6357 | − assetFolder.remove(".zip?noDownload=false"); | |
| 6358 | − mapping = "/" + assetFolder + "/" + filename; | |
| 6382 | + if (isZip || isBlocks) { | |
| 6383 | + QString assetName = zipFile.section("/", -1).remove(QRegExp("[.]zip(.*)$")); | |
| 6384 | + QString assetFolder = path.section("model_repo/", -1); | |
| 6385 | + mapping = "/" + assetName + "/" + assetFolder; | |
| 6359 | 6386 | } else { |
| 6360 | 6387 | mapping = "/" + filename; |
| 6361 | 6388 | } |
| @@ -6461,9 +6488,9 @@ void Application::addAssetToWorldAddEntity(QString filePath, QString mapping) { · 99 unmodified lines | ||
| 6461 | 6488 | properties.setShapeType(SHAPE_TYPE_SIMPLE_COMPOUND); |
| 6462 | 6489 | properties.setCollisionless(true); // Temporarily set so that doesn't collide with avatar. |
| 6463 | 6490 | properties.setVisible(false); // Temporarily set so that don't see at large unresized dimensions. |
| 6464 | − glm::vec3 positionOffset = getMyAvatar()->getOrientation() * (getMyAvatar()->getSensorToWorldScale() * glm::vec3(0.0f, 0.0f, -2.0f)); | |
| 6465 | − properties.setPosition(getMyAvatar()->getPosition() + positionOffset); | |
| 6466 | − properties.setRotation(getMyAvatar()->getOrientation()); | |
| 6491 | + glm::vec3 positionOffset = getMyAvatar()->getWorldOrientation() * (getMyAvatar()->getSensorToWorldScale() * glm::vec3(0.0f, 0.0f, -2.0f)); | |
| 6492 | + properties.setPosition(getMyAvatar()->getWorldPosition() + positionOffset); | |
| 6493 | + properties.setRotation(getMyAvatar()->getWorldOrientation()); | |
| 6467 | 6494 | properties.setGravity(glm::vec3(0.0f, 0.0f, 0.0f)); |
| 6468 | 6495 | auto entityID = DependencyManager::get<EntityScriptingInterface>()->addEntity(properties); |
| 6469 | 6496 | |
| @@ -6741,8 +6768,10 @@ void Application::handleUnzip(QString zipFile, QStringList unzipFile, bool autoA · 271 unmodified lines | ||
| 6741 | 6768 | if (autoAdd) { |
| 6742 | 6769 | if (!unzipFile.isEmpty()) { |
| 6743 | 6770 | for (int i = 0; i < unzipFile.length(); i++) { |
| 6744 | − qCDebug(interfaceapp) << "Preparing file for asset server: " << unzipFile.at(i); | |
| 6745 | − addAssetToWorld(unzipFile.at(i), zipFile, isZip, isBlocks); | |
| 6771 | + if (QFileInfo(unzipFile.at(i)).isFile()) { | |
| 6772 | + qCDebug(interfaceapp) << "Preparing file for asset server: " << unzipFile.at(i); | |
| 6773 | + addAssetToWorld(unzipFile.at(i), zipFile, isZip, isBlocks); | |
| 6774 | + } | |
| 6746 | 6775 | } |
| 6747 | 6776 | } else { |
| 6748 | 6777 | addAssetToWorldUnzipFailure(zipFile); |
| @@ -6804,6 +6833,10 @@ void Application::loadScriptURLDialog() const { · 55 unmodified lines | ||
| 6804 | 6833 | }); |
| 6805 | 6834 | } |
| 6806 | 6835 | |
| 6836 | +SharedSoundPointer Application::getSampleSound() const { | |
| 6837 | + return _sampleSound; | |
| 6838 | +} | |
| 6839 | + | |
| 6807 | 6840 | void Application::loadLODToolsDialog() { |
| 6808 | 6841 | auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>(); |
| 6809 | 6842 | auto tablet = dynamic_cast<TabletProxy*>(tabletScriptingInterface->getTablet(SYSTEM_TABLET)); |
| @@ -7096,6 +7129,7 @@ DisplayPluginPointer Application::getActiveDisplayPlugin() const { · 286 unmodified lines | ||
| 7096 | 7129 | return _displayPlugin; |
| 7097 | 7130 | } |
| 7098 | 7131 | |
| 7132 | +static const char* EXCLUSION_GROUP_KEY = "exclusionGroup"; | |
| 7099 | 7133 | |
| 7100 | 7134 | static void addDisplayPluginToMenu(DisplayPluginPointer displayPlugin, bool active = false) { |
| 7101 | 7135 | auto menu = Menu::getInstance(); |
| @@ -7131,6 +7165,8 @@ static void addDisplayPluginToMenu(DisplayPluginPointer displayPlugin, bool acti · 29 unmodified lines | ||
| 7131 | 7165 | action->setCheckable(true); |
| 7132 | 7166 | action->setChecked(active); |
| 7133 | 7167 | displayPluginGroup->addAction(action); |
| 7168 | + | |
| 7169 | + action->setProperty(EXCLUSION_GROUP_KEY, QVariant::fromValue(displayPluginGroup)); | |
| 7134 | 7170 | Q_ASSERT(menu->menuItemExists(MenuOption::OutputMenu, name)); |
| 7135 | 7171 | } |
| 7136 | 7172 | |
| @@ -7285,6 +7321,10 @@ void Application::updateDisplayMode() { · 148 unmodified lines | ||
| 7285 | 7321 | menu->setIsOptionChecked(MenuOption::FirstPerson, true); |
| 7286 | 7322 | cameraMenuChanged(); |
| 7287 | 7323 | } |
| 7324 | + | |
| 7325 | + // Remove the mirror camera option from menu if in HMD mode | |
| 7326 | + auto mirrorAction = menu->getActionForOption(MenuOption::FullscreenMirror); | |
| 7327 | + mirrorAction->setVisible(!isHmd); | |
| 7288 | 7328 | |
| 7289 | 7329 | Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin"); |
| 7290 | 7330 | } |
| @@ -7426,51 +7466,6 @@ bool Application::isForeground() const { · 135 unmodified lines | ||
| 7426 | 7466 | return _isForeground && !_window->isMinimized(); |
| 7427 | 7467 | } |
| 7428 | 7468 | |
| 7429 | −void Application::sendMousePressOnEntity(QUuid id, PointerEvent event) { | |
| 7430 | − EntityItemID entityItemID(id); | |
| 7431 | − emit getEntities()->mousePressOnEntity(entityItemID, event); | |
| 7432 | −} | |
| 7433 | − | |
| 7434 | −void Application::sendMouseMoveOnEntity(QUuid id, PointerEvent event) { | |
| 7435 | − EntityItemID entityItemID(id); | |
| 7436 | − emit getEntities()->mouseMoveOnEntity(entityItemID, event); | |
| 7437 | −} | |
| 7438 | − | |
| 7439 | −void Application::sendMouseReleaseOnEntity(QUuid id, PointerEvent event) { | |
| 7440 | − EntityItemID entityItemID(id); | |
| 7441 | − emit getEntities()->mouseReleaseOnEntity(entityItemID, event); | |
| 7442 | −} | |
| 7443 | − | |
| 7444 | −void Application::sendClickDownOnEntity(QUuid id, PointerEvent event) { | |
| 7445 | − EntityItemID entityItemID(id); | |
| 7446 | − emit getEntities()->clickDownOnEntity(entityItemID, event); | |
| 7447 | −} | |
| 7448 | − | |
| 7449 | −void Application::sendHoldingClickOnEntity(QUuid id, PointerEvent event) { | |
| 7450 | − EntityItemID entityItemID(id); | |
| 7451 | − emit getEntities()->holdingClickOnEntity(entityItemID, event); | |
| 7452 | −} | |
| 7453 | − | |
| 7454 | −void Application::sendClickReleaseOnEntity(QUuid id, PointerEvent event) { | |
| 7455 | − EntityItemID entityItemID(id); | |
| 7456 | − emit getEntities()->clickReleaseOnEntity(entityItemID, event); | |
| 7457 | −} | |
| 7458 | − | |
| 7459 | −void Application::sendHoverEnterEntity(QUuid id, PointerEvent event) { | |
| 7460 | − EntityItemID entityItemID(id); | |
| 7461 | − emit getEntities()->hoverEnterEntity(entityItemID, event); | |
| 7462 | −} | |
| 7463 | − | |
| 7464 | −void Application::sendHoverOverEntity(QUuid id, PointerEvent event) { | |
| 7465 | − EntityItemID entityItemID(id); | |
| 7466 | − emit getEntities()->hoverOverEntity(entityItemID, event); | |
| 7467 | −} | |
| 7468 | − | |
| 7469 | −void Application::sendHoverLeaveEntity(QUuid id, PointerEvent event) { | |
| 7470 | − EntityItemID entityItemID(id); | |
| 7471 | − emit getEntities()->hoverLeaveEntity(entityItemID, event); | |
| 7472 | −} | |
| 7473 | − | |
| 7474 | 7469 | // FIXME? perhaps two, one for the main thread and one for the offscreen UI rendering thread? |
| 7475 | 7470 | static const int UI_RESERVED_THREADS = 1; |
| 7476 | 7471 | // Windows won't let you have all the cores |