From 1e3549d2637bd7ee30f67f0cd32c6b7ed239cbc3 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 2 Nov 2018 08:33:14 +1300 Subject: [PATCH 1/4] Increase delay in shrinking the mini tablet after start of trigger --- scripts/system/miniTablet.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/miniTablet.js b/scripts/system/miniTablet.js index a2f0d074f0..63ee91d976 100644 --- a/scripts/system/miniTablet.js +++ b/scripts/system/miniTablet.js @@ -551,7 +551,7 @@ // Trigger values. leftTriggerOn = 0, rightTriggerOn = 0, - MAX_TRIGGER_ON_TIME = 100, + MAX_TRIGGER_ON_TIME = 400, // Visibility. MAX_HAND_CAMERA_ANGLE = 30, From 8924f0832a547068fb73989b72fe63bb58eeafc0 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 2 Nov 2018 18:06:00 +1300 Subject: [PATCH 2/4] Use half angles relative to palm normal for mini tablet visibility --- scripts/system/miniTablet.js | 65 +++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/scripts/system/miniTablet.js b/scripts/system/miniTablet.js index 63ee91d976..16673d373f 100644 --- a/scripts/system/miniTablet.js +++ b/scripts/system/miniTablet.js @@ -250,11 +250,8 @@ } - function getUIPositionAndRotation(hand) { - return { - position: MINI_POSITIONS[hand], - rotation: MINI_ROTATIONS[hand] - }; + function getUIPosition(hand) { + return MINI_POSITIONS[hand]; } function getMiniTabletID() { @@ -492,7 +489,7 @@ create(); return { - getUIPositionAndRotation: getUIPositionAndRotation, + getUIPosition: getUIPosition, getMiniTabletID: getMiniTabletID, getMiniTabletProperties: getMiniTabletProperties, isLaserPointingAt: isLaserPointingAt, @@ -554,13 +551,22 @@ MAX_TRIGGER_ON_TIME = 400, // Visibility. - MAX_HAND_CAMERA_ANGLE = 30, - MAX_CAMERA_HAND_ANGLE = 30, + MAX_MEDIAL_FINGER_CAMERA_ANGLE = 25, // From palm normal along palm towards fingers. + MAX_MEDIAL_WRIST_CAMERA_ANGLE = 65, // From palm normal along palm towards wrist. + MAX_LATERAL_THUMB_CAMERA_ANGLE = 25, // From palm normal across palm towards of thumb. + MAX_LATERAL_PINKY_CAMERA_ANGLE = 25, // From palm normal across palm towards pinky. DEGREES_180 = 180, - MAX_HAND_CAMERA_ANGLE_COS = Math.cos(Math.PI * MAX_HAND_CAMERA_ANGLE / DEGREES_180), - MAX_CAMERA_HAND_ANGLE_COS = Math.cos(Math.PI * MAX_CAMERA_HAND_ANGLE / DEGREES_180), + DEGREES_TO_RADIANS = Math.PI / DEGREES_180, + MAX_MEDIAL_FINGER_CAMERA_ANGLE_RAD = DEGREES_TO_RADIANS * MAX_MEDIAL_FINGER_CAMERA_ANGLE, + MAX_MEDIAL_WRIST_CAMERA_ANGLE_RAD = DEGREES_TO_RADIANS * MAX_MEDIAL_WRIST_CAMERA_ANGLE, + MAX_LATERAL_THUMB_CAMERA_ANGLE_RAD = DEGREES_TO_RADIANS * MAX_LATERAL_THUMB_CAMERA_ANGLE, + MAX_LATERAL_PINKY_CAMERA_ANGLE_RAD = DEGREES_TO_RADIANS * MAX_LATERAL_PINKY_CAMERA_ANGLE, + MAX_CAMERA_MINI_ANGLE = 30, + MAX_CAMERA_MINI_ANGLE_COS = Math.cos(MAX_CAMERA_MINI_ANGLE * DEGREES_TO_RADIANS), HIDING_DELAY = 1000, // ms - lastVisible = [0, 0]; + lastVisible = [0, 0], + + HALF_PI = Math.PI / 2; function enterMiniDisabled() { @@ -597,11 +603,13 @@ jointIndex, handPosition, handOrientation, - uiPositionAndOrientation, miniPosition, - miniOrientation, miniToCameraDirection, - cameraToHand; + medialHandVector, + lateralHandVector, + medialAngle, + lateralAngle, + cameraToMini; // Shouldn't show mini tablet if hand isn't being controlled. pose = Controller.getPoseValue(hand === LEFT_HAND ? Controller.Standard.LeftHand : Controller.Standard.RightHand); @@ -646,15 +654,24 @@ Vec3.multiplyQbyV(MyAvatar.orientation, MyAvatar.getAbsoluteJointTranslationInObjectFrame(jointIndex))); handOrientation = Quat.multiply(MyAvatar.orientation, MyAvatar.getAbsoluteJointRotationInObjectFrame(jointIndex)); - uiPositionAndOrientation = ui.getUIPositionAndRotation(hand); + var uiPosition = ui.getUIPosition(hand); miniPosition = Vec3.sum(handPosition, Vec3.multiply(MyAvatar.sensorToWorldScale, - Vec3.multiplyQbyV(handOrientation, uiPositionAndOrientation.position))); - miniOrientation = Quat.multiply(handOrientation, uiPositionAndOrientation.rotation); + Vec3.multiplyQbyV(handOrientation, uiPosition))); miniToCameraDirection = Vec3.normalize(Vec3.subtract(Camera.position, miniPosition)); - show = Vec3.dot(miniToCameraDirection, Quat.getForward(miniOrientation)) > MAX_HAND_CAMERA_ANGLE_COS; - show = show || (-Vec3.dot(miniToCameraDirection, Quat.getForward(handOrientation)) > MAX_HAND_CAMERA_ANGLE_COS); - cameraToHand = -Vec3.dot(miniToCameraDirection, Quat.getForward(Camera.orientation)); - show = show && (cameraToHand > MAX_CAMERA_HAND_ANGLE_COS); + + // Mini tablet aimed toward camera? + medialHandVector = Vec3.multiplyQbyV(handOrientation, Vec3.UNIT_NEG_Y); + lateralHandVector = Vec3.multiplyQbyV(handOrientation, hand === LEFT_HAND ? Vec3.UNIT_X : Vec3.UNIT_NEG_X); + medialAngle = Math.acos(Vec3.dot(medialHandVector, miniToCameraDirection)) - HALF_PI; + lateralAngle = Math.acos(Vec3.dot(lateralHandVector, miniToCameraDirection)) - HALF_PI; + show = -MAX_MEDIAL_WRIST_CAMERA_ANGLE_RAD <= medialAngle + && medialAngle <= MAX_MEDIAL_FINGER_CAMERA_ANGLE_RAD + && -MAX_LATERAL_PINKY_CAMERA_ANGLE_RAD <= lateralAngle + && lateralAngle <= MAX_LATERAL_THUMB_CAMERA_ANGLE_RAD; + + // Camera looking at mini tablet? + cameraToMini = -Vec3.dot(miniToCameraDirection, Quat.getForward(Camera.orientation)); + show = show && (cameraToMini > MAX_CAMERA_MINI_ANGLE_COS); // Persist showing for a while after it would otherwise be hidden. if (show) { @@ -666,7 +683,7 @@ return { show: show, - cameraToHand: cameraToHand + cameraToMini: cameraToMini }; } @@ -689,7 +706,7 @@ showRight = shouldShowMini(RIGHT_HAND); if (showLeft.show && showRight.show) { // Both hands would be pointing at camera; show the one the camera is gazing at. - if (showLeft.cameraToHand > showRight.cameraToHand) { + if (showLeft.cameraToMini > showRight.cameraToMini) { setState(MINI_SHOWING, LEFT_HAND); } else { setState(MINI_SHOWING, RIGHT_HAND); @@ -751,7 +768,7 @@ showLeft = shouldShowMini(LEFT_HAND); showRight = shouldShowMini(RIGHT_HAND); if (showLeft.show && showRight.show) { - if (showLeft.cameraToHand > showRight.cameraToHand) { + if (showLeft.cameraToMini > showRight.cameraToMini) { if (miniHand !== LEFT_HAND) { setState(MINI_HIDING); } From 55d0822b1a3224af0c95de0ed41de965693a80b7 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 2 Nov 2018 18:18:41 +1300 Subject: [PATCH 3/4] Delay showing mini tablet --- scripts/system/miniTablet.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/scripts/system/miniTablet.js b/scripts/system/miniTablet.js index 16673d373f..a4cd0baf45 100644 --- a/scripts/system/miniTablet.js +++ b/scripts/system/miniTablet.js @@ -563,6 +563,8 @@ MAX_LATERAL_PINKY_CAMERA_ANGLE_RAD = DEGREES_TO_RADIANS * MAX_LATERAL_PINKY_CAMERA_ANGLE, MAX_CAMERA_MINI_ANGLE = 30, MAX_CAMERA_MINI_ANGLE_COS = Math.cos(MAX_CAMERA_MINI_ANGLE * DEGREES_TO_RADIANS), + SHOWING_DELAY = 1000, // ms + lastInvisible = [0, 0], HIDING_DELAY = 1000, // ms lastVisible = [0, 0], @@ -609,7 +611,8 @@ lateralHandVector, medialAngle, lateralAngle, - cameraToMini; + cameraToMini, + now; // Shouldn't show mini tablet if hand isn't being controlled. pose = Controller.getPoseValue(hand === LEFT_HAND ? Controller.Standard.LeftHand : Controller.Standard.RightHand); @@ -673,11 +676,19 @@ cameraToMini = -Vec3.dot(miniToCameraDirection, Quat.getForward(Camera.orientation)); show = show && (cameraToMini > MAX_CAMERA_MINI_ANGLE_COS); + // Delay showing for a while after it would otherwise be shown, unless it was showing on the other hand. + now = Date.now(); + if (show) { + show = now - lastInvisible[hand] >= SHOWING_DELAY || now - lastVisible[otherHand(hand)] <= HIDING_DELAY; + } else { + lastInvisible[hand] = now; + } + // Persist showing for a while after it would otherwise be hidden. if (show) { - lastVisible[hand] = Date.now(); + lastVisible[hand] = now; } else { - show = Date.now() - lastVisible[hand] <= HIDING_DELAY; + show = now - lastVisible[hand] <= HIDING_DELAY; } } From aa952e91429af6ee05224aa5c9815c4e2f163be1 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 6 Dec 2018 15:24:03 +1300 Subject: [PATCH 4/4] Fix mini tablet visibility angle calculations --- scripts/system/miniTablet.js | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/scripts/system/miniTablet.js b/scripts/system/miniTablet.js index a933116dc8..780dacf85e 100644 --- a/scripts/system/miniTablet.js +++ b/scripts/system/miniTablet.js @@ -567,9 +567,7 @@ SHOWING_DELAY = 1000, // ms lastInvisible = [0, 0], HIDING_DELAY = 1000, // ms - lastVisible = [0, 0], - - HALF_PI = Math.PI / 2; + lastVisible = [0, 0]; function enterMiniDisabled() { @@ -608,8 +606,12 @@ handOrientation, miniPosition, miniToCameraDirection, + normalHandVector, medialHandVector, lateralHandVector, + normalDot, + medialDot, + lateralDot, medialAngle, lateralAngle, cameraToMini, @@ -664,14 +666,18 @@ miniToCameraDirection = Vec3.normalize(Vec3.subtract(Camera.position, miniPosition)); // Mini tablet aimed toward camera? - medialHandVector = Vec3.multiplyQbyV(handOrientation, Vec3.UNIT_NEG_Y); + medialHandVector = Vec3.multiplyQbyV(handOrientation, Vec3.UNIT_Y); lateralHandVector = Vec3.multiplyQbyV(handOrientation, hand === LEFT_HAND ? Vec3.UNIT_X : Vec3.UNIT_NEG_X); - medialAngle = Math.acos(Vec3.dot(medialHandVector, miniToCameraDirection)) - HALF_PI; - lateralAngle = Math.acos(Vec3.dot(lateralHandVector, miniToCameraDirection)) - HALF_PI; + normalHandVector = Vec3.multiplyQbyV(handOrientation, Vec3.UNIT_Z); + medialDot = Vec3.dot(medialHandVector, miniToCameraDirection); + lateralDot = Vec3.dot(lateralHandVector, miniToCameraDirection); + normalDot = Vec3.dot(normalHandVector, miniToCameraDirection); + medialAngle = Math.atan2(medialDot, normalDot); + lateralAngle = Math.atan2(lateralDot, normalDot); show = -MAX_MEDIAL_WRIST_CAMERA_ANGLE_RAD <= medialAngle && medialAngle <= MAX_MEDIAL_FINGER_CAMERA_ANGLE_RAD - && -MAX_LATERAL_PINKY_CAMERA_ANGLE_RAD <= lateralAngle - && lateralAngle <= MAX_LATERAL_THUMB_CAMERA_ANGLE_RAD; + && -MAX_LATERAL_THUMB_CAMERA_ANGLE_RAD <= lateralAngle + && lateralAngle <= MAX_LATERAL_PINKY_CAMERA_ANGLE_RAD; // Camera looking at mini tablet? cameraToMini = -Vec3.dot(miniToCameraDirection, Quat.getForward(Camera.orientation));