diff --git a/examples/libraries/entityCameraTool.js b/examples/libraries/entityCameraTool.js index 8e267e9544..63121d88a9 100644 --- a/examples/libraries/entityCameraTool.js +++ b/examples/libraries/entityCameraTool.js @@ -97,11 +97,12 @@ EntityCameraTool = function() { that.focus = function(entityProperties) { var dim = entityProperties.dimensions; + dim = SelectionManager.worldDimensions; var size = Math.max(dim.x, Math.max(dim.y, dim.z)); that.targetZoomDistance = Math.max(size * FOCUS_ZOOM_SCALE, FOCUS_MIN_ZOOM); - that.setFocalPoint(entityProperties.position); + that.setFocalPoint(SelectionManager.worldPosition);//entityProperties.position); that.updateCamera(); } @@ -184,7 +185,7 @@ EntityCameraTool = function() { // Scale based on current zoom level dZoom *= that.targetZoomDistance * ZOOM_SCALING; - that.targetZoomDistance = Math.max(Math.min(that.targetZoomDistance + dZoom, MAX_ZOOM_DISTANCE), MIN_ZOOM_DISTANCE); + that.targetZoomDistance = Math.max(that.targetZoomDistance + dZoom, MIN_ZOOM_DISTANCE); that.updateCamera(); } diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index 5e344c9c8d..b70c2187c2 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -13,6 +13,124 @@ Script.include("libraries/globals.js"); +SPACE_LOCAL = "local"; +SPACE_WORLD = "world"; + +SelectionManager = (function() { + var that = {}; + + + that.savedProperties = {}; + + that.eventListener = null; + that.selections = []; + + that.localRotation = Quat.fromPitchYawRollDegrees(0, 0, 0); + that.localPosition = { x: 0, y: 0, z: 0 }; + that.localDimensions = { x: 0, y: 0, z: 0 }; + + that.worldRotation = Quat.fromPitchYawRollDegrees(0, 0, 0); + that.worldPosition = { x: 0, y: 0, z: 0 }; + that.worldDimensions = { x: 0, y: 0, z: 0 }; + that.centerPosition = { x: 0, y: 0, z: 0 }; + + that.saveProperties = function() { + that.savedProperties = {}; + for (var i = 0; i < that.selections.length; i++) { + var entityID = that.selections[i]; + that.savedProperties[entityID.id] = Entities.getEntityProperties(entityID); + } + }; + + that.setEventListener = function(func) { + that.eventListener = func; + }; + + that.addEntity = function(entityID) { + print("Adding: " + entityID.id); + var idx = that.selections.indexOf(entityID); + if (idx == -1) { + that.selections.push(entityID); + } + + that._update(); + }; + + that.removeEntity = function(entityID) { + var idx = that.selections.indexOf(entityID); + if (idx >= 0) { + that.selections.splice(idx, 1); + } + + that._update(); + }; + + that.clearSelections = function() { + that.selections = []; + + that._update(); + }; + + that._update = function() { + if (that.selections.length == 0) { + that.localDimensions = null; + that.localPosition = null; + that.worldDimensions = null; + that.worldPosition = null; + } else if (that.selections.length == 1) { + var properties = Entities.getEntityProperties(that.selections[0]); + that.localDimensions = properties.dimensions; + that.localPosition = properties.position; + that.localRotation = properties.rotation; + + that.worldDimensions = properties.boundingBox.dimensions; + that.worldPosition = properties.boundingBox.center; + } else { + // For 1+ selections we can only modify selections in world space + SelectionDisplay.setSpaceMode(SPACE_WORLD); + + that.localRotation = null; + that.localDimensions = null; + that.localPosition = null; + + var properties = Entities.getEntityProperties(that.selections[0]); + + var brn = properties.boundingBox.brn; + var tfl = properties.boundingBox.tfl; + + for (var i = 1; i < that.selections.length; i++) { + properties = Entities.getEntityProperties(that.selections[i]); + var bb = properties.boundingBox; + brn.x = Math.min(bb.brn.x, brn.x); + brn.y = Math.min(bb.brn.y, brn.y); + brn.z = Math.min(bb.brn.z, brn.z); + tfl.x = Math.max(bb.tfl.x, tfl.x); + tfl.y = Math.max(bb.tfl.y, tfl.y); + tfl.z = Math.max(bb.tfl.z, tfl.z); + } + + that.localDimensions = null; + that.localPosition = null; + that.worldDimensions = { + x: tfl.x - brn.x, + y: tfl.y - brn.y, + z: tfl.z - brn.z + }; + that.worldPosition = { + x: brn.x + (that.worldDimensions.x / 2), + y: brn.y + (that.worldDimensions.y / 2), + z: brn.z + (that.worldDimensions.z / 2), + }; + } + + if (that.eventListener) { + that.eventListener(); + } + }; + + return that; +})(); + SelectionDisplay = (function () { var that = {}; @@ -20,6 +138,7 @@ SelectionDisplay = (function () { var GRABBER_DISTANCE_TO_SIZE_RATIO = 0.015; + var spaceMode = SPACE_LOCAL; var mode = "UNKNOWN"; var overlayNames = new Array(); var lastCameraPosition = Camera.getPosition(); @@ -112,7 +231,6 @@ SelectionDisplay = (function () { lineWidth: grabberLineWidth, }; - var highlightBox = Overlays.addOverlay("cube", { position: { x:0, y: 0, z: 0}, size: 1, @@ -146,6 +264,15 @@ SelectionDisplay = (function () { scale: 0.1, isFacingAvatar: true }); + + // var normalLine = Overlays.addOverlay("line3d", { + // visible: true, + // lineWidth: 2.0, + // start: { x: 0, y: 0, z: 0 }, + // end: { x: 0, y: 0, z: 0 }, + // color: { red: 255, green: 255, blue: 0 }, + // ignoreRayIntersection: true, + // }); var grabberLBN = Overlays.addOverlay("cube", grabberPropertiesCorner); var grabberRBN = Overlays.addOverlay("cube", grabberPropertiesCorner); @@ -176,7 +303,7 @@ SelectionDisplay = (function () { var grabberEdgeFR = Overlays.addOverlay("cube", grabberPropertiesEdge); var grabberEdgeFL = Overlays.addOverlay("cube", grabberPropertiesEdge); - var cornerEdgeFaceGrabbers = [ + var stretchHandles = [ grabberLBN, grabberRBN, grabberLBF, @@ -205,6 +332,7 @@ SelectionDisplay = (function () { grabberEdgeFL, ]; + var baseOverlayAngles = { x: 0, y: 0, z: 0 }; var baseOverlayRotation = Quat.fromVec3Degrees(baseOverlayAngles); var baseOfEntityProjectionOverlay = Overlays.addOverlay("rectangle3d", { @@ -225,6 +353,34 @@ SelectionDisplay = (function () { var rollOverlayAngles = { x: 0, y: 180, z: 0 }; var rollOverlayRotation = Quat.fromVec3Degrees(rollOverlayAngles); + var xRailOverlay = Overlays.addOverlay("line3d", { + visible: false, + lineWidth: 1.0, + start: { x: 0, y: 0, z: 0 }, + end: { x: 0, y: 0, z: 0 }, + color: { red: 255, green: 0, blue: 0 }, + ignoreRayIntersection: true, // always ignore this + visible: false, + }); + var yRailOverlay = Overlays.addOverlay("line3d", { + visible: false, + lineWidth: 1.0, + start: { x: 0, y: 0, z: 0 }, + end: { x: 0, y: 0, z: 0 }, + color: { red: 0, green: 255, blue: 0 }, + ignoreRayIntersection: true, // always ignore this + visible: false, + }); + var zRailOverlay = Overlays.addOverlay("line3d", { + visible: false, + lineWidth: 1.0, + start: { x: 0, y: 0, z: 0 }, + end: { x: 0, y: 0, z: 0 }, + color: { red: 0, green: 0, blue: 255 }, + ignoreRayIntersection: true, // always ignore this + visible: false, + }); + var rotateZeroOverlay = Overlays.addOverlay("line3d", { visible: false, lineWidth: 2.0, @@ -340,6 +496,24 @@ SelectionDisplay = (function () { isFacingAvatar: false }); + var allOverlays = [ + highlightBox, + selectionBox, + grabberMoveUp, + yawHandle, + pitchHandle, + rollHandle, + rotateOverlayTarget, + rotateOverlayInner, + rotateOverlayOuter, + rotateOverlayCurrent, + rotateZeroOverlay, + rotateCurrentOverlay, + xRailOverlay, + yRailOverlay, + zRailOverlay, + ].concat(stretchHandles); + overlayNames[highlightBox] = "highlightBox"; overlayNames[selectionBox] = "selectionBox"; overlayNames[baseOfEntityProjectionOverlay] = "baseOfEntityProjectionOverlay"; @@ -384,60 +558,33 @@ SelectionDisplay = (function () { overlayNames[rotateZeroOverlay] = "rotateZeroOverlay"; overlayNames[rotateCurrentOverlay] = "rotateCurrentOverlay"; + + var activeTool = null; + var grabberTools = {}; + function addGrabberTool(overlay, tool) { + grabberTools[overlay] = { + mode: tool.mode, + onBegin: tool.onBegin, + onMove: tool.onMove, + onEnd: tool.onEnd, + } + } + that.cleanup = function () { - Overlays.deleteOverlay(highlightBox); - Overlays.deleteOverlay(selectionBox); - Overlays.deleteOverlay(grabberMoveUp); - Overlays.deleteOverlay(baseOfEntityProjectionOverlay); - Overlays.deleteOverlay(grabberLBN); - Overlays.deleteOverlay(grabberLBF); - Overlays.deleteOverlay(grabberRBN); - Overlays.deleteOverlay(grabberRBF); - Overlays.deleteOverlay(grabberLTN); - Overlays.deleteOverlay(grabberLTF); - Overlays.deleteOverlay(grabberRTN); - Overlays.deleteOverlay(grabberRTF); - - Overlays.deleteOverlay(grabberTOP); - Overlays.deleteOverlay(grabberBOTTOM); - Overlays.deleteOverlay(grabberLEFT); - Overlays.deleteOverlay(grabberRIGHT); - Overlays.deleteOverlay(grabberNEAR); - Overlays.deleteOverlay(grabberFAR); - - Overlays.deleteOverlay(grabberEdgeTR); - Overlays.deleteOverlay(grabberEdgeTL); - Overlays.deleteOverlay(grabberEdgeTF); - Overlays.deleteOverlay(grabberEdgeTN); - Overlays.deleteOverlay(grabberEdgeBR); - Overlays.deleteOverlay(grabberEdgeBL); - Overlays.deleteOverlay(grabberEdgeBF); - Overlays.deleteOverlay(grabberEdgeBN); - Overlays.deleteOverlay(grabberEdgeNR); - Overlays.deleteOverlay(grabberEdgeNL); - Overlays.deleteOverlay(grabberEdgeFR); - Overlays.deleteOverlay(grabberEdgeFL); - - Overlays.deleteOverlay(yawHandle); - Overlays.deleteOverlay(pitchHandle); - Overlays.deleteOverlay(rollHandle); - - Overlays.deleteOverlay(rotateOverlayTarget); - Overlays.deleteOverlay(rotateOverlayInner); - Overlays.deleteOverlay(rotateOverlayOuter); - Overlays.deleteOverlay(rotateOverlayCurrent); - - Overlays.deleteOverlay(rotateZeroOverlay); - Overlays.deleteOverlay(rotateCurrentOverlay); - - + for (var i = 0; i < allOverlays.length; i++) { + Overlays.deleteOverlay(allOverlays[i]); + } }; that.highlightSelectable = function(entityID) { var properties = Entities.getEntityProperties(entityID); - Overlays.editOverlay(highlightBox, { visible: true, position: properties.boundingBox.center, - dimensions: properties.boundingBox.dimensions }); + Overlays.editOverlay(highlightBox, { + visible: true, + position: properties.boundingBox.center, + dimensions: properties.dimensions, + rotation: properties.rotation + }); }; that.unhighlightSelectable = function(entityID) { @@ -446,9 +593,9 @@ SelectionDisplay = (function () { that.select = function(entityID, event) { var properties = Entities.getEntityProperties(entityID); - if (currentSelection.isKnownID == true) { - that.unselect(currentSelection); - } + // if (currentSelection.isKnownID == true) { + // that.unselect(currentSelection); + // } currentSelection = entityID; entitySelected = true; @@ -493,26 +640,29 @@ SelectionDisplay = (function () { var top, far, left, bottom, near, right, boundsCenter, objectCenter, BLN, BRN, BLF, TLN, TRN, TLF, TRF; - objectCenter = { x: properties.position.x, y: properties.position.y, z: properties.position.z }; - - top = properties.boundingBox.tfl.y; - far = properties.boundingBox.tfl.z; - left = properties.boundingBox.tfl.x; + // objectCenter = { x: properties.position.x, y: properties.position.y, z: properties.position.z }; - bottom = properties.boundingBox.brn.y; - right = properties.boundingBox.brn.x; - near = properties.boundingBox.brn.z; + var dimensions; + if (spaceMode == SPACE_LOCAL) { + objectCenter = SelectionManager.localPosition; + dimensions = SelectionManager.localDimensions; + } else { + objectCenter = SelectionManager.worldPosition; + dimensions = SelectionManager.worldDimensions; + } + objectCenter = SelectionManager.worldPosition; + dimensions = SelectionManager.worldDimensions; - boundsCenter = { x: properties.boundingBox.center.x, y: properties.boundingBox.center.y, z: properties.boundingBox.center.z }; + top = objectCenter.y + (dimensions.y / 2); + far = objectCenter.z + (dimensions.z / 2); + left = objectCenter.x + (dimensions.x / 2); - BLN = { x: left, y: bottom, z: near }; - BRN = { x: right, y: bottom, z: near }; - BLF = { x: left, y: bottom, z: far }; - BRF = { x: right, y: bottom, z: far }; - TLN = { x: left, y: top, z: near }; - TRN = { x: right, y: top, z: near }; - TLF = { x: left, y: top, z: far }; - TRF = { x: right, y: top, z: far }; + bottom = objectCenter.y - (dimensions.y / 2); + near = objectCenter.z - (dimensions.z / 2); + right = objectCenter.x - (dimensions.x / 2); + + // boundsCenter = { x: properties.boundingBox.center.x, y: properties.boundingBox.center.y, z: properties.boundingBox.center.z }; + boundsCenter = objectCenter; var yawCorner; var pitchCorner; @@ -531,9 +681,10 @@ SelectionDisplay = (function () { ------------------------------*/ - if (MyAvatar.position.x > objectCenter.x) { + var cameraPosition = Camera.getPosition(); + if (cameraPosition.x > objectCenter.x) { // must be BRF or BRN - if (MyAvatar.position.z < objectCenter.z) { + if (cameraPosition.z < objectCenter.z) { yawHandleRotation = Quat.fromVec3Degrees({ x: 270, y: 90, z: 0 }); pitchHandleRotation = Quat.fromVec3Degrees({ x: 0, y: 90, z: 0 }); @@ -598,7 +749,7 @@ SelectionDisplay = (function () { } else { // must be BLF or BLN - if (MyAvatar.position.z < objectCenter.z) { + if (cameraPosition.z < objectCenter.z) { yawHandleRotation = Quat.fromVec3Degrees({ x: 270, y: 180, z: 0 }); pitchHandleRotation = Quat.fromVec3Degrees({ x: 90, y: 0, z: 90 }); @@ -663,7 +814,7 @@ SelectionDisplay = (function () { var translateHandlesVisible = true; var stretchHandlesVisible = true; var selectionBoxVisible = true; - if (mode == "ROTATE_YAW" || mode == "ROTATE_PITCH" || mode == "ROTATE_ROLL" || mode == "TRANSLATE_XZ") { + if (mode == "ROTATE_YAW" || mode == "ROTATE_PITCH" || mode == "ROTATE_ROLL" || mode == "TRANSLATE_X in case they Z") { rotateHandlesVisible = false; translateHandlesVisible = false; stretchHandlesVisible = false; @@ -679,41 +830,20 @@ SelectionDisplay = (function () { Overlays.editOverlay(highlightBox, { visible: false }); - Overlays.editOverlay(selectionBox, { visible: selectionBoxVisible, position: properties.boundingBox.center, - dimensions: properties.boundingBox.dimensions }); - - + var dimensions, rotation, position; + if (spaceMode == SPACE_LOCAL) { + rotation = SelectionManager.localRotation; + dimensions = SelectionManager.localDimensions; + position = SelectionManager.localPosition; + } else { + rotation = SelectionManager.worldRotation; + dimensions = SelectionManager.worldDimensions; + position = SelectionManager.worldPosition; + } + Overlays.editOverlay(grabberMoveUp, { visible: translateHandlesVisible, position: { x: boundsCenter.x, y: top + grabberMoveUpOffset, z: boundsCenter.z } }); - Overlays.editOverlay(grabberLBN, { visible: stretchHandlesVisible, position: { x: left, y: bottom, z: near } }); - Overlays.editOverlay(grabberRBN, { visible: stretchHandlesVisible, position: { x: right, y: bottom, z: near } }); - Overlays.editOverlay(grabberLBF, { visible: stretchHandlesVisible, position: { x: left, y: bottom, z: far } }); - Overlays.editOverlay(grabberRBF, { visible: stretchHandlesVisible, position: { x: right, y: bottom, z: far } }); - Overlays.editOverlay(grabberLTN, { visible: stretchHandlesVisible, position: { x: left, y: top, z: near } }); - Overlays.editOverlay(grabberRTN, { visible: stretchHandlesVisible, position: { x: right, y: top, z: near } }); - Overlays.editOverlay(grabberLTF, { visible: stretchHandlesVisible, position: { x: left, y: top, z: far } }); - Overlays.editOverlay(grabberRTF, { visible: stretchHandlesVisible, position: { x: right, y: top, z: far } }); - - - Overlays.editOverlay(grabberTOP, { visible: stretchHandlesVisible, position: { x: boundsCenter.x, y: top, z: boundsCenter.z } }); - Overlays.editOverlay(grabberBOTTOM, { visible: stretchHandlesVisible, position: { x: boundsCenter.x, y: bottom, z: boundsCenter.z } }); - Overlays.editOverlay(grabberLEFT, { visible: stretchHandlesVisible, position: { x: left, y: boundsCenter.y, z: boundsCenter.z } }); - Overlays.editOverlay(grabberRIGHT, { visible: stretchHandlesVisible, position: { x: right, y: boundsCenter.y, z: boundsCenter.z } }); - Overlays.editOverlay(grabberNEAR, { visible: stretchHandlesVisible, position: { x: boundsCenter.x, y: boundsCenter.y, z: near } }); - Overlays.editOverlay(grabberFAR, { visible: stretchHandlesVisible, position: { x: boundsCenter.x, y: boundsCenter.y, z: far } }); - - Overlays.editOverlay(grabberEdgeTR, { visible: stretchHandlesVisible, position: { x: right, y: top, z: boundsCenter.z } }); - Overlays.editOverlay(grabberEdgeTL, { visible: stretchHandlesVisible, position: { x: left, y: top, z: boundsCenter.z } }); - Overlays.editOverlay(grabberEdgeTF, { visible: stretchHandlesVisible, position: { x: boundsCenter.x, y: top, z: far } }); - Overlays.editOverlay(grabberEdgeTN, { visible: stretchHandlesVisible, position: { x: boundsCenter.x, y: top, z: near } }); - Overlays.editOverlay(grabberEdgeBR, { visible: stretchHandlesVisible, position: { x: right, y: bottom, z: boundsCenter.z } }); - Overlays.editOverlay(grabberEdgeBL, { visible: stretchHandlesVisible, position: { x: left, y: bottom, z: boundsCenter.z } }); - Overlays.editOverlay(grabberEdgeBF, { visible: stretchHandlesVisible, position: { x: boundsCenter.x, y: bottom, z: far } }); - Overlays.editOverlay(grabberEdgeBN, { visible: stretchHandlesVisible, position: { x: boundsCenter.x, y: bottom, z: near } }); - Overlays.editOverlay(grabberEdgeNR, { visible: stretchHandlesVisible, position: { x: right, y: boundsCenter.y, z: near } }); - Overlays.editOverlay(grabberEdgeNL, { visible: stretchHandlesVisible, position: { x: left, y: boundsCenter.y, z: near } }); - Overlays.editOverlay(grabberEdgeFR, { visible: stretchHandlesVisible, position: { x: right, y: boundsCenter.y, z: far } }); - Overlays.editOverlay(grabberEdgeFL, { visible: stretchHandlesVisible, position: { x: left, y: boundsCenter.y, z: far } }); + that.updateHandles(entityID); Overlays.editOverlay(baseOfEntityProjectionOverlay, @@ -770,6 +900,22 @@ SelectionDisplay = (function () { Entities.editEntity(entityID, { localRenderAlpha: 0.1 }); }; + that.setSpaceMode = function(newSpaceMode) { + if (spaceMode != newSpaceMode) { + spaceMode = newSpaceMode; + that.updateHandles(); + } + }; + + that.toggleSpaceMode = function() { + if (spaceMode == SPACE_WORLD && SelectionManager.selections.length > 1) { + print("Local space editing is not available with multiple selections"); + return; + } + spaceMode = spaceMode == SPACE_LOCAL ? SPACE_WORLD : SPACE_LOCAL; + that.updateHandles(); + }; + that.unselectAll = function () { if (currentSelection.isKnownID == true) { that.unselect(currentSelection); @@ -778,50 +924,170 @@ SelectionDisplay = (function () { entitySelected = false; }; + that.updateHandles = function(entityID) { + if (!entitySelected) { + that.setOverlaysVisible(false); + return; + } + + var properties = Entities.getEntityProperties(entityID); + + var rotation, dimensions, position; + + if (spaceMode == SPACE_LOCAL) { + rotation = properties.rotation; + dimensions = SelectionManager.localDimensions; + position = SelectionManager.localPosition; + } else { + rotation = Quat.fromPitchYawRollDegrees(0, 0, 0); + dimensions = SelectionManager.worldDimensions; + position = SelectionManager.worldPosition; + } + + var halfDimensions = Vec3.multiply(0.5, dimensions); + + left = -halfDimensions.x; + right = halfDimensions.x; + top = halfDimensions.y; + bottom = -halfDimensions.y; + var front = far = halfDimensions.z; + near = -halfDimensions.z; + + var LBN = { x: left, y: bottom, z: near }; + var RBN = { x: right, y: bottom, z: near }; + var LBF = { x: left, y: bottom, z: far }; + var RBF = { x: right, y: bottom, z: far }; + var LTN = { x: left, y: top, z: near }; + var RTN = { x: right, y: top, z: near }; + var LTF = { x: left, y: top, z: far }; + var RTF = { x: right, y: top, z: far }; + + var TOP = { x: 0, y: top, z: 0 }; + var BOTTOM = { x: 0, y: bottom, z: 0 }; + var LEFT = { x: left, y: 0, z: 0 }; + var RIGHT = { x: right, y: 0, z: 0 }; + var NEAR = { x: 0, y: 0, z: near }; + var FAR = { x: 0, y: 0, z: far }; + + var EdgeTR = { x: right, y: top, z: 0 }; + var EdgeTL = { x: left, y: top, z: 0 }; + var EdgeTF = { x: 0, y: top, z: front }; + var EdgeTN = { x: 0, y: top, z: near }; + var EdgeBR = { x: right, y: bottom, z: 0 }; + var EdgeBL = { x: left, y: bottom, z: 0 }; + var EdgeBF = { x: 0, y: bottom, z: front }; + var EdgeBN = { x: 0, y: bottom, z: near }; + var EdgeNR = { x: right, y: 0, z: near }; + var EdgeNL = { x: left, y: 0, z: near }; + var EdgeFR = { x: right, y: 0, z: front }; + var EdgeFL = { x: left, y: 0, z: front }; + + LBN = Vec3.multiplyQbyV(rotation, LBN); + RBN = Vec3.multiplyQbyV(rotation, RBN); + LBF = Vec3.multiplyQbyV(rotation, LBF); + RBF = Vec3.multiplyQbyV(rotation, RBF); + LTN = Vec3.multiplyQbyV(rotation, LTN); + RTN = Vec3.multiplyQbyV(rotation, RTN); + LTF = Vec3.multiplyQbyV(rotation, LTF); + RTF = Vec3.multiplyQbyV(rotation, RTF); + + TOP = Vec3.multiplyQbyV(rotation, TOP); + BOTTOM = Vec3.multiplyQbyV(rotation, BOTTOM); + LEFT = Vec3.multiplyQbyV(rotation, LEFT); + RIGHT = Vec3.multiplyQbyV(rotation, RIGHT); + NEAR = Vec3.multiplyQbyV(rotation, NEAR); + FAR = Vec3.multiplyQbyV(rotation, FAR); + + EdgeTR = Vec3.multiplyQbyV(rotation, EdgeTR); + EdgeTL = Vec3.multiplyQbyV(rotation, EdgeTL); + EdgeTF = Vec3.multiplyQbyV(rotation, EdgeTF); + EdgeTN = Vec3.multiplyQbyV(rotation, EdgeTN); + EdgeBR = Vec3.multiplyQbyV(rotation, EdgeBR); + EdgeBL = Vec3.multiplyQbyV(rotation, EdgeBL); + EdgeBF = Vec3.multiplyQbyV(rotation, EdgeBF); + EdgeBN = Vec3.multiplyQbyV(rotation, EdgeBN); + EdgeNR = Vec3.multiplyQbyV(rotation, EdgeNR); + EdgeNL = Vec3.multiplyQbyV(rotation, EdgeNL); + EdgeFR = Vec3.multiplyQbyV(rotation, EdgeFR); + EdgeFL = Vec3.multiplyQbyV(rotation, EdgeFL); + + LBN = Vec3.sum(position, LBN); + RBN = Vec3.sum(position, RBN); + LBF = Vec3.sum(position, LBF); + RBF = Vec3.sum(position, RBF); + LTN = Vec3.sum(position, LTN); + RTN = Vec3.sum(position, RTN); + LTF = Vec3.sum(position, LTF); + RTF = Vec3.sum(position, RTF); + + TOP = Vec3.sum(position, TOP); + BOTTOM = Vec3.sum(position, BOTTOM); + LEFT = Vec3.sum(position, LEFT); + RIGHT = Vec3.sum(position, RIGHT); + NEAR = Vec3.sum(position, NEAR); + FAR = Vec3.sum(position, FAR); + + EdgeTR = Vec3.sum(position, EdgeTR); + EdgeTL = Vec3.sum(position, EdgeTL); + EdgeTF = Vec3.sum(position, EdgeTF); + EdgeTN = Vec3.sum(position, EdgeTN); + EdgeBR = Vec3.sum(position, EdgeBR); + EdgeBL = Vec3.sum(position, EdgeBL); + EdgeBF = Vec3.sum(position, EdgeBF); + EdgeBN = Vec3.sum(position, EdgeBN); + EdgeNR = Vec3.sum(position, EdgeNR); + EdgeNL = Vec3.sum(position, EdgeNL); + EdgeFR = Vec3.sum(position, EdgeFR); + EdgeFL = Vec3.sum(position, EdgeFL); + + var stretchHandlesVisible = spaceMode == SPACE_LOCAL; + Overlays.editOverlay(grabberLBN, { visible: stretchHandlesVisible, rotation: rotation, position: LBN }); + Overlays.editOverlay(grabberRBN, { visible: stretchHandlesVisible, rotation: rotation, position: RBN }); + Overlays.editOverlay(grabberLBF, { visible: stretchHandlesVisible, rotation: rotation, position: LBF }); + Overlays.editOverlay(grabberRBF, { visible: stretchHandlesVisible, rotation: rotation, position: RBF }); + Overlays.editOverlay(grabberLTN, { visible: stretchHandlesVisible, rotation: rotation, position: LTN }); + Overlays.editOverlay(grabberRTN, { visible: stretchHandlesVisible, rotation: rotation, position: RTN }); + Overlays.editOverlay(grabberLTF, { visible: stretchHandlesVisible, rotation: rotation, position: LTF }); + Overlays.editOverlay(grabberRTF, { visible: stretchHandlesVisible, rotation: rotation, position: RTF }); + + Overlays.editOverlay(grabberTOP, { visible: stretchHandlesVisible, rotation: rotation, position: TOP }); + Overlays.editOverlay(grabberBOTTOM, { visible: stretchHandlesVisible, rotation: rotation, position: BOTTOM }); + Overlays.editOverlay(grabberLEFT, { visible: stretchHandlesVisible, rotation: rotation, position: LEFT }); + Overlays.editOverlay(grabberRIGHT, { visible: stretchHandlesVisible, rotation: rotation, position: RIGHT }); + Overlays.editOverlay(grabberNEAR, { visible: stretchHandlesVisible, rotation: rotation, position: NEAR }); + Overlays.editOverlay(grabberFAR, { visible: stretchHandlesVisible, rotation: rotation, position: FAR }); + + Overlays.editOverlay(selectionBox, { + position: position, + dimensions: dimensions, + rotation: rotation, + visible: true, + }); + + Overlays.editOverlay(grabberEdgeTR, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeTR }); + Overlays.editOverlay(grabberEdgeTL, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeTL }); + Overlays.editOverlay(grabberEdgeTF, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeTF }); + Overlays.editOverlay(grabberEdgeTN, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeTN }); + Overlays.editOverlay(grabberEdgeBR, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeBR }); + Overlays.editOverlay(grabberEdgeBL, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeBL }); + Overlays.editOverlay(grabberEdgeBF, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeBF }); + Overlays.editOverlay(grabberEdgeBN, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeBN }); + Overlays.editOverlay(grabberEdgeNR, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeNR }); + Overlays.editOverlay(grabberEdgeNL, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeNL }); + Overlays.editOverlay(grabberEdgeFR, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeFR }); + Overlays.editOverlay(grabberEdgeFL, { visible: stretchHandlesVisible, rotation: rotation, position: EdgeFL }); + + }; + + that.setOverlaysVisible = function(isVisible) { + var length = allOverlays.length; + for (var i = 0; i < length; i++) { + Overlays.editOverlay(allOverlays[i], { visible: isVisible }); + } + }; + that.unselect = function (entityID) { - Overlays.editOverlay(selectionBox, { visible: false }); - Overlays.editOverlay(baseOfEntityProjectionOverlay, { visible: false }); - Overlays.editOverlay(grabberMoveUp, { visible: false }); - Overlays.editOverlay(grabberLBN, { visible: false }); - Overlays.editOverlay(grabberLBF, { visible: false }); - Overlays.editOverlay(grabberRBN, { visible: false }); - Overlays.editOverlay(grabberRBF, { visible: false }); - Overlays.editOverlay(grabberLTN, { visible: false }); - Overlays.editOverlay(grabberLTF, { visible: false }); - Overlays.editOverlay(grabberRTN, { visible: false }); - Overlays.editOverlay(grabberRTF, { visible: false }); - - Overlays.editOverlay(grabberTOP, { visible: false }); - Overlays.editOverlay(grabberBOTTOM, { visible: false }); - Overlays.editOverlay(grabberLEFT, { visible: false }); - Overlays.editOverlay(grabberRIGHT, { visible: false }); - Overlays.editOverlay(grabberNEAR, { visible: false }); - Overlays.editOverlay(grabberFAR, { visible: false }); - - Overlays.editOverlay(grabberEdgeTR, { visible: false }); - Overlays.editOverlay(grabberEdgeTL, { visible: false }); - Overlays.editOverlay(grabberEdgeTF, { visible: false }); - Overlays.editOverlay(grabberEdgeTN, { visible: false }); - Overlays.editOverlay(grabberEdgeBR, { visible: false }); - Overlays.editOverlay(grabberEdgeBL, { visible: false }); - Overlays.editOverlay(grabberEdgeBF, { visible: false }); - Overlays.editOverlay(grabberEdgeBN, { visible: false }); - Overlays.editOverlay(grabberEdgeNR, { visible: false }); - Overlays.editOverlay(grabberEdgeNL, { visible: false }); - Overlays.editOverlay(grabberEdgeFR, { visible: false }); - Overlays.editOverlay(grabberEdgeFL, { visible: false }); - - Overlays.editOverlay(yawHandle, { visible: false }); - Overlays.editOverlay(pitchHandle, { visible: false }); - Overlays.editOverlay(rollHandle, { visible: false }); - - Overlays.editOverlay(rotateOverlayTarget, { visible: false }); - Overlays.editOverlay(rotateOverlayInner, { visible: false }); - Overlays.editOverlay(rotateOverlayOuter, { visible: false }); - Overlays.editOverlay(rotateOverlayCurrent, { visible: false }); - - Overlays.editOverlay(rotateZeroOverlay, { visible: false }); - Overlays.editOverlay(rotateCurrentOverlay, { visible: false }); + that.setOverlaysVisible(false); Entities.editEntity(entityID, { localRenderAlpha: 1.0 }); @@ -829,1160 +1095,711 @@ SelectionDisplay = (function () { entitySelected = false; }; - that.translateXZ = function(event) { - if (!entitySelected || mode !== "TRANSLATE_XZ") { - return; // not allowed + var lastXZPick = null; + var translateXZTool = { + mode: 'TRANSLATE_XZ', + onBegin: function(event) { + SelectionManager.saveProperties(); + var position = SelectionManager.worldPosition; + var dimensions = SelectionManager.worldDimensions; + var bottom = position.y - (dimensions.y / 2) + + var pickRay = Camera.computePickRay(event.x, event.y); + lastXZPick = rayPlaneIntersection(pickRay, position, { x: 0, y: 1, z: 0 }); + }, + onEnd: function(event, reason) { + if (reason == 'cancel') { + for (var i = 0; i < SelectionManager.selections.length; i++) { + var entityID = SelectionManager.selections[i]; + var initialProperties = SelectionManager.savedProperties[entityID.id]; + Entities.editEntity(entityID, initialProperties); + } + } + }, + onMove: function(event) { + if (!entitySelected || mode !== "TRANSLATE_XZ") { + return; // not allowed + } + + pickRay = Camera.computePickRay(event.x, event.y); + + // translate mode left/right based on view toward entity + var newIntersection = rayPlaneIntersection(pickRay, + selectedEntityPropertiesOriginalPosition, + Quat.getFront(lastCameraOrientation)); + + var vector = Vec3.subtract(newIntersection, lastPlaneIntersection); + + var pickRay = Camera.computePickRay(event.x, event.y); + var pick = rayPlaneIntersection(pickRay, SelectionManager.worldPosition, { x: 0, y: 1, z: 0 }); + vector = Vec3.subtract(pick, lastXZPick); + lastXZPick = pick; + + var wantDebug = false; + + for (var i = 0; i < SelectionManager.selections.length; i++) { + var properties = Entities.getEntityProperties(SelectionManager.selections[i]); + var original = properties.position; + properties.position = Vec3.sum(properties.position, vector); + Entities.editEntity(SelectionManager.selections[i], properties); + + if (wantDebug) { + print("translateXZ... "); + Vec3.print(" lastPlaneIntersection:", lastPlaneIntersection); + Vec3.print(" newIntersection:", newIntersection); + Vec3.print(" vector:", vector); + Vec3.print(" originalPosition:", original); + Vec3.print(" newPosition:", properties.position); + Vec3.print(" newPosition:", newPosition); + } + } + + tooltip.updateText(selectedEntityProperties); + that.select(currentSelection, false); // TODO: this should be more than highlighted + SelectionManager._update(); } - pickRay = Camera.computePickRay(event.x, event.y); - - // translate mode left/right based on view toward entity - var newIntersection = rayPlaneIntersection(pickRay, - selectedEntityPropertiesOriginalPosition, - Quat.getFront(lastCameraOrientation)); - - var vector = Vec3.subtract(newIntersection, lastPlaneIntersection); - - // this allows us to use the old editModels "shifted" logic which makes the - // up/down behavior of the mouse move "in"/"out" of the screen. - var i = Vec3.dot(vector, Quat.getRight(orientation)); - var j = Vec3.dot(vector, Quat.getUp(orientation)); - vector = Vec3.sum(Vec3.multiply(Quat.getRight(orientation), i), - Vec3.multiply(Quat.getFront(orientation), j)); - - newPosition = Vec3.sum(selectedEntityPropertiesOriginalPosition, vector); - - var wantDebug = false; - if (wantDebug) { - print("translateXZ... "); - Vec3.print(" lastPlaneIntersection:", lastPlaneIntersection); - Vec3.print(" newIntersection:", newIntersection); - Vec3.print(" vector:", vector); - Vec3.print(" originalPosition:", selectedEntityPropertiesOriginalPosition); - Vec3.print(" recentPosition:", selectedEntityProperties.position); - Vec3.print(" newPosition:", newPosition); - } - - selectedEntityProperties.position = newPosition; - Entities.editEntity(currentSelection, selectedEntityProperties); - tooltip.updateText(selectedEntityProperties); - that.select(currentSelection, false); // TODO: this should be more than highlighted }; - that.translateUpDown = function(event) { - if (!entitySelected || mode !== "TRANSLATE_UP_DOWN") { - return; // not allowed - } - pickRay = Camera.computePickRay(event.x, event.y); - - // translate mode left/right based on view toward entity - var newIntersection = rayPlaneIntersection(pickRay, - selectedEntityPropertiesOriginalPosition, - Quat.getFront(lastCameraOrientation)); - - var vector = Vec3.subtract(newIntersection, lastPlaneIntersection); - - // we only care about the Y axis - vector.x = 0; - vector.z = 0; - - newPosition = Vec3.sum(selectedEntityPropertiesOriginalPosition, vector); - - var wantDebug = false; - if (wantDebug) { - print("translateUpDown... "); - print(" event.y:" + event.y); - Vec3.print(" lastPlaneIntersection:", lastPlaneIntersection); - Vec3.print(" newIntersection:", newIntersection); - Vec3.print(" vector:", vector); - Vec3.print(" originalPosition:", selectedEntityPropertiesOriginalPosition); - Vec3.print(" recentPosition:", selectedEntityProperties.position); - Vec3.print(" newPosition:", newPosition); - } - - selectedEntityProperties.position = newPosition; - Entities.editEntity(currentSelection, selectedEntityProperties); - tooltip.updateText(selectedEntityProperties); - that.select(currentSelection, false); // TODO: this should be more than highlighted - }; - - that.stretchNEAR = function(event) { - if (!entitySelected || mode !== "STRETCH_NEAR") { - return; // not allowed - } - pickRay = Camera.computePickRay(event.x, event.y); - - // translate mode left/right based on view toward entity - var newIntersection = rayPlaneIntersection(pickRay, - selectedEntityPropertiesOriginalPosition, - Quat.getFront(lastCameraOrientation)); - - var vector = Vec3.subtract(newIntersection, lastPlaneIntersection); - - var halfDimensions = Vec3.multiply(selectedEntityPropertiesOriginalDimensions, 0.5); - var oldNEAR = selectedEntityPropertiesOriginalPosition.z - halfDimensions.z; - var newNEAR = oldNEAR + vector.z; - - // if near is changing, then... - // dimensions changes by: (oldNEAR - newNEAR) - var changeInDimensions = { x: 0, y: 0, z: (oldNEAR - newNEAR) }; - var newDimensions = Vec3.sum(selectedEntityPropertiesOriginalDimensions, changeInDimensions); - - if (newDimensions.z < MINIMUM_DIMENSION) { - newDimensions.z = MINIMUM_DIMENSION; - } - - var changeInPosition = { x: 0, y: 0, z: (oldNEAR - newNEAR) * -0.5 }; - var newPosition = Vec3.sum(selectedEntityPropertiesOriginalPosition, changeInPosition); - var wantDebug = false; - if (wantDebug) { - print("stretchNEAR... "); - Vec3.print(" lastPlaneIntersection:", lastPlaneIntersection); - Vec3.print(" newIntersection:", newIntersection); - Vec3.print(" vector:", vector); - print(" oldNEAR:" + oldNEAR); - print(" newNEAR:" + newNEAR); - Vec3.print(" oldDimensions:", selectedEntityPropertiesOriginalDimensions); - Vec3.print(" changeInDimensions:", changeInDimensions); - Vec3.print(" newDimensions:", newDimensions); - - Vec3.print(" oldPosition:", selectedEntityPropertiesOriginalPosition); - Vec3.print(" changeInPosition:", changeInPosition); - Vec3.print(" newPosition:", newPosition); - } - - - selectedEntityProperties.position = newPosition; - selectedEntityProperties.dimensions = newDimensions; - Entities.editEntity(currentSelection, selectedEntityProperties); - tooltip.updateText(selectedEntityProperties); - that.select(currentSelection, false); // TODO: this should be more than highlighted - }; - - that.stretchFAR = function(event) { - if (!entitySelected || mode !== "STRETCH_FAR") { - return; // not allowed - } - pickRay = Camera.computePickRay(event.x, event.y); - - // translate mode left/right based on view toward entity - var newIntersection = rayPlaneIntersection(pickRay, - selectedEntityPropertiesOriginalPosition, - Quat.getFront(lastCameraOrientation)); - - var vector = Vec3.subtract(newIntersection, lastPlaneIntersection); - - var halfDimensions = Vec3.multiply(selectedEntityPropertiesOriginalDimensions, 0.5); - var oldFAR = selectedEntityPropertiesOriginalPosition.z + halfDimensions.z; - var newFAR = oldFAR + vector.z; - var changeInDimensions = { x: 0, y: 0, z: (newFAR - oldFAR) }; - var newDimensions = Vec3.sum(selectedEntityPropertiesOriginalDimensions, changeInDimensions); - - if (newDimensions.z < MINIMUM_DIMENSION) { - newDimensions.z = MINIMUM_DIMENSION; - } - - var changeInPosition = { x: 0, y: 0, z: (newFAR - oldFAR) * 0.5 }; - var newPosition = Vec3.sum(selectedEntityPropertiesOriginalPosition, changeInPosition); - var wantDebug = false; - if (wantDebug) { - print("stretchFAR... "); - Vec3.print(" lastPlaneIntersection:", lastPlaneIntersection); - Vec3.print(" newIntersection:", newIntersection); - Vec3.print(" vector:", vector); - print(" oldFAR:" + oldFAR); - print(" newFAR:" + newFAR); - Vec3.print(" oldDimensions:", selectedEntityPropertiesOriginalDimensions); - Vec3.print(" changeInDimensions:", changeInDimensions); - Vec3.print(" newDimensions:", newDimensions); - - Vec3.print(" oldPosition:", selectedEntityPropertiesOriginalPosition); - Vec3.print(" changeInPosition:", changeInPosition); - Vec3.print(" newPosition:", newPosition); - } - - - selectedEntityProperties.position = newPosition; - selectedEntityProperties.dimensions = newDimensions; - Entities.editEntity(currentSelection, selectedEntityProperties); - tooltip.updateText(selectedEntityProperties); - that.select(currentSelection, false); // TODO: this should be more than highlighted - }; - - that.stretchTOP = function(event) { - if (!entitySelected || mode !== "STRETCH_TOP") { - return; // not allowed - } - pickRay = Camera.computePickRay(event.x, event.y); - - // translate mode left/right based on view toward entity - var newIntersection = rayPlaneIntersection(pickRay, - selectedEntityPropertiesOriginalPosition, - Quat.getFront(lastCameraOrientation)); - - var vector = Vec3.subtract(newIntersection, lastPlaneIntersection); - - var halfDimensions = Vec3.multiply(selectedEntityPropertiesOriginalDimensions, 0.5); - var oldTOP = selectedEntityPropertiesOriginalPosition.y + halfDimensions.y; - var newTOP = oldTOP + vector.y; - var changeInDimensions = { x: 0, y: (newTOP - oldTOP), z: 0 }; - var newDimensions = Vec3.sum(selectedEntityPropertiesOriginalDimensions, changeInDimensions); - - if (newDimensions.y < MINIMUM_DIMENSION) { - newDimensions.y = MINIMUM_DIMENSION; - } - - var changeInPosition = { x: 0, y: (newTOP - oldTOP) * 0.5, z: 0 }; - var newPosition = Vec3.sum(selectedEntityPropertiesOriginalPosition, changeInPosition); - var wantDebug = false; - if (wantDebug) { - print("stretchTOP... "); - Vec3.print(" lastPlaneIntersection:", lastPlaneIntersection); - Vec3.print(" newIntersection:", newIntersection); - Vec3.print(" vector:", vector); - print(" oldTOP:" + oldTOP); - print(" newTOP:" + newTOP); - Vec3.print(" oldDimensions:", selectedEntityPropertiesOriginalDimensions); - Vec3.print(" changeInDimensions:", changeInDimensions); - Vec3.print(" newDimensions:", newDimensions); - - Vec3.print(" oldPosition:", selectedEntityPropertiesOriginalPosition); - Vec3.print(" changeInPosition:", changeInPosition); - Vec3.print(" newPosition:", newPosition); - } - - selectedEntityProperties.position = newPosition; - selectedEntityProperties.dimensions = newDimensions; - Entities.editEntity(currentSelection, selectedEntityProperties); - tooltip.updateText(selectedEntityProperties); - that.select(currentSelection, false); // TODO: this should be more than highlighted - }; - - that.stretchBOTTOM = function(event) { - if (!entitySelected || mode !== "STRETCH_BOTTOM") { - return; // not allowed - } - pickRay = Camera.computePickRay(event.x, event.y); - - // translate mode left/right based on view toward entity - var newIntersection = rayPlaneIntersection(pickRay, - selectedEntityPropertiesOriginalPosition, - Quat.getFront(lastCameraOrientation)); - - var vector = Vec3.subtract(newIntersection, lastPlaneIntersection); - - var halfDimensions = Vec3.multiply(selectedEntityPropertiesOriginalDimensions, 0.5); - var oldBOTTOM = selectedEntityPropertiesOriginalPosition.y - halfDimensions.y; - var newBOTTOM = oldBOTTOM + vector.y; - var changeInDimensions = { x: 0, y: (oldBOTTOM - newBOTTOM), z: 0 }; - var newDimensions = Vec3.sum(selectedEntityPropertiesOriginalDimensions, changeInDimensions); - - if (newDimensions.y < MINIMUM_DIMENSION) { - newDimensions.y = MINIMUM_DIMENSION; - } - - var changeInPosition = { x: 0, y: (oldBOTTOM - newBOTTOM) * -0.5, z: 0 }; - var newPosition = Vec3.sum(selectedEntityPropertiesOriginalPosition, changeInPosition); - var wantDebug = false; - if (wantDebug) { - print("stretchBOTTOM... "); - Vec3.print(" lastPlaneIntersection:", lastPlaneIntersection); - Vec3.print(" newIntersection:", newIntersection); - Vec3.print(" vector:", vector); - print(" oldBOTTOM:" + oldBOTTOM); - print(" newBOTTOM:" + newBOTTOM); - Vec3.print(" oldDimensions:", selectedEntityPropertiesOriginalDimensions); - Vec3.print(" changeInDimensions:", changeInDimensions); - Vec3.print(" newDimensions:", newDimensions); - - Vec3.print(" oldPosition:", selectedEntityPropertiesOriginalPosition); - Vec3.print(" changeInPosition:", changeInPosition); - Vec3.print(" newPosition:", newPosition); - } - - selectedEntityProperties.position = newPosition; - selectedEntityProperties.dimensions = newDimensions; - Entities.editEntity(currentSelection, selectedEntityProperties); - tooltip.updateText(selectedEntityProperties); - that.select(currentSelection, false); // TODO: this should be more than highlighted - }; - - that.stretchRIGHT = function(event) { - if (!entitySelected || mode !== "STRETCH_RIGHT") { - return; // not allowed - } - pickRay = Camera.computePickRay(event.x, event.y); - - // translate mode left/right based on view toward entity - var newIntersection = rayPlaneIntersection(pickRay, - selectedEntityPropertiesOriginalPosition, - Quat.getFront(lastCameraOrientation)); - - var vector = Vec3.subtract(newIntersection, lastPlaneIntersection); - - var halfDimensions = Vec3.multiply(selectedEntityPropertiesOriginalDimensions, 0.5); - var oldRIGHT = selectedEntityPropertiesOriginalPosition.x - halfDimensions.x; - var newRIGHT = oldRIGHT + vector.x; - var changeInDimensions = { x: (oldRIGHT - newRIGHT), y: 0 , z: 0 }; - var newDimensions = Vec3.sum(selectedEntityPropertiesOriginalDimensions, changeInDimensions); - - if (newDimensions.x < MINIMUM_DIMENSION) { - newDimensions.x = MINIMUM_DIMENSION; - } - - var changeInPosition = { x: (oldRIGHT - newRIGHT) * -0.5, y: 0, z: 0 }; - var newPosition = Vec3.sum(selectedEntityPropertiesOriginalPosition, changeInPosition); - var wantDebug = false; - if (wantDebug) { - print("stretchRIGHT... "); - Vec3.print(" lastPlaneIntersection:", lastPlaneIntersection); - Vec3.print(" newIntersection:", newIntersection); - Vec3.print(" vector:", vector); - print(" oldRIGHT:" + oldRIGHT); - print(" newRIGHT:" + newRIGHT); - Vec3.print(" oldDimensions:", selectedEntityPropertiesOriginalDimensions); - Vec3.print(" changeInDimensions:", changeInDimensions); - Vec3.print(" newDimensions:", newDimensions); - - Vec3.print(" oldPosition:", selectedEntityPropertiesOriginalPosition); - Vec3.print(" changeInPosition:", changeInPosition); - Vec3.print(" newPosition:", newPosition); - } - - selectedEntityProperties.position = newPosition; - selectedEntityProperties.dimensions = newDimensions; - Entities.editEntity(currentSelection, selectedEntityProperties); - tooltip.updateText(selectedEntityProperties); - that.select(currentSelection, false); // TODO: this should be more than highlighted - }; - - that.stretchLEFT = function(event) { - if (!entitySelected || mode !== "STRETCH_LEFT") { - return; // not allowed - } - pickRay = Camera.computePickRay(event.x, event.y); - - // translate mode left/right based on view toward entity - var newIntersection = rayPlaneIntersection(pickRay, - selectedEntityPropertiesOriginalPosition, - Quat.getFront(lastCameraOrientation)); - - var vector = Vec3.subtract(newIntersection, lastPlaneIntersection); - - var halfDimensions = Vec3.multiply(selectedEntityPropertiesOriginalDimensions, 0.5); - var oldLEFT = selectedEntityPropertiesOriginalPosition.x + halfDimensions.x; - var newLEFT = oldLEFT + vector.x; - var changeInDimensions = { x: (newLEFT - oldLEFT), y: 0, z: 0 }; - var newDimensions = Vec3.sum(selectedEntityPropertiesOriginalDimensions, changeInDimensions); - - if (newDimensions.x < MINIMUM_DIMENSION) { - newDimensions.x = MINIMUM_DIMENSION; - } - - var changeInPosition = { x: (newLEFT - oldLEFT) * 0.5, y: 0, z: 0 }; - var newPosition = Vec3.sum(selectedEntityPropertiesOriginalPosition, changeInPosition); - var wantDebug = true; - if (wantDebug) { - print("stretchLEFT... "); - Vec3.print(" lastPlaneIntersection:", lastPlaneIntersection); - Vec3.print(" newIntersection:", newIntersection); - Vec3.print(" vector:", vector); - print(" oldLEFT:" + oldLEFT); - print(" newLEFT:" + newLEFT); - Vec3.print(" oldDimensions:", selectedEntityPropertiesOriginalDimensions); - Vec3.print(" changeInDimensions:", changeInDimensions); - Vec3.print(" newDimensions:", newDimensions); - - Vec3.print(" oldPosition:", selectedEntityPropertiesOriginalPosition); - Vec3.print(" changeInPosition:", changeInPosition); - Vec3.print(" newPosition:", newPosition); - } - - selectedEntityProperties.position = newPosition; - selectedEntityProperties.dimensions = newDimensions; - Entities.editEntity(currentSelection, selectedEntityProperties); - tooltip.updateText(selectedEntityProperties); - that.select(currentSelection, false); // TODO: this should be more than highlighted - }; - - that.stretchRBN = function(event) { - if (!entitySelected || mode !== "STRETCH_RBN") { - return; // not allowed - } - pickRay = Camera.computePickRay(event.x, event.y); - - // translate mode left/right based on view toward entity - var newIntersection = rayPlaneIntersection(pickRay, - selectedEntityPropertiesOriginalPosition, - Quat.getFront(lastCameraOrientation)); - - var vector = Vec3.subtract(newIntersection, lastPlaneIntersection); - - var halfDimensions = Vec3.multiply(selectedEntityPropertiesOriginalDimensions, 0.5); - var oldRIGHT = selectedEntityPropertiesOriginalPosition.x + halfDimensions.x; - var newRIGHT = oldRIGHT + vector.x; - - var oldBOTTOM = selectedEntityPropertiesOriginalPosition.y - halfDimensions.y; - var newBOTTOM = oldBOTTOM - vector.y; - - var oldNEAR = selectedEntityPropertiesOriginalPosition.z - halfDimensions.z; - var newNEAR = oldNEAR - vector.z; - - - var changeInDimensions = { x: (newRIGHT - oldRIGHT), y: (newBOTTOM - oldBOTTOM) , z: (newNEAR - oldNEAR) }; - var newDimensions = Vec3.sum(selectedEntityPropertiesOriginalDimensions, changeInDimensions); - - if (newDimensions.x < MINIMUM_DIMENSION) { - newDimensions.x = MINIMUM_DIMENSION; - } - - if (newDimensions.y < MINIMUM_DIMENSION) { - newDimensions.y = MINIMUM_DIMENSION; - } - - if (newDimensions.z < MINIMUM_DIMENSION) { - newDimensions.z = MINIMUM_DIMENSION; - } - - var changeInPosition = { x: (newRIGHT - oldRIGHT) * 0.5, - y: (newBOTTOM - oldBOTTOM) * -0.5, - z: (newNEAR - oldNEAR) * -0.5 }; - var newPosition = Vec3.sum(selectedEntityPropertiesOriginalPosition, changeInPosition); - var wantDebug = false; - if (wantDebug) { - print("stretchRBN... "); - Vec3.print(" lastPlaneIntersection:", lastPlaneIntersection); - Vec3.print(" newIntersection:", newIntersection); - Vec3.print(" vector:", vector); - print(" oldRIGHT:" + oldRIGHT); - print(" newRIGHT:" + newRIGHT); - Vec3.print(" oldDimensions:", selectedEntityPropertiesOriginalDimensions); - Vec3.print(" changeInDimensions:", changeInDimensions); - Vec3.print(" newDimensions:", newDimensions); - - Vec3.print(" oldPosition:", selectedEntityPropertiesOriginalPosition); - Vec3.print(" changeInPosition:", changeInPosition); - Vec3.print(" newPosition:", newPosition); - } - - selectedEntityProperties.position = newPosition; - selectedEntityProperties.dimensions = newDimensions; - Entities.editEntity(currentSelection, selectedEntityProperties); - tooltip.updateText(selectedEntityProperties); - that.select(currentSelection, false); // TODO: this should be more than highlighted - }; - - that.stretchLBN = function(event) { - if (!entitySelected || mode !== "STRETCH_LBN") { - return; // not allowed - } - pickRay = Camera.computePickRay(event.x, event.y); - - // translate mode left/right based on view toward entity - var newIntersection = rayPlaneIntersection(pickRay, - selectedEntityPropertiesOriginalPosition, - Quat.getFront(lastCameraOrientation)); - - var vector = Vec3.subtract(newIntersection, lastPlaneIntersection); - - var halfDimensions = Vec3.multiply(selectedEntityPropertiesOriginalDimensions, 0.5); - var oldLEFT = selectedEntityPropertiesOriginalPosition.x - halfDimensions.x; - var newLEFT = oldLEFT - vector.x; - - var oldBOTTOM = selectedEntityPropertiesOriginalPosition.y - halfDimensions.y; - var newBOTTOM = oldBOTTOM - vector.y; - - var oldNEAR = selectedEntityPropertiesOriginalPosition.z - halfDimensions.z; - var newNEAR = oldNEAR - vector.z; - - - var changeInDimensions = { x: (newLEFT - oldLEFT), y: (newBOTTOM - oldBOTTOM) , z: (newNEAR - oldNEAR) }; - var newDimensions = Vec3.sum(selectedEntityPropertiesOriginalDimensions, changeInDimensions); - - if (newDimensions.x < MINIMUM_DIMENSION) { - newDimensions.x = MINIMUM_DIMENSION; - } - - if (newDimensions.y < MINIMUM_DIMENSION) { - newDimensions.y = MINIMUM_DIMENSION; - } - - if (newDimensions.z < MINIMUM_DIMENSION) { - newDimensions.z = MINIMUM_DIMENSION; - } - - var changeInPosition = { x: (newLEFT - oldLEFT) * -0.5, - y: (newBOTTOM - oldBOTTOM) * -0.5, - z: (newNEAR - oldNEAR) * -0.5 }; - var newPosition = Vec3.sum(selectedEntityPropertiesOriginalPosition, changeInPosition); - var wantDebug = false; - if (wantDebug) { - print("stretchLBN... "); - Vec3.print(" lastPlaneIntersection:", lastPlaneIntersection); - Vec3.print(" newIntersection:", newIntersection); - Vec3.print(" vector:", vector); - print(" oldLEFT:" + oldLEFT); - print(" newLEFT:" + newLEFT); - Vec3.print(" oldDimensions:", selectedEntityPropertiesOriginalDimensions); - Vec3.print(" changeInDimensions:", changeInDimensions); - Vec3.print(" newDimensions:", newDimensions); - - Vec3.print(" oldPosition:", selectedEntityPropertiesOriginalPosition); - Vec3.print(" changeInPosition:", changeInPosition); - Vec3.print(" newPosition:", newPosition); - } - - selectedEntityProperties.position = newPosition; - selectedEntityProperties.dimensions = newDimensions; - Entities.editEntity(currentSelection, selectedEntityProperties); - tooltip.updateText(selectedEntityProperties); - that.select(currentSelection, false); // TODO: this should be more than highlighted - }; - - that.stretchRTN = function(event) { - if (!entitySelected || mode !== "STRETCH_RTN") { - return; // not allowed - } - pickRay = Camera.computePickRay(event.x, event.y); - - // translate mode left/right based on view toward entity - var newIntersection = rayPlaneIntersection(pickRay, - selectedEntityPropertiesOriginalPosition, - Quat.getFront(lastCameraOrientation)); - - var vector = Vec3.subtract(newIntersection, lastPlaneIntersection); - - var halfDimensions = Vec3.multiply(selectedEntityPropertiesOriginalDimensions, 0.5); - var oldRIGHT = selectedEntityPropertiesOriginalPosition.x + halfDimensions.x; - var newRIGHT = oldRIGHT + vector.x; - - var oldTOP = selectedEntityPropertiesOriginalPosition.y + halfDimensions.y; - var newTOP = oldTOP + vector.y; - - var oldNEAR = selectedEntityPropertiesOriginalPosition.z - halfDimensions.z; - var newNEAR = oldNEAR - vector.z; - - - var changeInDimensions = { x: (newRIGHT - oldRIGHT), y: (newTOP - oldTOP) , z: (newNEAR - oldNEAR) }; - var newDimensions = Vec3.sum(selectedEntityPropertiesOriginalDimensions, changeInDimensions); - - if (newDimensions.x < MINIMUM_DIMENSION) { - newDimensions.x = MINIMUM_DIMENSION; - } - - if (newDimensions.y < MINIMUM_DIMENSION) { - newDimensions.y = MINIMUM_DIMENSION; - } - - if (newDimensions.z < MINIMUM_DIMENSION) { - newDimensions.z = MINIMUM_DIMENSION; - } - - var changeInPosition = { x: (newRIGHT - oldRIGHT) * 0.5, - y: (newTOP - oldTOP) * 0.5, - z: (newNEAR - oldNEAR) * -0.5 }; - var newPosition = Vec3.sum(selectedEntityPropertiesOriginalPosition, changeInPosition); - var wantDebug = false; - if (wantDebug) { - print("stretchRTN... "); - Vec3.print(" lastPlaneIntersection:", lastPlaneIntersection); - Vec3.print(" newIntersection:", newIntersection); - Vec3.print(" vector:", vector); - print(" oldRIGHT:" + oldRIGHT); - print(" newRIGHT:" + newRIGHT); - Vec3.print(" oldDimensions:", selectedEntityPropertiesOriginalDimensions); - Vec3.print(" changeInDimensions:", changeInDimensions); - Vec3.print(" newDimensions:", newDimensions); - - Vec3.print(" oldPosition:", selectedEntityPropertiesOriginalPosition); - Vec3.print(" changeInPosition:", changeInPosition); - Vec3.print(" newPosition:", newPosition); - } - - selectedEntityProperties.position = newPosition; - selectedEntityProperties.dimensions = newDimensions; - Entities.editEntity(currentSelection, selectedEntityProperties); - tooltip.updateText(selectedEntityProperties); - that.select(currentSelection, false); // TODO: this should be more than highlighted - }; - - that.stretchLTN = function(event) { - if (!entitySelected || mode !== "STRETCH_LTN") { - return; // not allowed - } - pickRay = Camera.computePickRay(event.x, event.y); - - // translate mode left/right based on view toward entity - var newIntersection = rayPlaneIntersection(pickRay, - selectedEntityPropertiesOriginalPosition, - Quat.getFront(lastCameraOrientation)); - - var vector = Vec3.subtract(newIntersection, lastPlaneIntersection); - - var halfDimensions = Vec3.multiply(selectedEntityPropertiesOriginalDimensions, 0.5); - var oldLEFT = selectedEntityPropertiesOriginalPosition.x - halfDimensions.x; - var newLEFT = oldLEFT - vector.x; - - var oldTOP = selectedEntityPropertiesOriginalPosition.y + halfDimensions.y; - var newTOP = oldTOP + vector.y; - - var oldNEAR = selectedEntityPropertiesOriginalPosition.z - halfDimensions.z; - var newNEAR = oldNEAR - vector.z; - - - var changeInDimensions = { x: (newLEFT - oldLEFT), y: (newTOP - oldTOP) , z: (newNEAR - oldNEAR) }; - var newDimensions = Vec3.sum(selectedEntityPropertiesOriginalDimensions, changeInDimensions); - - if (newDimensions.x < MINIMUM_DIMENSION) { - newDimensions.x = MINIMUM_DIMENSION; - } - - if (newDimensions.y < MINIMUM_DIMENSION) { - newDimensions.y = MINIMUM_DIMENSION; - } - - if (newDimensions.z < MINIMUM_DIMENSION) { - newDimensions.z = MINIMUM_DIMENSION; - } - - var changeInPosition = { x: (newLEFT - oldLEFT) * -0.5, - y: (newTOP - oldTOP) * 0.5, - z: (newNEAR - oldNEAR) * -0.5 }; - var newPosition = Vec3.sum(selectedEntityPropertiesOriginalPosition, changeInPosition); - var wantDebug = false; - if (wantDebug) { - print("stretchLTN... "); - Vec3.print(" lastPlaneIntersection:", lastPlaneIntersection); - Vec3.print(" newIntersection:", newIntersection); - Vec3.print(" vector:", vector); - print(" oldLEFT:" + oldLEFT); - print(" newLEFT:" + newLEFT); - Vec3.print(" oldDimensions:", selectedEntityPropertiesOriginalDimensions); - Vec3.print(" changeInDimensions:", changeInDimensions); - Vec3.print(" newDimensions:", newDimensions); - - Vec3.print(" oldPosition:", selectedEntityPropertiesOriginalPosition); - Vec3.print(" changeInPosition:", changeInPosition); - Vec3.print(" newPosition:", newPosition); - } - - selectedEntityProperties.position = newPosition; - selectedEntityProperties.dimensions = newDimensions; - Entities.editEntity(currentSelection, selectedEntityProperties); - tooltip.updateText(selectedEntityProperties); - that.select(currentSelection, false); // TODO: this should be more than highlighted - }; - - that.stretchRBF = function(event) { - if (!entitySelected || mode !== "STRETCH_RBF") { - return; // not allowed - } - pickRay = Camera.computePickRay(event.x, event.y); - - // translate mode left/right based on view toward entity - var newIntersection = rayPlaneIntersection(pickRay, - selectedEntityPropertiesOriginalPosition, - Quat.getFront(lastCameraOrientation)); - - var vector = Vec3.subtract(newIntersection, lastPlaneIntersection); - - var halfDimensions = Vec3.multiply(selectedEntityPropertiesOriginalDimensions, 0.5); - var oldRIGHT = selectedEntityPropertiesOriginalPosition.x + halfDimensions.x; - var newRIGHT = oldRIGHT + vector.x; - - var oldBOTTOM = selectedEntityPropertiesOriginalPosition.y - halfDimensions.y; - var newBOTTOM = oldBOTTOM - vector.y; - - var oldFAR = selectedEntityPropertiesOriginalPosition.z + halfDimensions.z; - var newFAR = oldFAR + vector.z; - - - var changeInDimensions = { x: (newRIGHT - oldRIGHT), y: (newBOTTOM - oldBOTTOM) , z: (newFAR - oldFAR) }; - var newDimensions = Vec3.sum(selectedEntityPropertiesOriginalDimensions, changeInDimensions); - - if (newDimensions.x < MINIMUM_DIMENSION) { - newDimensions.x = MINIMUM_DIMENSION; - } - - if (newDimensions.y < MINIMUM_DIMENSION) { - newDimensions.y = MINIMUM_DIMENSION; - } - - if (newDimensions.z < MINIMUM_DIMENSION) { - newDimensions.z = MINIMUM_DIMENSION; - } - - var changeInPosition = { x: (newRIGHT - oldRIGHT) * 0.5, - y: (newBOTTOM - oldBOTTOM) * -0.5, - z: (newFAR - oldFAR) * 0.5 }; - var newPosition = Vec3.sum(selectedEntityPropertiesOriginalPosition, changeInPosition); - var wantDebug = false; - if (wantDebug) { - print("stretchRBF... "); - Vec3.print(" lastPlaneIntersection:", lastPlaneIntersection); - Vec3.print(" newIntersection:", newIntersection); - Vec3.print(" vector:", vector); - print(" oldRIGHT:" + oldRIGHT); - print(" newRIGHT:" + newRIGHT); - Vec3.print(" oldDimensions:", selectedEntityPropertiesOriginalDimensions); - Vec3.print(" changeInDimensions:", changeInDimensions); - Vec3.print(" newDimensions:", newDimensions); - - Vec3.print(" oldPosition:", selectedEntityPropertiesOriginalPosition); - Vec3.print(" changeInPosition:", changeInPosition); - Vec3.print(" newPosition:", newPosition); - } - - selectedEntityProperties.position = newPosition; - selectedEntityProperties.dimensions = newDimensions; - Entities.editEntity(currentSelection, selectedEntityProperties); - tooltip.updateText(selectedEntityProperties); - that.select(currentSelection, false); // TODO: this should be more than highlighted - }; - - that.stretchLBF = function(event) { - if (!entitySelected || mode !== "STRETCH_LBF") { - return; // not allowed - } - pickRay = Camera.computePickRay(event.x, event.y); - - // translate mode left/right based on view toward entity - var newIntersection = rayPlaneIntersection(pickRay, - selectedEntityPropertiesOriginalPosition, - Quat.getFront(lastCameraOrientation)); - - var vector = Vec3.subtract(newIntersection, lastPlaneIntersection); - - var halfDimensions = Vec3.multiply(selectedEntityPropertiesOriginalDimensions, 0.5); - var oldLEFT = selectedEntityPropertiesOriginalPosition.x - halfDimensions.x; - var newLEFT = oldLEFT - vector.x; - - var oldBOTTOM = selectedEntityPropertiesOriginalPosition.y - halfDimensions.y; - var newBOTTOM = oldBOTTOM - vector.y; - - var oldFAR = selectedEntityPropertiesOriginalPosition.z + halfDimensions.z; - var newFAR = oldFAR + vector.z; - - - var changeInDimensions = { x: (newLEFT - oldLEFT), y: (newBOTTOM - oldBOTTOM) , z: (newFAR - oldFAR) }; - var newDimensions = Vec3.sum(selectedEntityPropertiesOriginalDimensions, changeInDimensions); - - if (newDimensions.x < MINIMUM_DIMENSION) { - newDimensions.x = MINIMUM_DIMENSION; - } - - if (newDimensions.y < MINIMUM_DIMENSION) { - newDimensions.y = MINIMUM_DIMENSION; - } - - if (newDimensions.z < MINIMUM_DIMENSION) { - newDimensions.z = MINIMUM_DIMENSION; - } - - var changeInPosition = { x: (newLEFT - oldLEFT) * -0.5, - y: (newBOTTOM - oldBOTTOM) * -0.5, - z: (newFAR - oldFAR) * 0.5 }; - var newPosition = Vec3.sum(selectedEntityPropertiesOriginalPosition, changeInPosition); - var wantDebug = false; - if (wantDebug) { - print("stretchLBF... "); - Vec3.print(" lastPlaneIntersection:", lastPlaneIntersection); - Vec3.print(" newIntersection:", newIntersection); - Vec3.print(" vector:", vector); - print(" oldLEFT:" + oldLEFT); - print(" newLEFT:" + newLEFT); - Vec3.print(" oldDimensions:", selectedEntityPropertiesOriginalDimensions); - Vec3.print(" changeInDimensions:", changeInDimensions); - Vec3.print(" newDimensions:", newDimensions); - - Vec3.print(" oldPosition:", selectedEntityPropertiesOriginalPosition); - Vec3.print(" changeInPosition:", changeInPosition); - Vec3.print(" newPosition:", newPosition); - } - - selectedEntityProperties.position = newPosition; - selectedEntityProperties.dimensions = newDimensions; - Entities.editEntity(currentSelection, selectedEntityProperties); - tooltip.updateText(selectedEntityProperties); - that.select(currentSelection, false); // TODO: this should be more than highlighted - }; - - that.stretchRTF = function(event) { - if (!entitySelected || mode !== "STRETCH_RTF") { - return; // not allowed - } - pickRay = Camera.computePickRay(event.x, event.y); - - // translate mode left/right based on view toward entity - var newIntersection = rayPlaneIntersection(pickRay, - selectedEntityPropertiesOriginalPosition, - Quat.getFront(lastCameraOrientation)); - - var vector = Vec3.subtract(newIntersection, lastPlaneIntersection); - - var halfDimensions = Vec3.multiply(selectedEntityPropertiesOriginalDimensions, 0.5); - var oldRIGHT = selectedEntityPropertiesOriginalPosition.x + halfDimensions.x; - var newRIGHT = oldRIGHT + vector.x; - - var oldTOP = selectedEntityPropertiesOriginalPosition.y + halfDimensions.y; - var newTOP = oldTOP + vector.y; - - var oldFAR = selectedEntityPropertiesOriginalPosition.z + halfDimensions.z; - var newFAR = oldFAR + vector.z; - - - var changeInDimensions = { x: (newRIGHT - oldRIGHT), y: (newTOP - oldTOP) , z: (newFAR - oldFAR) }; - var newDimensions = Vec3.sum(selectedEntityPropertiesOriginalDimensions, changeInDimensions); - - if (newDimensions.x < MINIMUM_DIMENSION) { - newDimensions.x = MINIMUM_DIMENSION; - } - - if (newDimensions.y < MINIMUM_DIMENSION) { - newDimensions.y = MINIMUM_DIMENSION; - } - - if (newDimensions.z < MINIMUM_DIMENSION) { - newDimensions.z = MINIMUM_DIMENSION; - } - - var changeInPosition = { x: (newRIGHT - oldRIGHT) * 0.5, - y: (newTOP - oldTOP) * 0.5, - z: (newFAR - oldFAR) * 0.5 }; - var newPosition = Vec3.sum(selectedEntityPropertiesOriginalPosition, changeInPosition); - var wantDebug = false; - if (wantDebug) { - print("stretchRTF... "); - Vec3.print(" lastPlaneIntersection:", lastPlaneIntersection); - Vec3.print(" newIntersection:", newIntersection); - Vec3.print(" vector:", vector); - print(" oldRIGHT:" + oldRIGHT); - print(" newRIGHT:" + newRIGHT); - Vec3.print(" oldDimensions:", selectedEntityPropertiesOriginalDimensions); - Vec3.print(" changeInDimensions:", changeInDimensions); - Vec3.print(" newDimensions:", newDimensions); - - Vec3.print(" oldPosition:", selectedEntityPropertiesOriginalPosition); - Vec3.print(" changeInPosition:", changeInPosition); - Vec3.print(" newPosition:", newPosition); - } - - selectedEntityProperties.position = newPosition; - selectedEntityProperties.dimensions = newDimensions; - Entities.editEntity(currentSelection, selectedEntityProperties); - tooltip.updateText(selectedEntityProperties); - that.select(currentSelection, false); // TODO: this should be more than highlighted - }; - - that.stretchLTF = function(event) { - if (!entitySelected || mode !== "STRETCH_LTF") { - return; // not allowed - } - pickRay = Camera.computePickRay(event.x, event.y); - - // translate mode left/right based on view toward entity - var newIntersection = rayPlaneIntersection(pickRay, - selectedEntityPropertiesOriginalPosition, - Quat.getFront(lastCameraOrientation)); - - var vector = Vec3.subtract(newIntersection, lastPlaneIntersection); - - var halfDimensions = Vec3.multiply(selectedEntityPropertiesOriginalDimensions, 0.5); - var oldLEFT = selectedEntityPropertiesOriginalPosition.x - halfDimensions.x; - var newLEFT = oldLEFT - vector.x; - - var oldTOP = selectedEntityPropertiesOriginalPosition.y + halfDimensions.y; - var newTOP = oldTOP + vector.y; - - var oldFAR = selectedEntityPropertiesOriginalPosition.z + halfDimensions.z; - var newFAR = oldFAR + vector.z; - - - var changeInDimensions = { x: (newLEFT - oldLEFT), y: (newTOP - oldTOP) , z: (newFAR - oldFAR) }; - var newDimensions = Vec3.sum(selectedEntityPropertiesOriginalDimensions, changeInDimensions); - - if (newDimensions.x < MINIMUM_DIMENSION) { - newDimensions.x = MINIMUM_DIMENSION; - } - - if (newDimensions.y < MINIMUM_DIMENSION) { - newDimensions.y = MINIMUM_DIMENSION; - } - - if (newDimensions.z < MINIMUM_DIMENSION) { - newDimensions.z = MINIMUM_DIMENSION; - } - - var changeInPosition = { x: (newLEFT - oldLEFT) * -0.5, - y: (newTOP - oldTOP) * 0.5, - z: (newFAR - oldFAR) * 0.5 }; - var newPosition = Vec3.sum(selectedEntityPropertiesOriginalPosition, changeInPosition); - var wantDebug = false; - if (wantDebug) { - print("stretchLTF... "); - Vec3.print(" lastPlaneIntersection:", lastPlaneIntersection); - Vec3.print(" newIntersection:", newIntersection); - Vec3.print(" vector:", vector); - print(" oldLEFT:" + oldLEFT); - print(" newLEFT:" + newLEFT); - Vec3.print(" oldDimensions:", selectedEntityPropertiesOriginalDimensions); - Vec3.print(" changeInDimensions:", changeInDimensions); - Vec3.print(" newDimensions:", newDimensions); - - Vec3.print(" oldPosition:", selectedEntityPropertiesOriginalPosition); - Vec3.print(" changeInPosition:", changeInPosition); - Vec3.print(" newPosition:", newPosition); - } - - selectedEntityProperties.position = newPosition; - selectedEntityProperties.dimensions = newDimensions; - Entities.editEntity(currentSelection, selectedEntityProperties); - tooltip.updateText(selectedEntityProperties); - that.select(currentSelection, false); // TODO: this should be more than highlighted - }; - - that.rotateYaw = function(event) { - if (!entitySelected || mode !== "ROTATE_YAW") { - return; // not allowed - } - - var debug = Menu.isOptionChecked("Debug Ryans Rotation Problems"); - - if (debug) { - print("rotateYaw()..."); - print(" event.x,y:" + event.x + "," + event.y); - } - - var pickRay = Camera.computePickRay(event.x, event.y); - Overlays.editOverlay(selectionBox, { ignoreRayIntersection: true, visible: false}); - Overlays.editOverlay(baseOfEntityProjectionOverlay, { ignoreRayIntersection: true, visible: false }); - Overlays.editOverlay(rotateOverlayTarget, { ignoreRayIntersection: false }); - Overlays.editOverlay(rotateOverlayInner, { ignoreRayIntersection: true }); - Overlays.editOverlay(rotateOverlayOuter, { ignoreRayIntersection: true }); - Overlays.editOverlay(rotateOverlayCurrent, { ignoreRayIntersection: true }); - - var result = Overlays.findRayIntersection(pickRay); - - if (debug) { - print(" findRayIntersection() .... result.intersects:" + result.intersects); - } - - if (result.intersects) { - - + addGrabberTool(grabberMoveUp, { + mode: "TRANSLATE_UP_DOWN", + onBegin: function(event) { + SelectionManager.saveProperties(); + }, + onEnd: function(event, reason) { + if (reason == 'cancel') { + for (var i = 0; i < SelectionManager.selections.length; i++) { + var entityID = SelectionManager.selections[i]; + var initialProperties = SelectionManager.savedProperties[entityID.id]; + Entities.editEntity(entityID, initialProperties); + } + } + }, + onMove: function(event) { + if (!entitySelected || mode !== "TRANSLATE_UP_DOWN") { + return; // not allowed + } + pickRay = Camera.computePickRay(event.x, event.y); + + // translate mode left/right based on view toward entity + var newIntersection = rayPlaneIntersection(pickRay, + selectedEntityPropertiesOriginalPosition, + Quat.getFront(lastCameraOrientation)); + + var vector = Vec3.subtract(newIntersection, lastPlaneIntersection); + lastPlaneIntersection = newIntersection; + + // we only care about the Y axis + vector.x = 0; + vector.z = 0; + + // newPosition = Vec3.sum(selectedEntityPropertiesOriginalPosition, vector); + + var wantDebug = false; + if (wantDebug) { + print("translateUpDown... "); + print(" event.y:" + event.y); + Vec3.print(" lastPlaneIntersection:", lastPlaneIntersection); + Vec3.print(" newIntersection:", newIntersection); + Vec3.print(" vector:", vector); + Vec3.print(" originalPosition:", selectedEntityPropertiesOriginalPosition); + Vec3.print(" recentPosition:", selectedEntityProperties.position); + Vec3.print(" newPosition:", newPosition); + } + for (var i = 0; i < SelectionManager.selections.length; i++) { + var properties = Entities.getEntityProperties(SelectionManager.selections[i]); + var original = properties.position; + properties.position = Vec3.sum(properties.position, vector); + Entities.editEntity(SelectionManager.selections[i], properties); + } + + tooltip.updateText(selectedEntityProperties); + that.select(currentSelection, false); // TODO: this should be more than highlighted + SelectionManager._update(); + }, + }); + + var vec3Mult = function(v1, v2) { + return { x: v1.x * v2.x, y: v1.y * v2.y, z: v1.z * v2.z }; + } + var makeStretchTool = function(stretchMode, direction, pivot) { + var signs = { + x: direction.x < 0 ? -1 : (direction.x > 0 ? 1 : 0), + y: direction.y < 0 ? -1 : (direction.y > 0 ? 1 : 0), + z: direction.z < 0 ? -1 : (direction.z > 0 ? 1 : 0), + }; + + var mask = { + x: Math.abs(direction.x) > 0 ? 1 : 0, + y: Math.abs(direction.y) > 0 ? 1 : 0, + z: Math.abs(direction.z) > 0 ? 1 : 0, + }; + + var numDimensions = mask.x + mask.y + mask.z; + + var planeNormal = null; + var lastPick = null; + var initialPosition = null; + var initialDimensions = null; + var initialIntersection = null; + var initialProperties = null; + var rotation = null; + + var onBegin = function(event) { + print("STARTING: " + stretchMode); var properties = Entities.getEntityProperties(currentSelection); - var center = yawCenter; - var zero = yawZero; - var centerToZero = Vec3.subtract(center, zero); - var centerToIntersect = Vec3.subtract(center, result.intersection); - var angleFromZero = Vec3.orientedAngle(centerToZero, centerToIntersect, rotationNormal); - - var distanceFromCenter = Vec3.distance(center, result.intersection); - var snapToInner = false; - if (distanceFromCenter < innerRadius) { - angleFromZero = Math.floor(angleFromZero/innerSnapAngle) * innerSnapAngle; - snapToInner = true; - } - - // for debugging - if (debug) { - Vec3.print(" result.intersection:",result.intersection); - Overlays.editOverlay(rotateCurrentOverlay, { visible: true, start: center, end: result.intersection }); - print(" angleFromZero:" + angleFromZero); + initialProperties = properties; + rotation = spaceMode == SPACE_LOCAL ? properties.rotation : Quat.fromPitchYawRollDegrees(0, 0, 0); + + if (spaceMode == SPACE_LOCAL) { + initialPosition = SelectionManager.localPosition; + initialDimensions = SelectionManager.localDimensions; + } else { + initialPosition = SelectionManager.worldPosition; + initialDimensions = SelectionManager.worldDimensions; } - var yawChange = Quat.fromVec3Degrees({ x: 0, y: angleFromZero, z: 0 }); - var newRotation = Quat.multiply(yawChange, originalRotation); - - Entities.editEntity(currentSelection, { rotation: newRotation }); - - // update the rotation display accordingly... - var startAtCurrent = 0; - var endAtCurrent = angleFromZero; - var startAtRemainder = angleFromZero; - var endAtRemainder = 360; - if (angleFromZero < 0) { - startAtCurrent = 360 + angleFromZero; - endAtCurrent = 360; - startAtRemainder = 0; - endAtRemainder = startAtCurrent; + if (numDimensions == 1 && mask.x) { + var start = Vec3.multiplyQbyV(rotation, { x: -10000, y: 0, z: 0 }); + start = Vec3.sum(start, properties.position); + var end = Vec3.multiplyQbyV(rotation, { x: 10000, y: 0, z: 0 }); + end = Vec3.sum(end, properties.position); + Overlays.editOverlay(xRailOverlay, { + start: start, + end: end, + visible: true, + }); } - if (snapToInner) { - Overlays.editOverlay(rotateOverlayOuter, { startAt: 0, endAt: 360 }); - Overlays.editOverlay(rotateOverlayInner, { startAt: startAtRemainder, endAt: endAtRemainder }); - Overlays.editOverlay(rotateOverlayCurrent, { startAt: startAtCurrent, endAt: endAtCurrent, size: innerRadius, - majorTickMarksAngle: innerSnapAngle, minorTickMarksAngle: 0, - majorTickMarksLength: -0.25, minorTickMarksLength: 0, }); + if (numDimensions == 1 && mask.y) { + var start = Vec3.multiplyQbyV(rotation, { x: 0, y: -10000, z: 0 }); + start = Vec3.sum(start, properties.position); + var end = Vec3.multiplyQbyV(rotation, { x: 0, y: 10000, z: 0 }); + end = Vec3.sum(end, properties.position); + Overlays.editOverlay(yRailOverlay, { + start: start, + end: end, + visible: true, + }); + } + if (numDimensions == 1 && mask.z) { + var start = Vec3.multiplyQbyV(rotation, { x: 0, y: 0, z: -10000 }); + start = Vec3.sum(start, properties.position); + var end = Vec3.multiplyQbyV(rotation, { x: 0, y: 0, z: 10000 }); + end = Vec3.sum(end, properties.position); + Overlays.editOverlay(zRailOverlay, { + start: start, + end: end, + visible: true, + }); + } + if (numDimensions == 1) { + if (mask.x == 1) { + planeNormal = { x: 0, y: 1, z: 0 }; + } else if (mask.y == 1) { + planeNormal = { x: 1, y: 0, z: 0 }; + } else { + planeNormal = { x: 0, y: 1, z: 0 }; + } + } else if (numDimensions == 2) { + if (mask.x == 0) { + planeNormal = { x: 1, y: 0, z: 0 }; + } else if (mask.y == 0) { + planeNormal = { x: 0, y: 1, z: 0 }; + } else { + planeNormal = { x: 0, y: 0, z: z }; + } + } + planeNormal = Vec3.multiplyQbyV(rotation, planeNormal); + var pickRay = Camera.computePickRay(event.x, event.y); + lastPick = rayPlaneIntersection(pickRay, + initialPosition, + planeNormal); + + // Overlays.editOverlay(normalLine, { + // start: initialPosition, + // end: Vec3.sum(Vec3.multiply(100000, planeNormal), initialPosition), + // }); + + SelectionManager.saveProperties(); + }; + + var onEnd = function(event, reason) { + print("ENDING: " + stretchMode); + Overlays.editOverlay(xRailOverlay, { visible: false }); + Overlays.editOverlay(yRailOverlay, { visible: false }); + Overlays.editOverlay(zRailOverlay, { visible: false }); + + if (reason == 'cancel') { + for (var i = 0; i < SelectionManager.selections.length; i++) { + var entityID = SelectionManager.selections[i]; + var initialProperties = SelectionManager.savedProperties[entityID.id]; + Entities.editEntity(entityID, initialProperties); + } + } + }; + + var onMove = function(event) { + if (!entitySelected || mode !== stretchMode) { + return; // not allowed + } + var proportional = spaceMode == SPACE_WORLD || event.isShifted; + + var position, dimensions, rotation; + if (spaceMode == SPACE_LOCAL) { + position = SelectionManager.localPosition; + dimensions = SelectionManager.localDimensions; + rotation = SelectionManager.localRotation; } else { - Overlays.editOverlay(rotateOverlayInner, { startAt: 0, endAt: 360 }); - Overlays.editOverlay(rotateOverlayOuter, { startAt: startAtRemainder, endAt: endAtRemainder }); - Overlays.editOverlay(rotateOverlayCurrent, { startAt: startAtCurrent, endAt: endAtCurrent, size: outerRadius, - majorTickMarksAngle: 45.0, minorTickMarksAngle: 5, - majorTickMarksLength: 0.25, minorTickMarksLength: 0.1, }); + position = SelectionManager.worldPosition; + dimensions = SelectionManager.worldDimensions; + rotation = SelectionManager.worldRotation; + } + + var pickRay = Camera.computePickRay(event.x, event.y); + newPick = rayPlaneIntersection(pickRay, + initialPosition, + planeNormal); + var vector = Vec3.subtract(newPick, lastPick); + + vector = Vec3.multiplyQbyV(Quat.inverse(rotation), vector); + + vector = vec3Mult(mask, vector); + + var changeInDimensions = Vec3.multiply(-1, vec3Mult(signs, vector)); + var newDimensions; + if (proportional) { + var absX = Math.abs(changeInDimensions.x); + var absY = Math.abs(changeInDimensions.y); + var absZ = Math.abs(changeInDimensions.z); + print('abs: ' + absX + ', ' + absY + ', ' + absZ); + var pctChange = 0; + if (absX > absY && absX > absZ) { + pctChange = changeInDimensions.x / initialProperties.dimensions.x; + pctChange = changeInDimensions.x / initialDimensions.x; + } else if (absY > absZ) { + pctChange = changeInDimensions.y / initialProperties.dimensions.y; + pctChange = changeInDimensions.y / initialDimensions.y; + } else { + pctChange = changeInDimensions.z / initialProperties.dimensions.z; + pctChange = changeInDimensions.z / initialDimensions.z; + } + print('change: ' + pctChange); + pctChange += 1.0; + newDimensions = Vec3.multiply(pctChange, initialDimensions); + } else { + newDimensions = Vec3.sum(initialDimensions, changeInDimensions); } + newDimensions.x = Math.max(newDimensions.x, MINIMUM_DIMENSION); + newDimensions.y = Math.max(newDimensions.y, MINIMUM_DIMENSION); + newDimensions.z = Math.max(newDimensions.z, MINIMUM_DIMENSION); + + var p = Vec3.multiply(0.5, pivot); + var changeInPosition = Vec3.multiplyQbyV(rotation, vec3Mult(p, changeInDimensions)); + var newPosition = Vec3.sum(initialPosition, changeInPosition); + + + selectedEntityProperties.position = newPosition; + selectedEntityProperties.dimensions = newDimensions; + for (var i = 0; i < SelectionManager.selections.length; i++) { + Entities.editEntity(SelectionManager.selections[i], selectedEntityProperties); + } + + var wantDebug = false; + if (wantDebug) { + print(stretchMode); + Vec3.print(" lastPlaneIntersection:", lastPlaneIntersection); + Vec3.print(" newIntersection:", newIntersection); + Vec3.print(" vector:", vector); + Vec3.print(" oldPOS:", oldPOS); + Vec3.print(" newPOS:", newPOS); + Vec3.print(" oldDimensions:", selectedEntityPropertiesOriginalDimensions); + Vec3.print(" changeInDimensions:", changeInDimensions); + Vec3.print(" newDimensions:", newDimensions); + + Vec3.print(" oldPosition:", selectedEntityPropertiesOriginalPosition); + Vec3.print(" changeInPosition:", changeInPosition); + Vec3.print(" newPosition:", newPosition); + } + + tooltip.updateText(selectedEntityProperties); + SelectionManager._update(); + that.select(currentSelection, false); // TODO: this should be more than highlighted + + }; + + return { + mode: stretchMode, + onBegin: onBegin, + onMove: onMove, + onEnd: onEnd + }; + }; + + that.cancelTool = function() { + if (activeTool) { + activeTool.onEnd(null, 'cancel'); + activeTool = null; + SelectionManager._update(); } }; - that.rotatePitch = function(event) { - if (!entitySelected || mode !== "ROTATE_PITCH") { - return; // not allowed + function addStretchTool(overlay, mode, pivot, direction) { + if (!pivot) { + pivot = Vec3.multiply(-1, direction); + pivot.y = direction.y; } - var debug = Menu.isOptionChecked("Debug Ryans Rotation Problems"); + var tool = makeStretchTool(mode, direction, pivot); - if (debug) { - print("rotatePitch()..."); - print(" event.x,y:" + event.x + "," + event.y); - } + addGrabberTool(overlay, tool); + } - var pickRay = Camera.computePickRay(event.x, event.y); - Overlays.editOverlay(selectionBox, { ignoreRayIntersection: true, visible: false}); - Overlays.editOverlay(baseOfEntityProjectionOverlay, { ignoreRayIntersection: true, visible: false }); - Overlays.editOverlay(rotateOverlayTarget, { ignoreRayIntersection: false }); - Overlays.editOverlay(rotateOverlayInner, { ignoreRayIntersection: true }); - Overlays.editOverlay(rotateOverlayOuter, { ignoreRayIntersection: true }); - Overlays.editOverlay(rotateOverlayCurrent, { ignoreRayIntersection: true }); - var result = Overlays.findRayIntersection(pickRay); + addStretchTool(grabberNEAR, "STRETCH_NEAR", { x: 0, y: 0, z: -1 }, { x: 0, y: 0, z: 1 }); + addStretchTool(grabberFAR, "STRETCH_FAR", { x: 0, y: 0, z: 1 }, { x: 0, y: 0, z: -1 }); + addStretchTool(grabberTOP, "STRETCH_TOP", { x: 0, y: 1, z: 0 }, { x: 0, y: -1, z: 0 }); + addStretchTool(grabberBOTTOM, "STRETCH_BOTTOM", { x: 0, y: -1, z: 0 }, { x: 0, y: 1, z: 0 }); + addStretchTool(grabberRIGHT, "STRETCH_RIGHT", { x: 1, y: 0, z: 0 }, { x: -1, y: 0, z: 0 }); + addStretchTool(grabberLEFT, "STRETCH_LEFT", { x: -1, y: 0, z: 0 }, { x: 1, y: 0, z: 0 }); - if (debug) { - print(" findRayIntersection() .... result.intersects:" + result.intersects); - } + addStretchTool(grabberLBN, "STRETCH_LBN", null, {x: 1, y: 0, z: 1}); + addStretchTool(grabberRBN, "STRETCH_RBN", null, {x: -1, y: 0, z: 1}); + addStretchTool(grabberLBF, "STRETCH_LBF", null, {x: 1, y: 0, z: -1}); + addStretchTool(grabberRBF, "STRETCH_RBF", null, {x: -1, y: 0, z: -1}); + addStretchTool(grabberLTN, "STRETCH_LTN", null, {x: 1, y: 0, z: 1}); + addStretchTool(grabberRTN, "STRETCH_RTN", null, {x: -1, y: 0, z: 1}); + addStretchTool(grabberLTF, "STRETCH_LTF", null, {x: 1, y: 0, z: -1}); + addStretchTool(grabberRTF, "STRETCH_RTF", null, {x: -1, y: 0, z: -1}); - if (result.intersects) { - var properties = Entities.getEntityProperties(currentSelection); - var center = pitchCenter; - var zero = pitchZero; - var centerToZero = Vec3.subtract(center, zero); - var centerToIntersect = Vec3.subtract(center, result.intersection); - var angleFromZero = Vec3.orientedAngle(centerToZero, centerToIntersect, rotationNormal); + addStretchTool(grabberEdgeTR, "STRETCH_EdgeTR", null, {x: 1, y: 1, z: 0}); + addStretchTool(grabberEdgeTL, "STRETCH_EdgeTL", null, {x: -1, y: 1, z: 0}); + addStretchTool(grabberEdgeTF, "STRETCH_EdgeTF", null, {x: 0, y: 1, z: -1}); + addStretchTool(grabberEdgeTN, "STRETCH_EdgeTN", null, {x: 0, y: 1, z: 1}); + addStretchTool(grabberEdgeBR, "STRETCH_EdgeBR", null, {x: 1, y: -1, z: 0}); + addStretchTool(grabberEdgeBL, "STRETCH_EdgeBL", null, {x: -1, y: -1, z: 0}); + addStretchTool(grabberEdgeBF, "STRETCH_EdgeBF", null, {x: 0, y: -1, z: 1}); + addStretchTool(grabberEdgeBN, "STRETCH_EdgeBN", null, {x: 0, y: -1, z: -1}); + addStretchTool(grabberEdgeNR, "STRETCH_EdgeNR", null, {x: -1, y: 0, z: 1}); + addStretchTool(grabberEdgeNL, "STRETCH_EdgeNL", null, {x: 1, y: 0, z: 1}); + addStretchTool(grabberEdgeFR, "STRETCH_EdgeFR", null, {x: -1, y: 0, z: -1}); + addStretchTool(grabberEdgeFL, "STRETCH_EdgeFL", null, {x: 1, y: 0, z: -1}); - var distanceFromCenter = Vec3.distance(center, result.intersection); - var snapToInner = false; - if (distanceFromCenter < innerRadius) { - angleFromZero = Math.floor(angleFromZero/innerSnapAngle) * innerSnapAngle; - snapToInner = true; + var initialPosition = SelectionManager.worldPosition; + addGrabberTool(yawHandle, { + mode: "ROTATE_YAW", + onBegin: function(event) { + SelectionManager.saveProperties(); + initialPosition = SelectionManager.worldPosition; + }, + onEnd: function(event, reason) { + if (reason == 'cancel') { + for (var i = 0; i < SelectionManager.selections.length; i++) { + var entityID = SelectionManager.selections[i]; + var initialProperties = SelectionManager.savedProperties[entityID.id]; + Entities.editEntity(entityID, initialProperties); + } + } + }, + onMove: function(event) { + if (!entitySelected || mode !== "ROTATE_YAW") { + return; // not allowed } - // for debugging + var debug = Menu.isOptionChecked("Debug Ryans Rotation Problems"); + if (debug) { - Vec3.print(" result.intersection:",result.intersection); - Overlays.editOverlay(rotateCurrentOverlay, { visible: true, start: center, end: result.intersection }); - print(" angleFromZero:" + angleFromZero); + print("rotateYaw()..."); + print(" event.x,y:" + event.x + "," + event.y); } - var pitchChange = Quat.fromVec3Degrees({ x: angleFromZero, y: 0, z: 0 }); - var newRotation = Quat.multiply(pitchChange, originalRotation); - - Entities.editEntity(currentSelection, { rotation: newRotation }); - - // update the rotation display accordingly... - var startAtCurrent = 0; - var endAtCurrent = angleFromZero; - var startAtRemainder = angleFromZero; - var endAtRemainder = 360; - if (angleFromZero < 0) { - startAtCurrent = 360 + angleFromZero; - endAtCurrent = 360; - startAtRemainder = 0; - endAtRemainder = startAtCurrent; - } - if (snapToInner) { - Overlays.editOverlay(rotateOverlayOuter, { startAt: 0, endAt: 360 }); - Overlays.editOverlay(rotateOverlayInner, { startAt: startAtRemainder, endAt: endAtRemainder }); - Overlays.editOverlay(rotateOverlayCurrent, { startAt: startAtCurrent, endAt: endAtCurrent, size: innerRadius, - majorTickMarksAngle: innerSnapAngle, minorTickMarksAngle: 0, - majorTickMarksLength: -0.25, minorTickMarksLength: 0, }); - } else { - Overlays.editOverlay(rotateOverlayInner, { startAt: 0, endAt: 360 }); - Overlays.editOverlay(rotateOverlayOuter, { startAt: startAtRemainder, endAt: endAtRemainder }); - Overlays.editOverlay(rotateOverlayCurrent, { startAt: startAtCurrent, endAt: endAtCurrent, size: outerRadius, - majorTickMarksAngle: 45.0, minorTickMarksAngle: 5, - majorTickMarksLength: 0.25, minorTickMarksLength: 0.1, }); - } - } - }; - - that.rotateRoll = function(event) { - if (!entitySelected || mode !== "ROTATE_ROLL") { - return; // not allowed - } - var debug = Menu.isOptionChecked("Debug Ryans Rotation Problems"); - - if (debug) { - print("rotateRoll()..."); - print(" event.x,y:" + event.x + "," + event.y); - } - - var pickRay = Camera.computePickRay(event.x, event.y); - Overlays.editOverlay(selectionBox, { ignoreRayIntersection: true, visible: false}); - Overlays.editOverlay(baseOfEntityProjectionOverlay, { ignoreRayIntersection: true, visible: false }); - Overlays.editOverlay(rotateOverlayTarget, { ignoreRayIntersection: false }); - Overlays.editOverlay(rotateOverlayInner, { ignoreRayIntersection: true }); - Overlays.editOverlay(rotateOverlayOuter, { ignoreRayIntersection: true }); - Overlays.editOverlay(rotateOverlayCurrent, { ignoreRayIntersection: true }); - var result = Overlays.findRayIntersection(pickRay); - - if (debug) { - print(" findRayIntersection() .... result.intersects:" + result.intersects); - } - - if (result.intersects) { - var properties = Entities.getEntityProperties(currentSelection); - var center = rollCenter; - var zero = rollZero; - var centerToZero = Vec3.subtract(center, zero); - var centerToIntersect = Vec3.subtract(center, result.intersection); - var angleFromZero = Vec3.orientedAngle(centerToZero, centerToIntersect, rotationNormal); - - var distanceFromCenter = Vec3.distance(center, result.intersection); - var snapToInner = false; - if (distanceFromCenter < innerRadius) { - angleFromZero = Math.floor(angleFromZero/innerSnapAngle) * innerSnapAngle; - snapToInner = true; - } - - // for debugging - if (debug) { - Vec3.print(" result.intersection:",result.intersection); - Overlays.editOverlay(rotateCurrentOverlay, { visible: true, start: center, end: result.intersection }); - print(" angleFromZero:" + angleFromZero); - } - - var rollChange = Quat.fromVec3Degrees({ x: 0, y: 0, z: angleFromZero }); - var newRotation = Quat.multiply(rollChange, originalRotation); + var pickRay = Camera.computePickRay(event.x, event.y); + Overlays.editOverlay(selectionBox, { ignoreRayIntersection: true, visible: false}); + Overlays.editOverlay(baseOfEntityProjectionOverlay, { ignoreRayIntersection: true, visible: false }); + Overlays.editOverlay(rotateOverlayTarget, { ignoreRayIntersection: false }); + Overlays.editOverlay(rotateOverlayInner, { ignoreRayIntersection: true }); + Overlays.editOverlay(rotateOverlayOuter, { ignoreRayIntersection: true }); + Overlays.editOverlay(rotateOverlayCurrent, { ignoreRayIntersection: true }); - Entities.editEntity(currentSelection, { rotation: newRotation }); + var result = Overlays.findRayIntersection(pickRay); - // update the rotation display accordingly... - var startAtCurrent = 0; - var endAtCurrent = angleFromZero; - var startAtRemainder = angleFromZero; - var endAtRemainder = 360; - if (angleFromZero < 0) { - startAtCurrent = 360 + angleFromZero; - endAtCurrent = 360; - startAtRemainder = 0; - endAtRemainder = startAtCurrent; + if (debug) { + print(" findRayIntersection() .... result.intersects:" + result.intersects); } - if (snapToInner) { - Overlays.editOverlay(rotateOverlayOuter, { startAt: 0, endAt: 360 }); - Overlays.editOverlay(rotateOverlayInner, { startAt: startAtRemainder, endAt: endAtRemainder }); - Overlays.editOverlay(rotateOverlayCurrent, { startAt: startAtCurrent, endAt: endAtCurrent, size: innerRadius, - majorTickMarksAngle: innerSnapAngle, minorTickMarksAngle: 0, - majorTickMarksLength: -0.25, minorTickMarksLength: 0, }); - } else { - Overlays.editOverlay(rotateOverlayInner, { startAt: 0, endAt: 360 }); - Overlays.editOverlay(rotateOverlayOuter, { startAt: startAtRemainder, endAt: endAtRemainder }); - Overlays.editOverlay(rotateOverlayCurrent, { startAt: startAtCurrent, endAt: endAtCurrent, size: outerRadius, - majorTickMarksAngle: 45.0, minorTickMarksAngle: 5, - majorTickMarksLength: 0.25, minorTickMarksLength: 0.1, }); + + if (result.intersects) { + var properties = Entities.getEntityProperties(currentSelection); + var center = yawCenter; + var zero = yawZero; + var centerToZero = Vec3.subtract(center, zero); + var centerToIntersect = Vec3.subtract(center, result.intersection); + var angleFromZero = Vec3.orientedAngle(centerToZero, centerToIntersect, rotationNormal); + + var distanceFromCenter = Vec3.distance(center, result.intersection); + var snapToInner = false; + if (distanceFromCenter < innerRadius) { + angleFromZero = Math.floor(angleFromZero/innerSnapAngle) * innerSnapAngle; + snapToInner = true; + } + + // for debugging + if (debug) { + Vec3.print(" result.intersection:",result.intersection); + Overlays.editOverlay(rotateCurrentOverlay, { visible: true, start: center, end: result.intersection }); + print(" angleFromZero:" + angleFromZero); + } + + var yawChange = Quat.fromVec3Degrees({ x: 0, y: angleFromZero, z: 0 }); + for (var i = 0; i < SelectionManager.selections.length; i++) { + var entityID = SelectionManager.selections[i]; + var properties = Entities.getEntityProperties(entityID); + var initialProperties = SelectionManager.savedProperties[entityID.id]; + var dPos = Vec3.subtract(initialProperties.position, initialPosition); + dPos = Vec3.multiplyQbyV(yawChange, dPos); + + Entities.editEntity(entityID, { + position: Vec3.sum(initialPosition, dPos), + rotation: Quat.multiply(yawChange, initialProperties.rotation), + }); + } + + // update the rotation display accordingly... + var startAtCurrent = 0; + var endAtCurrent = angleFromZero; + var startAtRemainder = angleFromZero; + var endAtRemainder = 360; + if (angleFromZero < 0) { + startAtCurrent = 360 + angleFromZero; + endAtCurrent = 360; + startAtRemainder = 0; + endAtRemainder = startAtCurrent; + } + if (snapToInner) { + Overlays.editOverlay(rotateOverlayOuter, { startAt: 0, endAt: 360 }); + Overlays.editOverlay(rotateOverlayInner, { startAt: startAtRemainder, endAt: endAtRemainder }); + Overlays.editOverlay(rotateOverlayCurrent, { startAt: startAtCurrent, endAt: endAtCurrent, size: innerRadius, + majorTickMarksAngle: innerSnapAngle, minorTickMarksAngle: 0, + majorTickMarksLength: -0.25, minorTickMarksLength: 0, }); + } else { + Overlays.editOverlay(rotateOverlayInner, { startAt: 0, endAt: 360 }); + Overlays.editOverlay(rotateOverlayOuter, { startAt: startAtRemainder, endAt: endAtRemainder }); + Overlays.editOverlay(rotateOverlayCurrent, { startAt: startAtCurrent, endAt: endAtCurrent, size: outerRadius, + majorTickMarksAngle: 45.0, minorTickMarksAngle: 5, + majorTickMarksLength: 0.25, minorTickMarksLength: 0.1, }); + } + } } - }; + }); + + addGrabberTool(pitchHandle, { + mode: "ROTATE_PITCH", + onBegin: function(event) { + SelectionManager.saveProperties(); + initialPosition = SelectionManager.worldPosition; + }, + onEnd: function(event, reason) { + if (reason == 'cancel') { + for (var i = 0; i < SelectionManager.selections.length; i++) { + var entityID = SelectionManager.selections[i]; + var initialProperties = SelectionManager.savedProperties[entityID.id]; + Entities.editEntity(entityID, initialProperties); + } + } + }, + onMove: function(event) { + if (!entitySelected || mode !== "ROTATE_PITCH") { + return; // not allowed + } + var debug = Menu.isOptionChecked("Debug Ryans Rotation Problems"); + + if (debug) { + print("rotatePitch()..."); + print(" event.x,y:" + event.x + "," + event.y); + } + + var pickRay = Camera.computePickRay(event.x, event.y); + Overlays.editOverlay(selectionBox, { ignoreRayIntersection: true, visible: false}); + Overlays.editOverlay(baseOfEntityProjectionOverlay, { ignoreRayIntersection: true, visible: false }); + Overlays.editOverlay(rotateOverlayTarget, { ignoreRayIntersection: false }); + Overlays.editOverlay(rotateOverlayInner, { ignoreRayIntersection: true }); + Overlays.editOverlay(rotateOverlayOuter, { ignoreRayIntersection: true }); + Overlays.editOverlay(rotateOverlayCurrent, { ignoreRayIntersection: true }); + var result = Overlays.findRayIntersection(pickRay); + + if (debug) { + print(" findRayIntersection() .... result.intersects:" + result.intersects); + } + + if (result.intersects) { + var properties = Entities.getEntityProperties(currentSelection); + var center = pitchCenter; + var zero = pitchZero; + var centerToZero = Vec3.subtract(center, zero); + var centerToIntersect = Vec3.subtract(center, result.intersection); + var angleFromZero = Vec3.orientedAngle(centerToZero, centerToIntersect, rotationNormal); + + var distanceFromCenter = Vec3.distance(center, result.intersection); + var snapToInner = false; + if (distanceFromCenter < innerRadius) { + angleFromZero = Math.floor(angleFromZero/innerSnapAngle) * innerSnapAngle; + snapToInner = true; + } + + // for debugging + if (debug) { + Vec3.print(" result.intersection:",result.intersection); + Overlays.editOverlay(rotateCurrentOverlay, { visible: true, start: center, end: result.intersection }); + print(" angleFromZero:" + angleFromZero); + } + + var pitchChange = Quat.fromVec3Degrees({ x: angleFromZero, y: 0, z: 0 }); + + for (var i = 0; i < SelectionManager.selections.length; i++) { + var entityID = SelectionManager.selections[i]; + var properties = Entities.getEntityProperties(entityID); + var initialProperties = SelectionManager.savedProperties[entityID.id]; + var dPos = Vec3.subtract(initialProperties.position, initialPosition); + dPos = Vec3.multiplyQbyV(pitchChange, dPos); + + Entities.editEntity(entityID, { + position: Vec3.sum(initialPosition, dPos), + rotation: Quat.multiply(pitchChange, initialProperties.rotation), + }); + } + + // update the rotation display accordingly... + var startAtCurrent = 0; + var endAtCurrent = angleFromZero; + var startAtRemainder = angleFromZero; + var endAtRemainder = 360; + if (angleFromZero < 0) { + startAtCurrent = 360 + angleFromZero; + endAtCurrent = 360; + startAtRemainder = 0; + endAtRemainder = startAtCurrent; + } + if (snapToInner) { + Overlays.editOverlay(rotateOverlayOuter, { startAt: 0, endAt: 360 }); + Overlays.editOverlay(rotateOverlayInner, { startAt: startAtRemainder, endAt: endAtRemainder }); + Overlays.editOverlay(rotateOverlayCurrent, { startAt: startAtCurrent, endAt: endAtCurrent, size: innerRadius, + majorTickMarksAngle: innerSnapAngle, minorTickMarksAngle: 0, + majorTickMarksLength: -0.25, minorTickMarksLength: 0, }); + } else { + Overlays.editOverlay(rotateOverlayInner, { startAt: 0, endAt: 360 }); + Overlays.editOverlay(rotateOverlayOuter, { startAt: startAtRemainder, endAt: endAtRemainder }); + Overlays.editOverlay(rotateOverlayCurrent, { startAt: startAtCurrent, endAt: endAtCurrent, size: outerRadius, + majorTickMarksAngle: 45.0, minorTickMarksAngle: 5, + majorTickMarksLength: 0.25, minorTickMarksLength: 0.1, }); + } + } + } + }); + + addGrabberTool(rollHandle, { + mode: "ROTATE_ROLL", + onBegin: function(event) { + SelectionManager.saveProperties(); + initialPosition = SelectionManager.worldPosition; + }, + onEnd: function(event, reason) { + if (reason == 'cancel') { + for (var i = 0; i < SelectionManager.selections.length; i++) { + var entityID = SelectionManager.selections[i]; + var initialProperties = SelectionManager.savedProperties[entityID.id]; + Entities.editEntity(entityID, initialProperties); + } + } + }, + onMove: function(event) { + if (!entitySelected || mode !== "ROTATE_ROLL") { + return; // not allowed + } + var debug = Menu.isOptionChecked("Debug Ryans Rotation Problems"); + + if (debug) { + print("rotateRoll()..."); + print(" event.x,y:" + event.x + "," + event.y); + } + + var pickRay = Camera.computePickRay(event.x, event.y); + Overlays.editOverlay(selectionBox, { ignoreRayIntersection: true, visible: false}); + Overlays.editOverlay(baseOfEntityProjectionOverlay, { ignoreRayIntersection: true, visible: false }); + Overlays.editOverlay(rotateOverlayTarget, { ignoreRayIntersection: false }); + Overlays.editOverlay(rotateOverlayInner, { ignoreRayIntersection: true }); + Overlays.editOverlay(rotateOverlayOuter, { ignoreRayIntersection: true }); + Overlays.editOverlay(rotateOverlayCurrent, { ignoreRayIntersection: true }); + var result = Overlays.findRayIntersection(pickRay); + + if (debug) { + print(" findRayIntersection() .... result.intersects:" + result.intersects); + } + + if (result.intersects) { + var properties = Entities.getEntityProperties(currentSelection); + var center = rollCenter; + var zero = rollZero; + var centerToZero = Vec3.subtract(center, zero); + var centerToIntersect = Vec3.subtract(center, result.intersection); + var angleFromZero = Vec3.orientedAngle(centerToZero, centerToIntersect, rotationNormal); + + var distanceFromCenter = Vec3.distance(center, result.intersection); + var snapToInner = false; + if (distanceFromCenter < innerRadius) { + angleFromZero = Math.floor(angleFromZero/innerSnapAngle) * innerSnapAngle; + snapToInner = true; + } + + // for debugging + if (debug) { + Vec3.print(" result.intersection:",result.intersection); + Overlays.editOverlay(rotateCurrentOverlay, { visible: true, start: center, end: result.intersection }); + print(" angleFromZero:" + angleFromZero); + } + + var rollChange = Quat.fromVec3Degrees({ x: 0, y: 0, z: angleFromZero }); + for (var i = 0; i < SelectionManager.selections.length; i++) { + var entityID = SelectionManager.selections[i]; + var properties = Entities.getEntityProperties(entityID); + var initialProperties = SelectionManager.savedProperties[entityID.id]; + var dPos = Vec3.subtract(initialProperties.position, initialPosition); + dPos = Vec3.multiplyQbyV(rollChange, dPos); + + Entities.editEntity(entityID, { + position: Vec3.sum(initialPosition, dPos), + rotation: Quat.multiply(rollChange, initialProperties.rotation), + }); + } + + // update the rotation display accordingly... + var startAtCurrent = 0; + var endAtCurrent = angleFromZero; + var startAtRemainder = angleFromZero; + var endAtRemainder = 360; + if (angleFromZero < 0) { + startAtCurrent = 360 + angleFromZero; + endAtCurrent = 360; + startAtRemainder = 0; + endAtRemainder = startAtCurrent; + } + if (snapToInner) { + Overlays.editOverlay(rotateOverlayOuter, { startAt: 0, endAt: 360 }); + Overlays.editOverlay(rotateOverlayInner, { startAt: startAtRemainder, endAt: endAtRemainder }); + Overlays.editOverlay(rotateOverlayCurrent, { startAt: startAtCurrent, endAt: endAtCurrent, size: innerRadius, + majorTickMarksAngle: innerSnapAngle, minorTickMarksAngle: 0, + majorTickMarksLength: -0.25, minorTickMarksLength: 0, }); + } else { + Overlays.editOverlay(rotateOverlayInner, { startAt: 0, endAt: 360 }); + Overlays.editOverlay(rotateOverlayOuter, { startAt: startAtRemainder, endAt: endAtRemainder }); + Overlays.editOverlay(rotateOverlayCurrent, { startAt: startAtCurrent, endAt: endAtCurrent, size: outerRadius, + majorTickMarksAngle: 45.0, minorTickMarksAngle: 5, + majorTickMarksLength: 0.25, minorTickMarksLength: 0.1, }); + } + } + } + }); that.checkMove = function() { if (currentSelection.isKnownID && (!Vec3.equal(Camera.getPosition(), lastCameraPosition) || !Quat.equal(Camera.getOrientation(), lastCameraOrientation))){ - that.select(currentSelection, false); + that.select(currentSelection, false, false); } }; @@ -2011,119 +1828,66 @@ SelectionDisplay = (function () { Vec3.print(" result.intersection:", result.intersection); } - switch(result.overlayID) { - case grabberMoveUp: - mode = "TRANSLATE_UP_DOWN"; - somethingClicked = true; + var tool = grabberTools[result.overlayID]; + if (tool) { + print("FOUND TOOL! " + tool.mode); + activeTool = tool; + mode = tool.mode; + somethingClicked = true; + if (activeTool && activeTool.onBegin) { + activeTool.onBegin(event); + } + } else { + switch(result.overlayID) { + case grabberMoveUp: + mode = "TRANSLATE_UP_DOWN"; + somethingClicked = true; - // in translate mode, we hide our stretch handles... - Overlays.editOverlay(grabberLBN, { visible: false }); - Overlays.editOverlay(grabberLBF, { visible: false }); - Overlays.editOverlay(grabberRBN, { visible: false }); - Overlays.editOverlay(grabberRBF, { visible: false }); - Overlays.editOverlay(grabberLTN, { visible: false }); - Overlays.editOverlay(grabberLTF, { visible: false }); - Overlays.editOverlay(grabberRTN, { visible: false }); - Overlays.editOverlay(grabberRTF, { visible: false }); + // in translate mode, we hide our stretch handles... + for (var i = 0; i < stretchHandles.length; i++) { + Overlays.editOverlay(stretchHandles[i], { visible: false }); + } + break; - Overlays.editOverlay(grabberTOP, { visible: false }); - Overlays.editOverlay(grabberBOTTOM, { visible: false }); - Overlays.editOverlay(grabberLEFT, { visible: false }); - Overlays.editOverlay(grabberRIGHT, { visible: false }); - Overlays.editOverlay(grabberNEAR, { visible: false }); - Overlays.editOverlay(grabberFAR, { visible: false }); - Overlays.editOverlay(grabberEdgeTR, { visible: false }); - Overlays.editOverlay(grabberEdgeTL, { visible: false }); - Overlays.editOverlay(grabberEdgeTF, { visible: false }); - Overlays.editOverlay(grabberEdgeTN, { visible: false }); - Overlays.editOverlay(grabberEdgeBR, { visible: false }); - Overlays.editOverlay(grabberEdgeBL, { visible: false }); - Overlays.editOverlay(grabberEdgeBF, { visible: false }); - Overlays.editOverlay(grabberEdgeBN, { visible: false }); - Overlays.editOverlay(grabberEdgeNR, { visible: false }); - Overlays.editOverlay(grabberEdgeNL, { visible: false }); - Overlays.editOverlay(grabberEdgeFR, { visible: false }); - Overlays.editOverlay(grabberEdgeFL, { visible: false }); - break; + case grabberNEAR: + case grabberEdgeTN: // TODO: maybe this should be TOP+NEAR stretching? + case grabberEdgeBN: // TODO: maybe this should be BOTTOM+FAR stretching? + mode = "STRETCH_NEAR"; + somethingClicked = true; + break; - case grabberRBN: - mode = "STRETCH_RBN"; - somethingClicked = true; - break; + case grabberFAR: + case grabberEdgeTF: // TODO: maybe this should be TOP+FAR stretching? + case grabberEdgeBF: // TODO: maybe this should be BOTTOM+FAR stretching? + mode = "STRETCH_FAR"; + somethingClicked = true; + break; + case grabberTOP: + mode = "STRETCH_TOP"; + somethingClicked = true; + break; + case grabberBOTTOM: + mode = "STRETCH_BOTTOM"; + somethingClicked = true; + break; + case grabberRIGHT: + case grabberEdgeTR: // TODO: maybe this should be TOP+RIGHT stretching? + case grabberEdgeBR: // TODO: maybe this should be BOTTOM+RIGHT stretching? + mode = "STRETCH_RIGHT"; + somethingClicked = true; + break; + case grabberLEFT: + case grabberEdgeTL: // TODO: maybe this should be TOP+LEFT stretching? + case grabberEdgeBL: // TODO: maybe this should be BOTTOM+LEFT stretching? + mode = "STRETCH_LEFT"; + somethingClicked = true; + break; - case grabberLBN: - mode = "STRETCH_LBN"; - somethingClicked = true; - break; - - case grabberRTN: - mode = "STRETCH_RTN"; - somethingClicked = true; - break; - - case grabberLTN: - mode = "STRETCH_LTN"; - somethingClicked = true; - break; - - case grabberRBF: - mode = "STRETCH_RBF"; - somethingClicked = true; - break; - - case grabberLBF: - mode = "STRETCH_LBF"; - somethingClicked = true; - break; - - case grabberRTF: - mode = "STRETCH_RTF"; - somethingClicked = true; - break; - - case grabberLTF: - mode = "STRETCH_LTF"; - somethingClicked = true; - break; - - case grabberNEAR: - case grabberEdgeTN: // TODO: maybe this should be TOP+NEAR stretching? - case grabberEdgeBN: // TODO: maybe this should be BOTTOM+FAR stretching? - mode = "STRETCH_NEAR"; - somethingClicked = true; - break; - - case grabberFAR: - case grabberEdgeTF: // TODO: maybe this should be TOP+FAR stretching? - case grabberEdgeBF: // TODO: maybe this should be BOTTOM+FAR stretching? - mode = "STRETCH_FAR"; - somethingClicked = true; - break; - case grabberTOP: - mode = "STRETCH_TOP"; - somethingClicked = true; - break; - case grabberBOTTOM: - mode = "STRETCH_BOTTOM"; - somethingClicked = true; - break; - case grabberRIGHT: - case grabberEdgeTR: // TODO: maybe this should be TOP+RIGHT stretching? - case grabberEdgeBR: // TODO: maybe this should be BOTTOM+RIGHT stretching? - mode = "STRETCH_RIGHT"; - somethingClicked = true; - break; - case grabberLEFT: - case grabberEdgeTL: // TODO: maybe this should be TOP+LEFT stretching? - case grabberEdgeBL: // TODO: maybe this should be BOTTOM+LEFT stretching? - mode = "STRETCH_LEFT"; - somethingClicked = true; - break; - - default: - mode = "UNKNOWN"; - break; + default: + mode = "UNKNOWN"; + break; + } } } @@ -2164,6 +1928,16 @@ SelectionDisplay = (function () { originalRoll = roll; if (result.intersects) { + var tool = grabberTools[result.overlayID]; + if (tool) { + print("FOUND TOOL! " + tool.mode); + activeTool = tool; + mode = tool.mode; + somethingClicked = true; + if (activeTool && activeTool.onBegin) { + activeTool.onBegin(event); + } + } switch(result.overlayID) { case yawHandle: mode = "ROTATE_YAW"; @@ -2176,6 +1950,7 @@ SelectionDisplay = (function () { case pitchHandle: mode = "ROTATE_PITCH"; + initialPosition = SelectionManager.worldPosition; somethingClicked = true; overlayOrientation = pitchHandleRotation; overlayCenter = pitchCenter; @@ -2263,7 +2038,9 @@ SelectionDisplay = (function () { if (result.intersects) { switch(result.overlayID) { case selectionBox: - mode = "TRANSLATE_XZ"; + activeTool = translateXZTool; + mode = translateXZTool.mode; + activeTool.onBegin(event); somethingClicked = true; break; default: @@ -2296,169 +2073,111 @@ SelectionDisplay = (function () { }; that.mouseMoveEvent = function(event) { - //print("mouseMoveEvent()... mode:" + mode); - switch (mode) { - case "ROTATE_YAW": - that.rotateYaw(event); - break; - case "ROTATE_PITCH": - that.rotatePitch(event); - break; - case "ROTATE_ROLL": - that.rotateRoll(event); - break; - case "TRANSLATE_UP_DOWN": - that.translateUpDown(event); - break; - case "TRANSLATE_XZ": - that.translateXZ(event); - break; - case "STRETCH_RBN": - that.stretchRBN(event); - break; - case "STRETCH_LBN": - that.stretchLBN(event); - break; - case "STRETCH_RTN": - that.stretchRTN(event); - break; - case "STRETCH_LTN": - that.stretchLTN(event); - break; + if (activeTool) { + activeTool.onMove(event); + SelectionManager._update(); + return true; + } - case "STRETCH_RBF": - that.stretchRBF(event); - break; - case "STRETCH_LBF": - that.stretchLBF(event); - break; - case "STRETCH_RTF": - that.stretchRTF(event); - break; - case "STRETCH_LTF": - that.stretchLTF(event); - break; + // if no tool is active, then just look for handles to highlight... + var pickRay = Camera.computePickRay(event.x, event.y); + var result = Overlays.findRayIntersection(pickRay); + var pickedColor; + var pickedAlpha; + var highlightNeeded = false; - case "STRETCH_NEAR": - that.stretchNEAR(event); - break; - case "STRETCH_FAR": - that.stretchFAR(event); - break; - case "STRETCH_TOP": - that.stretchTOP(event); - break; - case "STRETCH_BOTTOM": - that.stretchBOTTOM(event); - break; - case "STRETCH_RIGHT": - that.stretchRIGHT(event); - break; - case "STRETCH_LEFT": - that.stretchLEFT(event); - break; - default: - // if not in any specific mode, then just look for handles to highlight... - var pickRay = Camera.computePickRay(event.x, event.y); - var result = Overlays.findRayIntersection(pickRay); - var pickedColor; - var pickedAlpha; - var highlightNeeded = false; - - if (result.intersects) { - switch(result.overlayID) { - case yawHandle: - case pitchHandle: - case rollHandle: - pickedColor = rotateHandleColor; - pickedAlpha = rotateHandleAlpha; - highlightNeeded = true; - break; - - case grabberMoveUp: - pickedColor = rotateHandleColor; - pickedAlpha = rotateHandleAlpha; - highlightNeeded = true; - break; - - case grabberLBN: - case grabberLBF: - case grabberRBN: - case grabberRBF: - case grabberLTN: - case grabberLTF: - case grabberRTN: - case grabberRTF: - pickedColor = grabberColorCorner; - pickedAlpha = grabberAlpha; - highlightNeeded = true; - break; - - case grabberTOP: - case grabberBOTTOM: - case grabberLEFT: - case grabberRIGHT: - case grabberNEAR: - case grabberFAR: - pickedColor = grabberColorFace; - pickedAlpha = grabberAlpha; - highlightNeeded = true; - break; - - case grabberEdgeTR: - case grabberEdgeTL: - case grabberEdgeTF: - case grabberEdgeTN: - case grabberEdgeBR: - case grabberEdgeBL: - case grabberEdgeBF: - case grabberEdgeBN: - case grabberEdgeNR: - case grabberEdgeNL: - case grabberEdgeFR: - case grabberEdgeFL: - pickedColor = grabberColorEdge; - pickedAlpha = grabberAlpha; - highlightNeeded = true; - break; - - default: - if (previousHandle) { - Overlays.editOverlay(previousHandle, { color: previousHandleColor, alpha: previousHandleAlpha }); - previousHandle = false; - } - break; - } + if (result.intersects) { + switch(result.overlayID) { + case yawHandle: + case pitchHandle: + case rollHandle: + pickedColor = rotateHandleColor; + pickedAlpha = rotateHandleAlpha; + highlightNeeded = true; + break; - if (highlightNeeded) { - if (previousHandle) { - Overlays.editOverlay(previousHandle, { color: previousHandleColor, alpha: previousHandleAlpha }); - previousHandle = false; - } - Overlays.editOverlay(result.overlayID, { color: highlightedHandleColor, alpha: highlightedHandleAlpha }); - previousHandle = result.overlayID; - previousHandleColor = pickedColor; - previousHandleAlpha = pickedAlpha; - } - - } else { + case grabberMoveUp: + pickedColor = rotateHandleColor; + pickedAlpha = rotateHandleAlpha; + highlightNeeded = true; + break; + + case grabberLBN: + case grabberLBF: + case grabberRBN: + case grabberRBF: + case grabberLTN: + case grabberLTF: + case grabberRTN: + case grabberRTF: + pickedColor = grabberColorCorner; + pickedAlpha = grabberAlpha; + highlightNeeded = true; + break; + + case grabberTOP: + case grabberBOTTOM: + case grabberLEFT: + case grabberRIGHT: + case grabberNEAR: + case grabberFAR: + pickedColor = grabberColorFace; + pickedAlpha = grabberAlpha; + highlightNeeded = true; + break; + + case grabberEdgeTR: + case grabberEdgeTL: + case grabberEdgeTF: + case grabberEdgeTN: + case grabberEdgeBR: + case grabberEdgeBL: + case grabberEdgeBF: + case grabberEdgeBN: + case grabberEdgeNR: + case grabberEdgeNL: + case grabberEdgeFR: + case grabberEdgeFL: + pickedColor = grabberColorEdge; + pickedAlpha = grabberAlpha; + highlightNeeded = true; + break; + + default: if (previousHandle) { Overlays.editOverlay(previousHandle, { color: previousHandleColor, alpha: previousHandleAlpha }); previousHandle = false; } + break; + } + + if (highlightNeeded) { + if (previousHandle) { + Overlays.editOverlay(previousHandle, { color: previousHandleColor, alpha: previousHandleAlpha }); + previousHandle = false; } - - return false; + Overlays.editOverlay(result.overlayID, { color: highlightedHandleColor, alpha: highlightedHandleAlpha }); + previousHandle = result.overlayID; + previousHandleColor = pickedColor; + previousHandleAlpha = pickedAlpha; + } + + } else { + if (previousHandle) { + Overlays.editOverlay(previousHandle, { color: previousHandleColor, alpha: previousHandleAlpha }); + previousHandle = false; + } } - return true; + + return false; }; that.updateHandleSizes = function() { if (selectedEntityProperties) { var diff = Vec3.subtract(selectedEntityProperties.position, Camera.getPosition()); var grabberSize = Vec3.length(diff) * GRABBER_DISTANCE_TO_SIZE_RATIO; - for (var i = 0; i < cornerEdgeFaceGrabbers.length; i++) { - Overlays.editOverlay(cornerEdgeFaceGrabbers[i], { + for (var i = 0; i < stretchHandles.length; i++) { + Overlays.editOverlay(stretchHandles[i], { size: grabberSize, }); } @@ -2481,6 +2200,10 @@ SelectionDisplay = (function () { that.mouseReleaseEvent = function(event) { var showHandles = false; + if (activeTool && activeTool.onEnd) { + activeTool.onEnd(event); + } + activeTool = null; // hide our rotation overlays..., and show our handles if (mode == "ROTATE_YAW" || mode == "ROTATE_PITCH" || mode == "ROTATE_ROLL") { Overlays.editOverlay(rotateOverlayTarget, { visible: false }); diff --git a/examples/newEditEntities.js b/examples/newEditEntities.js index 8e1ccab67e..9b46cdaf3f 100644 --- a/examples/newEditEntities.js +++ b/examples/newEditEntities.js @@ -21,6 +21,7 @@ Script.include("libraries/progressDialog.js"); Script.include("libraries/entitySelectionTool.js"); var selectionDisplay = SelectionDisplay; +var selectionManager = SelectionManager; Script.include("libraries/ModelImporter.js"); var modelImporter = new ModelImporter(); @@ -34,6 +35,8 @@ var entityPropertyDialogBox = EntityPropertyDialogBox; Script.include("libraries/entityCameraTool.js"); var entityCameraTool = new EntityCameraTool(); +selectionManager.setEventListener(selectionDisplay.updateHandles()); + var windowDimensions = Controller.getViewportDimensions(); var toolIconUrl = HIFI_PUBLIC_BUCKET + "images/tools/"; var toolHeight = 50; @@ -440,6 +443,11 @@ function mousePressEvent(event) { orientation = MyAvatar.orientation; intersection = rayPlaneIntersection(pickRay, P, Quat.getFront(orientation)); + if (!event.isShifted) { + selectionManager.clearSelections(); + } + selectionManager.addEntity(foundEntity); + print("Model selected selectedEntityID:" + selectedEntityID.id); } @@ -641,11 +649,16 @@ Menu.menuItemEvent.connect(handeMenuEvent); Controller.keyReleaseEvent.connect(function (event) { // since sometimes our menu shortcut keys don't work, trap our menu items here also and fire the appropriate menu items + print(event.text); if (event.text == "`") { handeMenuEvent("Edit Properties..."); } if (event.text == "BACKSPACE") { handeMenuEvent("Delete"); + } else if (event.text == "TAB") { + selectionDisplay.toggleSpaceMode(); + } else if (event.text == "ESC") { + selectionDisplay.cancelTool(); } else if (event.text == "f") { if (entitySelected) { // Get latest properties