From 5796cbc898b3c82a02718339f6b25704e7d3af01 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Mon, 27 Mar 2017 10:26:33 -0700 Subject: [PATCH 1/2] Bug-fix for touching deleted entities or overlays. --- .../system/controllers/handControllerGrab.js | 51 ++++++++++++++----- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index c8b78b4d08..c93a721248 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -28,7 +28,7 @@ Script.include("/~/system/libraries/controllers.js"); // var WANT_DEBUG = false; -var WANT_DEBUG_STATE = true; +var WANT_DEBUG_STATE = false; var WANT_DEBUG_SEARCH_NAME = null; var FORCE_IGNORE_IK = false; @@ -670,12 +670,12 @@ function sendTouchMoveEventToStylusTarget(hand, stylusTarget) { } } +// will return undefined if entity does not exist. function calculateStylusTargetFromEntity(stylusTip, entityID) { var props = entityPropertiesCache.getProps(entityID); - - // entity could have been deleted. - if (props === undefined) { - return undefined; + if (props.rotation === undefined) { + // if rotation is missing from props object, then this entity has probably been deleted. + return; } // project stylus tip onto entity plane. @@ -706,16 +706,18 @@ function calculateStylusTargetFromEntity(stylusTip, entityID) { }; } +// will return undefined if overlayID does not exist. function calculateStylusTargetFromOverlay(stylusTip, overlayID) { var overlayPosition = Overlays.getProperty(overlayID, "position"); - - // overlay could have been deleted. if (overlayPosition === undefined) { - return undefined; + return; } // project stylusTip onto overlay plane. var overlayRotation = Overlays.getProperty(overlayID, "rotation"); + if (overlayRotation === undefined) { + return; + } var normal = Vec3.multiplyQbyV(overlayRotation, {x: 0, y: 0, z: 1}); var distance = Vec3.dot(Vec3.subtract(stylusTip.position, overlayPosition), normal); var position = Vec3.subtract(stylusTip.position, Vec3.multiply(normal, distance)); @@ -724,16 +726,28 @@ function calculateStylusTargetFromOverlay(stylusTip, overlayID) { var invRot = Quat.inverse(overlayRotation); var localPos = Vec3.multiplyQbyV(invRot, Vec3.subtract(position, overlayPosition)); var dpi = Overlays.getProperty(overlayID, "dpi"); + if (dpi === undefined) { + return; + } var dimensions; if (dpi) { // Calculate physical dimensions for web3d overlay from resolution and dpi; "dimensions" property is used as a scale. var resolution = Overlays.getProperty(overlayID, "resolution"); + if (resolution === undefined) { + return; + } resolution.z = 1; // Circumvent divide-by-zero. var scale = Overlays.getProperty(overlayID, "dimensions"); + if (scale === undefined) { + return; + } scale.z = 0.01; // overlay dimensions are 2D, not 3D. dimensions = Vec3.multiplyVbyV(Vec3.multiply(resolution, INCHES_TO_METERS / dpi), scale); } else { dimensions = Overlays.getProperty(overlayID, "dimensions"); + if (dimensions === undefined) { + return; + } if (!dimensions.z) { dimensions.z = 0.01; // sometimes overlay dimensions are 2D, not 3D. } @@ -1631,22 +1645,31 @@ function MyController(hand) { var stylusTargets = []; var candidateEntities = Entities.findEntities(tipPosition, WEB_DISPLAY_STYLUS_DISTANCE); entityPropertiesCache.addEntities(candidateEntities); - var i, props; + var i, props, stylusTarget; for (i = 0; i < candidateEntities.length; i++) { props = entityPropertiesCache.getProps(candidateEntities[i]); if (props && (props.type === "Web" || this.isTablet(candidateEntities[i]))) { - stylusTargets.push(calculateStylusTargetFromEntity(this.stylusTip, candidateEntities[i])); + stylusTarget = calculateStylusTargetFromEntity(this.stylusTip, candidateEntities[i]); + if (stylusTarget) { + stylusTargets.push(stylusTarget); + } } } // add the tabletScreen, if it is valid if (HMD.tabletScreenID && HMD.tabletScreenID !== NULL_UUID && Overlays.getProperty(HMD.tabletScreenID, "visible")) { - stylusTargets.push(calculateStylusTargetFromOverlay(this.stylusTip, HMD.tabletScreenID)); + stylusTarget = calculateStylusTargetFromOverlay(this.stylusTip, HMD.tabletScreenID); + if (stylusTarget) { + stylusTargets.push(stylusTarget); + } } // add the tablet home button. if (HMD.homeButtonID && HMD.homeButtonID !== NULL_UUID && Overlays.getProperty(HMD.homeButtonID, "visible")) { - stylusTargets.push(calculateStylusTargetFromOverlay(this.stylusTip, HMD.homeButtonID)); + stylusTarget = calculateStylusTargetFromOverlay(this.stylusTip, HMD.homeButtonID); + if (stylusTarget) { + stylusTargets.push(stylusTarget); + } } var TABLET_MIN_HOVER_DISTANCE = 0.01; @@ -3582,6 +3605,10 @@ function MyController(hand) { this.stylusTouchingExit = function () { + if (this.stylusTarget === undefined) { + return; + } + // special case to handle home button. if (this.stylusTarget.overlayID === HMD.homeButtonID) { Messages.sendLocalMessage("home", this.stylusTarget.overlayID); From a0c42bacdba585c06423078ab1ab6e2649bda401 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Mon, 27 Mar 2017 14:26:17 -0700 Subject: [PATCH 2/2] Fix problem with ContextMenu triggering on button up and button down. This is fixed by clearing the ButtonPressedMap in the KeyboardMouseDevice every update. Previously, this button would never be cleared, causing other controller actions mapped to the same button to have the incorrect state. In this case, ContextMenu action would become 2 when pressed and 1 when released, anytime after the right mouse button was pressed. --- .../input-plugins/src/input-plugins/KeyboardMouseDevice.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp index ddb2f482a1..b5a2fc6b3c 100755 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp @@ -25,6 +25,7 @@ void KeyboardMouseDevice::pluginUpdate(float deltaTime, const controller::InputC auto userInputMapper = DependencyManager::get(); userInputMapper->withLock([&, this]() { _inputDevice->update(deltaTime, inputCalibrationData); + eraseMouseClicked(); _inputDevice->_axisStateMap[MOUSE_AXIS_X] = _lastCursor.x(); _inputDevice->_axisStateMap[MOUSE_AXIS_Y] = _lastCursor.y(); @@ -78,8 +79,6 @@ void KeyboardMouseDevice::mousePressEvent(QMouseEvent* event) { _mousePressPos = event->pos(); _clickDeadspotActive = true; - - eraseMouseClicked(); } void KeyboardMouseDevice::mouseReleaseEvent(QMouseEvent* event) { @@ -122,7 +121,6 @@ void KeyboardMouseDevice::mouseMoveEvent(QMouseEvent* event) { const int CLICK_EVENT_DEADSPOT = 6; // pixels if (_clickDeadspotActive && (_mousePressPos - currentPos).manhattanLength() > CLICK_EVENT_DEADSPOT) { - eraseMouseClicked(); _clickDeadspotActive = false; } }