diff --git a/examples/editModels.js b/examples/editModels.js index e0ade3b6a3..0b71edec07 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -1884,7 +1884,7 @@ function controller(wichSide) { this.jointsIntersectingFromStart = []; this.laser = Overlays.addOverlay("line3d", { - position: { x: 0, y: 0, z: 0 }, + start: { x: 0, y: 0, z: 0 }, end: { x: 0, y: 0, z: 0 }, color: LASER_COLOR, alpha: 1, @@ -1904,7 +1904,7 @@ function controller(wichSide) { anchor: "MyAvatar" }); this.leftRight = Overlays.addOverlay("line3d", { - position: { x: 0, y: 0, z: 0 }, + start: { x: 0, y: 0, z: 0 }, end: { x: 0, y: 0, z: 0 }, color: { red: 0, green: 0, blue: 255 }, alpha: 1, @@ -1913,7 +1913,7 @@ function controller(wichSide) { anchor: "MyAvatar" }); this.topDown = Overlays.addOverlay("line3d", { - position: { x: 0, y: 0, z: 0 }, + start: { x: 0, y: 0, z: 0 }, end: { x: 0, y: 0, z: 0 }, color: { red: 0, green: 0, blue: 255 }, alpha: 1, @@ -2066,7 +2066,7 @@ function controller(wichSide) { var endPosition = Vec3.sum(startPosition, direction); Overlays.editOverlay(this.laser, { - position: startPosition, + start: startPosition, end: endPosition }); @@ -2075,10 +2075,11 @@ function controller(wichSide) { position: endPosition }); Overlays.editOverlay(this.leftRight, { - position: Vec3.sum(endPosition, Vec3.multiply(this.right, 2 * this.guideScale)), + start: Vec3.sum(endPosition, Vec3.multiply(this.right, 2 * this.guideScale)), end: Vec3.sum(endPosition, Vec3.multiply(this.right, -2 * this.guideScale)) }); - Overlays.editOverlay(this.topDown, { position: Vec3.sum(endPosition, Vec3.multiply(this.up, 2 * this.guideScale)), + Overlays.editOverlay(this.topDown, { + start: Vec3.sum(endPosition, Vec3.multiply(this.up, 2 * this.guideScale)), end: Vec3.sum(endPosition, Vec3.multiply(this.up, -2 * this.guideScale)) }); this.showLaser(!this.grabbing || mode == 0); diff --git a/examples/editVoxels.js b/examples/editVoxels.js index ff096973a3..439921d412 100644 --- a/examples/editVoxels.js +++ b/examples/editVoxels.js @@ -178,7 +178,7 @@ var currentCursor = 0; function addLineOverlay() { return Overlays.addOverlay("line3d", { - position: { x: 0, y: 0, z: 0}, + start: { x: 0, y: 0, z: 0}, end: { x: 0, y: 0, z: 0}, color: { red: 255, green: 255, blue: 255}, alpha: 1, @@ -474,7 +474,7 @@ function initImport() { }); xImportGuide = Overlays.addOverlay("line3d", { - position: { x: 0, y: 0, z: 0}, + start: { x: 0, y: 0, z: 0}, end: { x: 0, y: 0, z: 0}, color: { red: 255, green: 0, blue: 0}, alpha: 1, @@ -482,7 +482,7 @@ function initImport() { lineWidth: previewLineWidth }); yImportGuide = Overlays.addOverlay("line3d", { - position: { x: 0, y: 0, z: 0}, + start: { x: 0, y: 0, z: 0}, end: { x: 0, y: 0, z: 0}, color: { red: 0, green: 255, blue: 0}, alpha: 1, @@ -490,7 +490,7 @@ function initImport() { lineWidth: previewLineWidth }); zImportGuide = Overlays.addOverlay("line3d", { - position: { x: 0, y: 0, z: 0}, + start: { x: 0, y: 0, z: 0}, end: { x: 0, y: 0, z: 0}, color: { red: 0, green: 0, blue: 255}, alpha: 1, @@ -519,15 +519,15 @@ function moveImport(position) { Overlays.editOverlay(xImportGuide, { - position: { x: importPosition.x, y: 0, z: importPosition.z }, + start: { x: importPosition.x, y: 0, z: importPosition.z }, end: { x: importPosition.x + scaleSelector.scale, y: 0, z: importPosition.z } }); Overlays.editOverlay(yImportGuide, { - position: { x: importPosition.x, y: importPosition.y, z: importPosition.z }, + start: { x: importPosition.x, y: importPosition.y, z: importPosition.z }, end: { x: importPosition.x, y: 0, z: importPosition.z } }); Overlays.editOverlay(zImportGuide, { - position: { x: importPosition.x, y: 0, z: importPosition.z }, + start: { x: importPosition.x, y: 0, z: importPosition.z }, end: { x: importPosition.x, y: 0, z: importPosition.z + scaleSelector.scale } }); rescaleImport(); diff --git a/examples/fallingSand.js b/examples/fallingSand.js index c85196f10e..e4161334dd 100644 --- a/examples/fallingSand.js +++ b/examples/fallingSand.js @@ -28,7 +28,7 @@ var MIN_VOXEL_SCALE = Math.pow(2.0, MIN_VOXEL_SCALE_POWER); var linePreviewTop = Overlays.addOverlay("line3d", { - position: { x: 0, y: 0, z: 0}, + start: { x: 0, y: 0, z: 0}, end: { x: 0, y: 0, z: 0}, color: { red: 0, green: 0, blue: 255}, alpha: 1, @@ -37,7 +37,7 @@ var linePreviewTop = Overlays.addOverlay("line3d", { }); var linePreviewBottom = Overlays.addOverlay("line3d", { - position: { x: 0, y: 0, z: 0}, + start: { x: 0, y: 0, z: 0}, end: { x: 0, y: 0, z: 0}, color: { red: 0, green: 0, blue: 255}, alpha: 1, @@ -46,7 +46,7 @@ var linePreviewBottom = Overlays.addOverlay("line3d", { }); var linePreviewLeft = Overlays.addOverlay("line3d", { - position: { x: 0, y: 0, z: 0}, + start: { x: 0, y: 0, z: 0}, end: { x: 0, y: 0, z: 0}, color: { red: 0, green: 0, blue: 255}, alpha: 1, @@ -55,7 +55,7 @@ var linePreviewLeft = Overlays.addOverlay("line3d", { }); var linePreviewRight = Overlays.addOverlay("line3d", { - position: { x: 0, y: 0, z: 0}, + start: { x: 0, y: 0, z: 0}, end: { x: 0, y: 0, z: 0}, color: { red: 0, green: 0, blue: 255}, alpha: 1, @@ -362,10 +362,10 @@ function showPreviewLines() { if (intersection.intersects) { var resultVoxel = calculateVoxelFromIntersection(intersection, ""); - Overlays.editOverlay(linePreviewTop, { position: resultVoxel.topLeft, end: resultVoxel.topRight, visible: true }); - Overlays.editOverlay(linePreviewBottom, { position: resultVoxel.bottomLeft, end: resultVoxel.bottomRight, visible: true }); - Overlays.editOverlay(linePreviewLeft, { position: resultVoxel.topLeft, end: resultVoxel.bottomLeft, visible: true }); - Overlays.editOverlay(linePreviewRight, { position: resultVoxel.topRight, end: resultVoxel.bottomRight, visible: true }); + Overlays.editOverlay(linePreviewTop, { start: resultVoxel.topLeft, end: resultVoxel.topRight, visible: true }); + Overlays.editOverlay(linePreviewBottom, { start: resultVoxel.bottomLeft, end: resultVoxel.bottomRight, visible: true }); + Overlays.editOverlay(linePreviewLeft, { start: resultVoxel.topLeft, end: resultVoxel.bottomLeft, visible: true }); + Overlays.editOverlay(linePreviewRight, { start: resultVoxel.topRight, end: resultVoxel.bottomRight, visible: true }); } else { Overlays.editOverlay(linePreviewTop, { visible: false }); Overlays.editOverlay(linePreviewBottom, { visible: false }); @@ -645,4 +645,4 @@ Script.update.connect(update); Script.scriptEnding.connect(scriptEnding); Voxels.setMaxPacketSize(1); //this is needed or a bug occurs :( -Voxels.setPacketsPerSecond(10000); \ No newline at end of file +Voxels.setPacketsPerSecond(10000); diff --git a/examples/gamepad.js b/examples/gamepad.js index cc275e6267..5a11f49cb2 100644 --- a/examples/gamepad.js +++ b/examples/gamepad.js @@ -75,7 +75,7 @@ var warpSphere = Overlays.addOverlay("sphere", { var WARP_LINE_HEIGHT = 10; var warpLine = Overlays.addOverlay("line3d", { - position: { x: 0, y: 0, z:0 }, + start: { x: 0, y: 0, z:0 }, end: { x: 0, y: 0, z: 0 }, color: { red: 0, green: 255, blue: 255}, alpha: 1, @@ -131,7 +131,7 @@ function updateWarp() { visible: true, }); Overlays.editOverlay(warpLine, { - position: warpPosition, + start: warpPosition, end: Vec3.sum(warpPosition, { x: 0, y: WARP_LINE_HEIGHT, z: 0 }), visible: true, }); diff --git a/examples/growTrees.js b/examples/growTrees.js index a5b55eecd6..8a23d0ee1c 100644 --- a/examples/growTrees.js +++ b/examples/growTrees.js @@ -27,7 +27,7 @@ var MIN_VOXEL_SCALE = Math.pow(2.0, MIN_VOXEL_SCALE_POWER); var linePreviewTop = Overlays.addOverlay("line3d", { - position: { x: 0, y: 0, z: 0}, + start: { x: 0, y: 0, z: 0}, end: { x: 0, y: 0, z: 0}, color: { red: 0, green: 255, blue: 0}, alpha: 1, @@ -36,7 +36,7 @@ var linePreviewTop = Overlays.addOverlay("line3d", { }); var linePreviewBottom = Overlays.addOverlay("line3d", { - position: { x: 0, y: 0, z: 0}, + start: { x: 0, y: 0, z: 0}, end: { x: 0, y: 0, z: 0}, color: { red: 0, green: 255, blue: 0}, alpha: 1, @@ -45,7 +45,7 @@ var linePreviewBottom = Overlays.addOverlay("line3d", { }); var linePreviewLeft = Overlays.addOverlay("line3d", { - position: { x: 0, y: 0, z: 0}, + start: { x: 0, y: 0, z: 0}, end: { x: 0, y: 0, z: 0}, color: { red: 0, green: 255, blue: 0}, alpha: 1, @@ -54,7 +54,7 @@ var linePreviewLeft = Overlays.addOverlay("line3d", { }); var linePreviewRight = Overlays.addOverlay("line3d", { - position: { x: 0, y: 0, z: 0}, + start: { x: 0, y: 0, z: 0}, end: { x: 0, y: 0, z: 0}, color: { red: 0, green: 255, blue: 0}, alpha: 1, @@ -362,10 +362,10 @@ function showPreviewLines() { if (intersection.intersects) { var resultVoxel = calculateVoxelFromIntersection(intersection, ""); - Overlays.editOverlay(linePreviewTop, { position: resultVoxel.topLeft, end: resultVoxel.topRight, visible: true }); - Overlays.editOverlay(linePreviewBottom, { position: resultVoxel.bottomLeft, end: resultVoxel.bottomRight, visible: true }); - Overlays.editOverlay(linePreviewLeft, { position: resultVoxel.topLeft, end: resultVoxel.bottomLeft, visible: true }); - Overlays.editOverlay(linePreviewRight, { position: resultVoxel.topRight, end: resultVoxel.bottomRight, visible: true }); + Overlays.editOverlay(linePreviewTop, { start: resultVoxel.topLeft, end: resultVoxel.topRight, visible: true }); + Overlays.editOverlay(linePreviewBottom, { start: resultVoxel.bottomLeft, end: resultVoxel.bottomRight, visible: true }); + Overlays.editOverlay(linePreviewLeft, { start: resultVoxel.topLeft, end: resultVoxel.bottomLeft, visible: true }); + Overlays.editOverlay(linePreviewRight, { start: resultVoxel.topRight, end: resultVoxel.bottomRight, visible: true }); } else { Overlays.editOverlay(linePreviewTop, { visible: false }); Overlays.editOverlay(linePreviewBottom, { visible: false }); diff --git a/examples/headMove.js b/examples/headMove.js index 943664b70f..3152976383 100644 --- a/examples/headMove.js +++ b/examples/headMove.js @@ -36,7 +36,7 @@ var warpSphere = Overlays.addOverlay("sphere", { var WARP_LINE_HEIGHT = 5; var warpLine = Overlays.addOverlay("line3d", { - position: { x: 0, y: 0, z:0 }, + start: { x: 0, y: 0, z:0 }, end: { x: 0, y: 0, z: 0 }, color: { red: 0, green: 255, blue: 255}, alpha: 1, @@ -120,7 +120,7 @@ function updateWarp() { visible: willMove, }); Overlays.editOverlay(warpLine, { - position: Vec3.sum(warpPosition, { x: 0, y: -WARP_LINE_HEIGHT / 2.0, z: 0 }), + start: Vec3.sum(warpPosition, { x: 0, y: -WARP_LINE_HEIGHT / 2.0, z: 0 }), end: Vec3.sum(warpPosition, { x: 0, y: WARP_LINE_HEIGHT / 2.0, z: 0 }), visible: willMove, }); diff --git a/examples/libraries/entityCameraTool.js b/examples/libraries/entityCameraTool.js index 803a58f48e..cd8aa3656b 100644 --- a/examples/libraries/entityCameraTool.js +++ b/examples/libraries/entityCameraTool.js @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/overlayUtils.js"); + var MOUSE_SENSITIVITY = 0.9; var SCROLL_SENSITIVITY = 0.05; var PAN_ZOOM_SCALE_RATIO = 0.4; @@ -41,6 +43,17 @@ var easeOutCubic = function(t) { EASE_TIME = 0.5; +function mergeObjects(obj1, obj2) { + var newObj = {}; + for (key in obj1) { + newObj[key] = obj1[key]; + } + for (key in obj2) { + newObj[key] = obj2[key]; + } + return newObj; +} + CameraManager = function() { var that = {}; @@ -92,8 +105,6 @@ CameraManager = function() { Camera.mode = "independent"; that.updateCamera(); - - cameraTool.setVisible(false); } that.disable = function(ignoreCamera) { @@ -104,7 +115,6 @@ CameraManager = function() { if (!ignoreCamera) { Camera.mode = that.previousCameraMode; } - cameraTool.setVisible(false); } that.focus = function(position, dimensions, easeOrientation) { @@ -140,6 +150,11 @@ CameraManager = function() { that.updateCamera(); } + that.setTargetPitchYaw = function(pitch, yaw) { + that.targetPitch = pitch; + that.targetYaw = yaw; + } + that.moveFocalPoint = function(dPos) { that.setFocalPoint(Vec3.sum(that.focalPoint, dPos)); } @@ -228,6 +243,10 @@ CameraManager = function() { } that.mousePressEvent = function(event) { + if (cameraTool.mousePressEvent(event)) { + return true; + } + if (!that.enabled) return; if (event.isRightButton || (event.isLeftButton && event.isControl && !event.isShifted)) { @@ -247,7 +266,7 @@ CameraManager = function() { return true; } - return cameraTool.mousePressEvent(event); + return false; } that.mouseReleaseEvent = function(event) { @@ -271,7 +290,10 @@ CameraManager = function() { } that.updateCamera = function() { - if (!that.enabled || Camera.mode != "independent") return; + if (!that.enabled || Camera.mode != "independent") { + cameraTool.update(); + return; + } var yRot = Quat.angleAxis(that.yaw, { x: 0, y: 1, z: 0 }); var xRot = Quat.angleAxis(that.pitch, { x: 1, y: 0, z: 0 }); @@ -290,6 +312,8 @@ CameraManager = function() { } Camera.setOrientation(q); + + cameraTool.update(); } function normalizeDegrees(degrees) { @@ -301,6 +325,7 @@ CameraManager = function() { // Ease the position and orbit of the camera that.update = function(dt) { if (Camera.mode != "independent") { + that.updateCamera(); return; } @@ -363,316 +388,210 @@ CameraManager = function() { return that; } -var ZoomTool = function(opts) { - var that = {}; - - var position = opts.position || { x: 0, y: 0 }; - var height = opts.height || 200; - var color = opts.color || { red: 255, green: 0, blue: 0 }; - var arrowButtonSize = opts.buttonSize || 20; - var arrowButtonBackground = opts.arrowBackground || { red: 255, green: 255, blue: 255 }; - var zoomBackground = { red: 128, green: 0, blue: 0 }; - var zoomHeight = height - (arrowButtonSize * 2); - var zoomBarY = position.y + arrowButtonSize, - - var onIncreasePressed = opts.onIncreasePressed; - var onDecreasePressed = opts.onDecreasePressed; - var onPercentageSet = opts.onPercentageSet; - - var increaseButton = Overlays.addOverlay("text", { - x: position.x, - y: position.y, - width: arrowButtonSize, - height: arrowButtonSize, - color: color, - backgroundColor: arrowButtonBackground, - topMargin: 4, - leftMargin: 4, - text: "+", - alpha: 1.0, - backgroundAlpha: 1.0, - visible: true, - }); - var decreaseButton = Overlays.addOverlay("text", { - x: position.x, - y: position.y + arrowButtonSize + zoomHeight, - width: arrowButtonSize, - height: arrowButtonSize, - color: color, - backgroundColor: arrowButtonBackground, - topMargin: 4, - leftMargin: 4, - text: "-", - alpha: 1.0, - backgroundAlpha: 1.0, - visible: true, - }); - var zoomBar = Overlays.addOverlay("text", { - x: position.x + 5, - y: zoomBarY, - width: 10, - height: zoomHeight, - color: { red: 0, green: 255, blue: 0 }, - backgroundColor: zoomBackground, - topMargin: 4, - leftMargin: 4, - text: "", - alpha: 1.0, - backgroundAlpha: 1.0, - visible: true, - }); - var zoomHandle = Overlays.addOverlay("text", { - x: position.x, - y: position.y + arrowButtonSize, - width: arrowButtonSize, - height: 10, - backgroundColor: { red: 0, green: 255, blue: 0 }, - topMargin: 4, - leftMargin: 4, - text: "", - alpha: 1.0, - backgroundAlpha: 1.0, - visible: true, - }); - - var allOverlays = [ - increaseButton, - decreaseButton, - zoomBar, - zoomHandle, - ]; - - that.destroy = function() { - for (var i = 0; i < allOverlays.length; i++) { - Overlays.deleteOverlay(allOverlays[i]); - } - }; - - that.setVisible = function(visible) { - for (var i = 0; i < allOverlays.length; i++) { - Overlays.editOverlay(allOverlays[i], { visible: visible }); - } - } - - that.setZoomPercentage = function(pct) { - var yOffset = (zoomHeight - 10) * pct; - Overlays.editOverlay(zoomHandle, { - y: position.y + arrowButtonSize + yOffset, - }); - } - - that.mouseReleaseEvent = function(event) { - var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); - var clicked = false; - if (clickedOverlay == increaseButton) { - if (onIncreasePressed) onIncreasePressed(); - clicked = true; - } else if (clickedOverlay == decreaseButton) { - if (onDecreasePressed) onDecreasePressed(); - clicked = true; - } else if (clickedOverlay == zoomBar) { - if (onPercentageSet) onPercentageSet((event.y - zoomBarY) / zoomHeight); - clicked = true; - } - return clicked; - } - - return that; -}; - -var ArrowTool = function(opts) { - var that = {}; - - var position = opts.position || { x: 0, y: 0 }; - var arrowButtonSize = opts.buttonSize || 20; - var color = opts.color || { red: 255, green: 0, blue: 0 }; - var arrowButtonBackground = opts.arrowBackground || { red: 255, green: 255, blue: 255 }; - var centerButtonBackground = opts.centerBackground || { red: 255, green: 255, blue: 255 }; - var onUpPressed = opts.onUpPressed; - var onDownPressed = opts.onDownPressed; - var onLeftPressed = opts.onLeftPressed; - var onRightPressed = opts.onRightPressed; - var onCenterPressed = opts.onCenterPressed; - - var upButton = Overlays.addOverlay("text", { - x: position.x + arrowButtonSize, - y: position.y, - width: arrowButtonSize, - height: arrowButtonSize, - color: color, - backgroundColor: arrowButtonBackground, - topMargin: 4, - leftMargin: 4, - text: "^", - alpha: 1.0, - backgroundAlpha: 1.0, - visible: true, - }); - var leftButton = Overlays.addOverlay("text", { - x: position.x, - y: position.y + arrowButtonSize, - width: arrowButtonSize, - height: arrowButtonSize, - color: color, - backgroundColor: arrowButtonBackground, - topMargin: 4, - leftMargin: 4, - text: "<", - alpha: 1.0, - backgroundAlpha: 1.0, - visible: true, - }); - var rightButton = Overlays.addOverlay("text", { - x: position.x + (arrowButtonSize * 2), - y: position.y + arrowButtonSize, - width: arrowButtonSize, - height: arrowButtonSize, - color: color, - backgroundColor: arrowButtonBackground, - topMargin: 4, - leftMargin: 4, - text: ">", - alpha: 1.0, - visible: true, - }); - var downButton = Overlays.addOverlay("text", { - x: position.x + arrowButtonSize, - y: position.y + (arrowButtonSize * 2), - width: arrowButtonSize, - height: arrowButtonSize, - color: color, - backgroundColor: arrowButtonBackground, - topMargin: 4, - leftMargin: 4, - text: "v", - alpha: 1.0, - backgroundAlpha: 1.0, - visible: true, - }); - var centerButton = Overlays.addOverlay("text", { - x: position.x + arrowButtonSize, - y: position.y + arrowButtonSize, - width: arrowButtonSize, - height: arrowButtonSize, - color: color, - backgroundColor: centerButtonBackground, - topMargin: 4, - leftMargin: 4, - text: "", - alpha: 1.0, - backgroundAlpha: 1.0, - visible: true, - }); - - var allOverlays = [ - upButton, - downButton, - leftButton, - rightButton, - centerButton, - ]; - - that.destroy = function() { - for (var i = 0; i < allOverlays.length; i++) { - Overlays.deleteOverlay(allOverlays[i]); - } - }; - - that.setVisible = function(visible) { - for (var i = 0; i < allOverlays.length; i++) { - Overlays.editOverlay(allOverlays[i], { visible: visible }); - } - } - - that.mouseReleaseEvent = function(event) { - var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); - var clicked = false; - if (clickedOverlay == leftButton) { - if (onLeftPressed) onLeftPressed(); - clicked = true; - } else if (clickedOverlay == rightButton) { - if (onRightPressed) onRightPressed(); - clicked = true; - } else if (clickedOverlay == upButton) { - if (onUpPressed) onUpPressed(); - clicked = true; - } else if (clickedOverlay == downButton) { - if (onDownPressed) onDownPressed(); - clicked = true; - } else if (clickedOverlay == centerButton) { - if (onCenterPressed) onCenterPressed(); - clicked = true; - } - return clicked; - } - - return that; -} - - CameraTool = function(cameraManager) { var that = {}; - var toolsPosition = { x: 20, y: 280 }; - var orbitToolPosition = toolsPosition; - var panToolPosition = { x: toolsPosition.x + 80, y: toolsPosition.y }; - var zoomToolPosition = { x: toolsPosition.x + 20, y: toolsPosition.y + 80 }; + var RED = { red: 191, green: 78, blue: 38 }; + var GREEN = { red: 26, green: 193, blue: 105 }; + var BLUE = { red: 0, green: 131, blue: 204 }; - var orbitIncrement = 15; - orbitTool = ArrowTool({ - position: orbitToolPosition, - arrowBackground: { red: 192, green: 192, blue: 192 }, - centerBackground: { red: 128, green: 128, blue: 255 }, - color: { red: 0, green: 0, blue: 0 }, - onUpPressed: function() { cameraManager.addPitch(orbitIncrement); }, - onDownPressed: function() { cameraManager.addPitch(-orbitIncrement); }, - onLeftPressed: function() { cameraManager.addYaw(-orbitIncrement); }, - onRightPressed: function() { cameraManager.addYaw(orbitIncrement); }, - onCenterPressed: function() { cameraManager.focus(); }, + var ORIENTATION_OVERLAY_SIZE = 20; + var ORIENTATION_OVERLAY_HALF_SIZE = ORIENTATION_OVERLAY_SIZE / 2; + var ORIENTATION_OVERLAY_CUBE_SIZE = 8, + + var ORIENTATION_OVERLAY_OFFSET = { + x: 96, + y: 30, + } + + var UI_URL = HIFI_PUBLIC_BUCKET + "images/tools/camera-controls.svg"; + + var UI_WIDTH = 128; + var UI_HEIGHT = 61; + var UI_PADDING = 10; + + var UI_BUTTON_WIDTH = 64; + var UI_BUTTON_HEIGHT = 30; + + var UI_SUBIMAGE_FIRST_PERSON = { + x: 0, + y: 0, + width: UI_WIDTH, + height: UI_HEIGHT + }, + var UI_SUBIMAGE_THIRD_PERSON = { + x: 0, + y: UI_HEIGHT, + width: UI_WIDTH, + height: UI_HEIGHT + }, + var UI_SUBIMAGE_OTHER = { + x: 0, + y: UI_HEIGHT * 2, + width: UI_WIDTH, + height: UI_HEIGHT + }, + + var lastKnownWidth = Window.innerWidth; + + var uiPosition = { + x: lastKnownWidth - UI_WIDTH - UI_PADDING, + y: UI_PADDING, + }; + + var ui = Overlays.addOverlay("image", { + imageURL: UI_URL, + x: uiPosition.x, + y: uiPosition.y, + subImage: { + x: 0, + y: 0, + width: UI_WIDTH, + height: UI_HEIGHT + }, + width: UI_WIDTH, + height: UI_HEIGHT, + alpha: 1.0, + visible: true }); - panTool = ArrowTool({ - position: panToolPosition, - arrowBackground: { red: 192, green: 192, blue: 192 }, - centerBackground: { red: 128, green: 128, blue: 255 }, - color: { red: 0, green: 0, blue: 0 }, - onUpPressed: function() { cameraManager.pan({ x: 0, y: 15 }); }, - onDownPressed: function() { cameraManager.pan({ x: 0, y: -15 }); }, - onLeftPressed: function() { cameraManager.pan({ x: -15, y: 0 }); }, - onRightPressed: function() { cameraManager.pan({ x: 15, y: 0 }); }, - }); - zoomTool = ZoomTool({ - position: zoomToolPosition, - arrowBackground: { red: 192, green: 192, blue: 192 }, - color: { red: 0, green: 0, blue: 0 }, - onIncreasePressed: function() { cameraManager.addZoom(-10); }, - onDecreasePressed: function() { cameraManager.addZoom(10); }, - onPercentageSet: function(pct) { cameraManager.setZoomPercentage(pct); } + + var defaultCubeProps = { + size: ORIENTATION_OVERLAY_CUBE_SIZE, + alpha: 1, + color: { red: 255, green: 0, blue: 0 }, + solid: true, + visible: true, + drawOnHUD: true, + }; + var defaultLineProps = { + lineWidth: 1.5, + alpha: 1, + position: { x: 0, y: 0, z: 0 }, + start: { x: 0, y: 0, z: 0 }, + end: { x: 0, y: 0, z: 0 }, + color: { red: 255, green: 0, blue: 0 }, + visible: true, + drawOnHUD: true, + }; + + var orientationOverlay = OverlayGroup({ + position: { + x: uiPosition.x + ORIENTATION_OVERLAY_OFFSET.x, + y: uiPosition.y + ORIENTATION_OVERLAY_OFFSET.y, + } }); + var OOHS = ORIENTATION_OVERLAY_HALF_SIZE; + var cubeX = orientationOverlay.createOverlay("cube", mergeObjects(defaultCubeProps, { + position: { x: -OOHS, y: OOHS, z: OOHS }, + color: RED, + })); + var cubeY = orientationOverlay.createOverlay("cube", mergeObjects(defaultCubeProps, { + position: { x: OOHS, y: -OOHS, z: OOHS }, + color: GREEN, + })); + var cubeZ = orientationOverlay.createOverlay("cube", mergeObjects(defaultCubeProps, { + position: { x: OOHS, y: OOHS, z: -OOHS }, + color: BLUE, + })); + orientationOverlay.createOverlay("line3d", mergeObjects(defaultLineProps, { + start: { x: -OOHS, y: OOHS, z: OOHS }, + end: { x: OOHS, y: OOHS, z: OOHS }, + color: RED, + })); + orientationOverlay.createOverlay("line3d", mergeObjects(defaultLineProps, { + start: { x: OOHS, y: -OOHS, z: OOHS }, + end: { x: OOHS, y: OOHS, z: OOHS }, + color: GREEN, + })); + orientationOverlay.createOverlay("line3d", mergeObjects(defaultLineProps, { + start: { x: OOHS, y: OOHS, z: -OOHS }, + end: { x: OOHS, y: OOHS, z: OOHS }, + color: BLUE, + })); + Script.scriptEnding.connect(function() { - orbitTool.destroy(); - panTool.destroy(); - zoomTool.destroy(); + orientationOverlay.destroy(); + Overlays.deleteOverlay(ui); }); + var flip = Quat.fromPitchYawRollDegrees(0, 180, 0); + that.update = function() { + orientationOverlay.setProperties({ + rotation: Quat.multiply(flip, Quat.inverse(Camera.orientation)), + }); + + if (Window.innerWidth != lastKnownWidth) { + lastKnownWidth = Window.innerWidth; + uiPosition = { + x: lastKnownWidth - UI_WIDTH - UI_PADDING, + y: UI_PADDING, + }; + Overlays.editOverlay(ui, { + x: uiPosition.x, + y: uiPosition.y + }); + orientationOverlay.setProperties({ + position: { + x: uiPosition.x + ORIENTATION_OVERLAY_OFFSET.x, + y: uiPosition.y + ORIENTATION_OVERLAY_OFFSET.y, + } + }); + } + } + that.mousePressEvent = function(event) { - return orbitTool.mouseReleaseEvent(event) - || panTool.mouseReleaseEvent(event) - || zoomTool.mouseReleaseEvent(event); + var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); + + if (clickedOverlay == cubeX) { + targetPitch = 0; + targetYaw = event.isLeftButton ? 90 : -90; + cameraManager.setTargetPitchYaw(targetPitch, targetYaw); + return true; + } else if (clickedOverlay == cubeY) { + targetPitch = event.isLeftButton ? 90 : -90; + targetYaw = 0; + cameraManager.setTargetPitchYaw(targetPitch, targetYaw); + return true; + } else if (clickedOverlay == cubeZ) { + targetPitch = 0; + targetYaw = event.isLeftButton ? 0 : 180; + cameraManager.setTargetPitchYaw(targetPitch, targetYaw); + return true; + } else if (clickedOverlay == ui) { + var x = event.x - uiPosition.x; + var y = event.y - uiPosition.y; + + // Did we hit a button? + if (x < UI_BUTTON_WIDTH) { + if (y < UI_BUTTON_HEIGHT) { + Camera.mode = "first person"; + } else { + Camera.mode = "third person"; + } + } + return true; + } }; + function updateMode() { + var mode = Camera.mode; + + var subImage = UI_SUBIMAGE_OTHER; + if (mode == "first person") { + subImage = UI_SUBIMAGE_FIRST_PERSON; + } else if (mode == "third person") { + subImage = UI_SUBIMAGE_THIRD_PERSON; + } + + Overlays.editOverlay(ui, { subImage: subImage }); + } + + Camera.modeUpdated.connect(updateMode); + updateMode(); + that.setVisible = function(visible) { - orbitTool.setVisible(visible); - panTool.setVisible(visible); - zoomTool.setVisible(visible); }; - Script.update.connect(function() { - cameraManager.getZoomPercentage(); - zoomTool.setZoomPercentage(cameraManager.getZoomPercentage()); - }); - - that.setVisible(false); - return that; }; diff --git a/examples/libraries/overlayUtils.js b/examples/libraries/overlayUtils.js new file mode 100644 index 0000000000..7623bfbb30 --- /dev/null +++ b/examples/libraries/overlayUtils.js @@ -0,0 +1,64 @@ +/** + * OverlayGroup provides a way to create composite overlays and control their + * position relative to a settable rootPosition and rootRotation. + */ +OverlayGroup = function(opts) { + var that = {}; + + var overlays = {}; + + var rootPosition = opts.position || { x: 0, y: 0, z: 0 }; + var rootRotation = opts.rotation || Quat.fromPitchYawRollRadians(0, 0, 0); + var visible = true; + + function updateOverlays() { + for (overlayID in overlays) { + var overlay = overlays[overlayID]; + var newPosition = Vec3.multiplyQbyV(rootRotation, overlay.position); + newPosition = Vec3.sum(rootPosition, newPosition); + Overlays.editOverlay(overlayID, { + visible: visible, + position: newPosition, + rotation: Quat.multiply(rootRotation, overlay.rotation), + }); + }; + } + + that.createOverlay = function(type, properties) { + properties.position = properties.position || { x: 0, y: 0, z: 0 }; + properties.rotation = properties.rotation || Quat.fromPitchYawRollRadians(0, 0, 0); + + var overlay = Overlays.addOverlay(type, properties); + + overlays[overlay] = { + position: properties.position, + rotation: properties.rotation, + }; + + updateOverlays(); + + return overlay; + } + + that.setProperties = function(properties) { + if (properties.position !== undefined) { + rootPosition = properties.position; + } + if (properties.rotation !== undefined) { + rootRotation = properties.rotation; + } + if (properties.visible !== undefined) { + visible = properties.visible; + } + updateOverlays(); + }; + + that.destroy = function() { + for (var overlay in overlays) { + Overlays.deleteOverlay(overlay); + } + overlays = {}; + } + + return that; +}; diff --git a/examples/overlaysExample.js b/examples/overlaysExample.js index 4aa5b1cd75..821f8a11d1 100644 --- a/examples/overlaysExample.js +++ b/examples/overlaysExample.js @@ -154,7 +154,7 @@ var sphere = Overlays.addOverlay("sphere", { }); var line3d = Overlays.addOverlay("line3d", { - position: { x: 0, y: 0, z:0 }, + start: { x: 0, y: 0, z:0 }, end: { x: 10, y: 10, z:10 }, color: { red: 0, green: 255, blue: 255}, alpha: 1, diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1c7ab452a0..f294da6fd5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2896,12 +2896,12 @@ void Application::updateShadowMap() { // render JS/scriptable overlays { PerformanceTimer perfTimer("3dOverlays"); - _overlays.render3D(false, RenderArgs::SHADOW_RENDER_MODE); + _overlays.renderWorld(false, RenderArgs::SHADOW_RENDER_MODE); } { PerformanceTimer perfTimer("3dOverlaysFront"); - _overlays.render3D(true, RenderArgs::SHADOW_RENDER_MODE); + _overlays.renderWorld(true, RenderArgs::SHADOW_RENDER_MODE); } glDisable(GL_POLYGON_OFFSET_FILL); @@ -3129,7 +3129,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly, RenderAr // render JS/scriptable overlays { PerformanceTimer perfTimer("3dOverlays"); - _overlays.render3D(false); + _overlays.renderWorld(false); } // render the ambient occlusion effect if enabled @@ -3218,7 +3218,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly, RenderAr { PerformanceTimer perfTimer("3dOverlaysFront"); glClear(GL_DEPTH_BUFFER_BIT); - _overlays.render3D(true); + _overlays.renderWorld(true); } } diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 120c5b3043..6b45d792d0 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -181,8 +181,10 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) { } glPushMatrix(); { + const float NEAR_CLIP = -10000; + const float FAR_CLIP = 10000; glLoadIdentity(); - glOrtho(0, glCanvas->width(), glCanvas->height(), 0, -1.0, 1.0); + glOrtho(0, glCanvas->width(), glCanvas->height(), 0, NEAR_CLIP, FAR_CLIP); renderAudioMeter(); @@ -195,7 +197,7 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) { // give external parties a change to hook in emit application->renderingOverlay(); - overlays.render2D(); + overlays.renderHUD(); renderPointers(); @@ -1102,7 +1104,7 @@ void ApplicationOverlay::TexturedHemisphere::buildFramebufferObject() { delete _framebufferObject; } - _framebufferObject = new QOpenGLFramebufferObject(size); + _framebufferObject = new QOpenGLFramebufferObject(size, QOpenGLFramebufferObject::Depth); bindTexture(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index a9588cd7a3..12e593a1d0 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -14,6 +14,7 @@ #include #include +#include "Application.h" #include "Base3DOverlay.h" const glm::vec3 DEFAULT_POSITION = glm::vec3(0.0f, 0.0f, 0.0f); @@ -28,7 +29,8 @@ Base3DOverlay::Base3DOverlay() : _isSolid(DEFAULT_IS_SOLID), _isDashedLine(DEFAULT_IS_DASHED_LINE), _ignoreRayIntersection(false), - _drawInFront(false) + _drawInFront(false), + _drawOnHUD(false) { } @@ -46,6 +48,13 @@ Base3DOverlay::Base3DOverlay(const Base3DOverlay* base3DOverlay) : Base3DOverlay::~Base3DOverlay() { } +void Base3DOverlay::setDrawOnHUD(bool value) { + if (_drawOnHUD != value) { + _drawOnHUD = value; + Application::getInstance()->getOverlays().overlayDrawOnChanged(this); + } +} + void Base3DOverlay::setProperties(const QScriptValue& properties) { Overlay::setProperties(properties); @@ -56,16 +65,20 @@ void Base3DOverlay::setProperties(const QScriptValue& properties) { setDrawInFront(value); } + QScriptValue drawOnHUD = properties.property("drawOnHUD"); + + if (drawOnHUD.isValid()) { + bool value = drawOnHUD.toVariant().toBool(); + setDrawOnHUD(value); + } + QScriptValue position = properties.property("position"); - // if "position" property was not there, check to see if they included aliases: start, point, p1 + // if "position" property was not there, check to see if they included aliases: point, p1 if (!position.isValid()) { - position = properties.property("start"); + position = properties.property("p1"); if (!position.isValid()) { - position = properties.property("p1"); - if (!position.isValid()) { - position = properties.property("point"); - } + position = properties.property("point"); } } @@ -162,6 +175,9 @@ QScriptValue Base3DOverlay::getProperty(const QString& property) { if (property == "drawInFront") { return _drawInFront; } + if (property == "drawOnHUD") { + return _drawOnHUD; + } return Overlay::getProperty(property); } diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index b5314bd6d3..0e10a5f63b 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -37,6 +37,7 @@ public: const glm::quat& getRotation() const { return _rotation; } bool getIgnoreRayIntersection() const { return _ignoreRayIntersection; } bool getDrawInFront() const { return _drawInFront; } + bool getDrawOnHUD() const { return _drawOnHUD; } // setters void setPosition(const glm::vec3& position) { _position = position; } @@ -46,6 +47,7 @@ public: void setRotation(const glm::quat& value) { _rotation = value; } void setIgnoreRayIntersection(bool value) { _ignoreRayIntersection = value; } void setDrawInFront(bool value) { _drawInFront = value; } + void setDrawOnHUD(bool value); virtual void setProperties(const QScriptValue& properties); virtual QScriptValue getProperty(const QString& property); @@ -67,6 +69,7 @@ protected: bool _isDashedLine; bool _ignoreRayIntersection; bool _drawInFront; + bool _drawOnHUD; }; #endif // hifi_Base3DOverlay_h diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index c61d68f05d..2242a642ca 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -76,7 +76,13 @@ void Cube3DOverlay::render(RenderArgs* args) { glPushMatrix(); glColor4f(1.0f, 1.0f, 1.0f, alpha); glScalef(dimensions.x * _borderSize, dimensions.y * _borderSize, dimensions.z * _borderSize); - DependencyManager::get()->renderSolidCube(1.0f); + + if (_drawOnHUD) { + DependencyManager::get()->renderSolidCube(1.0f); + } else { + DependencyManager::get()->renderSolidCube(1.0f); + } + glPopMatrix(); glDepthMask(GL_TRUE); } @@ -84,7 +90,11 @@ void Cube3DOverlay::render(RenderArgs* args) { glPushMatrix(); glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); glScalef(dimensions.x, dimensions.y, dimensions.z); - DependencyManager::get()->renderSolidCube(1.0f); + if (_drawOnHUD) { + DependencyManager::get()->renderSolidCube(1.0f); + } else { + DependencyManager::get()->renderSolidCube(1.0f); + } glPopMatrix(); } else { glLineWidth(_lineWidth); diff --git a/interface/src/ui/overlays/Line3DOverlay.cpp b/interface/src/ui/overlays/Line3DOverlay.cpp index 4facd779de..83cb48899c 100644 --- a/interface/src/ui/overlays/Line3DOverlay.cpp +++ b/interface/src/ui/overlays/Line3DOverlay.cpp @@ -39,6 +39,8 @@ void Line3DOverlay::render(RenderArgs* args) { glower = new Glower(glowLevel); } + glPushMatrix(); + glDisable(GL_LIGHTING); glLineWidth(_lineWidth); @@ -47,16 +49,25 @@ void Line3DOverlay::render(RenderArgs* args) { const float MAX_COLOR = 255.0f; glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); + glm::vec3 position = getPosition(); + glm::quat rotation = getRotation(); + + glTranslatef(position.x, position.y, position.z); + glm::vec3 axis = glm::axis(rotation); + glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); + if (getIsDashedLine()) { drawDashedLine(_position, _end); } else { glBegin(GL_LINES); - glVertex3f(_position.x, _position.y, _position.z); + glVertex3f(_start.x, _start.y, _start.z); glVertex3f(_end.x, _end.y, _end.z); glEnd(); } glEnable(GL_LIGHTING); + glPopMatrix(); + if (glower) { delete glower; } @@ -65,13 +76,28 @@ void Line3DOverlay::render(RenderArgs* args) { void Line3DOverlay::setProperties(const QScriptValue& properties) { Base3DOverlay::setProperties(properties); + QScriptValue start = properties.property("start"); + // if "start" property was not there, check to see if they included aliases: startPoint + if (!start.isValid()) { + start = properties.property("startPoint"); + } + if (start.isValid()) { + QScriptValue x = start.property("x"); + QScriptValue y = start.property("y"); + QScriptValue z = start.property("z"); + if (x.isValid() && y.isValid() && z.isValid()) { + glm::vec3 newStart; + newStart.x = x.toVariant().toFloat(); + newStart.y = y.toVariant().toFloat(); + newStart.z = z.toVariant().toFloat(); + setStart(newStart); + } + } + QScriptValue end = properties.property("end"); - // if "end" property was not there, check to see if they included aliases: endPoint, or p2 + // if "end" property was not there, check to see if they included aliases: endPoint if (!end.isValid()) { end = properties.property("endPoint"); - if (!end.isValid()) { - end = properties.property("p2"); - } } if (end.isValid()) { QScriptValue x = end.property("x"); diff --git a/interface/src/ui/overlays/Line3DOverlay.h b/interface/src/ui/overlays/Line3DOverlay.h index 607fb0e0bb..afe0ade585 100644 --- a/interface/src/ui/overlays/Line3DOverlay.h +++ b/interface/src/ui/overlays/Line3DOverlay.h @@ -23,9 +23,11 @@ public: virtual void render(RenderArgs* args); // getters + const glm::vec3& getStart() const { return _start; } const glm::vec3& getEnd() const { return _end; } // setters + void setStart(const glm::vec3& start) { _start = start; } void setEnd(const glm::vec3& end) { _end = end; } virtual void setProperties(const QScriptValue& properties); @@ -34,6 +36,7 @@ public: virtual Line3DOverlay* createClone() const; protected: + glm::vec3 _start; glm::vec3 _end; }; diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index ace4ecf353..1dbe9af930 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -37,14 +37,14 @@ Overlays::~Overlays() { { QWriteLocker lock(&_lock); - foreach(Overlay* thisOverlay, _overlays2D) { + foreach(Overlay* thisOverlay, _overlaysHUD) { delete thisOverlay; } - _overlays2D.clear(); - foreach(Overlay* thisOverlay, _overlays3D) { + _overlaysHUD.clear(); + foreach(Overlay* thisOverlay, _overlaysWorld) { delete thisOverlay; } - _overlays3D.clear(); + _overlaysWorld.clear(); } if (!_overlaysToDelete.isEmpty()) { @@ -65,10 +65,10 @@ void Overlays::update(float deltatime) { { QWriteLocker lock(&_lock); - foreach(Overlay* thisOverlay, _overlays2D) { + foreach(Overlay* thisOverlay, _overlaysHUD) { thisOverlay->update(deltatime); } - foreach(Overlay* thisOverlay, _overlays3D) { + foreach(Overlay* thisOverlay, _overlaysWorld) { thisOverlay->update(deltatime); } } @@ -82,21 +82,31 @@ void Overlays::update(float deltatime) { } -void Overlays::render2D() { +void Overlays::renderHUD() { QReadLocker lock(&_lock); RenderArgs args = { NULL, Application::getInstance()->getViewFrustum(), Menu::getInstance()->getVoxelSizeScale(), Menu::getInstance()->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - foreach(Overlay* thisOverlay, _overlays2D) { - thisOverlay->render(&args); + foreach(Overlay* thisOverlay, _overlaysHUD) { + if (thisOverlay->is3D()) { + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + + thisOverlay->render(&args); + + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + } else{ + thisOverlay->render(&args); + } } } -void Overlays::render3D(bool drawFront, RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) { +void Overlays::renderWorld(bool drawFront, RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) { QReadLocker lock(&_lock); - if (_overlays3D.size() == 0) { + if (_overlaysWorld.size() == 0) { return; } bool myAvatarComputed = false; @@ -112,7 +122,7 @@ void Overlays::render3D(bool drawFront, RenderArgs::RenderMode renderMode, Rende renderMode, renderSide, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - foreach(Overlay* thisOverlay, _overlays3D) { + foreach(Overlay* thisOverlay, _overlaysWorld) { Base3DOverlay* overlay3D = static_cast(thisOverlay); if (overlay3D->getDrawInFront() != drawFront) { continue; @@ -193,9 +203,14 @@ unsigned int Overlays::addOverlay(Overlay* overlay) { unsigned int thisID = _nextOverlayID; _nextOverlayID++; if (overlay->is3D()) { - _overlays3D[thisID] = overlay; + Base3DOverlay* overlay3D = static_cast(overlay); + if (overlay3D->getDrawOnHUD()) { + _overlaysHUD[thisID] = overlay; + } else { + _overlaysWorld[thisID] = overlay; + } } else { - _overlays2D[thisID] = overlay; + _overlaysHUD[thisID] = overlay; } return thisID; @@ -203,21 +218,23 @@ unsigned int Overlays::addOverlay(Overlay* overlay) { unsigned int Overlays::cloneOverlay(unsigned int id) { Overlay* thisOverlay = NULL; - if (_overlays2D.contains(id)) { - thisOverlay = _overlays2D[id]; - } else if (_overlays3D.contains(id)) { - thisOverlay = _overlays3D[id]; + if (_overlaysHUD.contains(id)) { + thisOverlay = _overlaysHUD[id]; + } else if (_overlaysWorld.contains(id)) { + thisOverlay = _overlaysWorld[id]; } return addOverlay(thisOverlay->createClone()); } bool Overlays::editOverlay(unsigned int id, const QScriptValue& properties) { Overlay* thisOverlay = NULL; - QWriteLocker lock(&_lock); - if (_overlays2D.contains(id)) { - thisOverlay = _overlays2D[id]; - } else if (_overlays3D.contains(id)) { - thisOverlay = _overlays3D[id]; + { + QReadLocker lock(&_lock); + if (_overlaysHUD.contains(id)) { + thisOverlay = _overlaysHUD[id]; + } else if (_overlaysWorld.contains(id)) { + thisOverlay = _overlaysWorld[id]; + } } if (thisOverlay) { thisOverlay->setProperties(properties); @@ -231,10 +248,10 @@ void Overlays::deleteOverlay(unsigned int id) { { QWriteLocker lock(&_lock); - if (_overlays2D.contains(id)) { - overlayToDelete = _overlays2D.take(id); - } else if (_overlays3D.contains(id)) { - overlayToDelete = _overlays3D.take(id); + if (_overlaysHUD.contains(id)) { + overlayToDelete = _overlaysHUD.take(id); + } else if (_overlaysWorld.contains(id)) { + overlayToDelete = _overlaysWorld.take(id); } else { return; } @@ -251,17 +268,34 @@ unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) { } QReadLocker lock(&_lock); - QMapIterator i(_overlays2D); + QMapIterator i(_overlaysHUD); i.toBack(); + + const float LARGE_NEGATIVE_FLOAT = -9999999; + glm::vec3 origin(pointCopy.x, pointCopy.y, LARGE_NEGATIVE_FLOAT); + glm::vec3 direction(0, 0, 1); + BoxFace thisFace; + float distance; + while (i.hasPrevious()) { i.previous(); unsigned int thisID = i.key(); - Overlay2D* thisOverlay = static_cast(i.value()); - if (thisOverlay->getVisible() && thisOverlay->isLoaded() && - thisOverlay->getBounds().contains(pointCopy.x, pointCopy.y, false)) { - return thisID; + if (i.value()->is3D()) { + Base3DOverlay* thisOverlay = static_cast(i.value()); + if (!thisOverlay->getIgnoreRayIntersection()) { + if (thisOverlay->findRayIntersection(origin, direction, distance, thisFace)) { + return thisID; + } + } + } else { + Overlay2D* thisOverlay = static_cast(i.value()); + if (thisOverlay->getVisible() && thisOverlay->isLoaded() && + thisOverlay->getBounds().contains(pointCopy.x, pointCopy.y, false)) { + return thisID; + } } } + return 0; // not found } @@ -269,10 +303,10 @@ OverlayPropertyResult Overlays::getProperty(unsigned int id, const QString& prop OverlayPropertyResult result; Overlay* thisOverlay = NULL; QReadLocker lock(&_lock); - if (_overlays2D.contains(id)) { - thisOverlay = _overlays2D[id]; - } else if (_overlays3D.contains(id)) { - thisOverlay = _overlays3D[id]; + if (_overlaysHUD.contains(id)) { + thisOverlay = _overlaysHUD[id]; + } else if (_overlaysWorld.contains(id)) { + thisOverlay = _overlaysWorld[id]; } if (thisOverlay) { result.value = thisOverlay->getProperty(property); @@ -314,7 +348,7 @@ RayToOverlayIntersectionResult Overlays::findRayIntersection(const PickRay& ray) float bestDistance = std::numeric_limits::max(); bool bestIsFront = false; RayToOverlayIntersectionResult result; - QMapIterator i(_overlays3D); + QMapIterator i(_overlaysWorld); i.toBack(); while (i.hasPrevious()) { i.previous(); @@ -419,13 +453,32 @@ void RayToOverlayIntersectionResultFromScriptValue(const QScriptValue& object, R value.extraInfo = object.property("extraInfo").toVariant().toString(); } +void Overlays::overlayDrawOnChanged(Base3DOverlay* overlay) { + QWriteLocker lock(&_lock); + if (overlay->getDrawOnHUD()) { + for (unsigned int id : _overlaysWorld.keys()) { + if (_overlaysWorld[id] == overlay) { + _overlaysWorld.remove(id); + _overlaysHUD[id] = overlay; + } + } + } else { + for (unsigned int id : _overlaysHUD.keys()) { + if (_overlaysHUD[id] == overlay) { + _overlaysHUD.remove(id); + _overlaysWorld[id] = overlay; + } + } + } +} + bool Overlays::isLoaded(unsigned int id) { QReadLocker lock(&_lock); Overlay* thisOverlay = NULL; - if (_overlays2D.contains(id)) { - thisOverlay = _overlays2D[id]; - } else if (_overlays3D.contains(id)) { - thisOverlay = _overlays3D[id]; + if (_overlaysHUD.contains(id)) { + thisOverlay = _overlaysHUD[id]; + } else if (_overlaysWorld.contains(id)) { + thisOverlay = _overlaysWorld[id]; } else { return false; // not found } @@ -433,13 +486,13 @@ bool Overlays::isLoaded(unsigned int id) { } QSizeF Overlays::textSize(unsigned int id, const QString& text) const { - Overlay* thisOverlay = _overlays2D[id]; + Overlay* thisOverlay = _overlaysHUD[id]; if (thisOverlay) { if (typeid(*thisOverlay) == typeid(TextOverlay)) { return static_cast(thisOverlay)->textSize(text); } } else { - thisOverlay = _overlays3D[id]; + thisOverlay = _overlaysWorld[id]; if (thisOverlay) { if (typeid(*thisOverlay) == typeid(Text3DOverlay)) { return static_cast(thisOverlay)->textSize(text); diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index fb2c936a64..d3030b0ac1 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -15,6 +15,7 @@ #include #include +#include "Base3DOverlay.h" #include "Overlay.h" class OverlayPropertyResult { @@ -52,9 +53,9 @@ public: ~Overlays(); void init(QGLWidget* parent); void update(float deltatime); - void render3D(bool drawFront, RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, + void renderWorld(bool drawFront, RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::RenderSide renderSide = RenderArgs::MONO); - void render2D(); + void renderHUD(); public slots: /// adds an overlay with the specific properties @@ -81,6 +82,9 @@ public slots: /// returns details about the closest 3D Overlay hit by the pick ray RayToOverlayIntersectionResult findRayIntersection(const PickRay& ray); + + // called by Base3DOverlay when drawOnHUD changes + void overlayDrawOnChanged(Base3DOverlay* overlay); /// returns whether the overlay's assets are loaded or not bool isLoaded(unsigned int id); @@ -90,8 +94,8 @@ public slots: QSizeF textSize(unsigned int id, const QString& text) const; private: - QMap _overlays2D; - QMap _overlays3D; + QMap _overlaysHUD; + QMap _overlaysWorld; QList _overlaysToDelete; unsigned int _nextOverlayID; QGLWidget* _parent;