From f014025b81209beff0603c0e0e6dad0c2e70a99b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 22 Nov 2014 14:28:06 -0800 Subject: [PATCH 1/7] first cut at lobby tweaks --- examples/lobby.js | 68 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 3 deletions(-) diff --git a/examples/lobby.js b/examples/lobby.js index 58dba7c5b4..c255836d37 100644 --- a/examples/lobby.js +++ b/examples/lobby.js @@ -14,7 +14,9 @@ Script.include("libraries/globals.js"); var panelWall = false; var orbShell = false; var reticle = false; - +var descriptionText = false; +var lastMouseMove = 0; +var IDLE_HOVER_TIME = 2000; // if you haven't moved the mouse in 2 seconds, and in HMD mode, then we use reticle for hover var avatarStickPosition = {}; var orbNaturalExtentsMin = { x: -1.230354, y: -1.22077, z: -1.210487 }; @@ -80,11 +82,32 @@ function drawLobby() { dimensions: orbDimensions, ignoreRayIntersection: true }; + + var windowDimensions = Controller.getViewportDimensions(); + var textWidth = 400; + var textHeight = 100; + var textBottomMargin = 20; + var textFontHeight = 20; + + var descriptionTextProps = { + x: (windowDimensions.x - textWidth) / 2, + y: windowDimensions.y - textHeight - textBottomMargin, + width: textWidth, + height: textHeight, + backgroundColor: { red: 100, green: 100, blue: 100}, + color: { red: 255, green: 255, blue: 255}, + topMargin: 4, + leftMargin: 4, + text: "", + font: { size: textFontHeight }, + alpha: 0.9 + }; avatarStickPosition = MyAvatar.position; panelWall = Overlays.addOverlay("model", panelWallProps); orbShell = Overlays.addOverlay("model", orbShellProps); + descriptionText = Overlays.addOverlay("text", descriptionTextProps); inOculusMode = Menu.isOptionChecked("Enable VR Mode"); @@ -186,6 +209,8 @@ function cleanupLobby() { Overlays.deleteOverlay(panelWall); Overlays.deleteOverlay(orbShell); + Overlays.deleteOverlay(descriptionText); + if (reticle) { Overlays.deleteOverlay(reticle); @@ -209,7 +234,6 @@ function cleanupLobby() { function actionStartEvent(event) { if (panelWall) { - // we've got an action event and our panel wall is up // check if we hit a panel and if we should jump there var result = Overlays.findRayIntersection(event.actionRay); @@ -259,6 +283,27 @@ function toggleEnvironmentRendering(shouldRender) { Menu.setIsOptionChecked("Avatars", shouldRender); } +function handleLookAt(pickRay) { + if (panelWall && descriptionText) { + // we've got an action event and our panel wall is up + // check if we hit a panel and if we should jump there + var result = Overlays.findRayIntersection(pickRay); + if (result.intersects && result.overlayID == panelWall) { + var panelName = result.extraInfo; + var panelStringIndex = panelName.indexOf("Panel"); + if (panelStringIndex != -1) { + var panelIndex = parseInt(panelName.slice(5)) - 1; + if (panelIndex < locations.length) { + var actionLocation = locations[panelIndex]; + + Overlays.editOverlay(descriptionText, { text: actionLocation.description }); + + } + } + } + } +} + function update(deltaTime) { maybeCleanupLobby(); if (panelWall) { @@ -267,8 +312,17 @@ function update(deltaTime) { Overlays.editOverlay(reticle, { position: reticlePosition() }); + + var nowDate = new Date(); + var now = nowDate.getTime(); + if (now - lastMouseMove > IDLE_HOVER_TIME) { + var windowDimensions = Controller.getViewportDimensions(); + var pickRay = Camera.computePickRay(windowDimensions.x / 2, windowDimensions.y / 2); + handleLookAt(pickRay); + } + } - + // if the reticle is up then we may need to play the next muzak if (!Audio.isInjectorPlaying(currentMuzakInjector)) { playNextMuzak(); @@ -276,6 +330,14 @@ function update(deltaTime) { } } +function mouseMoveEvent(event) { + var nowDate = new Date(); + lastMouseMove = nowDate.getTime(); + var pickRay = Camera.computePickRay(event.x, event.y); + handleLookAt(pickRay); +} + +Controller.mouseMoveEvent.connect(mouseMoveEvent); Controller.actionStartEvent.connect(actionStartEvent); Controller.backStartEvent.connect(backStartEvent); Script.update.connect(update); From 310e31377dc06cda504f14b344b209d72c7f6112 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 22 Nov 2014 14:49:56 -0800 Subject: [PATCH 2/7] handle line wrapping in description --- examples/lobby.js | 44 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/examples/lobby.js b/examples/lobby.js index c255836d37..8c1b8de708 100644 --- a/examples/lobby.js +++ b/examples/lobby.js @@ -15,6 +15,13 @@ var panelWall = false; var orbShell = false; var reticle = false; var descriptionText = false; + +// used for formating the description text +var textWidth = 400; +var textHeight = 100; +var textBottomMargin = 20; +var textFontHeight = 20; + var lastMouseMove = 0; var IDLE_HOVER_TIME = 2000; // if you haven't moved the mouse in 2 seconds, and in HMD mode, then we use reticle for hover var avatarStickPosition = {}; @@ -84,10 +91,6 @@ function drawLobby() { }; var windowDimensions = Controller.getViewportDimensions(); - var textWidth = 400; - var textHeight = 100; - var textBottomMargin = 20; - var textFontHeight = 20; var descriptionTextProps = { x: (windowDimensions.x - textWidth) / 2, @@ -295,9 +298,38 @@ function handleLookAt(pickRay) { var panelIndex = parseInt(panelName.slice(5)) - 1; if (panelIndex < locations.length) { var actionLocation = locations[panelIndex]; - - Overlays.editOverlay(descriptionText, { text: actionLocation.description }); + // handle line wrapping + var allWords = actionLocation.description.split(" "); + var currentGoodLine = ""; + var currentTestLine = ""; + var formatedDescription = ""; + var wordsFormated = 0; + var currentTestWord = 0; + var wordsOnLine = 0; + while (wordsFormated < allWords.length) { + // first add the "next word" to the line and test it. + currentTestLine = currentGoodLine; + if (wordsOnLine > 0) { + currentTestLine += " " + allWords[currentTestWord]; + } else { + currentTestLine = allWords[currentTestWord]; + } + var lineLength = Overlays.textWidth(descriptionText, currentTestLine); + if (lineLength < textWidth || wordsOnLine == 0) { + wordsFormated++; + currentTestWord++; + wordsOnLine++; + currentGoodLine = currentTestLine; + } else { + formatedDescription += currentGoodLine + "\n"; + wordsOnLine = 0; + currentGoodLine = ""; + currentTestLine = ""; + } + } + formatedDescription += currentGoodLine; + Overlays.editOverlay(descriptionText, { text: formatedDescription }); } } } From efe202b7e82b018b2885c14d6f348fe8a05633ba Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 22 Nov 2014 21:25:43 -0800 Subject: [PATCH 3/7] make a version of computePick that works off of view frustum even when in HMD mode, updates to lobby --- examples/lobby.js | 21 ++++++++++++--------- interface/src/Camera.cpp | 6 ++++++ interface/src/Camera.h | 1 + 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/examples/lobby.js b/examples/lobby.js index 8c1b8de708..79c79c7199 100644 --- a/examples/lobby.js +++ b/examples/lobby.js @@ -329,7 +329,9 @@ function handleLookAt(pickRay) { } } formatedDescription += currentGoodLine; - Overlays.editOverlay(descriptionText, { text: formatedDescription }); + Overlays.editOverlay(descriptionText, { text: formatedDescription, visible: true }); + } else { + Overlays.editOverlay(descriptionText, { text: "", visible: false }); } } } @@ -348,8 +350,7 @@ function update(deltaTime) { var nowDate = new Date(); var now = nowDate.getTime(); if (now - lastMouseMove > IDLE_HOVER_TIME) { - var windowDimensions = Controller.getViewportDimensions(); - var pickRay = Camera.computePickRay(windowDimensions.x / 2, windowDimensions.y / 2); + var pickRay = Camera.computeViewPickRay(0.5, 0.5); handleLookAt(pickRay); } @@ -363,14 +364,16 @@ function update(deltaTime) { } function mouseMoveEvent(event) { - var nowDate = new Date(); - lastMouseMove = nowDate.getTime(); - var pickRay = Camera.computePickRay(event.x, event.y); - handleLookAt(pickRay); + if (panelWall) { + var nowDate = new Date(); + lastMouseMove = nowDate.getTime(); + var pickRay = Camera.computePickRay(event.x, event.y); + handleLookAt(pickRay); + } } -Controller.mouseMoveEvent.connect(mouseMoveEvent); Controller.actionStartEvent.connect(actionStartEvent); Controller.backStartEvent.connect(backStartEvent); Script.update.connect(update); -Script.scriptEnding.connect(maybeCleanupLobby); \ No newline at end of file +Script.scriptEnding.connect(maybeCleanupLobby); +Controller.mouseMoveEvent.connect(mouseMoveEvent); diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 121833bd16..6e5a83790e 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -108,6 +108,12 @@ PickRay Camera::computePickRay(float x, float y) { return result; } +PickRay Camera::computeViewPickRay(float xRatio, float yRatio) { + PickRay result; + Application::getInstance()->getViewFrustum()->computePickRay(xRatio, yRatio, result.origin, result.direction); + return result; +} + void Camera::setModeString(const QString& mode) { CameraMode targetMode = stringToMode(mode); diff --git a/interface/src/Camera.h b/interface/src/Camera.h index 06db3dc3ef..7fcf9404cd 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -79,6 +79,7 @@ public slots: glm::quat getOrientation() const { return getRotation(); } PickRay computePickRay(float x, float y); + PickRay computeViewPickRay(float xRatio, float yRatio); signals: void modeUpdated(const QString& newMode); From 53bd8fd6d2bf770e390000dfa42fff3ea8fd8820 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 22 Nov 2014 21:30:58 -0800 Subject: [PATCH 4/7] handle no description and blank panels better --- examples/lobby.js | 67 +++++++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/examples/lobby.js b/examples/lobby.js index 79c79c7199..508889d1b0 100644 --- a/examples/lobby.js +++ b/examples/lobby.js @@ -103,7 +103,8 @@ function drawLobby() { leftMargin: 4, text: "", font: { size: textFontHeight }, - alpha: 0.9 + alpha: 0.9, + visible: false // starts out hidden }; avatarStickPosition = MyAvatar.position; @@ -299,37 +300,41 @@ function handleLookAt(pickRay) { if (panelIndex < locations.length) { var actionLocation = locations[panelIndex]; - // handle line wrapping - var allWords = actionLocation.description.split(" "); - var currentGoodLine = ""; - var currentTestLine = ""; - var formatedDescription = ""; - var wordsFormated = 0; - var currentTestWord = 0; - var wordsOnLine = 0; - while (wordsFormated < allWords.length) { - // first add the "next word" to the line and test it. - currentTestLine = currentGoodLine; - if (wordsOnLine > 0) { - currentTestLine += " " + allWords[currentTestWord]; - } else { - currentTestLine = allWords[currentTestWord]; + if (actionLocation.description == "") { + Overlays.editOverlay(descriptionText, { text: actionLocation.name, visible: true }); + } else { + // handle line wrapping + var allWords = actionLocation.description.split(" "); + var currentGoodLine = ""; + var currentTestLine = ""; + var formatedDescription = ""; + var wordsFormated = 0; + var currentTestWord = 0; + var wordsOnLine = 0; + while (wordsFormated < allWords.length) { + // first add the "next word" to the line and test it. + currentTestLine = currentGoodLine; + if (wordsOnLine > 0) { + currentTestLine += " " + allWords[currentTestWord]; + } else { + currentTestLine = allWords[currentTestWord]; + } + var lineLength = Overlays.textWidth(descriptionText, currentTestLine); + if (lineLength < textWidth || wordsOnLine == 0) { + wordsFormated++; + currentTestWord++; + wordsOnLine++; + currentGoodLine = currentTestLine; + } else { + formatedDescription += currentGoodLine + "\n"; + wordsOnLine = 0; + currentGoodLine = ""; + currentTestLine = ""; + } + } + formatedDescription += currentGoodLine; + Overlays.editOverlay(descriptionText, { text: formatedDescription, visible: true }); } - var lineLength = Overlays.textWidth(descriptionText, currentTestLine); - if (lineLength < textWidth || wordsOnLine == 0) { - wordsFormated++; - currentTestWord++; - wordsOnLine++; - currentGoodLine = currentTestLine; - } else { - formatedDescription += currentGoodLine + "\n"; - wordsOnLine = 0; - currentGoodLine = ""; - currentTestLine = ""; - } - } - formatedDescription += currentGoodLine; - Overlays.editOverlay(descriptionText, { text: formatedDescription, visible: true }); } else { Overlays.editOverlay(descriptionText, { text: "", visible: false }); } From 5ea6973fe73940de02025e601fd8f94c543dd1bc Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sun, 23 Nov 2014 10:53:03 -0800 Subject: [PATCH 5/7] fix isFacingAvatar for 3d text overlays --- interface/src/ui/overlays/Text3DOverlay.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index 88ac009ac7..dbb423ad99 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -75,13 +75,14 @@ void Text3DOverlay::render(RenderArgs* args) { glPushMatrix(); { glTranslatef(_position.x, _position.y, _position.z); glm::quat rotation; + if (_isFacingAvatar) { // rotate about vertical to face the camera rotation = Application::getInstance()->getCamera()->getRotation(); - rotation *= glm::angleAxis(glm::pi(), glm::vec3(0.0f, 1.0f, 0.0f)); } else { rotation = getRotation(); } + glm::vec3 axis = glm::axis(rotation); glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); From 437af0624543ed3b7950a9a2555f624082c5cd9d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sun, 23 Nov 2014 11:16:33 -0800 Subject: [PATCH 6/7] switch to 3d text for description --- examples/lobby.js | 46 +++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/examples/lobby.js b/examples/lobby.js index 508889d1b0..3f13f01e7f 100644 --- a/examples/lobby.js +++ b/examples/lobby.js @@ -16,11 +16,12 @@ var orbShell = false; var reticle = false; var descriptionText = false; -// used for formating the description text -var textWidth = 400; -var textHeight = 100; -var textBottomMargin = 20; -var textFontHeight = 20; +// used for formating the description text, in meters +var textWidth = 4; +var textHeight = 1; +var numberOfLines = 4; +var textMargin = 0.0625; +var lineHeight = (textHeight - (2 * textMargin)) / numberOfLines; var lastMouseMove = 0; var IDLE_HOVER_TIME = 2000; // if you haven't moved the mouse in 2 seconds, and in HMD mode, then we use reticle for hover @@ -63,6 +64,14 @@ function reticlePosition() { return Vec3.sum(Camera.position, Vec3.multiply(Quat.getFront(Camera.orientation), RETICLE_DISTANCE)); } +function textOverlayPosition() { + var TEXT_DISTANCE_OUT = 5; + var TEXT_DISTANCE_DOWN = -1; + return Vec3.sum(Vec3.sum(Camera.position, Vec3.multiply(Quat.getFront(Camera.orientation), TEXT_DISTANCE_OUT)), + Vec3.multiply(Quat.getUp(Camera.orientation), TEXT_DISTANCE_DOWN)); +} + + var MAX_NUM_PANELS = 21; var DRONE_VOLUME = 0.3; @@ -91,27 +100,29 @@ function drawLobby() { }; var windowDimensions = Controller.getViewportDimensions(); - + var descriptionTextProps = { - x: (windowDimensions.x - textWidth) / 2, - y: windowDimensions.y - textHeight - textBottomMargin, - width: textWidth, - height: textHeight, - backgroundColor: { red: 100, green: 100, blue: 100}, + position: textOverlayPosition(), + dimensions: { x: textWidth, y: textHeight }, + backgroundColor: { red: 0, green: 0, blue: 0}, color: { red: 255, green: 255, blue: 255}, - topMargin: 4, - leftMargin: 4, + topMargin: textMargin, + leftMargin: textMargin, + bottomMargin: textMargin, + rightMargin: textMargin, text: "", - font: { size: textFontHeight }, + lineHeight: lineHeight, alpha: 0.9, - visible: false // starts out hidden + ignoreRayIntersection: true, + visible: false, + isFacingAvatar: true }; avatarStickPosition = MyAvatar.position; panelWall = Overlays.addOverlay("model", panelWallProps); orbShell = Overlays.addOverlay("model", orbShellProps); - descriptionText = Overlays.addOverlay("text", descriptionTextProps); + descriptionText = Overlays.addOverlay("text3d", descriptionTextProps); inOculusMode = Menu.isOptionChecked("Enable VR Mode"); @@ -358,9 +369,10 @@ function update(deltaTime) { var pickRay = Camera.computeViewPickRay(0.5, 0.5); handleLookAt(pickRay); } - } + Overlays.editOverlay(descriptionText, { position: textOverlayPosition() }); + // if the reticle is up then we may need to play the next muzak if (!Audio.isInjectorPlaying(currentMuzakInjector)) { playNextMuzak(); From f23d8f6c2005b5a30b2d09f6f18dd9fbad6437d8 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sun, 23 Nov 2014 11:21:05 -0800 Subject: [PATCH 7/7] text sizing tweaks --- examples/lobby.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/lobby.js b/examples/lobby.js index 3f13f01e7f..9e454eccc9 100644 --- a/examples/lobby.js +++ b/examples/lobby.js @@ -18,8 +18,8 @@ var descriptionText = false; // used for formating the description text, in meters var textWidth = 4; -var textHeight = 1; -var numberOfLines = 4; +var textHeight = .5; +var numberOfLines = 2; var textMargin = 0.0625; var lineHeight = (textHeight - (2 * textMargin)) / numberOfLines; @@ -65,8 +65,8 @@ function reticlePosition() { } function textOverlayPosition() { - var TEXT_DISTANCE_OUT = 5; - var TEXT_DISTANCE_DOWN = -1; + var TEXT_DISTANCE_OUT = 6; + var TEXT_DISTANCE_DOWN = -2; return Vec3.sum(Vec3.sum(Camera.position, Vec3.multiply(Quat.getFront(Camera.orientation), TEXT_DISTANCE_OUT)), Vec3.multiply(Quat.getUp(Camera.orientation), TEXT_DISTANCE_DOWN)); }