diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 33e67f7ebf..cd3c9fe418 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -13,11 +13,12 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -/* global SPACE_LOCAL, SelectionManager */ +/* global SelectionManager, grid, rayPlaneIntersection, rayPlaneIntersection2, pushCommandForSelections, + getMainTabletIDs, getControllerWorldLocation */ -SPACE_LOCAL = "local"; -SPACE_WORLD = "world"; -HIGHLIGHT_LIST_NAME = "editHandleHighlightList"; +var SPACE_LOCAL = "local"; +var SPACE_WORLD = "world"; +var HIGHLIGHT_LIST_NAME = "editHandleHighlightList"; Script.include([ "./controllers.js", @@ -84,7 +85,7 @@ SelectionManager = (function() { outlineWidth: 3, isOutlineSmooth: true }; - //disabling this for now as it is causing rendering issues with the other handle overlays + // disabling this for now as it is causing rendering issues with the other handle overlays //Selection.enableListHighlight(HIGHLIGHT_LIST_NAME, editHandleOutlineStyle); that.savedProperties = {}; @@ -192,7 +193,7 @@ SelectionManager = (function() { } }); return duplicatedEntityIDs; - } + }; that._update = function(selectionUpdated) { var properties = null; @@ -270,11 +271,12 @@ SelectionManager = (function() { // Normalize degrees to be in the range (-180, 180) function normalizeDegrees(degrees) { - degrees = ((degrees + 180) % 360) - 180; - if (degrees <= -180) { - degrees += 360; + var maxDegrees = 360; + var halfMaxDegrees = maxDegrees / 2; + degrees = ((degrees + halfMaxDegrees) % maxDegrees) - halfMaxDegrees; + if (degrees <= -halfMaxDegrees) { + degrees += maxDegrees; } - return degrees; } @@ -284,14 +286,14 @@ SelectionDisplay = (function() { var NEGATE_VECTOR = -1; - var COLOR_GREEN = { red:31, green:198, blue:166 }; - var COLOR_BLUE = { red:0, green:147, blue:197 }; - var COLOR_RED = { red:226, green:51, blue:77 }; - var COLOR_HOVER = { red:227, green:227, blue:227 }; + var COLOR_GREEN = { red: 31, green: 198, blue: 166 }; + var COLOR_BLUE = { red: 0, green: 147, blue: 197 }; + var COLOR_RED = { red: 226, green: 51, blue: 77 }; + var COLOR_HOVER = { red: 227, green: 227, blue: 227 }; var COLOR_ROTATE_CURRENT_RING = { red: 255, green: 99, blue: 9 }; - var COLOR_SCALE_EDGE = { red:87, green:87, blue:87 }; - var COLOR_SCALE_CUBE = { red:106, green:106, blue:106 }; - var COLOR_SCALE_CUBE_SELECTED = { red:18, green:18, blue:18 }; + var COLOR_SCALE_EDGE = { red: 87, green: 87, blue: 87 }; + var COLOR_SCALE_CUBE = { red: 106, green: 106, blue: 106 }; + var COLOR_SCALE_CUBE_SELECTED = { red: 18, green: 18, blue: 18 }; var TRANSLATE_ARROW_CYLINDER_OFFSET = 0.1; var TRANSLATE_ARROW_CYLINDER_CAMERA_DISTANCE_MULTIPLE = 0.005; @@ -320,41 +322,41 @@ SelectionDisplay = (function() { var STRETCH_PANEL_WIDTH = 0.01; var SCALE_CUBE_OFFSET = 0.5; - var SCALE_CUBE_CAMERA_DISTANCE_MULTIPLE = 0.015; + var SCALE_CUBE_CAMERA_DISTANCE_MULTIPLE = 0.0125; - var CLONER_OFFSET = { x:0.9, y:-0.9, z:0.9 }; + var CLONER_OFFSET = { x: 0.9, y: -0.9, z: 0.9 }; var CTRL_KEY_CODE = 16777249; var TRANSLATE_DIRECTION = { - X : 0, - Y : 1, - Z : 2 - } + X: 0, + Y: 1, + Z: 2 + }; var STRETCH_DIRECTION = { - X : 0, - Y : 1, - Z : 2, - ALL : 3 - } + X: 0, + Y: 1, + Z: 2, + ALL: 3 + }; var SCALE_DIRECTION = { - LBN : 0, - RBN : 1, - LBF : 2, - RBF : 3, - LTN : 4, - RTN : 5, - LTF : 6, - RTF : 7 - } + LBN: 0, + RBN: 1, + LBF: 2, + RBF: 3, + LTN: 4, + RTN: 5, + LTF: 6, + RTF: 7 + }; var ROTATE_DIRECTION = { - PITCH : 0, - YAW : 1, - ROLL : 2 - } + PITCH: 0, + YAW: 1, + ROLL: 2 + }; var spaceMode = SPACE_LOCAL; var overlayNames = []; @@ -397,16 +399,16 @@ SelectionDisplay = (function() { }; var handleTranslateXCone = Overlays.addOverlay("shape", handlePropertiesTranslateArrowCones); var handleTranslateXCylinder = Overlays.addOverlay("shape", handlePropertiesTranslateArrowCylinders); - Overlays.editOverlay(handleTranslateXCone, { color : COLOR_RED }); - Overlays.editOverlay(handleTranslateXCylinder, { color : COLOR_RED }); + Overlays.editOverlay(handleTranslateXCone, { color: COLOR_RED }); + Overlays.editOverlay(handleTranslateXCylinder, { color: COLOR_RED }); var handleTranslateYCone = Overlays.addOverlay("shape", handlePropertiesTranslateArrowCones); var handleTranslateYCylinder = Overlays.addOverlay("shape", handlePropertiesTranslateArrowCylinders); - Overlays.editOverlay(handleTranslateYCone, { color : COLOR_GREEN }); - Overlays.editOverlay(handleTranslateYCylinder, { color : COLOR_GREEN }); + Overlays.editOverlay(handleTranslateYCone, { color: COLOR_GREEN }); + Overlays.editOverlay(handleTranslateYCylinder, { color: COLOR_GREEN }); var handleTranslateZCone = Overlays.addOverlay("shape", handlePropertiesTranslateArrowCones); var handleTranslateZCylinder = Overlays.addOverlay("shape", handlePropertiesTranslateArrowCylinders); - Overlays.editOverlay(handleTranslateZCone, { color : COLOR_BLUE }); - Overlays.editOverlay(handleTranslateZCylinder, { color : COLOR_BLUE }); + Overlays.editOverlay(handleTranslateZCone, { color: COLOR_BLUE }); + Overlays.editOverlay(handleTranslateZCylinder, { color: COLOR_BLUE }); var handlePropertiesRotateRings = { alpha: 1, @@ -422,18 +424,18 @@ SelectionDisplay = (function() { }; var handleRotatePitchRing = Overlays.addOverlay("circle3d", handlePropertiesRotateRings); Overlays.editOverlay(handleRotatePitchRing, { - color : COLOR_RED, - majorTickMarksColor: COLOR_RED, + color: COLOR_RED, + majorTickMarksColor: COLOR_RED }); var handleRotateYawRing = Overlays.addOverlay("circle3d", handlePropertiesRotateRings); Overlays.editOverlay(handleRotateYawRing, { - color : COLOR_GREEN, - majorTickMarksColor: COLOR_GREEN, + color: COLOR_GREEN, + majorTickMarksColor: COLOR_GREEN }); var handleRotateRollRing = Overlays.addOverlay("circle3d", handlePropertiesRotateRings); Overlays.editOverlay(handleRotateRollRing, { - color : COLOR_BLUE, - majorTickMarksColor: COLOR_BLUE, + color: COLOR_BLUE, + majorTickMarksColor: COLOR_BLUE }); var handleRotateCurrentRing = Overlays.addOverlay("circle3d", { @@ -472,11 +474,11 @@ SelectionDisplay = (function() { drawInFront: true }; var handleStretchXSphere = Overlays.addOverlay("shape", handlePropertiesStretchSpheres); - Overlays.editOverlay(handleStretchXSphere, { color : COLOR_RED }); + Overlays.editOverlay(handleStretchXSphere, { color: COLOR_RED }); var handleStretchYSphere = Overlays.addOverlay("shape", handlePropertiesStretchSpheres); - Overlays.editOverlay(handleStretchYSphere, { color : COLOR_GREEN }); + Overlays.editOverlay(handleStretchYSphere, { color: COLOR_GREEN }); var handleStretchZSphere = Overlays.addOverlay("shape", handlePropertiesStretchSpheres); - Overlays.editOverlay(handleStretchZSphere, { color : COLOR_BLUE }); + Overlays.editOverlay(handleStretchZSphere, { color: COLOR_BLUE }); var handlePropertiesStretchPanel = { shape: "Quad", @@ -485,13 +487,13 @@ SelectionDisplay = (function() { visible: false, ignoreRayIntersection: true, drawInFront: true - } + }; var handleStretchXPanel = Overlays.addOverlay("shape", handlePropertiesStretchPanel); - Overlays.editOverlay(handleStretchXPanel, { color : COLOR_RED }); + Overlays.editOverlay(handleStretchXPanel, { color: COLOR_RED }); var handleStretchYPanel = Overlays.addOverlay("shape", handlePropertiesStretchPanel); - Overlays.editOverlay(handleStretchYPanel, { color : COLOR_GREEN }); + Overlays.editOverlay(handleStretchYPanel, { color: COLOR_GREEN }); var handleStretchZPanel = Overlays.addOverlay("shape", handlePropertiesStretchPanel); - Overlays.editOverlay(handleStretchZPanel, { color : COLOR_BLUE }); + Overlays.editOverlay(handleStretchZPanel, { color: COLOR_BLUE }); var handlePropertiesScaleCubes = { size: 0.025, @@ -517,7 +519,7 @@ SelectionDisplay = (function() { ignoreRayIntersection: true, drawInFront: true, lineWidth: 0.2 - } + }; var handleScaleTREdge = Overlays.addOverlay("line3d", handlePropertiesScaleEdge); var handleScaleTLEdge = Overlays.addOverlay("line3d", handlePropertiesScaleEdge); var handleScaleTFEdge = Overlays.addOverlay("line3d", handlePropertiesScaleEdge); @@ -785,11 +787,11 @@ SelectionDisplay = (function() { }; that.resetPreviousHandleColor = function() { - if (previousHandle != null) { + if (previousHandle !== null) { Overlays.editOverlay(previousHandle, { color: previousHandleColor }); previousHandle = null; } - if (previousHandleHelper != null) { + if (previousHandleHelper !== null) { Overlays.editOverlay(previousHandleHelper, { color: previousHandleColor }); previousHandleHelper = null; } @@ -886,7 +888,7 @@ SelectionDisplay = (function() { Overlays.editOverlay(result.overlayID, { color: COLOR_HOVER }); previousHandle = result.overlayID; previousHandleHelper = that.getHandleHelper(result.overlayID); - if (previousHandleHelper != null) { + if (previousHandleHelper !== null) { Overlays.editOverlay(previousHandleHelper, { color: COLOR_HOVER }); } previousHandleColor = pickedColor; @@ -944,7 +946,7 @@ SelectionDisplay = (function() { ctrlPressed = false; that.updateActiveRotateRing(); } - } + }; // Triggers notification on specific key driven events that.keyPressEvent = function(key) { @@ -952,7 +954,7 @@ SelectionDisplay = (function() { ctrlPressed = true; that.updateActiveRotateRing(); } - } + }; // NOTE: mousePressEvent and mouseMoveEvent from the main script should call us., so we don't hook these: // Controller.mousePressEvent.connect(that.mousePressEvent); @@ -994,6 +996,11 @@ SelectionDisplay = (function() { var toCameraDistance = Vec3.length(Vec3.subtract(cameraPosition, position)); return toCameraDistance; } + + function usePreviousPickRay(pickRayDirection, previousPickRayDirection, normal) { + return (Vec3.dot(pickRayDirection, normal) > 0 && Vec3.dot(previousPickRayDirection, normal) < 0) || + (Vec3.dot(pickRayDirection, normal) < 0 && Vec3.dot(previousPickRayDirection, normal) > 0); + } // @return string - The mode of the currently active tool; // otherwise, "UNKNOWN" if there's no active tool. @@ -1014,8 +1021,6 @@ SelectionDisplay = (function() { lastCameraOrientation = Camera.getOrientation(); if (event !== false) { - pickRay = generalComputePickRay(event.x, event.y); - var wantDebug = false; if (wantDebug) { print("select() with EVENT...... "); @@ -1041,7 +1046,8 @@ SelectionDisplay = (function() { spaceMode = newSpaceMode; that.updateHandles(); } else if (wantDebug) { - print("WARNING: entitySelectionTool.setSpaceMode - Can't update SpaceMode. CurrentMode: " + spaceMode + " DesiredMode: " + newSpaceMode); + print("WARNING: entitySelectionTool.setSpaceMode - Can't update SpaceMode. CurrentMode: " + + spaceMode + " DesiredMode: " + newSpaceMode); } if (wantDebug) { print("====== SetSpaceMode called. <========"); @@ -1091,7 +1097,8 @@ SelectionDisplay = (function() { } if (!handleTools.hasOwnProperty(toolHandle)) { - print("WARNING: entitySelectionTool.isActiveTool - Encountered unknown grabberToolHandle: " + toolHandle + ". Tools should be registered via addHandleTool."); + print("WARNING: entitySelectionTool.isActiveTool - Encountered unknown grabberToolHandle: " + + toolHandle + ". Tools should be registered via addHandleTool."); // EARLY EXIT return false; } @@ -1121,13 +1128,14 @@ SelectionDisplay = (function() { var rotationInverse = Quat.inverse(rotation); var toCameraDistance = getDistanceToCamera(position); - var localRotationX = Quat.fromPitchYawRollDegrees(0, 0, -90); + var rotationDegrees = 90; + var localRotationX = Quat.fromPitchYawRollDegrees(0, 0, -rotationDegrees); var rotationX = Quat.multiply(rotation, localRotationX); worldRotationX = rotationX; - var localRotationY = Quat.fromPitchYawRollDegrees(0, 90, 0); + var localRotationY = Quat.fromPitchYawRollDegrees(0, rotationDegrees, 0); var rotationY = Quat.multiply(rotation, localRotationY); worldRotationY = rotationY; - var localRotationZ = Quat.fromPitchYawRollDegrees(90, 0, 0); + var localRotationZ = Quat.fromPitchYawRollDegrees(rotationDegrees, 0, 0); var rotationZ = Quat.multiply(rotation, localRotationZ); worldRotationZ = rotationZ; @@ -1140,7 +1148,7 @@ SelectionDisplay = (function() { // UPDATE ROTATION RINGS // rotateDimension is used as the base dimension for all overlays var rotateDimension = Math.max(maxHandleDimension, toCameraDistance * ROTATE_RING_CAMERA_DISTANCE_MULTIPLE); - var rotateDimensions = { x:rotateDimension, y:rotateDimension, z:rotateDimension }; + var rotateDimensions = { x: rotateDimension, y: rotateDimension, z: rotateDimension }; if (!isActiveTool(handleRotatePitchRing)) { Overlays.editOverlay(handleRotatePitchRing, { position: position, @@ -1172,16 +1180,16 @@ SelectionDisplay = (function() { var arrowCylinderDimension = rotateDimension * TRANSLATE_ARROW_CYLINDER_CAMERA_DISTANCE_MULTIPLE / ROTATE_RING_CAMERA_DISTANCE_MULTIPLE; var arrowCylinderDimensions = { - x:arrowCylinderDimension, - y:arrowCylinderDimension * TRANSLATE_ARROW_CYLINDER_Y_MULTIPLE, - z:arrowCylinderDimension + x: arrowCylinderDimension, + y: arrowCylinderDimension * TRANSLATE_ARROW_CYLINDER_Y_MULTIPLE, + z: arrowCylinderDimension }; var arrowConeDimension = rotateDimension * TRANSLATE_ARROW_CONE_CAMERA_DISTANCE_MULTIPLE / ROTATE_RING_CAMERA_DISTANCE_MULTIPLE; - var arrowConeDimensions = { x:arrowConeDimension, y:arrowConeDimension, z:arrowConeDimension }; + var arrowConeDimensions = { x: arrowConeDimension, y: arrowConeDimension, z: arrowConeDimension }; var arrowCylinderOffset = rotateDimension * TRANSLATE_ARROW_CYLINDER_OFFSET / ROTATE_RING_CAMERA_DISTANCE_MULTIPLE; var arrowConeOffset = arrowCylinderDimensions.y * TRANSLATE_ARROW_CONE_OFFSET_CYLINDER_DIMENSION_MULTIPLE; - var cylinderXPosition = { x:arrowCylinderOffset, y:0, z:0 }; + var cylinderXPosition = { x: arrowCylinderOffset, y: 0, z: 0 }; cylinderXPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, cylinderXPosition)); Overlays.editOverlay(handleTranslateXCylinder, { position: cylinderXPosition, @@ -1195,7 +1203,7 @@ SelectionDisplay = (function() { rotation: rotationX, dimensions: arrowConeDimensions }); - var cylinderYPosition = { x:0, y:arrowCylinderOffset, z:0 }; + var cylinderYPosition = { x: 0, y: arrowCylinderOffset, z: 0 }; cylinderYPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, cylinderYPosition)); Overlays.editOverlay(handleTranslateYCylinder, { position: cylinderYPosition, @@ -1209,7 +1217,7 @@ SelectionDisplay = (function() { rotation: rotationY, dimensions: arrowConeDimensions }); - var cylinderZPosition = { x:0, y:0, z:arrowCylinderOffset }; + var cylinderZPosition = { x: 0, y: 0, z: arrowCylinderOffset }; cylinderZPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, cylinderZPosition)); Overlays.editOverlay(handleTranslateZCylinder, { position: cylinderZPosition, @@ -1228,61 +1236,73 @@ SelectionDisplay = (function() { var scaleCubeOffsetX = SCALE_CUBE_OFFSET * dimensions.x; var scaleCubeOffsetY = SCALE_CUBE_OFFSET * dimensions.y; var scaleCubeOffsetZ = SCALE_CUBE_OFFSET * dimensions.z; - var scaleCubeDimension = rotateDimension * SCALE_CUBE_CAMERA_DISTANCE_MULTIPLE / - ROTATE_RING_CAMERA_DISTANCE_MULTIPLE; - var scaleCubeDimensions = { x:scaleCubeDimension, y:scaleCubeDimension, z:scaleCubeDimension }; var scaleCubeRotation = spaceMode === SPACE_LOCAL ? rotation : Quat.IDENTITY; - var scaleLBNCubePosition = { x:-scaleCubeOffsetX, y:-scaleCubeOffsetY, z:-scaleCubeOffsetZ }; + var scaleLBNCubePosition = { x: -scaleCubeOffsetX, y: -scaleCubeOffsetY, z: -scaleCubeOffsetZ }; scaleLBNCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleLBNCubePosition)); + var scaleLBNCubeToCamera = getDistanceToCamera(scaleLBNCubePosition); + var scaleRBNCubePosition = { x: scaleCubeOffsetX, y: -scaleCubeOffsetY, z: -scaleCubeOffsetZ }; + scaleRBNCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleRBNCubePosition)); + var scaleRBNCubeToCamera = getDistanceToCamera(scaleRBNCubePosition); + var scaleLBFCubePosition = { x: -scaleCubeOffsetX, y: -scaleCubeOffsetY, z: scaleCubeOffsetZ }; + scaleLBFCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleLBFCubePosition)); + var scaleLBFCubeToCamera = getDistanceToCamera(scaleLBFCubePosition); + var scaleRBFCubePosition = { x: scaleCubeOffsetX, y: -scaleCubeOffsetY, z: scaleCubeOffsetZ }; + scaleRBFCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleRBFCubePosition)); + var scaleRBFCubeToCamera = getDistanceToCamera(scaleRBFCubePosition); + var scaleLTNCubePosition = { x: -scaleCubeOffsetX, y: scaleCubeOffsetY, z: -scaleCubeOffsetZ }; + scaleLTNCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleLTNCubePosition)); + var scaleLTNCubeToCamera = getDistanceToCamera(scaleLTNCubePosition); + var scaleRTNCubePosition = { x: scaleCubeOffsetX, y: scaleCubeOffsetY, z: -scaleCubeOffsetZ }; + scaleRTNCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleRTNCubePosition)); + var scaleRTNCubeToCamera = getDistanceToCamera(scaleRTNCubePosition); + var scaleLTFCubePosition = { x: -scaleCubeOffsetX, y: scaleCubeOffsetY, z: scaleCubeOffsetZ }; + scaleLTFCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleLTFCubePosition)); + var scaleLTFCubeToCamera = getDistanceToCamera(scaleLTFCubePosition); + var scaleRTFCubePosition = { x: scaleCubeOffsetX, y: scaleCubeOffsetY, z: scaleCubeOffsetZ }; + scaleRTFCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleRTFCubePosition)); + var scaleRTFCubeToCamera = getDistanceToCamera(scaleRTFCubePosition); + + var scaleCubeToCamera = Math.min(scaleLBNCubeToCamera, scaleRBNCubeToCamera, scaleLBFCubeToCamera, + scaleRBFCubeToCamera, scaleLTNCubeToCamera, scaleRTNCubeToCamera, + scaleLTFCubeToCamera, scaleRTFCubeToCamera); + var scaleCubeDimension = scaleCubeToCamera * SCALE_CUBE_CAMERA_DISTANCE_MULTIPLE; + var scaleCubeDimensions = { x: scaleCubeDimension, y: scaleCubeDimension, z: scaleCubeDimension }; + Overlays.editOverlay(handleScaleLBNCube, { position: scaleLBNCubePosition, rotation: scaleCubeRotation, dimensions: scaleCubeDimensions }); - var scaleRBNCubePosition = { x:scaleCubeOffsetX, y:-scaleCubeOffsetY, z:-scaleCubeOffsetZ }; - scaleRBNCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleRBNCubePosition)); Overlays.editOverlay(handleScaleRBNCube, { position: scaleRBNCubePosition, rotation: scaleCubeRotation, dimensions: scaleCubeDimensions }); - var scaleLBFCubePosition = { x:-scaleCubeOffsetX, y:-scaleCubeOffsetY, z:scaleCubeOffsetZ }; - scaleLBFCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleLBFCubePosition)); Overlays.editOverlay(handleScaleLBFCube, { position: scaleLBFCubePosition, rotation: scaleCubeRotation, dimensions: scaleCubeDimensions }); - var scaleRBFCubePosition = { x:scaleCubeOffsetX, y:-scaleCubeOffsetY, z:scaleCubeOffsetZ }; - scaleRBFCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleRBFCubePosition)); Overlays.editOverlay(handleScaleRBFCube, { position: scaleRBFCubePosition, rotation: scaleCubeRotation, dimensions: scaleCubeDimensions }); - var scaleLTNCubePosition = { x:-scaleCubeOffsetX, y:scaleCubeOffsetY, z:-scaleCubeOffsetZ }; - scaleLTNCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleLTNCubePosition)); Overlays.editOverlay(handleScaleLTNCube, { position: scaleLTNCubePosition, rotation: scaleCubeRotation, dimensions: scaleCubeDimensions }); - var scaleRTNCubePosition = { x:scaleCubeOffsetX, y:scaleCubeOffsetY, z:-scaleCubeOffsetZ }; - scaleRTNCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleRTNCubePosition)); Overlays.editOverlay(handleScaleRTNCube, { position: scaleRTNCubePosition, rotation: scaleCubeRotation, dimensions: scaleCubeDimensions }); - var scaleLTFCubePosition = { x:-scaleCubeOffsetX, y:scaleCubeOffsetY, z:scaleCubeOffsetZ }; - scaleLTFCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleLTFCubePosition)); Overlays.editOverlay(handleScaleLTFCube, { position: scaleLTFCubePosition, rotation: scaleCubeRotation, dimensions: scaleCubeDimensions }); - var scaleRTFCubePosition = { x:scaleCubeOffsetX, y:scaleCubeOffsetY, z:scaleCubeOffsetZ }; - scaleRTFCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleRTFCubePosition)); Overlays.editOverlay(handleScaleRTFCube, { position: scaleRTFCubePosition, rotation: scaleCubeRotation, @@ -1306,21 +1326,21 @@ SelectionDisplay = (function() { // UPDATE STRETCH SPHERES var stretchSphereDimension = rotateDimension * STRETCH_SPHERE_CAMERA_DISTANCE_MULTIPLE / ROTATE_RING_CAMERA_DISTANCE_MULTIPLE; - var stretchSphereDimensions = { x:stretchSphereDimension, y:stretchSphereDimension, z:stretchSphereDimension }; + var stretchSphereDimensions = { x: stretchSphereDimension, y: stretchSphereDimension, z: stretchSphereDimension }; var stretchSphereOffset = rotateDimension * STRETCH_SPHERE_OFFSET / ROTATE_RING_CAMERA_DISTANCE_MULTIPLE; - var stretchXPosition = { x:stretchSphereOffset, y:0, z:0 }; + var stretchXPosition = { x: stretchSphereOffset, y: 0, z: 0 }; stretchXPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, stretchXPosition)); Overlays.editOverlay(handleStretchXSphere, { position: stretchXPosition, dimensions: stretchSphereDimensions }); - var stretchYPosition = { x:0, y:stretchSphereOffset, z:0 }; + var stretchYPosition = { x: 0, y: stretchSphereOffset, z: 0 }; stretchYPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, stretchYPosition)); Overlays.editOverlay(handleStretchYSphere, { position: stretchYPosition, dimensions: stretchSphereDimensions }); - var stretchZPosition = { x:0, y:0, z:stretchSphereOffset }; + var stretchZPosition = { x: 0, y: 0, z: stretchSphereOffset }; stretchZPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, stretchZPosition)); Overlays.editOverlay(handleStretchZSphere, { position: stretchZPosition, @@ -1337,27 +1357,29 @@ SelectionDisplay = (function() { stretchPanelXDimensions.x = STRETCH_PANEL_WIDTH; stretchPanelXDimensions.y = Math.abs(stretchPanelXDimensions.z); stretchPanelXDimensions.z = tempY; - var stretchPanelXPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, { x:dimensions.x / 2, y:0, z:0 })); + var stretchPanelXPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, { x: dimensions.x / 2, y: 0, z: 0 })); Overlays.editOverlay(handleStretchXPanel, { position: stretchPanelXPosition, rotation: rotationZ, dimensions: stretchPanelXDimensions }); var stretchPanelYDimensions = Vec3.subtract(scaleLTNCubePositionRotated, scaleRTFCubePositionRotated); + var tempX = Math.abs(stretchPanelYDimensions.x); stretchPanelYDimensions.x = Math.abs(stretchPanelYDimensions.z); stretchPanelYDimensions.y = STRETCH_PANEL_WIDTH; - stretchPanelYDimensions.z = Math.abs(stretchPanelYDimensions.x); - var stretchPanelYPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, { x:0, y:dimensions.y / 2, z:0 })); + stretchPanelYDimensions.z = tempX; + var stretchPanelYPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, { x: 0, y: dimensions.y / 2, z: 0 })); Overlays.editOverlay(handleStretchYPanel, { position: stretchPanelYPosition, rotation: rotationY, dimensions: stretchPanelYDimensions }); var stretchPanelZDimensions = Vec3.subtract(scaleLTNCubePositionRotated, scaleRBFCubePositionRotated); + tempX = Math.abs(stretchPanelZDimensions.x); stretchPanelZDimensions.x = Math.abs(stretchPanelZDimensions.y); - stretchPanelZDimensions.y = Math.abs(stretchPanelZDimensions.x); + stretchPanelZDimensions.y = tempX; stretchPanelZDimensions.z = STRETCH_PANEL_WIDTH; - var stretchPanelZPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, { x:0, y:0, z:dimensions.z / 2 })); + var stretchPanelZPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, { x: 0, y: 0, z: dimensions.z / 2 })); Overlays.editOverlay(handleStretchZPanel, { position: stretchPanelZPosition, rotation: rotationX, @@ -1390,10 +1412,10 @@ SelectionDisplay = (function() { } // UPDATE CLONER (CURRENTLY HIDDEN FOR NOW) - var handleClonerOffset = { - x:CLONER_OFFSET.x * dimensions.x, - y:CLONER_OFFSET.y * dimensions.y, - z:CLONER_OFFSET.z * dimensions.z + var handleClonerOffset = { + x: CLONER_OFFSET.x * dimensions.x, + y: CLONER_OFFSET.y * dimensions.y, + z: CLONER_OFFSET.z * dimensions.z }; var handleClonerPos = Vec3.sum(position, Vec3.multiplyQbyV(rotation, handleClonerOffset)); Overlays.editOverlay(handleCloner, { @@ -1431,9 +1453,9 @@ SelectionDisplay = (function() { !isActiveTool(handleRotateYawRing) && !isActiveTool(handleRotateRollRing))); - //keep cloner always hidden for now since you can hold Alt to clone while - //translating an entity - we may bring cloner back for HMD only later - //that.setHandleClonerVisible(!activeTool || isActiveTool(handleCloner)); + // keep cloner always hidden for now since you can hold Alt to clone while + // translating an entity - we may bring cloner back for HMD only later + // that.setHandleClonerVisible(!activeTool || isActiveTool(handleCloner)); if (wantDebug) { print("====== Update Handles <======="); @@ -1451,8 +1473,8 @@ SelectionDisplay = (function() { } else if (isActiveTool(handleRotateRollRing)) { activeRotateRing = handleRotateRollRing; } - if (activeRotateRing != null) { - var tickMarksAngle = ctrlPressed ? ROTATE_CTRL_SNAP_ANGLE : ROTATE_DEFAULT_TICK_MARKS_ANGLE; + if (activeRotateRing !== null) { + var tickMarksAngle = ctrlPressed ? ROTATE_CTRL_SNAP_ANGLE : ROTATE_DEFAULT_TICK_MARKS_ANGLE; Overlays.editOverlay(activeRotateRing, { majorTickMarksAngle: tickMarksAngle }); } }; @@ -1633,7 +1655,7 @@ SelectionDisplay = (function() { }, onMove: function(event) { var wantDebug = false; - pickRay = generalComputePickRay(event.x, event.y); + var pickRay = generalComputePickRay(event.x, event.y); var pick = rayPlaneIntersection2(pickRay, translateXZTool.pickPlanePosition, { x: 0, @@ -1699,7 +1721,8 @@ SelectionDisplay = (function() { } constrainMajorOnly = event.isControl; - var cornerPosition = Vec3.sum(startPosition, Vec3.multiply(-0.5, SelectionManager.worldDimensions)); + var negateAndHalve = -0.5; + var cornerPosition = Vec3.sum(startPosition, Vec3.multiply(negateAndHalve, SelectionManager.worldDimensions)); vector = Vec3.subtract( grid.snapToGrid(Vec3.sum(cornerPosition, vector), constrainMajorOnly), cornerPosition); @@ -1745,15 +1768,16 @@ SelectionDisplay = (function() { var pickNormal = null; var lastPick = null; var projectionVector = null; + var previousPickRay = null; addHandleTool(overlay, { mode: mode, onBegin: function(event, pickRay, pickResult) { if (direction === TRANSLATE_DIRECTION.X) { - pickNormal = { x:0, y:1, z:1 }; + pickNormal = { x: 0, y: 1, z: 1 }; } else if (direction === TRANSLATE_DIRECTION.Y) { - pickNormal = { x:1, y:0, z:1 }; + pickNormal = { x: 1, y: 0, z: 1 }; } else if (direction === TRANSLATE_DIRECTION.Z) { - pickNormal = { x:1, y:1, z:0 }; + pickNormal = { x: 1, y: 1, z: 0 }; } var rotation = spaceMode === SPACE_LOCAL ? SelectionManager.localRotation : SelectionManager.worldRotation; @@ -1780,22 +1804,29 @@ SelectionDisplay = (function() { } else { duplicatedEntityIDs = null; } + + previousPickRay = pickRay; }, onEnd: function(event, reason) { pushCommandForSelections(duplicatedEntityIDs); }, onMove: function(event) { - pickRay = generalComputePickRay(event.x, event.y); + var pickRay = generalComputePickRay(event.x, event.y); + + // Use previousPickRay if new pickRay will cause resulting rayPlaneIntersection values to wrap around + if (usePreviousPickRay(pickRay.direction, previousPickRay.direction, pickNormal)) { + pickRay = previousPickRay; + } var newIntersection = rayPlaneIntersection(pickRay, SelectionManager.worldPosition, pickNormal); var vector = Vec3.subtract(newIntersection, lastPick); if (direction === TRANSLATE_DIRECTION.X) { - projectionVector = { x:1, y:0, z:0 }; + projectionVector = { x: 1, y: 0, z: 0 }; } else if (direction === TRANSLATE_DIRECTION.Y) { - projectionVector = { x:0, y:1, z:0 }; + projectionVector = { x: 0, y: 1, z: 0 }; } else if (direction === TRANSLATE_DIRECTION.Z) { - projectionVector = { x:0, y:0, z:1 }; + projectionVector = { x: 0, y: 0, z: 1 }; } var rotation = spaceMode === SPACE_LOCAL ? SelectionManager.localRotation : SelectionManager.worldRotation; @@ -1829,6 +1860,8 @@ SelectionDisplay = (function() { var newPosition = Vec3.sum(properties.position, vector); Entities.editEntity(id, { position: newPosition }); } + + previousPickRay = pickRay; SelectionManager._update(); } @@ -1869,7 +1902,6 @@ SelectionDisplay = (function() { var lastPick3D = null; var initialPosition = null; var initialDimensions = null; - var initialIntersection = null; var initialProperties = null; var registrationPoint = null; var deltaPivot = null; @@ -1877,6 +1909,7 @@ SelectionDisplay = (function() { var pickRayPosition = null; var pickRayPosition3D = null; var rotation = null; + var previousPickRay = null; var onBegin = function(event, pickRay, pickResult) { var properties = Entities.getEntityProperties(SelectionManager.selections[0]); @@ -1909,7 +1942,7 @@ SelectionDisplay = (function() { var scaledOffset = Vec3.multiply(0.5, offset); // Offset from the registration point - offsetRP = Vec3.subtract(scaledOffset, centeredRP); + var offsetRP = Vec3.subtract(scaledOffset, centeredRP); // Scaled offset in world coordinates var scaledOffsetWorld = vec3Mult(initialDimensions, offsetRP); @@ -1919,57 +1952,10 @@ SelectionDisplay = (function() { if (directionFor3DStretch) { // pivot, offset and pickPlanePosition for 3D manipulation var scaledPivot3D = Vec3.multiply(0.5, Vec3.multiply(1.0, directionFor3DStretch)); - deltaPivot3D = Vec3.subtract(centeredRP, scaledPivot3D); - - var scaledOffsetWorld3D = vec3Mult(initialDimensions, - Vec3.subtract(Vec3.multiply(0.5, Vec3.multiply(-1.0, directionFor3DStretch)), centeredRP)); - + deltaPivot3D = Vec3.subtract(centeredRP, scaledPivot3D); pickRayPosition3D = Vec3.sum(initialPosition, Vec3.multiplyQbyV(rotation, scaledOffsetWorld)); } - var start = null; - var end = null; - if ((numDimensions === 1) && mask.x) { - start = Vec3.multiplyQbyV(rotation, { - x: -10000, - y: 0, - z: 0 - }); - start = Vec3.sum(start, properties.position); - end = Vec3.multiplyQbyV(rotation, { - x: 10000, - y: 0, - z: 0 - }); - end = Vec3.sum(end, properties.position); - } - if ((numDimensions === 1) && mask.y) { - start = Vec3.multiplyQbyV(rotation, { - x: 0, - y: -10000, - z: 0 - }); - start = Vec3.sum(start, properties.position); - end = Vec3.multiplyQbyV(rotation, { - x: 0, - y: 10000, - z: 0 - }); - end = Vec3.sum(end, properties.position); - } - if ((numDimensions === 1) && mask.z) { - start = Vec3.multiplyQbyV(rotation, { - x: 0, - y: 0, - z: -10000 - }); - start = Vec3.sum(start, properties.position); - end = Vec3.multiplyQbyV(rotation, { - x: 0, - y: 0, - z: 10000 - }); - end = Vec3.sum(end, properties.position); - } + if (numDimensions === 1) { if (mask.x === 1) { planeNormal = { @@ -2040,10 +2026,10 @@ SelectionDisplay = (function() { SelectionManager.saveProperties(); that.resetPreviousHandleColor(); - if (stretchPanel != null) { + if (stretchPanel !== null) { Overlays.editOverlay(stretchPanel, { visible: true }); } - if (scaleHandle != null) { + if (scaleHandle !== null) { Overlays.editOverlay(scaleHandle, { color: COLOR_SCALE_CUBE_SELECTED }); } @@ -2053,13 +2039,15 @@ SelectionDisplay = (function() { Entities.editEntity(SelectionManager.selections[0], {collidesWith: newCollidesWith}); that.replaceCollisionsAfterStretch = true; } + + previousPickRay = pickRay; }; var onEnd = function(event, reason) { - if (stretchPanel != null) { + if (stretchPanel !== null) { Overlays.editOverlay(stretchPanel, { visible: false }); } - if (scaleHandle != null) { + if (scaleHandle !== null) { Overlays.editOverlay(scaleHandle, { color: COLOR_SCALE_CUBE }); } @@ -2075,14 +2063,12 @@ SelectionDisplay = (function() { var onMove = function(event) { var proportional = (spaceMode === SPACE_WORLD) || directionEnum === STRETCH_DIRECTION.ALL; - var position, dimensions, rotation; + var position, rotation; if (spaceMode === SPACE_LOCAL) { position = SelectionManager.localPosition; - dimensions = SelectionManager.localDimensions; rotation = SelectionManager.localRotation; } else { position = SelectionManager.worldPosition; - dimensions = SelectionManager.worldDimensions; rotation = SelectionManager.worldRotation; } @@ -2090,9 +2076,15 @@ SelectionDisplay = (function() { var localSigns = signs; var pickRay = generalComputePickRay(event.x, event.y); + // Use previousPickRay if new pickRay will cause resulting rayPlaneIntersection values to wrap around + if (usePreviousPickRay(pickRay.direction, previousPickRay.direction, planeNormal)) { + pickRay = previousPickRay; + } + // Are we using handControllers or Mouse - only relevant for 3D tools var controllerPose = getControllerWorldLocation(activeHand, true); var vector = null; + var newPick = null; if (HMD.isHMDAvailable() && HMD.isHandControllerAvailable() && controllerPose.valid && that.triggered && directionFor3DStretch) { localDeltaPivot = deltaPivot3D; @@ -2143,14 +2135,23 @@ SelectionDisplay = (function() { } var minimumDimension = directionEnum === STRETCH_DIRECTION.ALL ? STRETCH_ALL_MINIMUM_DIMENSION : - STRETCH_MINIMUM_DIMENSION; - newDimensions.x = Math.max(newDimensions.x, minimumDimension); - newDimensions.y = Math.max(newDimensions.y, minimumDimension); - newDimensions.z = Math.max(newDimensions.z, minimumDimension); + STRETCH_MINIMUM_DIMENSION; + if (newDimensions.x < minimumDimension) { + newDimensions.x = minimumDimension; + changeInDimensions.x = minimumDimension - initialDimensions.x; + } + if (newDimensions.y < minimumDimension) { + newDimensions.y = minimumDimension; + changeInDimensions.y = minimumDimension - initialDimensions.y; + } + if (newDimensions.z < minimumDimension) { + newDimensions.z = minimumDimension; + changeInDimensions.z = minimumDimension - initialDimensions.z; + } var changeInPosition = Vec3.multiplyQbyV(rotation, vec3Mult(localDeltaPivot, changeInDimensions)); if (directionEnum === STRETCH_DIRECTION.ALL) { - changeInPosition = { x:0, y:0, z:0 }; + changeInPosition = { x: 0, y: 0, z: 0 }; } var newPosition = Vec3.sum(initialPosition, changeInPosition); @@ -2168,6 +2169,8 @@ SelectionDisplay = (function() { Vec3.print(" changeInPosition:", changeInPosition); Vec3.print(" newPosition:", newPosition); } + + previousPickRay = pickRay; SelectionManager._update(); };// End of onMove def @@ -2184,13 +2187,13 @@ SelectionDisplay = (function() { var directionVector, offset, stretchPanel; if (directionEnum === STRETCH_DIRECTION.X) { stretchPanel = handleStretchXPanel; - directionVector = { x:-1, y:0, z:0 }; + directionVector = { x: -1, y: 0, z: 0 }; } else if (directionEnum === STRETCH_DIRECTION.Y) { stretchPanel = handleStretchYPanel; - directionVector = { x:0, y:-1, z:0 }; + directionVector = { x: 0, y: -1, z: 0 }; } else if (directionEnum === STRETCH_DIRECTION.Z) { - stretchPanel = handleStretchZPanel - directionVector = { x:0, y:0, z:-1 }; + stretchPanel = handleStretchZPanel; + directionVector = { x: 0, y: 0, z: -1 }; } offset = Vec3.multiply(directionVector, NEGATE_VECTOR); var tool = makeStretchTool(mode, directionEnum, directionVector, directionVector, offset, stretchPanel, null); @@ -2201,28 +2204,28 @@ SelectionDisplay = (function() { function addHandleScaleTool(overlay, mode, directionEnum) { var directionVector, offset, selectedHandle; if (directionEnum === SCALE_DIRECTION.LBN) { - directionVector = { x:1, y:1, z:1 }; + directionVector = { x: 1, y: 1, z: 1 }; selectedHandle = handleScaleLBNCube; } else if (directionEnum === SCALE_DIRECTION.RBN) { - directionVector = { x:-1, y:1, z:1 }; + directionVector = { x: -1, y: 1, z: 1 }; selectedHandle = handleScaleRBNCube; } else if (directionEnum === SCALE_DIRECTION.LBF) { - directionVector = { x:1, y:1, z:-1 }; + directionVector = { x: 1, y: 1, z: -1 }; selectedHandle = handleScaleLBFCube; } else if (directionEnum === SCALE_DIRECTION.RBF) { - directionVector = { x:-1, y:1, z:-1 }; + directionVector = { x: -1, y: 1, z: -1 }; selectedHandle = handleScaleRBFCube; } else if (directionEnum === SCALE_DIRECTION.LTN) { - directionVector = { x:1, y:-1, z:1 }; + directionVector = { x: 1, y: -1, z: 1 }; selectedHandle = handleScaleLTNCube; } else if (directionEnum === SCALE_DIRECTION.RTN) { - directionVector = { x:-1, y:-1, z:1 }; + directionVector = { x: -1, y: -1, z: 1 }; selectedHandle = handleScaleRTNCube; } else if (directionEnum === SCALE_DIRECTION.LTF) { - directionVector = { x:1, y:-1, z:-1 }; + directionVector = { x: 1, y: -1, z: -1 }; selectedHandle = handleScaleLTFCube; } else if (directionEnum === SCALE_DIRECTION.RTF) { - directionVector = { x:-1, y:-1, z:-1 }; + directionVector = { x: -1, y: -1, z: -1 }; selectedHandle = handleScaleRTFCube; } offset = Vec3.multiply(directionVector, NEGATE_VECTOR); @@ -2233,7 +2236,6 @@ SelectionDisplay = (function() { // FUNCTION: UPDATE ROTATION DEGREES OVERLAY function updateRotationDegreesOverlay(angleFromZero, position) { - var angle = angleFromZero * (Math.PI / 180); var toCameraDistance = getDistanceToCamera(position); var overlayProps = { position: position, @@ -2424,9 +2426,10 @@ SelectionDisplay = (function() { var startAtCurrent = 0; var endAtCurrent = angleFromZero; + var maxDegrees = 360; if (angleFromZero < 0) { - startAtCurrent = 360 + angleFromZero; - endAtCurrent = 360; + startAtCurrent = maxDegrees + angleFromZero; + endAtCurrent = maxDegrees; } Overlays.editOverlay(handleRotateCurrentRing, { startAt: startAtCurrent, @@ -2438,8 +2441,9 @@ SelectionDisplay = (function() { if (spaceMode === SPACE_LOCAL) { Overlays.editOverlay(handleRotateCurrentRing, { rotation: worldRotationZ }); } else { + var rotationDegrees = 90; Overlays.editOverlay(handleRotateCurrentRing, { - rotation: Quat.fromPitchYawRollDegrees(-90, 0, 0) + rotation: Quat.fromPitchYawRollDegrees(-rotationDegrees, 0, 0) }); } }