From 9bd7912f9f08f022b1a95f06777576e027c4c554 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 17 Dec 2014 16:25:25 -0800 Subject: [PATCH 01/19] Add support for drawing 3d overlays on the Application Overlay --- interface/src/ui/ApplicationOverlay.cpp | 6 ++-- interface/src/ui/overlays/Base3DOverlay.cpp | 6 +++- interface/src/ui/overlays/Base3DOverlay.h | 3 ++ interface/src/ui/overlays/Overlays.cpp | 39 +++++++++++++++++++-- 4 files changed, 49 insertions(+), 5 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index f4e0c9769d..e54ee613ff 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -177,8 +177,10 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) { } glPushMatrix(); { + const float NEAR_CLIP = -10000; + const float FAR_CLIP = 10000; glLoadIdentity(); - gluOrtho2D(0, glWidget->width(), glWidget->height(), 0); + glOrtho(0, glWidget->width(), glWidget->height(), 0, NEAR_CLIP, FAR_CLIP); renderAudioMeter(); @@ -1081,7 +1083,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..7e5bb543d6 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -28,7 +28,8 @@ Base3DOverlay::Base3DOverlay() : _isSolid(DEFAULT_IS_SOLID), _isDashedLine(DEFAULT_IS_DASHED_LINE), _ignoreRayIntersection(false), - _drawInFront(false) + _drawInFront(false), + _drawOnApplicationOverlay(false) { } @@ -162,6 +163,9 @@ QScriptValue Base3DOverlay::getProperty(const QString& property) { if (property == "drawInFront") { return _drawInFront; } + if (property == "drawOnApplicationOverlay") { + return _drawOnApplicationOverlay; + } return Overlay::getProperty(property); } diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index b5314bd6d3..b3e3c3df8a 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 getDrawOnApplicationOverlay() const { return _drawOnApplicationOverlay; } // 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 setDrawOnApplicationOverlay(bool value) { _drawOnApplicationOverlay = 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 _drawOnApplicationOverlay; }; #endif // hifi_Base3DOverlay_h diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index ace4ecf353..5871f408da 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -92,6 +92,17 @@ void Overlays::render2D() { foreach(Overlay* thisOverlay, _overlays2D) { thisOverlay->render(&args); } + + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + foreach(Overlay* thisOverlay, _overlays3D) { + Base3DOverlay* overlay3D = static_cast(thisOverlay); + if (overlay3D->getDrawOnApplicationOverlay()) { + thisOverlay->render(&args); + } + } + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); } void Overlays::render3D(bool drawFront, RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) { @@ -114,7 +125,7 @@ void Overlays::render3D(bool drawFront, RenderArgs::RenderMode renderMode, Rende foreach(Overlay* thisOverlay, _overlays3D) { Base3DOverlay* overlay3D = static_cast(thisOverlay); - if (overlay3D->getDrawInFront() != drawFront) { + if (overlay3D->getDrawInFront() != drawFront || overlay3D->getDrawOnApplicationOverlay()) { continue; } glPushMatrix(); @@ -251,7 +262,27 @@ unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) { } QReadLocker lock(&_lock); - QMapIterator i(_overlays2D); + QMapIterator i(_overlays3D); + 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(); + Base3DOverlay* thisOverlay = static_cast(i.value()); + if (thisOverlay->getDrawOnApplicationOverlay() && !thisOverlay->getIgnoreRayIntersection()) { + if (thisOverlay->findRayIntersection(origin, direction, distance, thisFace)) { + return thisID; + } + } + } + + i = QMapIterator(_overlays2D); i.toBack(); while (i.hasPrevious()) { i.previous(); @@ -262,6 +293,7 @@ unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) { return thisID; } } + return 0; // not found } @@ -320,6 +352,9 @@ RayToOverlayIntersectionResult Overlays::findRayIntersection(const PickRay& ray) i.previous(); unsigned int thisID = i.key(); Base3DOverlay* thisOverlay = static_cast(i.value()); + if (thisOverlay->getDrawOnApplicationOverlay()) { + continue; + } if (thisOverlay->getVisible() && !thisOverlay->getIgnoreRayIntersection() && thisOverlay->isLoaded()) { float thisDistance; BoxFace thisFace; From a0623c930b5e04975df72e2811453fef39fcfacb Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 17 Dec 2014 16:39:52 -0800 Subject: [PATCH 02/19] Add setting of drawOnApplicaitonOverlay --- interface/src/ui/overlays/Base3DOverlay.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 7e5bb543d6..625633222b 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -57,6 +57,13 @@ void Base3DOverlay::setProperties(const QScriptValue& properties) { setDrawInFront(value); } + QScriptValue drawOnApplicationOverlay = properties.property("drawOnApplicationOverlay"); + + if (drawOnApplicationOverlay.isValid()) { + bool value = drawOnApplicationOverlay.toVariant().toBool(); + setDrawOnApplicationOverlay(value); + } + QScriptValue position = properties.property("position"); // if "position" property was not there, check to see if they included aliases: start, point, p1 From 27e13385edc40bffb442bd70b314372bdf4b7e0b Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 17 Dec 2014 16:40:04 -0800 Subject: [PATCH 03/19] Fix drawing of Cube3D on the ApplicationOverlay This seems to break because the ApplicationOverlay is drawn to a texture buffer first, which is incompatible with the DeferredLightingEffect implementation. --- interface/src/ui/overlays/Cube3DOverlay.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index 8e37dedd77..6aa625c7ab 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -74,7 +74,11 @@ void Cube3DOverlay::render(RenderArgs* args) { glPushMatrix(); glColor4f(1.0f, 1.0f, 1.0f, alpha); glScalef(dimensions.x * _borderSize, dimensions.y * _borderSize, dimensions.z * _borderSize); - Application::getInstance()->getDeferredLightingEffect()->renderSolidCube(1.0f); + if (_drawOnApplicationOverlay) { + glutSolidCube(1.0f); + } else { + Application::getInstance()->getDeferredLightingEffect()->renderSolidCube(1.0f); + } glPopMatrix(); glDepthMask(GL_TRUE); } @@ -82,7 +86,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); - Application::getInstance()->getDeferredLightingEffect()->renderSolidCube(1.0f); + if (_drawOnApplicationOverlay) { + glutSolidCube(1.0f); + } else { + Application::getInstance()->getDeferredLightingEffect()->renderSolidCube(1.0f); + } glPopMatrix(); } else { glLineWidth(_lineWidth); From 5537fb970bdc0b953d39c5fbaa491a4290a50c56 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 18 Dec 2014 16:23:24 -0800 Subject: [PATCH 04/19] Update scripts to use instead of for line3d --- examples/editVoxels.js | 14 +++++++------- examples/fallingSand.js | 18 +++++++++--------- examples/gamepad.js | 4 ++-- examples/growTrees.js | 16 ++++++++-------- examples/headMove.js | 4 ++-- examples/overlaysExample.js | 2 +- 6 files changed, 29 insertions(+), 29 deletions(-) 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/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, From 74f8579922877b60aac1e2abc0d4820ee6733b60 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 18 Dec 2014 16:37:19 -0800 Subject: [PATCH 05/19] Update line3d to have a separate 'start' property and use transform/rotation --- interface/src/ui/overlays/Line3DOverlay.cpp | 36 ++++++++++++++++++--- interface/src/ui/overlays/Line3DOverlay.h | 3 ++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/interface/src/ui/overlays/Line3DOverlay.cpp b/interface/src/ui/overlays/Line3DOverlay.cpp index ae67bf9d92..10331f617b 100644 --- a/interface/src/ui/overlays/Line3DOverlay.cpp +++ b/interface/src/ui/overlays/Line3DOverlay.cpp @@ -38,6 +38,8 @@ void Line3DOverlay::render(RenderArgs* args) { glower = new Glower(glowLevel); } + glPushMatrix(); + glDisable(GL_LIGHTING); glLineWidth(_lineWidth); @@ -46,16 +48,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; } @@ -64,13 +75,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; }; From 2e95618beddb2f50160a937118e5788c9160c459 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 18 Dec 2014 16:38:27 -0800 Subject: [PATCH 06/19] Remove 'start' property alias from Base3DOverlay --- interface/src/ui/overlays/Base3DOverlay.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 625633222b..4b0b8166ee 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -66,14 +66,11 @@ void Base3DOverlay::setProperties(const QScriptValue& properties) { 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"); } } From 1776b2dee250e4f6bf2b7eab5cc8ff51a879933e Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 18 Dec 2014 16:41:41 -0800 Subject: [PATCH 07/19] Update line3d in editModels to use start instead of position --- examples/editModels.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) 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); From 93aaa38c4c99093993b0aa174353b6cece86aa63 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 19 Dec 2014 09:03:04 -0800 Subject: [PATCH 08/19] Add camera orientation overlay --- examples/editEntities.js | 4 +- examples/libraries/entityCameraTool.js | 443 ++++++++----------------- examples/libraries/overlayUtils.js | 64 ++++ 3 files changed, 209 insertions(+), 302 deletions(-) create mode 100644 examples/libraries/overlayUtils.js diff --git a/examples/editEntities.js b/examples/editEntities.js index 0b5c089c07..2039b4ba33 100644 --- a/examples/editEntities.js +++ b/examples/editEntities.js @@ -495,11 +495,11 @@ var mouseHasMovedSincePress = false; function mousePressEvent(event) { mouseHasMovedSincePress = false; - if (toolBar.mousePressEvent(event) || progressDialog.mousePressEvent(event)) { + if (toolBar.mousePressEvent(event) || cameraManager.mousePressEvent(event) || progressDialog.mousePressEvent(event)) { return; } if (isActive) { - if (cameraManager.mousePressEvent(event) || selectionDisplay.mousePressEvent(event)) { + if (selectionDisplay.mousePressEvent(event)) { // Event handled; do nothing. return; } diff --git a/examples/libraries/entityCameraTool.js b/examples/libraries/entityCameraTool.js index 803a58f48e..085f3ffc0d 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,27 @@ var easeOutCubic = function(t) { EASE_TIME = 0.5; +var ORIENTATION_OVERLAY_SIZE = 30; +var ORIENTATION_OVERLAY_HALF_SIZE = ORIENTATION_OVERLAY_SIZE / 2; +var orientationOverlayPosition = { + x: Window.innerWidth - 46, + y: 46, +}; +var orientationOverlay = OverlayGroup({ + position: orientationOverlayPosition, +}); + +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 +115,6 @@ CameraManager = function() { Camera.mode = "independent"; that.updateCamera(); - - cameraTool.setVisible(false); } that.disable = function(ignoreCamera) { @@ -104,7 +125,6 @@ CameraManager = function() { if (!ignoreCamera) { Camera.mode = that.previousCameraMode; } - cameraTool.setVisible(false); } that.focus = function(position, dimensions, easeOrientation) { @@ -140,6 +160,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)); } @@ -230,6 +255,10 @@ CameraManager = function() { that.mousePressEvent = function(event) { if (!that.enabled) return; + if (cameraTool.mousePressEvent(event)) { + return true; + } + if (event.isRightButton || (event.isLeftButton && event.isControl && !event.isShifted)) { that.mode = MODE_ORBIT; } else if (event.isMiddleButton || (event.isLeftButton && event.isControl && event.isShifted)) { @@ -247,7 +276,7 @@ CameraManager = function() { return true; } - return cameraTool.mousePressEvent(event); + return false; } that.mouseReleaseEvent = function(event) { @@ -270,8 +299,18 @@ CameraManager = function() { that.updateCamera(); } + that.updateOrientationOverlay = function() { + var flip = Quat.fromPitchYawRollDegrees(0, 180, 0); + orientationOverlay.setProperties({ + rotation: Quat.multiply(flip, Quat.inverse(Camera.orientation)), + }); + } + that.updateCamera = function() { - if (!that.enabled || Camera.mode != "independent") return; + if (!that.enabled || Camera.mode != "independent") { + that.updateOrientationOverlay(); + 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 +329,8 @@ CameraManager = function() { } Camera.setOrientation(q); + + that.updateOrientationOverlay(); } function normalizeDegrees(degrees) { @@ -301,6 +342,7 @@ CameraManager = function() { // Ease the position and orbit of the camera that.update = function(dt) { if (Camera.mode != "independent") { + that.updateCamera(); return; } @@ -363,316 +405,117 @@ 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 defaultCubeProps = { + size: 8, + alpha: 1, + color: { red: 255, green: 0, blue: 0 }, + solid: true, + visible: true, + drawOnApplicationOverlay: 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, + drawOnApplicationOverlay: true, + }; + + var padding = 40; + var borderWidth = 4; + var backgroundBorder = Overlays.addOverlay("text", { + x: orientationOverlayPosition.x - (ORIENTATION_OVERLAY_HALF_SIZE + padding / 2 + borderWidth / 2), + y: orientationOverlayPosition.y - (ORIENTATION_OVERLAY_HALF_SIZE + padding / 2 + borderWidth / 2), + width: ORIENTATION_OVERLAY_SIZE + padding + borderWidth, + height: ORIENTATION_OVERLAY_SIZE + padding + borderWidth, + backgroundColor: { red: 192, green: 192, blue: 192 }, + text: "", + alpha: 1.0, + backgroundAlpha: 0.8, + 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 background = Overlays.addOverlay("text", { + x: orientationOverlayPosition.x - (ORIENTATION_OVERLAY_HALF_SIZE + padding / 2), + y: orientationOverlayPosition.y - (ORIENTATION_OVERLAY_HALF_SIZE + padding / 2), + width: ORIENTATION_OVERLAY_SIZE + padding, + height: ORIENTATION_OVERLAY_SIZE + padding, + backgroundColor: { x: 0, y: 0, z: 0 }, + text: "", + alpha: 1.0, + backgroundAlpha: 0.9, + visible: true }); + 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(background); + Overlays.deleteOverlay(backgroundBorder); }); that.mousePressEvent = function(event) { - return orbitTool.mouseReleaseEvent(event) - || panTool.mouseReleaseEvent(event) - || zoomTool.mouseReleaseEvent(event); + var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); + print("Overlays: " + cubeX + ", " + cubeY); + print("Clicked: " + clickedOverlay); + 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; + } }; 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; +}; From 51a64650e41104d27531e0d5b8ed11827880347e Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 19 Dec 2014 09:04:54 -0800 Subject: [PATCH 09/19] Fix use of glOrtho and replace getDeferredLightingEffect w/ DependencyManager --- interface/src/ui/ApplicationOverlay.cpp | 2 +- interface/src/ui/overlays/Cube3DOverlay.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index c344c055c7..01d2ea64f9 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -182,7 +182,7 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) { const float NEAR_CLIP = -10000; const float FAR_CLIP = 10000; glLoadIdentity(); - glOrtho(0, glWidget->width(), glWidget->height(), 0, NEAR_CLIP, FAR_CLIP); + glOrtho(0, glCanvas->width(), glCanvas->height(), 0, NEAR_CLIP, FAR_CLIP); renderAudioMeter(); diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index 05676bb478..b2c3d005c2 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -93,7 +93,6 @@ void Cube3DOverlay::render(RenderArgs* args) { if (_drawOnApplicationOverlay) { glutSolidCube(1.0f); } else { - Application::getInstance()->getDeferredLightingEffect()->renderSolidCube(1.0f); DependencyManager::get()->renderSolidCube(1.0f); } glPopMatrix(); From 15389b5fcecbdd05c6e755c03d36dc7139ee20d9 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 19 Dec 2014 10:37:21 -0800 Subject: [PATCH 10/19] Add camera UI to camera tool --- examples/libraries/entityCameraTool.js | 176 ++++++++++++++++++------- 1 file changed, 126 insertions(+), 50 deletions(-) diff --git a/examples/libraries/entityCameraTool.js b/examples/libraries/entityCameraTool.js index 085f3ffc0d..4fdcbc0485 100644 --- a/examples/libraries/entityCameraTool.js +++ b/examples/libraries/entityCameraTool.js @@ -43,16 +43,6 @@ var easeOutCubic = function(t) { EASE_TIME = 0.5; -var ORIENTATION_OVERLAY_SIZE = 30; -var ORIENTATION_OVERLAY_HALF_SIZE = ORIENTATION_OVERLAY_SIZE / 2; -var orientationOverlayPosition = { - x: Window.innerWidth - 46, - y: 46, -}; -var orientationOverlay = OverlayGroup({ - position: orientationOverlayPosition, -}); - function mergeObjects(obj1, obj2) { var newObj = {}; for (key in obj1) { @@ -253,12 +243,12 @@ CameraManager = function() { } that.mousePressEvent = function(event) { - if (!that.enabled) return; - if (cameraTool.mousePressEvent(event)) { return true; } + if (!that.enabled) return; + if (event.isRightButton || (event.isLeftButton && event.isControl && !event.isShifted)) { that.mode = MODE_ORBIT; } else if (event.isMiddleButton || (event.isLeftButton && event.isControl && event.isShifted)) { @@ -299,16 +289,9 @@ CameraManager = function() { that.updateCamera(); } - that.updateOrientationOverlay = function() { - var flip = Quat.fromPitchYawRollDegrees(0, 180, 0); - orientationOverlay.setProperties({ - rotation: Quat.multiply(flip, Quat.inverse(Camera.orientation)), - }); - } - that.updateCamera = function() { if (!that.enabled || Camera.mode != "independent") { - that.updateOrientationOverlay(); + cameraTool.update(); return; } @@ -330,7 +313,7 @@ CameraManager = function() { Camera.setOrientation(q); - that.updateOrientationOverlay(); + cameraTool.update(); } function normalizeDegrees(degrees) { @@ -412,8 +395,68 @@ CameraTool = function(cameraManager) { var GREEN = { red: 26, green: 193, blue: 105 }; var BLUE = { red: 0, green: 131, blue: 204 }; + 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 = "https://s3.amazonaws.com/uploads.hipchat.com/33953/231344/FYPfAu0teMAYhMF/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 + }); + var defaultCubeProps = { - size: 8, + size: ORIENTATION_OVERLAY_CUBE_SIZE, alpha: 1, color: { red: 255, green: 0, blue: 0 }, solid: true, @@ -431,30 +474,11 @@ CameraTool = function(cameraManager) { drawOnApplicationOverlay: true, }; - var padding = 40; - var borderWidth = 4; - var backgroundBorder = Overlays.addOverlay("text", { - x: orientationOverlayPosition.x - (ORIENTATION_OVERLAY_HALF_SIZE + padding / 2 + borderWidth / 2), - y: orientationOverlayPosition.y - (ORIENTATION_OVERLAY_HALF_SIZE + padding / 2 + borderWidth / 2), - width: ORIENTATION_OVERLAY_SIZE + padding + borderWidth, - height: ORIENTATION_OVERLAY_SIZE + padding + borderWidth, - backgroundColor: { red: 192, green: 192, blue: 192 }, - text: "", - alpha: 1.0, - backgroundAlpha: 0.8, - visible: true - }); - - var background = Overlays.addOverlay("text", { - x: orientationOverlayPosition.x - (ORIENTATION_OVERLAY_HALF_SIZE + padding / 2), - y: orientationOverlayPosition.y - (ORIENTATION_OVERLAY_HALF_SIZE + padding / 2), - width: ORIENTATION_OVERLAY_SIZE + padding, - height: ORIENTATION_OVERLAY_SIZE + padding, - backgroundColor: { x: 0, y: 0, z: 0 }, - text: "", - alpha: 1.0, - backgroundAlpha: 0.9, - visible: 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; @@ -488,14 +512,37 @@ CameraTool = function(cameraManager) { Script.scriptEnding.connect(function() { orientationOverlay.destroy(); - Overlays.deleteOverlay(background); - Overlays.deleteOverlay(backgroundBorder); + 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) { var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); - print("Overlays: " + cubeX + ", " + cubeY); - print("Clicked: " + clickedOverlay); + if (clickedOverlay == cubeX) { targetPitch = 0; targetYaw = event.isLeftButton ? 90 : -90; @@ -511,9 +558,38 @@ CameraTool = function(cameraManager) { 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) { }; From f3a600da7e2ce55e7ea54c1739371c959334a2c5 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 19 Dec 2014 12:01:18 -0800 Subject: [PATCH 11/19] Remove glut call --- interface/src/ui/overlays/Cube3DOverlay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index b2c3d005c2..cba7719faa 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -91,7 +91,7 @@ void Cube3DOverlay::render(RenderArgs* args) { glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); glScalef(dimensions.x, dimensions.y, dimensions.z); if (_drawOnApplicationOverlay) { - glutSolidCube(1.0f); + DependencyManager::get()->renderSolidCube(1.0f); } else { DependencyManager::get()->renderSolidCube(1.0f); } From 588d7e62f4506410561e6b6799fad4ae0666cbda Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 19 Dec 2014 15:18:26 -0800 Subject: [PATCH 12/19] Update camera-controls.svg url --- examples/libraries/entityCameraTool.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/libraries/entityCameraTool.js b/examples/libraries/entityCameraTool.js index 4fdcbc0485..fd99741d67 100644 --- a/examples/libraries/entityCameraTool.js +++ b/examples/libraries/entityCameraTool.js @@ -404,7 +404,7 @@ CameraTool = function(cameraManager) { y: 30, } - var UI_URL = "https://s3.amazonaws.com/uploads.hipchat.com/33953/231344/FYPfAu0teMAYhMF/camera-controls.svg", + var UI_URL = HIFI_PUBLIC_BUCKET + "images/tools/camera-controls.svg"; var UI_WIDTH = 128; var UI_HEIGHT = 61; From 468c564566a7443faf3722ba4fb52b1e1541d9ec Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 19 Dec 2014 15:29:00 -0800 Subject: [PATCH 13/19] Replace glutSolidCube with GeometryCache::renderSolidCube --- interface/src/ui/overlays/Cube3DOverlay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index cba7719faa..5e7030a443 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -78,7 +78,7 @@ void Cube3DOverlay::render(RenderArgs* args) { glScalef(dimensions.x * _borderSize, dimensions.y * _borderSize, dimensions.z * _borderSize); if (_drawOnApplicationOverlay) { - glutSolidCube(1.0f); + DependencyManager::get()->renderSolidCube(1.0f); } else { DependencyManager::get()->renderSolidCube(1.0f); } From 2b835e621c183c65cda5a2d42dd20cff80d386bb Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 30 Dec 2014 14:50:17 -0800 Subject: [PATCH 14/19] Rename 2D -> HUD, 3D -> World in Overlays --- examples/libraries/entityCameraTool.js | 4 +- interface/src/Application.cpp | 8 +- interface/src/ui/ApplicationOverlay.cpp | 2 +- interface/src/ui/overlays/Base3DOverlay.cpp | 14 +-- interface/src/ui/overlays/Base3DOverlay.h | 6 +- interface/src/ui/overlays/Cube3DOverlay.cpp | 4 +- interface/src/ui/overlays/Overlays.cpp | 128 ++++++++++---------- interface/src/ui/overlays/Overlays.h | 8 +- 8 files changed, 86 insertions(+), 88 deletions(-) diff --git a/examples/libraries/entityCameraTool.js b/examples/libraries/entityCameraTool.js index fd99741d67..cd8aa3656b 100644 --- a/examples/libraries/entityCameraTool.js +++ b/examples/libraries/entityCameraTool.js @@ -461,7 +461,7 @@ CameraTool = function(cameraManager) { color: { red: 255, green: 0, blue: 0 }, solid: true, visible: true, - drawOnApplicationOverlay: true, + drawOnHUD: true, }; var defaultLineProps = { lineWidth: 1.5, @@ -471,7 +471,7 @@ CameraTool = function(cameraManager) { end: { x: 0, y: 0, z: 0 }, color: { red: 255, green: 0, blue: 0 }, visible: true, - drawOnApplicationOverlay: true, + drawOnHUD: true, }; var orientationOverlay = OverlayGroup({ diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8c482d26ce..19b20a3406 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 eb77069aa4..2b16c5da9c 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -195,7 +195,7 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) { // give external parties a change to hook in emit application->renderingOverlay(); - overlays.render2D(); + overlays.renderHUD(); renderPointers(); diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 4b0b8166ee..e02d292796 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -29,7 +29,7 @@ Base3DOverlay::Base3DOverlay() : _isDashedLine(DEFAULT_IS_DASHED_LINE), _ignoreRayIntersection(false), _drawInFront(false), - _drawOnApplicationOverlay(false) + _drawOnHUD(false) { } @@ -57,11 +57,11 @@ void Base3DOverlay::setProperties(const QScriptValue& properties) { setDrawInFront(value); } - QScriptValue drawOnApplicationOverlay = properties.property("drawOnApplicationOverlay"); + QScriptValue drawOnHUD = properties.property("drawOnHUD"); - if (drawOnApplicationOverlay.isValid()) { - bool value = drawOnApplicationOverlay.toVariant().toBool(); - setDrawOnApplicationOverlay(value); + if (drawOnHUD.isValid()) { + bool value = drawOnHUD.toVariant().toBool(); + setDrawOnHUD(value); } QScriptValue position = properties.property("position"); @@ -167,8 +167,8 @@ QScriptValue Base3DOverlay::getProperty(const QString& property) { if (property == "drawInFront") { return _drawInFront; } - if (property == "drawOnApplicationOverlay") { - return _drawOnApplicationOverlay; + 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 b3e3c3df8a..015b59d702 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -37,7 +37,7 @@ public: const glm::quat& getRotation() const { return _rotation; } bool getIgnoreRayIntersection() const { return _ignoreRayIntersection; } bool getDrawInFront() const { return _drawInFront; } - bool getDrawOnApplicationOverlay() const { return _drawOnApplicationOverlay; } + bool getDrawOnHUD() const { return _drawOnHUD; } // setters void setPosition(const glm::vec3& position) { _position = position; } @@ -47,7 +47,7 @@ public: void setRotation(const glm::quat& value) { _rotation = value; } void setIgnoreRayIntersection(bool value) { _ignoreRayIntersection = value; } void setDrawInFront(bool value) { _drawInFront = value; } - void setDrawOnApplicationOverlay(bool value) { _drawOnApplicationOverlay = value; } + void setDrawOnHUD(bool value) { _drawOnHUD = value; } virtual void setProperties(const QScriptValue& properties); virtual QScriptValue getProperty(const QString& property); @@ -69,7 +69,7 @@ protected: bool _isDashedLine; bool _ignoreRayIntersection; bool _drawInFront; - bool _drawOnApplicationOverlay; + bool _drawOnHUD; }; #endif // hifi_Base3DOverlay_h diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index 5e7030a443..2242a642ca 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -77,7 +77,7 @@ void Cube3DOverlay::render(RenderArgs* args) { glColor4f(1.0f, 1.0f, 1.0f, alpha); glScalef(dimensions.x * _borderSize, dimensions.y * _borderSize, dimensions.z * _borderSize); - if (_drawOnApplicationOverlay) { + if (_drawOnHUD) { DependencyManager::get()->renderSolidCube(1.0f); } else { DependencyManager::get()->renderSolidCube(1.0f); @@ -90,7 +90,7 @@ 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); - if (_drawOnApplicationOverlay) { + if (_drawOnHUD) { DependencyManager::get()->renderSolidCube(1.0f); } else { DependencyManager::get()->renderSolidCube(1.0f); diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 5871f408da..bc10651377 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,32 +82,32 @@ 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()) { + qDebug() << "Rendering 3d HUD!"; + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); - glEnable(GL_DEPTH_TEST); - glEnable(GL_LIGHTING); - foreach(Overlay* thisOverlay, _overlays3D) { - Base3DOverlay* overlay3D = static_cast(thisOverlay); - if (overlay3D->getDrawOnApplicationOverlay()) { + thisOverlay->render(&args); + + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + } else{ thisOverlay->render(&args); } } - glDisable(GL_LIGHTING); - glDisable(GL_DEPTH_TEST); } -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; @@ -123,9 +123,9 @@ 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 || overlay3D->getDrawOnApplicationOverlay()) { + if (overlay3D->getDrawInFront() != drawFront) { continue; } glPushMatrix(); @@ -204,9 +204,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; @@ -214,10 +219,10 @@ 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()); } @@ -225,10 +230,10 @@ unsigned int Overlays::cloneOverlay(unsigned int id) { 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]; + if (_overlaysHUD.contains(id)) { + thisOverlay = _overlaysHUD[id]; + } else if (_overlaysWorld.contains(id)) { + thisOverlay = _overlaysWorld[id]; } if (thisOverlay) { thisOverlay->setProperties(properties); @@ -242,10 +247,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; } @@ -262,7 +267,7 @@ unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) { } QReadLocker lock(&_lock); - QMapIterator i(_overlays3D); + QMapIterator i(_overlaysHUD); i.toBack(); const float LARGE_NEGATIVE_FLOAT = -9999999; @@ -274,26 +279,22 @@ unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) { while (i.hasPrevious()) { i.previous(); unsigned int thisID = i.key(); - Base3DOverlay* thisOverlay = static_cast(i.value()); - if (thisOverlay->getDrawOnApplicationOverlay() && !thisOverlay->getIgnoreRayIntersection()) { - if (thisOverlay->findRayIntersection(origin, direction, distance, thisFace)) { + if (i.value()->is3D()) { + Base3DOverlay* thisOverlay = static_cast(i.value()); + if (thisOverlay->getDrawOnHUD() && !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; } } } - i = QMapIterator(_overlays2D); - i.toBack(); - 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; - } - } - return 0; // not found } @@ -301,10 +302,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); @@ -346,15 +347,12 @@ 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(); unsigned int thisID = i.key(); Base3DOverlay* thisOverlay = static_cast(i.value()); - if (thisOverlay->getDrawOnApplicationOverlay()) { - continue; - } if (thisOverlay->getVisible() && !thisOverlay->getIgnoreRayIntersection() && thisOverlay->isLoaded()) { float thisDistance; BoxFace thisFace; @@ -457,10 +455,10 @@ void RayToOverlayIntersectionResultFromScriptValue(const QScriptValue& object, R 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 } @@ -468,13 +466,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..90b422ca05 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -52,9 +52,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 @@ -90,8 +90,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; From cf798e0a2fe5daae11009312ebc53e95fb89e4e9 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 30 Dec 2014 15:30:25 -0800 Subject: [PATCH 15/19] Fix orbit camera capturing mouse --- examples/editEntities.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/examples/editEntities.js b/examples/editEntities.js index c4c8ab9732..632fed088c 100644 --- a/examples/editEntities.js +++ b/examples/editEntities.js @@ -496,14 +496,12 @@ function mousePressEvent(event) { mouseHasMovedSincePress = false; mouseCapturedByTool = false; - if (toolBar.mousePressEvent(event) || cameraManager.mousePressEvent(event) - || progressDialog.mousePressEvent(event) || gridTool.mousePressEvent(event)) { - + if (toolBar.mousePressEvent(event) || progressDialog.mousePressEvent(event) || gridTool.mousePressEvent(event)) { mouseCapturedByTool = true; return; } if (isActive) { - if (selectionDisplay.mousePressEvent(event)) { + if (cameraManager.mousePressEvent(event) || selectionDisplay.mousePressEvent(event)) { // Event handled; do nothing. return; } From 929200bc76a59527d42e4ed72bbc427b416fb5f9 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 30 Dec 2014 15:30:53 -0800 Subject: [PATCH 16/19] Remove qDebug --- interface/src/ui/overlays/Overlays.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index bc10651377..0c34aa0aba 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -91,7 +91,6 @@ void Overlays::renderHUD() { foreach(Overlay* thisOverlay, _overlaysHUD) { if (thisOverlay->is3D()) { - qDebug() << "Rendering 3d HUD!"; glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); From 3bfc298349f19c74d53d645c21828222edffcecc Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 30 Dec 2014 15:31:08 -0800 Subject: [PATCH 17/19] Remove extraneous getDrawonHUD call --- interface/src/ui/overlays/Overlays.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 0c34aa0aba..c1c25b576e 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -280,7 +280,7 @@ unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) { unsigned int thisID = i.key(); if (i.value()->is3D()) { Base3DOverlay* thisOverlay = static_cast(i.value()); - if (thisOverlay->getDrawOnHUD() && !thisOverlay->getIgnoreRayIntersection()) { + if (!thisOverlay->getIgnoreRayIntersection()) { if (thisOverlay->findRayIntersection(origin, direction, distance, thisFace)) { return thisID; } From 5caec4dea5ff144e3c3e35377707f7e9b5785658 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 31 Dec 2014 10:15:15 -0800 Subject: [PATCH 18/19] Update overlays to handle updates in drawOnHUD after creation --- interface/src/ui/overlays/Base3DOverlay.cpp | 8 ++++++ interface/src/ui/overlays/Base3DOverlay.h | 2 +- interface/src/ui/overlays/Overlays.cpp | 32 +++++++++++++++++---- interface/src/ui/overlays/Overlays.h | 4 +++ 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index e02d292796..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); @@ -47,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); diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index 015b59d702..0e10a5f63b 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -47,7 +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) { _drawOnHUD = value; } + void setDrawOnHUD(bool value); virtual void setProperties(const QScriptValue& properties); virtual QScriptValue getProperty(const QString& property); diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index c1c25b576e..8d33a06602 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -228,11 +228,13 @@ unsigned int Overlays::cloneOverlay(unsigned int id) { bool Overlays::editOverlay(unsigned int id, const QScriptValue& properties) { Overlay* thisOverlay = NULL; - QWriteLocker lock(&_lock); - if (_overlaysHUD.contains(id)) { - thisOverlay = _overlaysHUD[id]; - } else if (_overlaysWorld.contains(id)) { - thisOverlay = _overlaysWorld[id]; + { + QReadLocker lock(&_lock); + if (_overlaysHUD.contains(id)) { + thisOverlay = _overlaysHUD[id]; + } else if (_overlaysWorld.contains(id)) { + thisOverlay = _overlaysWorld[id]; + } } if (thisOverlay) { thisOverlay->setProperties(properties); @@ -451,6 +453,26 @@ void RayToOverlayIntersectionResultFromScriptValue(const QScriptValue& object, R value.extraInfo = object.property("extraInfo").toVariant().toString(); } +void Overlays::overlayDrawOnChanged(Base3DOverlay* overlay) { + if (overlay->getDrawOnHUD()) { + for (unsigned int id : _overlaysWorld.keys()) { + if (_overlaysWorld[id] == overlay) { + QWriteLocker lock(&_lock); + _overlaysWorld.remove(id); + _overlaysHUD[id] = overlay; + } + } + } else { + for (unsigned int id : _overlaysHUD.keys()) { + if (_overlaysHUD[id] == overlay) { + QWriteLocker lock(&_lock); + _overlaysHUD.remove(id); + _overlaysWorld[id] = overlay; + } + } + } +} + bool Overlays::isLoaded(unsigned int id) { QReadLocker lock(&_lock); Overlay* thisOverlay = NULL; diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 90b422ca05..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 { @@ -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); From 7478b631da0e27174dcb0d2d8717fa98f0bbc889 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 31 Dec 2014 10:16:29 -0800 Subject: [PATCH 19/19] Move write lock in Overlays::overlayDrawOnChanged to encompass reads --- interface/src/ui/overlays/Overlays.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 8d33a06602..1dbe9af930 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -454,10 +454,10 @@ void RayToOverlayIntersectionResultFromScriptValue(const QScriptValue& object, R } void Overlays::overlayDrawOnChanged(Base3DOverlay* overlay) { + QWriteLocker lock(&_lock); if (overlay->getDrawOnHUD()) { for (unsigned int id : _overlaysWorld.keys()) { if (_overlaysWorld[id] == overlay) { - QWriteLocker lock(&_lock); _overlaysWorld.remove(id); _overlaysHUD[id] = overlay; } @@ -465,7 +465,6 @@ void Overlays::overlayDrawOnChanged(Base3DOverlay* overlay) { } else { for (unsigned int id : _overlaysHUD.keys()) { if (_overlaysHUD[id] == overlay) { - QWriteLocker lock(&_lock); _overlaysHUD.remove(id); _overlaysWorld[id] = overlay; }