From c866bd814d6300442a05a23c1b43c7d63166384a Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 19 Jul 2017 12:21:06 -0700 Subject: [PATCH] Make clicks work right --- .../ui/overlays/ContextOverlayInterface.cpp | 2 +- interface/src/ui/overlays/Overlays.cpp | 87 +++++++------------ interface/src/ui/overlays/Overlays.h | 2 +- interface/src/ui/overlays/Planar3DOverlay.h | 1 + .../system/controllers/handControllerGrab.js | 23 +++-- 5 files changed, 50 insertions(+), 65 deletions(-) diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 9182346352..915ddca7bd 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -45,10 +45,10 @@ void ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID& _contextOverlay->setDrawInFront(true); _contextOverlay->setURL("http://i.imgur.com/gksZygp.png"); _contextOverlay->setIsFacingAvatar(true); - _contextOverlay->setDimensions(glm::vec2(0.2f, 0.2f) * glm::distance(entityProperties.getPosition(), qApp->getCamera().getPosition())); _contextOverlayID = qApp->getOverlays().addOverlay(_contextOverlay); } + _contextOverlay->setDimensions(glm::vec2(0.2f, 0.2f) * glm::distance(entityProperties.getPosition(), qApp->getCamera().getPosition())); _contextOverlay->setPosition(entityProperties.getPosition()); _contextOverlay->setRotation(entityProperties.getRotation()); _contextOverlay->setVisible(true); diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 862152bea9..3f175ffcc7 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -818,15 +818,17 @@ static PointerEvent::Button toPointerButton(const QMouseEvent& event) { } } -PointerEvent Overlays::calculateWeb3DPointerEvent(Overlay::Pointer overlay, PickRay ray, +PointerEvent Overlays::calculateOverlayPointerEvent(OverlayID overlayID, PickRay ray, RayToOverlayIntersectionResult rayPickResult, QMouseEvent* event, PointerEvent::EventType eventType) { + auto overlay = std::dynamic_pointer_cast(getOverlay(overlayID)); + if (!overlay) { + return PointerEvent(); + } + glm::vec3 position = overlay->getPosition(); + glm::quat rotation = overlay->getRotation(); + glm::vec2 dimensions = overlay->getSize(); - auto thisOverlay = std::dynamic_pointer_cast(overlay); - - auto position = thisOverlay->getPosition(); - auto rotation = thisOverlay->getRotation(); - auto dimensions = thisOverlay->getSize(); glm::vec2 pos2D = projectOntoOverlayXYPlane(position, rotation, dimensions, ray, rayPickResult); @@ -874,12 +876,7 @@ bool Overlays::mousePressEvent(QMouseEvent* event) { if (rayPickResult.intersects) { _currentClickingOnOverlayID = rayPickResult.overlayID; - // Only Web overlays can have focus. - auto thisWeb3DOverlay = std::dynamic_pointer_cast(getOverlay(_currentClickingOnOverlayID)); - PointerEvent pointerEvent; - if (thisWeb3DOverlay) { - pointerEvent = calculateWeb3DPointerEvent(thisWeb3DOverlay, ray, rayPickResult, event, PointerEvent::Press); - } + PointerEvent pointerEvent = calculateOverlayPointerEvent(_currentClickingOnOverlayID, ray, rayPickResult, event, PointerEvent::Press); emit mousePressOnOverlay(_currentClickingOnOverlayID, pointerEvent); return true; } @@ -895,13 +892,9 @@ bool Overlays::mouseDoublePressEvent(QMouseEvent* event) { if (rayPickResult.intersects) { _currentClickingOnOverlayID = rayPickResult.overlayID; - // Only Web overlays can have focus. - auto thisWeb3DOverlay = std::dynamic_pointer_cast(getOverlay(_currentClickingOnOverlayID)); - if (thisWeb3DOverlay) { - auto pointerEvent = calculateWeb3DPointerEvent(thisWeb3DOverlay, ray, rayPickResult, event, PointerEvent::Press); - emit mouseDoublePressOnOverlay(_currentClickingOnOverlayID, pointerEvent); - return true; - } + auto pointerEvent = calculateOverlayPointerEvent(_currentClickingOnOverlayID, ray, rayPickResult, event, PointerEvent::Press); + emit mouseDoublePressOnOverlay(_currentClickingOnOverlayID, pointerEvent); + return true; } emit mouseDoublePressOffOverlay(); return false; @@ -913,13 +906,8 @@ bool Overlays::mouseReleaseEvent(QMouseEvent* event) { PickRay ray = qApp->computePickRay(event->x(), event->y()); RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray); if (rayPickResult.intersects) { - - // Only Web overlays can have focus. - auto thisWeb3DOverlay = std::dynamic_pointer_cast(getOverlay(rayPickResult.overlayID)); - if (thisWeb3DOverlay) { - auto pointerEvent = calculateWeb3DPointerEvent(thisWeb3DOverlay, ray, rayPickResult, event, PointerEvent::Release); - emit mouseReleaseOnOverlay(rayPickResult.overlayID, pointerEvent); - } + auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Release); + emit mouseReleaseOnOverlay(rayPickResult.overlayID, pointerEvent); } _currentClickingOnOverlayID = UNKNOWN_OVERLAY_ID; @@ -932,40 +920,29 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) { PickRay ray = qApp->computePickRay(event->x(), event->y()); RayToOverlayIntersectionResult rayPickResult = findRayIntersectionForMouseEvent(ray); if (rayPickResult.intersects) { + auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Move); + emit mouseMoveOnOverlay(rayPickResult.overlayID, pointerEvent); - // Only Web overlays can have focus. - auto thisOverlay = std::dynamic_pointer_cast(getOverlay(rayPickResult.overlayID)); - if (thisOverlay) { - auto pointerEvent = calculateWeb3DPointerEvent(thisOverlay, ray, rayPickResult, event, PointerEvent::Move); - emit mouseMoveOnOverlay(rayPickResult.overlayID, pointerEvent); - - // If previously hovering over a different overlay then leave hover on that overlay. - if (_currentHoverOverOverlayID != UNKNOWN_OVERLAY_ID && rayPickResult.overlayID != _currentHoverOverOverlayID) { - auto thisOverlay = std::dynamic_pointer_cast(getOverlay(_currentHoverOverOverlayID)); - if (thisOverlay) { - auto pointerEvent = calculateWeb3DPointerEvent(thisOverlay, ray, rayPickResult, event, PointerEvent::Move); - emit hoverLeaveOverlay(_currentHoverOverOverlayID, pointerEvent); - } - } - - // If hovering over a new overlay then enter hover on that overlay. - if (rayPickResult.overlayID != _currentHoverOverOverlayID) { - emit hoverEnterOverlay(rayPickResult.overlayID, pointerEvent); - } - - // Hover over current overlay. - emit hoverOverOverlay(rayPickResult.overlayID, pointerEvent); - - _currentHoverOverOverlayID = rayPickResult.overlayID; + // If previously hovering over a different overlay then leave hover on that overlay. + if (_currentHoverOverOverlayID != UNKNOWN_OVERLAY_ID && rayPickResult.overlayID != _currentHoverOverOverlayID) { + auto pointerEvent = calculateOverlayPointerEvent(_currentHoverOverOverlayID, ray, rayPickResult, event, PointerEvent::Move); + emit hoverLeaveOverlay(_currentHoverOverOverlayID, pointerEvent); } + + // If hovering over a new overlay then enter hover on that overlay. + if (rayPickResult.overlayID != _currentHoverOverOverlayID) { + emit hoverEnterOverlay(rayPickResult.overlayID, pointerEvent); + } + + // Hover over current overlay. + emit hoverOverOverlay(rayPickResult.overlayID, pointerEvent); + + _currentHoverOverOverlayID = rayPickResult.overlayID; } else { // If previously hovering an overlay then leave hover. if (_currentHoverOverOverlayID != UNKNOWN_OVERLAY_ID) { - auto thisOverlay = std::dynamic_pointer_cast(getOverlay(_currentHoverOverOverlayID)); - if (thisOverlay) { - auto pointerEvent = calculateWeb3DPointerEvent(thisOverlay, ray, rayPickResult, event, PointerEvent::Move); - emit hoverLeaveOverlay(_currentHoverOverOverlayID, pointerEvent); - } + auto pointerEvent = calculateOverlayPointerEvent(_currentHoverOverOverlayID, ray, rayPickResult, event, PointerEvent::Move); + emit hoverLeaveOverlay(_currentHoverOverOverlayID, pointerEvent); _currentHoverOverOverlayID = UNKNOWN_OVERLAY_ID; } diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 7235937077..d52f6d5947 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -337,7 +337,7 @@ private: #endif bool _enabled = true; - PointerEvent calculateWeb3DPointerEvent(Overlay::Pointer overlay, PickRay ray, RayToOverlayIntersectionResult rayPickResult, + PointerEvent Overlays::calculateOverlayPointerEvent(OverlayID overlayID, PickRay ray, RayToOverlayIntersectionResult rayPickResult, QMouseEvent* event, PointerEvent::EventType eventType); OverlayID _currentClickingOnOverlayID { UNKNOWN_OVERLAY_ID }; diff --git a/interface/src/ui/overlays/Planar3DOverlay.h b/interface/src/ui/overlays/Planar3DOverlay.h index 9c502ab75e..2ccf2c4513 100644 --- a/interface/src/ui/overlays/Planar3DOverlay.h +++ b/interface/src/ui/overlays/Planar3DOverlay.h @@ -21,6 +21,7 @@ public: Planar3DOverlay(const Planar3DOverlay* planar3DOverlay); virtual AABox getBounds() const override; + glm::vec2 getSize() const { return _dimensions; }; glm::vec2 getDimensions() const { return _dimensions; } void setDimensions(float value) { _dimensions = glm::vec2(value); } diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index f173295a1e..5fd4df0e4d 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -188,6 +188,7 @@ var USE_BLACKLIST = true; var blacklist = []; var entityWithContextOverlay = false; +var contextualHand = -1; var FORBIDDEN_GRAB_NAMES = ["Grab Debug Entity", "grab pointer"]; var FORBIDDEN_GRAB_TYPES = ["Unknown", "Light", "PolyLine", "Zone"]; @@ -352,7 +353,9 @@ function projectOntoXYPlane(worldPos, position, rotation, dimensions, registrati function projectOntoEntityXYPlane(entityID, worldPos) { var props = entityPropertiesCache.getProps(entityID); - return projectOntoXYPlane(worldPos, props.position, props.rotation, props.dimensions, props.registrationPoint); + if (props) { + return projectOntoXYPlane(worldPos, props.position, props.rotation, props.dimensions, props.registrationPoint); + } } function projectOntoOverlayXYPlane(overlayID, worldPos) { @@ -2186,10 +2189,7 @@ function MyController(hand) { }; this.searchExit = function () { - if (entityWithContextOverlay) { - ContextOverlay.destroyContextOverlay(entityWithContextOverlay); - entityWithContextOverlay = false; - } + contextualHand = -1; }; this.search = function(deltaTime, timestamp) { @@ -2226,11 +2226,11 @@ function MyController(hand) { ContextOverlay.destroyContextOverlay(entityWithContextOverlay); entityWithContextOverlay = false; } - Script.setTimeout(function() { - if (rayPickInfo.entityID === entityWithContextOverlay) { + Script.setTimeout(function () { + if (rayPickInfo.entityID === entityWithContextOverlay && contextualHand !== -1) { var pointerEvent = { type: "Move", - id: this.hand + 1, // 0 is reserved for hardware mouse + id: contextualHand + 1, // 0 is reserved for hardware mouse pos2D: projectOntoEntityXYPlane(rayPickInfo.entityID, rayPickInfo.intersection), pos3D: rayPickInfo.intersection, normal: rayPickInfo.normal, @@ -2241,6 +2241,7 @@ function MyController(hand) { } }, 500); entityWithContextOverlay = rayPickInfo.entityID; + contextualHand = this.hand; } var candidateHotSpotEntities = Entities.findEntities(handPosition, MAX_EQUIP_HOTSPOT_RADIUS); @@ -3488,6 +3489,11 @@ function MyController(hand) { var existingSearchDistance = this.searchSphereDistance; this.release(); + if (entityWithContextOverlay) { + ContextOverlay.destroyContextOverlay(entityWithContextOverlay); + entityWithContextOverlay = false; + } + if (isInEditMode()) { this.searchSphereDistance = existingSearchDistance; } @@ -3624,6 +3630,7 @@ function MyController(hand) { }; Overlays.sendMousePressOnOverlay(this.grabbedOverlay, pointerEvent); + entityWithContextOverlay = false; this.touchingEnterTimer = 0; this.touchingEnterPointerEvent = pointerEvent;