diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2dc3645be0..1bd6af2eba 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -8476,6 +8476,16 @@ QUuid Application::getTabletFrameID() const { return HMD->getCurrentTabletFrameID(); } +QVector Application::getTabletIDs() const { + // Most important overlays first. + QVector result; + auto HMD = DependencyManager::get(); + result << HMD->getCurrentTabletScreenID(); + result << HMD->getCurrentHomeButtonID(); + result << HMD->getCurrentTabletFrameID(); + return result; +} + void Application::setAvatarOverrideUrl(const QUrl& url, bool save) { _avatarOverrideUrl = url; _saveAvatarOverrideUrl = save; diff --git a/interface/src/Application.h b/interface/src/Application.h index 75260b910f..c75c2e9efc 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -298,6 +298,7 @@ public: OverlayID getTabletScreenID() const; OverlayID getTabletHomeButtonID() const; QUuid getTabletFrameID() const; // may be an entity or an overlay + QVector getTabletIDs() const; // In order of most important IDs first. void setAvatarOverrideUrl(const QUrl& url, bool save); void clearAvatarOverrideUrl() { _avatarOverrideUrl = QUrl(); _saveAvatarOverrideUrl = false; } diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index e05c44c264..f4c98bb9e0 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -532,6 +532,8 @@ RayToOverlayIntersectionResult Overlays::findRayIntersectionVector(const PickRay bool visibleOnly, bool collidableOnly) { float bestDistance = std::numeric_limits::max(); bool bestIsFront = false; + bool bestIsTablet = false; + auto tabletIDs = qApp->getTabletIDs(); QMutexLocker locker(&_mutex); RayToOverlayIntersectionResult result; @@ -554,10 +556,11 @@ RayToOverlayIntersectionResult Overlays::findRayIntersectionVector(const PickRay if (thisOverlay->findRayIntersectionExtraInfo(ray.origin, ray.direction, thisDistance, thisFace, thisSurfaceNormal, thisExtraInfo, precisionPicking)) { bool isDrawInFront = thisOverlay->getDrawInFront(); - if ((bestIsFront && isDrawInFront && thisDistance < bestDistance) - || (!bestIsFront && (isDrawInFront || thisDistance < bestDistance))) { - + bool isTablet = tabletIDs.contains(thisID); + if ((isDrawInFront && !bestIsFront && !bestIsTablet) + || ((isTablet || isDrawInFront || !bestIsFront) && thisDistance < bestDistance)) { bestIsFront = isDrawInFront; + bestIsTablet = isTablet; bestDistance = thisDistance; result.intersects = true; result.distance = thisDistance; @@ -828,40 +831,12 @@ PointerEvent Overlays::calculateOverlayPointerEvent(OverlayID overlayID, PickRay } -RayToOverlayIntersectionResult Overlays::findRayIntersectionForMouseEvent(PickRay ray) { - QVector overlaysToInclude; - QVector overlaysToDiscard; - RayToOverlayIntersectionResult rayPickResult; - - // first priority is tablet screen - overlaysToInclude << qApp->getTabletScreenID(); - rayPickResult = findRayIntersectionVector(ray, true, overlaysToInclude, overlaysToDiscard); - if (rayPickResult.intersects) { - return rayPickResult; - } - // then tablet home button - overlaysToInclude.clear(); - overlaysToInclude << qApp->getTabletHomeButtonID(); - rayPickResult = findRayIntersectionVector(ray, true, overlaysToInclude, overlaysToDiscard); - if (rayPickResult.intersects) { - return rayPickResult; - } - // then tablet frame - overlaysToInclude.clear(); - overlaysToInclude << OverlayID(qApp->getTabletFrameID()); - rayPickResult = findRayIntersectionVector(ray, true, overlaysToInclude, overlaysToDiscard); - if (rayPickResult.intersects) { - return rayPickResult; - } - // then whatever - return findRayIntersection(ray); -} - bool Overlays::mousePressEvent(QMouseEvent* event) { PerformanceTimer perfTimer("Overlays::mousePressEvent"); PickRay ray = qApp->computePickRay(event->x(), event->y()); - RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray); + RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector(), + QVector()); if (rayPickResult.intersects) { _currentClickingOnOverlayID = rayPickResult.overlayID; @@ -901,7 +876,8 @@ bool Overlays::mouseDoublePressEvent(QMouseEvent* event) { PerformanceTimer perfTimer("Overlays::mouseDoublePressEvent"); PickRay ray = qApp->computePickRay(event->x(), event->y()); - RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray); + RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector(), + QVector()); if (rayPickResult.intersects) { _currentClickingOnOverlayID = rayPickResult.overlayID; @@ -964,7 +940,8 @@ bool Overlays::mouseReleaseEvent(QMouseEvent* event) { PerformanceTimer perfTimer("Overlays::mouseReleaseEvent"); PickRay ray = qApp->computePickRay(event->x(), event->y()); - RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray); + RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector(), + QVector()); if (rayPickResult.intersects) { auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Release); mouseReleasePointerEvent(rayPickResult.overlayID, pointerEvent); @@ -993,7 +970,8 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) { PerformanceTimer perfTimer("Overlays::mouseMoveEvent"); PickRay ray = qApp->computePickRay(event->x(), event->y()); - RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray); + RayToOverlayIntersectionResult rayPickResult = findRayIntersectionVector(ray, true, QVector(), + QVector()); if (rayPickResult.intersects) { auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Move); mouseMovePointerEvent(rayPickResult.overlayID, pointerEvent); diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 21b9e93648..208fc8d78d 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -44,8 +44,7 @@ void OverlayPropertyResultFromScriptValue(const QScriptValue& object, OverlayPro const OverlayID UNKNOWN_OVERLAY_ID = OverlayID(); /**jsdoc - * The result of a {@link PickRay} search using {@link Overlays.findRayIntersection|findRayIntersection} or - * {@link Overlays.findRayIntersectionVector|findRayIntersectionVector}. + * The result of a {@link PickRay} search using {@link Overlays.findRayIntersection|findRayIntersection}. * @typedef {object} Overlays.RayToOverlayIntersectionResult * @property {boolean} intersects - true if the {@link PickRay} intersected with a 3D overlay, otherwise * false. @@ -383,7 +382,11 @@ public slots: OverlayPropertyResult getOverlaysProperties(const QVariant& overlaysProperties); /**jsdoc - * Find the closest 3D overlay intersected by a {@link PickRay}. + * Find the closest 3D overlay intersected by a {@link PickRay}. Overlays with their drawInFront property set + * to true have priority over overlays that don't, except that tablet overlays have priority over any + * drawInFront overlays behind them. I.e., if a drawInFront overlay is behind one that isn't + * drawInFront, the drawInFront overlay is returned, but if a tablet overlay is in front of a + * drawInFront overlay, the tablet overlay is returned. * @function Overlays.findRayIntersection * @param {PickRay} pickRay - The PickRay to use for finding overlays. * @param {boolean} [precisionPicking=false] - Unused; exists to match Entity API. @@ -750,8 +753,6 @@ private: OverlayID _currentClickingOnOverlayID { UNKNOWN_OVERLAY_ID }; OverlayID _currentHoverOverOverlayID { UNKNOWN_OVERLAY_ID }; - RayToOverlayIntersectionResult findRayIntersectionForMouseEvent(PickRay ray); - private slots: void mousePressPointerEvent(const OverlayID& overlayID, const PointerEvent& event); void mouseMovePointerEvent(const OverlayID& overlayID, const PointerEvent& event);