From e883d1dbb7447d67250daffa4b4d3c76d7de9aac Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 17 Dec 2014 21:21:51 +0100 Subject: [PATCH 001/103] 3d mode --- examples/virtualKeyboard.js | 65 +++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 17 deletions(-) diff --git a/examples/virtualKeyboard.js b/examples/virtualKeyboard.js index ce793c6ea0..a788ccd76c 100644 --- a/examples/virtualKeyboard.js +++ b/examples/virtualKeyboard.js @@ -17,6 +17,9 @@ Script.include("libraries/globals.js"); +// experimental 3dmode +const THREE_D_MODE = true; + const KBD_UPPERCASE_DEFAULT = 0; const KBD_LOWERCASE_DEFAULT = 1; const KBD_UPPERCASE_HOVER = 2; @@ -272,14 +275,28 @@ function KeyboardKey(keyboard, keyProperties) { }; for (var i = 0; i < this.bounds.length; i++) { var newOverlay = Overlays.cloneOverlay(this.keyboard.background); - Overlays.editOverlay(newOverlay, { - x: this.keyboard.getX() + this.bounds[i][BOUND_X] * keyboard.scale, - y: this.keyboard.getY() + this.bounds[i][BOUND_Y] * keyboard.scale, - width: this.bounds[i][BOUND_W] * keyboard.scale, - height: this.bounds[i][BOUND_H] * keyboard.scale, - subImage: {width: this.bounds[i][BOUND_W], height: this.bounds[i][BOUND_H], x: this.bounds[i][BOUND_X], y: (KEYBOARD_HEIGHT * this.keyState) + this.bounds[i][BOUND_Y]}, - alpha: 1 - }); + if (THREE_D_MODE) { + Overlays.editOverlay(newOverlay, { + position: { + x: MyAvatar.position.x,// + this.bounds[i][BOUND_X] * 0.01,// /*+ this.keyboard.getX()*/ + this.bounds[i][BOUND_X] * keyboard.scale, + y: MyAvatar.position.y,// - this.bounds[i][BOUND_Y] * 0.01,// /*+ this.keyboard.getY()*/ + this.bounds[i][BOUND_Y] * keyboard.scale, + z: MyAvatar.position.z + }, + width: this.bounds[i][BOUND_W] * keyboard.scale, + height: this.bounds[i][BOUND_H] * keyboard.scale, + subImage: {width: this.bounds[i][BOUND_W], height: this.bounds[i][BOUND_H], x: this.bounds[i][BOUND_X], y: (KEYBOARD_HEIGHT * this.keyState) + this.bounds[i][BOUND_Y]}, + alpha: 1 + }); + } else { + Overlays.editOverlay(newOverlay, { + x: this.keyboard.getX() + this.bounds[i][BOUND_X] * keyboard.scale, + y: this.keyboard.getY() + this.bounds[i][BOUND_Y] * keyboard.scale, + width: this.bounds[i][BOUND_W] * keyboard.scale, + height: this.bounds[i][BOUND_H] * keyboard.scale, + subImage: {width: this.bounds[i][BOUND_W], height: this.bounds[i][BOUND_H], x: this.bounds[i][BOUND_X], y: (KEYBOARD_HEIGHT * this.keyState) + this.bounds[i][BOUND_Y]}, + alpha: 1 + }); + } this.overlays.push(newOverlay); } } @@ -301,15 +318,29 @@ function Keyboard() { this.getY = function() { return windowDimensions.y - this.height(); }; - this.background = Overlays.addOverlay("image", { - x: this.getX(), - y: this.getY(), - width: this.width(), - height: this.height(), - subImage: {width: KEYBOARD_WIDTH, height: KEYBOARD_HEIGHT, y: KEYBOARD_HEIGHT * KBD_BACKGROUND}, - imageURL: KEYBOARD_URL, - alpha: 1 - }); + if (THREE_D_MODE) { + this.background = Overlays.addOverlay("billboard", { + scale: 1, + position: MyAvatar.position, + rotation: MyAvatar.rotation, + width: this.width(), + height: this.height(), + subImage: {width: KEYBOARD_WIDTH, height: KEYBOARD_HEIGHT, y: KEYBOARD_HEIGHT * KBD_BACKGROUND}, + isFacingAvatar: false, + url: KEYBOARD_URL, + alpha: 1 + }); + } else { + this.background = Overlays.addOverlay("image", { + x: this.getX(), + y: this.getY(), + width: this.width(), + height: this.height(), + subImage: {width: KEYBOARD_WIDTH, height: KEYBOARD_HEIGHT, y: KEYBOARD_HEIGHT * KBD_BACKGROUND}, + imageURL: KEYBOARD_URL, + alpha: 1 + }); + } this.rescale = function() { this.scale = windowDimensions.x / KEYBOARD_WIDTH; Overlays.editOverlay(tthis.background, { From e38aa89418bde960d4132a269e6db27ae66a91de Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Mon, 29 Dec 2014 21:11:34 +0100 Subject: [PATCH 002/103] Overwrite keypress of Enter key --- examples/virtualKeyboard.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/virtualKeyboard.js b/examples/virtualKeyboard.js index ce793c6ea0..aede5c69d5 100644 --- a/examples/virtualKeyboard.js +++ b/examples/virtualKeyboard.js @@ -26,6 +26,8 @@ const KBD_BACKGROUND = 4; const KEYBOARD_URL = HIFI_PUBLIC_BUCKET + "images/keyboard.svg"; const CURSOR_URL = HIFI_PUBLIC_BUCKET + "images/cursor.svg"; +const RETURN_CHARCODE = 0x01000004; +const ENTER_CHARCODE = 0x01000005; const SPACEBAR_CHARCODE = 32; const KEYBOARD_WIDTH = 1174.7; @@ -576,7 +578,10 @@ function Cursor() { function keyPressEvent(event) { if (event.key === SPACEBAR_CHARCODE) { keyboard.pressFocussedKey(); + } else if (event.key === ENTER_CHARCODE || event.key === RETURN_CHARCODE) { + print("Enter pressed"); } + } function keyReleaseEvent(event) { @@ -591,7 +596,11 @@ function scriptEnding() { Overlays.deleteOverlay(text); Overlays.deleteOverlay(textSizeMeasureOverlay); Controller.releaseKeyEvents({key: SPACEBAR_CHARCODE}); + Controller.releaseKeyEvents({key: RETURN_CHARCODE}); + Controller.releaseKeyEvents({key: ENTER_CHARCODE}); } +Controller.captureKeyEvents({key: RETURN_CHARCODE}); +Controller.captureKeyEvents({key: ENTER_CHARCODE}); Controller.captureKeyEvents({key: SPACEBAR_CHARCODE}); Controller.keyPressEvent.connect(keyPressEvent); Controller.keyReleaseEvent.connect(keyReleaseEvent); From d299f3f0c5e0bb3acf07e6218b6025a264b0ba66 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Mon, 29 Dec 2014 23:10:15 +0100 Subject: [PATCH 003/103] no 3d mode for now --- examples/virtualKeyboard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/virtualKeyboard.js b/examples/virtualKeyboard.js index a580bc7bcc..24b6cd39a1 100644 --- a/examples/virtualKeyboard.js +++ b/examples/virtualKeyboard.js @@ -18,7 +18,7 @@ Script.include("libraries/globals.js"); // experimental 3dmode -const THREE_D_MODE = true; +const THREE_D_MODE = false; const KBD_UPPERCASE_DEFAULT = 0; const KBD_LOWERCASE_DEFAULT = 1; From 4eec066d691f83baccc59ef1291c7cabb4663b6a Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Tue, 30 Dec 2014 19:51:53 +0100 Subject: [PATCH 004/103] split up virtualKeyboard script in a library and two script that will use it: virtualKeyboardLocation.js - Location through virtual keyboard virtualKeyboardTextEntityExample.js - Initial example for virtual keyboard --- examples/{ => libraries}/virtualKeyboard.js | 202 +++---------------- examples/virtualKeyboardLocation.js | 185 +++++++++++++++++ examples/virtualKeyboardTextEntityExample.js | 177 ++++++++++++++++ 3 files changed, 385 insertions(+), 179 deletions(-) rename examples/{ => libraries}/virtualKeyboard.js (75%) create mode 100644 examples/virtualKeyboardLocation.js create mode 100644 examples/virtualKeyboardTextEntityExample.js diff --git a/examples/virtualKeyboard.js b/examples/libraries/virtualKeyboard.js similarity index 75% rename from examples/virtualKeyboard.js rename to examples/libraries/virtualKeyboard.js index 24b6cd39a1..ba9a30974e 100644 --- a/examples/virtualKeyboard.js +++ b/examples/libraries/virtualKeyboard.js @@ -9,8 +9,6 @@ // Usage: Enable VR-mode and go to First person mode, // look at the key that you would like to press, and press the spacebar on your "REAL" keyboard. // -// leased some code from newEditEntities.js for Text Entity example -// // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // @@ -18,26 +16,26 @@ Script.include("libraries/globals.js"); // experimental 3dmode -const THREE_D_MODE = false; +THREE_D_MODE = false; -const KBD_UPPERCASE_DEFAULT = 0; -const KBD_LOWERCASE_DEFAULT = 1; -const KBD_UPPERCASE_HOVER = 2; -const KBD_LOWERCASE_HOVER = 3; -const KBD_BACKGROUND = 4; +KBD_UPPERCASE_DEFAULT = 0; +KBD_LOWERCASE_DEFAULT = 1; +KBD_UPPERCASE_HOVER = 2; +KBD_LOWERCASE_HOVER = 3; +KBD_BACKGROUND = 4; -const KEYBOARD_URL = HIFI_PUBLIC_BUCKET + "images/keyboard.svg"; -const CURSOR_URL = HIFI_PUBLIC_BUCKET + "images/cursor.svg"; +KEYBOARD_URL = HIFI_PUBLIC_BUCKET + "images/keyboard.svg"; +CURSOR_URL = HIFI_PUBLIC_BUCKET + "images/cursor.svg"; -const RETURN_CHARCODE = 0x01000004; -const ENTER_CHARCODE = 0x01000005; -const SPACEBAR_CHARCODE = 32; +RETURN_CHARCODE = 0x01000004; +ENTER_CHARCODE = 0x01000005; +SPACEBAR_CHARCODE = 32; -const KEYBOARD_WIDTH = 1174.7; -const KEYBOARD_HEIGHT = 434.1; +KEYBOARD_WIDTH = 1174.7; +KEYBOARD_HEIGHT = 434.1; -const CURSOR_WIDTH = 33.9; -const CURSOR_HEIGHT = 33.9; +CURSOR_WIDTH = 33.9; +CURSOR_HEIGHT = 33.9; // VIEW_ANGLE can be adjusted to your likings, the smaller the faster movement. // Try setting it to 60 if it goes too fast for you. @@ -52,8 +50,8 @@ const BOUND_Y = 1; const BOUND_W = 2; const BOUND_H = 3; -const KEY_STATE_LOWER = 0; -const KEY_STATE_UPPER = 1; +KEY_STATE_LOWER = 0; +KEY_STATE_UPPER = 1; const TEXT_MARGIN_TOP = 0.15; const TEXT_MARGIN_LEFT = 0.15; @@ -62,131 +60,8 @@ const TEXT_MARGIN_BOTTOM = 0.17; var windowDimensions = Controller.getViewportDimensions(); var cursor = null; -var keyboard = new Keyboard(); -var textFontSize = 9; -var text = null; -var textText = ""; -var textSizeMeasureOverlay = Overlays.addOverlay("text3d", {visible: false}); -function appendChar(char) { - textText += char; - updateTextOverlay(); - Overlays.editOverlay(text, {text: textText}); -} - -function deleteChar() { - if (textText.length > 0) { - textText = textText.substring(0, textText.length - 1); - updateTextOverlay(); - } -} - -function updateTextOverlay() { - var textLines = textText.split("\n"); - var maxLineWidth = 0; - for (textLine in textLines) { - var lineWidth = Overlays.textSize(text, textLines[textLine]).width; - if (lineWidth > maxLineWidth) { - maxLineWidth = lineWidth; - } - } - var suggestedFontSize = (windowDimensions.x / maxLineWidth) * textFontSize * 0.90; - var maxFontSize = 190 / textLines.length; - textFontSize = (suggestedFontSize > maxFontSize) ? maxFontSize : suggestedFontSize; - var topMargin = (250 - (textFontSize * textLines.length)) / 4; - Overlays.editOverlay(text, {text: textText, font: {size: textFontSize}, topMargin: topMargin}); - var maxLineWidth = 0; - for (textLine in textLines) { - var lineWidth = Overlays.textSize(text, textLines[textLine]).width; - if (lineWidth > maxLineWidth) { - maxLineWidth = lineWidth; - } - } - Overlays.editOverlay(text, {leftMargin: (windowDimensions.x - maxLineWidth) / 2}); -} - -keyboard.onKeyPress = function(event) { - if (event.event == 'keypress') { - appendChar(event.char); - } else if (event.event == 'enter') { - appendChar("\n"); - } -}; - -keyboard.onKeyRelease = function(event) { - print("Key release event test"); - // you can cancel a key by releasing its focusing before releasing it - if (event.focus) { - if (event.event == 'delete') { - deleteChar(); - } else if (event.event == 'submit') { - print(textText); - - var position = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), SPAWN_DISTANCE)); - - var textLines = textText.split("\n"); - var maxLineWidth = 0; - for (textLine in textLines) { - var lineWidth = Overlays.textSize(textSizeMeasureOverlay, textLines[textLine]).width; - if (lineWidth > maxLineWidth) { - maxLineWidth = lineWidth; - } - } - var usernameLine = "--" + GlobalServices.myUsername; - var usernameWidth = Overlays.textSize(textSizeMeasureOverlay, usernameLine).width; - if (maxLineWidth < usernameWidth) { - maxLineWidth = usernameWidth; - } else { - var spaceableWidth = maxLineWidth - usernameWidth; - var spaceWidth = Overlays.textSize(textSizeMeasureOverlay, " ").width; - var numberOfSpaces = Math.floor(spaceableWidth / spaceWidth); - for (var i = 0; i < numberOfSpaces; i++) { - usernameLine = " " + usernameLine; - } - } - var dimension_x = maxLineWidth + TEXT_MARGIN_RIGHT + TEXT_MARGIN_LEFT; - if (position.x > 0 && position.y > 0 && position.z > 0) { - Entities.addEntity({ - type: "Text", - rotation: MyAvatar.orientation, - position: position, - dimensions: { x: dimension_x, y: (textLines.length + 1) * 0.14 + TEXT_MARGIN_TOP + TEXT_MARGIN_BOTTOM, z: DEFAULT_TEXT_DIMENSION_Z }, - backgroundColor: { red: 0, green: 0, blue: 0 }, - textColor: { red: 255, green: 255, blue: 255 }, - text: textText + "\n" + usernameLine - }); - } - textText = ""; - updateTextOverlay(); - } - } -}; - -keyboard.onFullyLoaded = function() { - print("Virtual-keyboard fully loaded."); - var dimensions = Controller.getViewportDimensions(); - text = Overlays.addOverlay("text", { - x: 0, - y: dimensions.y - keyboard.height() - 260, - width: dimensions.x, - height: 250, - backgroundColor: { red: 255, green: 255, blue: 255}, - color: { red: 0, green: 0, blue: 0}, - topMargin: 5, - leftMargin: 0, - font: {size: textFontSize}, - text: "", - alpha: 0.8 - }); - updateTextOverlay(); - // the cursor is being loaded after the keyboard, else it will be on the background of the keyboard - cursor = new Cursor(); - cursor.onUpdate = function(position) { - keyboard.setFocusPosition(position.x, position.y); - }; -}; - -function KeyboardKey(keyboard, keyProperties) { +KeyboardKey = (function(keyboard, keyProperties) { var tthis = this; this._focus = false; this._beingPressed = false; @@ -301,9 +176,9 @@ function KeyboardKey(keyboard, keyProperties) { } this.overlays.push(newOverlay); } -} +}); -function Keyboard() { +Keyboard = (function() { var tthis = this; this.focussed_key = -1; this.scale = windowDimensions.x / KEYBOARD_WIDTH; @@ -548,9 +423,9 @@ function Keyboard() { } }; this.keyboardTextureLoaded_timer = Script.setInterval(this.keyboardTextureLoaded, 250); -} +}); -function Cursor() { +Cursor = (function() { var tthis = this; this.x = windowDimensions.x / 2; this.y = windowDimensions.y / 2; @@ -604,35 +479,4 @@ function Cursor() { } }; Script.update.connect(this.update); -} - -function keyPressEvent(event) { - if (event.key === SPACEBAR_CHARCODE) { - keyboard.pressFocussedKey(); - } else if (event.key === ENTER_CHARCODE || event.key === RETURN_CHARCODE) { - print("Enter pressed"); - } - -} - -function keyReleaseEvent(event) { - if (event.key === SPACEBAR_CHARCODE) { - keyboard.releaseKeys(); - } -} - -function scriptEnding() { - keyboard.remove(); - cursor.remove(); - Overlays.deleteOverlay(text); - Overlays.deleteOverlay(textSizeMeasureOverlay); - Controller.releaseKeyEvents({key: SPACEBAR_CHARCODE}); - Controller.releaseKeyEvents({key: RETURN_CHARCODE}); - Controller.releaseKeyEvents({key: ENTER_CHARCODE}); -} -Controller.captureKeyEvents({key: RETURN_CHARCODE}); -Controller.captureKeyEvents({key: ENTER_CHARCODE}); -Controller.captureKeyEvents({key: SPACEBAR_CHARCODE}); -Controller.keyPressEvent.connect(keyPressEvent); -Controller.keyReleaseEvent.connect(keyReleaseEvent); -Script.scriptEnding.connect(scriptEnding); \ No newline at end of file +}); diff --git a/examples/virtualKeyboardLocation.js b/examples/virtualKeyboardLocation.js new file mode 100644 index 0000000000..a5688c4c34 --- /dev/null +++ b/examples/virtualKeyboardLocation.js @@ -0,0 +1,185 @@ +// +// virtualKeyboardTextEntityExample.js +// examples +// +// Created by Thijs Wenker on 11/18/14. +// Copyright 2014 High Fidelity, Inc. +// +// Control a virtual keyboard using your favorite HMD. +// Usage: Enable VR-mode and go to First person mode, +// look at the key that you would like to press, and press the spacebar on your "REAL" keyboard. +// +// Enter a location URL using your HMD. Press Enter to pop-up the virtual keyboard and location input. +// Press Space on the keyboard or the X button on your gamepad to press a key that you have selected. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +Script.include("libraries/virtualKeyboard.js"); + +const SPAWN_DISTANCE = 1; +const DEFAULT_TEXT_DIMENSION_Z = 0.02; + +const TEXT_MARGIN_TOP = 0.15; +const TEXT_MARGIN_LEFT = 0.15; +const TEXT_MARGIN_RIGHT = 0.17; +const TEXT_MARGIN_BOTTOM = 0.17; + +var windowDimensions = Controller.getViewportDimensions(); +var cursor = null; +var keyboard = new Keyboard(); +var textFontSize = 9; +var text = null; +var textText = ""; +var textSizeMeasureOverlay = Overlays.addOverlay("text3d", {visible: false}); + +function appendChar(char) { + textText += char; + updateTextOverlay(); + Overlays.editOverlay(text, {text: textText}); +} + +function deleteChar() { + if (textText.length > 0) { + textText = textText.substring(0, textText.length - 1); + updateTextOverlay(); + } +} + +function updateTextOverlay() { + var textLines = textText.split("\n"); + var maxLineWidth = 0; + for (textLine in textLines) { + var lineWidth = Overlays.textSize(text, textLines[textLine]).width; + if (lineWidth > maxLineWidth) { + maxLineWidth = lineWidth; + } + } + var suggestedFontSize = (windowDimensions.x / maxLineWidth) * textFontSize * 0.90; + var maxFontSize = 190 / textLines.length; + textFontSize = (suggestedFontSize > maxFontSize) ? maxFontSize : suggestedFontSize; + var topMargin = (250 - (textFontSize * textLines.length)) / 4; + Overlays.editOverlay(text, {text: textText, font: {size: textFontSize}, topMargin: topMargin}); + var maxLineWidth = 0; + for (textLine in textLines) { + var lineWidth = Overlays.textSize(text, textLines[textLine]).width; + if (lineWidth > maxLineWidth) { + maxLineWidth = lineWidth; + } + } + Overlays.editOverlay(text, {leftMargin: (windowDimensions.x - maxLineWidth) / 2}); +} + +keyboard.onKeyPress = function(event) { + if (event.event == 'keypress') { + appendChar(event.char); + } else if (event.event == 'enter') { + appendChar("\n"); + } +}; + +keyboard.onKeyRelease = function(event) { + print("Key release event test"); + // you can cancel a key by releasing its focusing before releasing it + if (event.focus) { + if (event.event == 'delete') { + deleteChar(); + } else if (event.event == 'submit') { + print(textText); + + var position = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), SPAWN_DISTANCE)); + + var textLines = textText.split("\n"); + var maxLineWidth = 0; + for (textLine in textLines) { + var lineWidth = Overlays.textSize(textSizeMeasureOverlay, textLines[textLine]).width; + if (lineWidth > maxLineWidth) { + maxLineWidth = lineWidth; + } + } + var usernameLine = "--" + GlobalServices.myUsername; + var usernameWidth = Overlays.textSize(textSizeMeasureOverlay, usernameLine).width; + if (maxLineWidth < usernameWidth) { + maxLineWidth = usernameWidth; + } else { + var spaceableWidth = maxLineWidth - usernameWidth; + var spaceWidth = Overlays.textSize(textSizeMeasureOverlay, " ").width; + var numberOfSpaces = Math.floor(spaceableWidth / spaceWidth); + for (var i = 0; i < numberOfSpaces; i++) { + usernameLine = " " + usernameLine; + } + } + var dimension_x = maxLineWidth + TEXT_MARGIN_RIGHT + TEXT_MARGIN_LEFT; + if (position.x > 0 && position.y > 0 && position.z > 0) { + Entities.addEntity({ + type: "Text", + rotation: MyAvatar.orientation, + position: position, + dimensions: { x: dimension_x, y: (textLines.length + 1) * 0.14 + TEXT_MARGIN_TOP + TEXT_MARGIN_BOTTOM, z: DEFAULT_TEXT_DIMENSION_Z }, + backgroundColor: { red: 0, green: 0, blue: 0 }, + textColor: { red: 255, green: 255, blue: 255 }, + text: textText + "\n" + usernameLine + }); + } + textText = ""; + updateTextOverlay(); + } + } +}; + +keyboard.onFullyLoaded = function() { + print("Virtual-keyboard fully loaded."); + var dimensions = Controller.getViewportDimensions(); + text = Overlays.addOverlay("text", { + x: 0, + y: dimensions.y - keyboard.height() - 260, + width: dimensions.x, + height: 250, + backgroundColor: { red: 255, green: 255, blue: 255}, + color: { red: 0, green: 0, blue: 0}, + topMargin: 5, + leftMargin: 0, + font: {size: textFontSize}, + text: "", + alpha: 0.8 + }); + updateTextOverlay(); + // the cursor is being loaded after the keyboard, else it will be on the background of the keyboard + cursor = new Cursor(); + cursor.onUpdate = function(position) { + keyboard.setFocusPosition(position.x, position.y); + }; +}; + +function keyPressEvent(event) { + if (event.key === SPACEBAR_CHARCODE) { + keyboard.pressFocussedKey(); + } else if (event.key === ENTER_CHARCODE || event.key === RETURN_CHARCODE) { + print("Enter pressed"); + } + +} + +function keyReleaseEvent(event) { + if (event.key === SPACEBAR_CHARCODE) { + keyboard.releaseKeys(); + } +} + +function scriptEnding() { + keyboard.remove(); + cursor.remove(); + Overlays.deleteOverlay(text); + Overlays.deleteOverlay(textSizeMeasureOverlay); + Controller.releaseKeyEvents({key: SPACEBAR_CHARCODE}); + Controller.releaseKeyEvents({key: RETURN_CHARCODE}); + Controller.releaseKeyEvents({key: ENTER_CHARCODE}); +} + +Controller.captureKeyEvents({key: RETURN_CHARCODE}); +Controller.captureKeyEvents({key: ENTER_CHARCODE}); +Controller.captureKeyEvents({key: SPACEBAR_CHARCODE}); +Controller.keyPressEvent.connect(keyPressEvent); +Controller.keyReleaseEvent.connect(keyReleaseEvent); +Script.scriptEnding.connect(scriptEnding); diff --git a/examples/virtualKeyboardTextEntityExample.js b/examples/virtualKeyboardTextEntityExample.js new file mode 100644 index 0000000000..830c50ab1e --- /dev/null +++ b/examples/virtualKeyboardTextEntityExample.js @@ -0,0 +1,177 @@ +// +// virtualKeyboardTextEntityExample.js +// examples +// +// Created by Thijs Wenker on 11/18/14. +// Copyright 2014 High Fidelity, Inc. +// +// Control a virtual keyboard using your favorite HMD. +// Usage: Enable VR-mode and go to First person mode, +// look at the key that you would like to press, and press the spacebar on your "REAL" keyboard. +// +// leased some code from newEditEntities.js for Text Entity example +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +Script.include("libraries/virtualKeyboard.js"); + +const SPAWN_DISTANCE = 1; +const DEFAULT_TEXT_DIMENSION_Z = 0.02; + +const TEXT_MARGIN_TOP = 0.15; +const TEXT_MARGIN_LEFT = 0.15; +const TEXT_MARGIN_RIGHT = 0.17; +const TEXT_MARGIN_BOTTOM = 0.17; + +var windowDimensions = Controller.getViewportDimensions(); +var cursor = null; +var keyboard = new Keyboard(); +var textFontSize = 9; +var text = null; +var textText = ""; +var textSizeMeasureOverlay = Overlays.addOverlay("text3d", {visible: false}); + +function appendChar(char) { + textText += char; + updateTextOverlay(); + Overlays.editOverlay(text, {text: textText}); +} + +function deleteChar() { + if (textText.length > 0) { + textText = textText.substring(0, textText.length - 1); + updateTextOverlay(); + } +} + +function updateTextOverlay() { + var textLines = textText.split("\n"); + var maxLineWidth = 0; + for (textLine in textLines) { + var lineWidth = Overlays.textSize(text, textLines[textLine]).width; + if (lineWidth > maxLineWidth) { + maxLineWidth = lineWidth; + } + } + var suggestedFontSize = (windowDimensions.x / maxLineWidth) * textFontSize * 0.90; + var maxFontSize = 190 / textLines.length; + textFontSize = (suggestedFontSize > maxFontSize) ? maxFontSize : suggestedFontSize; + var topMargin = (250 - (textFontSize * textLines.length)) / 4; + Overlays.editOverlay(text, {text: textText, font: {size: textFontSize}, topMargin: topMargin}); + var maxLineWidth = 0; + for (textLine in textLines) { + var lineWidth = Overlays.textSize(text, textLines[textLine]).width; + if (lineWidth > maxLineWidth) { + maxLineWidth = lineWidth; + } + } + Overlays.editOverlay(text, {leftMargin: (windowDimensions.x - maxLineWidth) / 2}); +} + +keyboard.onKeyPress = function(event) { + if (event.event == 'keypress') { + appendChar(event.char); + } else if (event.event == 'enter') { + appendChar("\n"); + } +}; + +keyboard.onKeyRelease = function(event) { + print("Key release event test"); + // you can cancel a key by releasing its focusing before releasing it + if (event.focus) { + if (event.event == 'delete') { + deleteChar(); + } else if (event.event == 'submit') { + print(textText); + + var position = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), SPAWN_DISTANCE)); + + var textLines = textText.split("\n"); + var maxLineWidth = 0; + for (textLine in textLines) { + var lineWidth = Overlays.textSize(textSizeMeasureOverlay, textLines[textLine]).width; + if (lineWidth > maxLineWidth) { + maxLineWidth = lineWidth; + } + } + var usernameLine = "--" + GlobalServices.myUsername; + var usernameWidth = Overlays.textSize(textSizeMeasureOverlay, usernameLine).width; + if (maxLineWidth < usernameWidth) { + maxLineWidth = usernameWidth; + } else { + var spaceableWidth = maxLineWidth - usernameWidth; + var spaceWidth = Overlays.textSize(textSizeMeasureOverlay, " ").width; + var numberOfSpaces = Math.floor(spaceableWidth / spaceWidth); + for (var i = 0; i < numberOfSpaces; i++) { + usernameLine = " " + usernameLine; + } + } + var dimension_x = maxLineWidth + TEXT_MARGIN_RIGHT + TEXT_MARGIN_LEFT; + if (position.x > 0 && position.y > 0 && position.z > 0) { + Entities.addEntity({ + type: "Text", + rotation: MyAvatar.orientation, + position: position, + dimensions: { x: dimension_x, y: (textLines.length + 1) * 0.14 + TEXT_MARGIN_TOP + TEXT_MARGIN_BOTTOM, z: DEFAULT_TEXT_DIMENSION_Z }, + backgroundColor: { red: 0, green: 0, blue: 0 }, + textColor: { red: 255, green: 255, blue: 255 }, + text: textText + "\n" + usernameLine + }); + } + textText = ""; + updateTextOverlay(); + } + } +}; + +keyboard.onFullyLoaded = function() { + print("Virtual-keyboard fully loaded."); + var dimensions = Controller.getViewportDimensions(); + text = Overlays.addOverlay("text", { + x: 0, + y: dimensions.y - keyboard.height() - 260, + width: dimensions.x, + height: 250, + backgroundColor: { red: 255, green: 255, blue: 255}, + color: { red: 0, green: 0, blue: 0}, + topMargin: 5, + leftMargin: 0, + font: {size: textFontSize}, + text: "", + alpha: 0.8 + }); + updateTextOverlay(); + // the cursor is being loaded after the keyboard, else it will be on the background of the keyboard + cursor = new Cursor(); + cursor.onUpdate = function(position) { + keyboard.setFocusPosition(position.x, position.y); + }; +}; + +function keyPressEvent(event) { + if (event.key === SPACEBAR_CHARCODE) { + keyboard.pressFocussedKey(); + } +} + +function keyReleaseEvent(event) { + if (event.key === SPACEBAR_CHARCODE) { + keyboard.releaseKeys(); + } +} + +function scriptEnding() { + keyboard.remove(); + cursor.remove(); + Overlays.deleteOverlay(text); + Overlays.deleteOverlay(textSizeMeasureOverlay); + Controller.releaseKeyEvents({key: SPACEBAR_CHARCODE}); +} + +Controller.captureKeyEvents({key: SPACEBAR_CHARCODE}); +Controller.keyPressEvent.connect(keyPressEvent); +Controller.keyReleaseEvent.connect(keyReleaseEvent); +Script.scriptEnding.connect(scriptEnding); From a8122e5a85e8927f93b12af9d82d38436a690d86 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Tue, 30 Dec 2014 23:30:48 +0100 Subject: [PATCH 005/103] virtualKeyboard.js - scale 50% virtualKeyboardLocation.js - toggle visibility with Enter/Return key virtualKeyboardTextEntityExample.js - attempt to fix character glyphs --- examples/libraries/virtualKeyboard.js | 112 ++++++++++++------- examples/virtualKeyboardLocation.js | 4 +- examples/virtualKeyboardTextEntityExample.js | 24 +--- 3 files changed, 78 insertions(+), 62 deletions(-) diff --git a/examples/libraries/virtualKeyboard.js b/examples/libraries/virtualKeyboard.js index ba9a30974e..9e5fd4accb 100644 --- a/examples/libraries/virtualKeyboard.js +++ b/examples/libraries/virtualKeyboard.js @@ -37,6 +37,8 @@ KEYBOARD_HEIGHT = 434.1; CURSOR_WIDTH = 33.9; CURSOR_HEIGHT = 33.9; +KEYBOARD_SCALE_MULTIPLIER = 0.50; + // VIEW_ANGLE can be adjusted to your likings, the smaller the faster movement. // Try setting it to 60 if it goes too fast for you. const VIEW_ANGLE = 40.0; @@ -127,6 +129,11 @@ KeyboardKey = (function(keyboard, keyProperties) { }); } }; + this.updateVisibility = function() { + for (var i = 0; i < tthis.bounds.length; i++) { + Overlays.editOverlay(tthis.overlays[i], {visible: tthis.keyboard.visible}); + } + }; this.rescale = function() { for (var i = 0; i < tthis.bounds.length; i++) { Overlays.editOverlay(tthis.overlays[i], { @@ -153,26 +160,26 @@ KeyboardKey = (function(keyboard, keyProperties) { for (var i = 0; i < this.bounds.length; i++) { var newOverlay = Overlays.cloneOverlay(this.keyboard.background); if (THREE_D_MODE) { - Overlays.editOverlay(newOverlay, { - position: { - x: MyAvatar.position.x,// + this.bounds[i][BOUND_X] * 0.01,// /*+ this.keyboard.getX()*/ + this.bounds[i][BOUND_X] * keyboard.scale, - y: MyAvatar.position.y,// - this.bounds[i][BOUND_Y] * 0.01,// /*+ this.keyboard.getY()*/ + this.bounds[i][BOUND_Y] * keyboard.scale, - z: MyAvatar.position.z - }, - width: this.bounds[i][BOUND_W] * keyboard.scale, - height: this.bounds[i][BOUND_H] * keyboard.scale, - subImage: {width: this.bounds[i][BOUND_W], height: this.bounds[i][BOUND_H], x: this.bounds[i][BOUND_X], y: (KEYBOARD_HEIGHT * this.keyState) + this.bounds[i][BOUND_Y]}, - alpha: 1 - }); + Overlays.editOverlay(newOverlay, { + position: { + x: MyAvatar.position.x,// + this.bounds[i][BOUND_X] * 0.01,// /*+ this.keyboard.getX()*/ + this.bounds[i][BOUND_X] * keyboard.scale, + y: MyAvatar.position.y,// - this.bounds[i][BOUND_Y] * 0.01,// /*+ this.keyboard.getY()*/ + this.bounds[i][BOUND_Y] * keyboard.scale, + z: MyAvatar.position.z + }, + width: this.bounds[i][BOUND_W] * keyboard.scale, + height: this.bounds[i][BOUND_H] * keyboard.scale, + subImage: {width: this.bounds[i][BOUND_W], height: this.bounds[i][BOUND_H], x: this.bounds[i][BOUND_X], y: (KEYBOARD_HEIGHT * this.keyState) + this.bounds[i][BOUND_Y]}, + alpha: 1 + }); } else { - Overlays.editOverlay(newOverlay, { - x: this.keyboard.getX() + this.bounds[i][BOUND_X] * keyboard.scale, - y: this.keyboard.getY() + this.bounds[i][BOUND_Y] * keyboard.scale, - width: this.bounds[i][BOUND_W] * keyboard.scale, - height: this.bounds[i][BOUND_H] * keyboard.scale, - subImage: {width: this.bounds[i][BOUND_W], height: this.bounds[i][BOUND_H], x: this.bounds[i][BOUND_X], y: (KEYBOARD_HEIGHT * this.keyState) + this.bounds[i][BOUND_Y]}, - alpha: 1 - }); + Overlays.editOverlay(newOverlay, { + x: this.keyboard.getX() + this.bounds[i][BOUND_X] * keyboard.scale, + y: this.keyboard.getY() + this.bounds[i][BOUND_Y] * keyboard.scale, + width: this.bounds[i][BOUND_W] * keyboard.scale, + height: this.bounds[i][BOUND_H] * keyboard.scale, + subImage: {width: this.bounds[i][BOUND_W], height: this.bounds[i][BOUND_H], x: this.bounds[i][BOUND_X], y: (KEYBOARD_HEIGHT * this.keyState) + this.bounds[i][BOUND_Y]}, + alpha: 1 + }); } this.overlays.push(newOverlay); } @@ -181,8 +188,9 @@ KeyboardKey = (function(keyboard, keyProperties) { Keyboard = (function() { var tthis = this; this.focussed_key = -1; - this.scale = windowDimensions.x / KEYBOARD_WIDTH; + this.scale = (windowDimensions.x / KEYBOARD_WIDTH) * KEYBOARD_SCALE_MULTIPLIER; this.shift = false; + this.visible = true; this.width = function() { return KEYBOARD_WIDTH * tthis.scale; }; @@ -196,30 +204,30 @@ Keyboard = (function() { return windowDimensions.y - this.height(); }; if (THREE_D_MODE) { - this.background = Overlays.addOverlay("billboard", { - scale: 1, - position: MyAvatar.position, - rotation: MyAvatar.rotation, - width: this.width(), - height: this.height(), - subImage: {width: KEYBOARD_WIDTH, height: KEYBOARD_HEIGHT, y: KEYBOARD_HEIGHT * KBD_BACKGROUND}, - isFacingAvatar: false, - url: KEYBOARD_URL, - alpha: 1 - }); + this.background = Overlays.addOverlay("billboard", { + scale: 1, + position: MyAvatar.position, + rotation: MyAvatar.rotation, + width: this.width(), + height: this.height(), + subImage: {width: KEYBOARD_WIDTH, height: KEYBOARD_HEIGHT, y: KEYBOARD_HEIGHT * KBD_BACKGROUND}, + isFacingAvatar: false, + url: KEYBOARD_URL, + alpha: 1 + }); } else { - this.background = Overlays.addOverlay("image", { - x: this.getX(), - y: this.getY(), - width: this.width(), - height: this.height(), - subImage: {width: KEYBOARD_WIDTH, height: KEYBOARD_HEIGHT, y: KEYBOARD_HEIGHT * KBD_BACKGROUND}, - imageURL: KEYBOARD_URL, - alpha: 1 - }); + this.background = Overlays.addOverlay("image", { + x: this.getX(), + y: this.getY(), + width: this.width(), + height: this.height(), + subImage: {width: KEYBOARD_WIDTH, height: KEYBOARD_HEIGHT, y: KEYBOARD_HEIGHT * KBD_BACKGROUND}, + imageURL: KEYBOARD_URL, + alpha: 1 + }); } this.rescale = function() { - this.scale = windowDimensions.x / KEYBOARD_WIDTH; + this.scale = (windowDimensions.x / KEYBOARD_WIDTH) * KEYBOARD_SCALE_MULTIPLIER; Overlays.editOverlay(tthis.background, { x: this.getX(), y: this.getY(), @@ -312,6 +320,28 @@ Keyboard = (function() { } }; + this.show = function() { + tthis.visible = true; + tthis.updateVisibility(); + }; + + this.hide = function() { + tthis.visible = false; + tthis.updateVisibility(); + }; + + this.toggle = function() { + tthis.visible = !tthis.visible; + tthis.updateVisibility(); + }; + + this.updateVisibility = function() { + Overlays.editOverlay(tthis.background, { visible: tthis.visible }); + for (var i = 0; i < this.keys.length; i++) { + this.keys[i].updateVisibility(); + } + }; + this.onKeyPress = null; this.onKeyRelease = null; this.onSubmit = null; diff --git a/examples/virtualKeyboardLocation.js b/examples/virtualKeyboardLocation.js index a5688c4c34..eae6c982b2 100644 --- a/examples/virtualKeyboardLocation.js +++ b/examples/virtualKeyboardLocation.js @@ -2,7 +2,7 @@ // virtualKeyboardTextEntityExample.js // examples // -// Created by Thijs Wenker on 11/18/14. +// Created by Thijs Wenker on 12/28/14. // Copyright 2014 High Fidelity, Inc. // // Control a virtual keyboard using your favorite HMD. @@ -156,7 +156,7 @@ function keyPressEvent(event) { if (event.key === SPACEBAR_CHARCODE) { keyboard.pressFocussedKey(); } else if (event.key === ENTER_CHARCODE || event.key === RETURN_CHARCODE) { - print("Enter pressed"); + keyboard.toggle(); } } diff --git a/examples/virtualKeyboardTextEntityExample.js b/examples/virtualKeyboardTextEntityExample.js index 830c50ab1e..2d46397831 100644 --- a/examples/virtualKeyboardTextEntityExample.js +++ b/examples/virtualKeyboardTextEntityExample.js @@ -2,7 +2,7 @@ // virtualKeyboardTextEntityExample.js // examples // -// Created by Thijs Wenker on 11/18/14. +// Created by Thijs Wenker on 12/28/14. // Copyright 2014 High Fidelity, Inc. // // Control a virtual keyboard using your favorite HMD. @@ -45,29 +45,15 @@ function deleteChar() { updateTextOverlay(); } } - + function updateTextOverlay() { var textLines = textText.split("\n"); - var maxLineWidth = 0; - for (textLine in textLines) { - var lineWidth = Overlays.textSize(text, textLines[textLine]).width; - if (lineWidth > maxLineWidth) { - maxLineWidth = lineWidth; - } - } - var suggestedFontSize = (windowDimensions.x / maxLineWidth) * textFontSize * 0.90; - var maxFontSize = 190 / textLines.length; + var suggestedFontSize = (windowDimensions.x / Overlays.textSize(text, textLines).width) * textFontSize * 0.90; + var maxFontSize = 170 / textLines.length; textFontSize = (suggestedFontSize > maxFontSize) ? maxFontSize : suggestedFontSize; var topMargin = (250 - (textFontSize * textLines.length)) / 4; Overlays.editOverlay(text, {text: textText, font: {size: textFontSize}, topMargin: topMargin}); - var maxLineWidth = 0; - for (textLine in textLines) { - var lineWidth = Overlays.textSize(text, textLines[textLine]).width; - if (lineWidth > maxLineWidth) { - maxLineWidth = lineWidth; - } - } - Overlays.editOverlay(text, {leftMargin: (windowDimensions.x - maxLineWidth) / 2}); + Overlays.editOverlay(text, {leftMargin: (windowDimensions.x - Overlays.textSize(text, textLines).width) / 2}); } keyboard.onKeyPress = function(event) { From 11d66ae83f81da354603f1f311092572a7d53688 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 31 Dec 2014 00:51:34 +0100 Subject: [PATCH 006/103] fixed text entity height --- examples/virtualKeyboardTextEntityExample.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/examples/virtualKeyboardTextEntityExample.js b/examples/virtualKeyboardTextEntityExample.js index 2d46397831..38beb08277 100644 --- a/examples/virtualKeyboardTextEntityExample.js +++ b/examples/virtualKeyboardTextEntityExample.js @@ -48,7 +48,7 @@ function deleteChar() { function updateTextOverlay() { var textLines = textText.split("\n"); - var suggestedFontSize = (windowDimensions.x / Overlays.textSize(text, textLines).width) * textFontSize * 0.90; + var suggestedFontSize = (windowDimensions.x / Overlays.textSize(text, textText).width) * textFontSize * 0.90; var maxFontSize = 170 / textLines.length; textFontSize = (suggestedFontSize > maxFontSize) ? maxFontSize : suggestedFontSize; var topMargin = (250 - (textFontSize * textLines.length)) / 4; @@ -76,13 +76,7 @@ keyboard.onKeyRelease = function(event) { var position = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), SPAWN_DISTANCE)); var textLines = textText.split("\n"); - var maxLineWidth = 0; - for (textLine in textLines) { - var lineWidth = Overlays.textSize(textSizeMeasureOverlay, textLines[textLine]).width; - if (lineWidth > maxLineWidth) { - maxLineWidth = lineWidth; - } - } + var maxLineWidth = Overlays.textSize(textSizeMeasureOverlay, textText).width; var usernameLine = "--" + GlobalServices.myUsername; var usernameWidth = Overlays.textSize(textSizeMeasureOverlay, usernameLine).width; if (maxLineWidth < usernameWidth) { @@ -104,7 +98,8 @@ keyboard.onKeyRelease = function(event) { dimensions: { x: dimension_x, y: (textLines.length + 1) * 0.14 + TEXT_MARGIN_TOP + TEXT_MARGIN_BOTTOM, z: DEFAULT_TEXT_DIMENSION_Z }, backgroundColor: { red: 0, green: 0, blue: 0 }, textColor: { red: 255, green: 255, blue: 255 }, - text: textText + "\n" + usernameLine + text: textText + "\n" + usernameLine, + lineHeight: 0.1 }); } textText = ""; From e856d302d38bee8d4ab9d421e78674842d757819 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 31 Dec 2014 01:37:51 +0100 Subject: [PATCH 007/103] - improved keyboard visibility setting - added posibility to teleport to location through hmd --- examples/libraries/virtualKeyboard.js | 19 ++++-- examples/virtualKeyboardLocation.js | 88 +++++---------------------- 2 files changed, 28 insertions(+), 79 deletions(-) diff --git a/examples/libraries/virtualKeyboard.js b/examples/libraries/virtualKeyboard.js index 9e5fd4accb..7e18ba1b5c 100644 --- a/examples/libraries/virtualKeyboard.js +++ b/examples/libraries/virtualKeyboard.js @@ -169,7 +169,8 @@ KeyboardKey = (function(keyboard, keyProperties) { width: this.bounds[i][BOUND_W] * keyboard.scale, height: this.bounds[i][BOUND_H] * keyboard.scale, subImage: {width: this.bounds[i][BOUND_W], height: this.bounds[i][BOUND_H], x: this.bounds[i][BOUND_X], y: (KEYBOARD_HEIGHT * this.keyState) + this.bounds[i][BOUND_Y]}, - alpha: 1 + alpha: 1, + visible: tthis.keyboard.visible }); } else { Overlays.editOverlay(newOverlay, { @@ -178,19 +179,20 @@ KeyboardKey = (function(keyboard, keyProperties) { width: this.bounds[i][BOUND_W] * keyboard.scale, height: this.bounds[i][BOUND_H] * keyboard.scale, subImage: {width: this.bounds[i][BOUND_W], height: this.bounds[i][BOUND_H], x: this.bounds[i][BOUND_X], y: (KEYBOARD_HEIGHT * this.keyState) + this.bounds[i][BOUND_Y]}, - alpha: 1 + alpha: 1, + visible: tthis.keyboard.visible }); } this.overlays.push(newOverlay); } }); -Keyboard = (function() { +Keyboard = (function(params) { var tthis = this; this.focussed_key = -1; this.scale = (windowDimensions.x / KEYBOARD_WIDTH) * KEYBOARD_SCALE_MULTIPLIER; this.shift = false; - this.visible = true; + this.visible = params.visible != undefined ? params.visible :true; this.width = function() { return KEYBOARD_WIDTH * tthis.scale; }; @@ -213,7 +215,8 @@ Keyboard = (function() { subImage: {width: KEYBOARD_WIDTH, height: KEYBOARD_HEIGHT, y: KEYBOARD_HEIGHT * KBD_BACKGROUND}, isFacingAvatar: false, url: KEYBOARD_URL, - alpha: 1 + alpha: 1, + visible: this.visible }); } else { this.background = Overlays.addOverlay("image", { @@ -223,7 +226,8 @@ Keyboard = (function() { height: this.height(), subImage: {width: KEYBOARD_WIDTH, height: KEYBOARD_HEIGHT, y: KEYBOARD_HEIGHT * KBD_BACKGROUND}, imageURL: KEYBOARD_URL, - alpha: 1 + alpha: 1, + visible: this.visible }); } this.rescale = function() { @@ -265,6 +269,9 @@ Keyboard = (function() { }; this.pressFocussedKey = function() { + if (!tthis.visible) { + return tthis; + } if (tthis.focussed_key != -1) { if (tthis.keys[tthis.focussed_key].event == 'shift') { tthis.toggleShift(); diff --git a/examples/virtualKeyboardLocation.js b/examples/virtualKeyboardLocation.js index eae6c982b2..2ff98c4c43 100644 --- a/examples/virtualKeyboardLocation.js +++ b/examples/virtualKeyboardLocation.js @@ -18,64 +18,40 @@ Script.include("libraries/virtualKeyboard.js"); -const SPAWN_DISTANCE = 1; -const DEFAULT_TEXT_DIMENSION_Z = 0.02; - -const TEXT_MARGIN_TOP = 0.15; -const TEXT_MARGIN_LEFT = 0.15; -const TEXT_MARGIN_RIGHT = 0.17; -const TEXT_MARGIN_BOTTOM = 0.17; - var windowDimensions = Controller.getViewportDimensions(); var cursor = null; -var keyboard = new Keyboard(); +var keyboard = new Keyboard({visible: false}); var textFontSize = 9; var text = null; -var textText = ""; -var textSizeMeasureOverlay = Overlays.addOverlay("text3d", {visible: false}); +var locationURL = ""; function appendChar(char) { - textText += char; + locationURL += char; updateTextOverlay(); - Overlays.editOverlay(text, {text: textText}); + Overlays.editOverlay(text, {text: locationURL}); } function deleteChar() { - if (textText.length > 0) { - textText = textText.substring(0, textText.length - 1); + if (locationURL.length > 0) { + locationURL = locationURL.substring(0, locationURL.length - 1); updateTextOverlay(); } } function updateTextOverlay() { - var textLines = textText.split("\n"); - var maxLineWidth = 0; - for (textLine in textLines) { - var lineWidth = Overlays.textSize(text, textLines[textLine]).width; - if (lineWidth > maxLineWidth) { - maxLineWidth = lineWidth; - } - } + var maxLineWidth = Overlays.textSize(text, locationURL).width; var suggestedFontSize = (windowDimensions.x / maxLineWidth) * textFontSize * 0.90; - var maxFontSize = 190 / textLines.length; + var maxFontSize = 140; textFontSize = (suggestedFontSize > maxFontSize) ? maxFontSize : suggestedFontSize; - var topMargin = (250 - (textFontSize * textLines.length)) / 4; - Overlays.editOverlay(text, {text: textText, font: {size: textFontSize}, topMargin: topMargin}); - var maxLineWidth = 0; - for (textLine in textLines) { - var lineWidth = Overlays.textSize(text, textLines[textLine]).width; - if (lineWidth > maxLineWidth) { - maxLineWidth = lineWidth; - } - } + var topMargin = (250 - textFontSize) / 4; + Overlays.editOverlay(text, {text: locationURL, font: {size: textFontSize}, topMargin: topMargin}); + maxLineWidth = Overlays.textSize(text, locationURL).width; Overlays.editOverlay(text, {leftMargin: (windowDimensions.x - maxLineWidth) / 2}); } keyboard.onKeyPress = function(event) { if (event.event == 'keypress') { appendChar(event.char); - } else if (event.event == 'enter') { - appendChar("\n"); } }; @@ -85,44 +61,10 @@ keyboard.onKeyRelease = function(event) { if (event.focus) { if (event.event == 'delete') { deleteChar(); - } else if (event.event == 'submit') { - print(textText); - - var position = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), SPAWN_DISTANCE)); - - var textLines = textText.split("\n"); - var maxLineWidth = 0; - for (textLine in textLines) { - var lineWidth = Overlays.textSize(textSizeMeasureOverlay, textLines[textLine]).width; - if (lineWidth > maxLineWidth) { - maxLineWidth = lineWidth; - } - } - var usernameLine = "--" + GlobalServices.myUsername; - var usernameWidth = Overlays.textSize(textSizeMeasureOverlay, usernameLine).width; - if (maxLineWidth < usernameWidth) { - maxLineWidth = usernameWidth; - } else { - var spaceableWidth = maxLineWidth - usernameWidth; - var spaceWidth = Overlays.textSize(textSizeMeasureOverlay, " ").width; - var numberOfSpaces = Math.floor(spaceableWidth / spaceWidth); - for (var i = 0; i < numberOfSpaces; i++) { - usernameLine = " " + usernameLine; - } - } - var dimension_x = maxLineWidth + TEXT_MARGIN_RIGHT + TEXT_MARGIN_LEFT; - if (position.x > 0 && position.y > 0 && position.z > 0) { - Entities.addEntity({ - type: "Text", - rotation: MyAvatar.orientation, - position: position, - dimensions: { x: dimension_x, y: (textLines.length + 1) * 0.14 + TEXT_MARGIN_TOP + TEXT_MARGIN_BOTTOM, z: DEFAULT_TEXT_DIMENSION_Z }, - backgroundColor: { red: 0, green: 0, blue: 0 }, - textColor: { red: 255, green: 255, blue: 255 }, - text: textText + "\n" + usernameLine - }); - } - textText = ""; + } else if (event.event == 'submit' || event.event == 'enter') { + print("going to hifi://" + locationURL); + location = "hifi://" + locationURL; + locationURL = ""; updateTextOverlay(); } } From 1365ecede309a2e774729aeba19a085dc2ca9b6e Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 31 Dec 2014 01:42:19 +0100 Subject: [PATCH 008/103] removed unused variables --- examples/libraries/virtualKeyboard.js | 9 --------- 1 file changed, 9 deletions(-) diff --git a/examples/libraries/virtualKeyboard.js b/examples/libraries/virtualKeyboard.js index 7e18ba1b5c..98d8bdf561 100644 --- a/examples/libraries/virtualKeyboard.js +++ b/examples/libraries/virtualKeyboard.js @@ -44,9 +44,6 @@ KEYBOARD_SCALE_MULTIPLIER = 0.50; const VIEW_ANGLE = 40.0; const VIEW_ANGLE_BY_TWO = VIEW_ANGLE / 2; -const SPAWN_DISTANCE = 1; -const DEFAULT_TEXT_DIMENSION_Z = 0.02; - const BOUND_X = 0; const BOUND_Y = 1; const BOUND_W = 2; @@ -55,13 +52,7 @@ const BOUND_H = 3; KEY_STATE_LOWER = 0; KEY_STATE_UPPER = 1; -const TEXT_MARGIN_TOP = 0.15; -const TEXT_MARGIN_LEFT = 0.15; -const TEXT_MARGIN_RIGHT = 0.17; -const TEXT_MARGIN_BOTTOM = 0.17; - var windowDimensions = Controller.getViewportDimensions(); -var cursor = null; KeyboardKey = (function(keyboard, keyProperties) { var tthis = this; From a0e209276b81c42d51044b9f8bd5a9067075173c Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 31 Dec 2014 01:46:01 +0100 Subject: [PATCH 009/103] textbox visibility --- examples/virtualKeyboardLocation.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/virtualKeyboardLocation.js b/examples/virtualKeyboardLocation.js index 2ff98c4c43..c07877f2f1 100644 --- a/examples/virtualKeyboardLocation.js +++ b/examples/virtualKeyboardLocation.js @@ -84,7 +84,8 @@ keyboard.onFullyLoaded = function() { leftMargin: 0, font: {size: textFontSize}, text: "", - alpha: 0.8 + alpha: 0.8, + visible: keyboard.visible }); updateTextOverlay(); // the cursor is being loaded after the keyboard, else it will be on the background of the keyboard @@ -99,8 +100,8 @@ function keyPressEvent(event) { keyboard.pressFocussedKey(); } else if (event.key === ENTER_CHARCODE || event.key === RETURN_CHARCODE) { keyboard.toggle(); + Overlays.editOverlay(text, {visible: keyboard.visible}); } - } function keyReleaseEvent(event) { From 33a4f8030054cc3c63a0e6f6d8d954fdfadb022f Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 31 Dec 2014 01:49:01 +0100 Subject: [PATCH 010/103] hide keyboard after submit --- examples/virtualKeyboardLocation.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/virtualKeyboardLocation.js b/examples/virtualKeyboardLocation.js index c07877f2f1..839fa6e743 100644 --- a/examples/virtualKeyboardLocation.js +++ b/examples/virtualKeyboardLocation.js @@ -44,7 +44,7 @@ function updateTextOverlay() { var maxFontSize = 140; textFontSize = (suggestedFontSize > maxFontSize) ? maxFontSize : suggestedFontSize; var topMargin = (250 - textFontSize) / 4; - Overlays.editOverlay(text, {text: locationURL, font: {size: textFontSize}, topMargin: topMargin}); + Overlays.editOverlay(text, {text: locationURL, font: {size: textFontSize}, topMargin: topMargin, visible: keyboard.visible}); maxLineWidth = Overlays.textSize(text, locationURL).width; Overlays.editOverlay(text, {leftMargin: (windowDimensions.x - maxLineWidth) / 2}); } @@ -65,6 +65,7 @@ keyboard.onKeyRelease = function(event) { print("going to hifi://" + locationURL); location = "hifi://" + locationURL; locationURL = ""; + keyboard.hide(); updateTextOverlay(); } } From 398e88107cbe9a391f05f46564c4e1f6137d464e Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 31 Dec 2014 01:53:10 +0100 Subject: [PATCH 011/103] renamed virtualKeyboardLocation.js to goTo.js as discussed --- examples/{virtualKeyboardLocation.js => goTo.js} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename examples/{virtualKeyboardLocation.js => goTo.js} (99%) diff --git a/examples/virtualKeyboardLocation.js b/examples/goTo.js similarity index 99% rename from examples/virtualKeyboardLocation.js rename to examples/goTo.js index 839fa6e743..13114024ed 100644 --- a/examples/virtualKeyboardLocation.js +++ b/examples/goTo.js @@ -1,5 +1,5 @@ // -// virtualKeyboardTextEntityExample.js +// goTo.js // examples // // Created by Thijs Wenker on 12/28/14. From c73b496cacaafb995762a1d72fae50b3b3dcb62a Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 31 Dec 2014 02:25:55 +0100 Subject: [PATCH 012/103] press X button with gamepad --- examples/goTo.js | 15 +++++++++++++++ examples/libraries/virtualKeyboard.js | 3 +++ examples/virtualKeyboardTextEntityExample.js | 15 +++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/examples/goTo.js b/examples/goTo.js index 13114024ed..ef93bc9268 100644 --- a/examples/goTo.js +++ b/examples/goTo.js @@ -121,6 +121,21 @@ function scriptEnding() { Controller.releaseKeyEvents({key: ENTER_CHARCODE}); } +function reportButtonValue(button, newValue, oldValue) { + if (button == Joysticks.BUTTON_FACE_LEFT) { + if (newValue) { + keyboard.pressFocussedKey(); + } else { + keyboard.releaseKeys(); + } + } +} + +function addJoystick(gamepad) { + gamepad.buttonStateChanged.connect(reportButtonValue); +} + +Joysticks.joystickAdded.connect(addJoystick); Controller.captureKeyEvents({key: RETURN_CHARCODE}); Controller.captureKeyEvents({key: ENTER_CHARCODE}); Controller.captureKeyEvents({key: SPACEBAR_CHARCODE}); diff --git a/examples/libraries/virtualKeyboard.js b/examples/libraries/virtualKeyboard.js index 98d8bdf561..492b49a4aa 100644 --- a/examples/libraries/virtualKeyboard.js +++ b/examples/libraries/virtualKeyboard.js @@ -179,6 +179,9 @@ KeyboardKey = (function(keyboard, keyProperties) { }); Keyboard = (function(params) { + if (params === undefined) { + params = {}; + } var tthis = this; this.focussed_key = -1; this.scale = (windowDimensions.x / KEYBOARD_WIDTH) * KEYBOARD_SCALE_MULTIPLIER; diff --git a/examples/virtualKeyboardTextEntityExample.js b/examples/virtualKeyboardTextEntityExample.js index 38beb08277..a6960d209a 100644 --- a/examples/virtualKeyboardTextEntityExample.js +++ b/examples/virtualKeyboardTextEntityExample.js @@ -152,6 +152,21 @@ function scriptEnding() { Controller.releaseKeyEvents({key: SPACEBAR_CHARCODE}); } +function reportButtonValue(button, newValue, oldValue) { + if (button == Joysticks.BUTTON_FACE_LEFT) { + if (newValue) { + keyboard.pressFocussedKey(); + } else { + keyboard.releaseKeys(); + } + } +} + +function addJoystick(gamepad) { + gamepad.buttonStateChanged.connect(reportButtonValue); +} + +Joysticks.joystickAdded.connect(addJoystick); Controller.captureKeyEvents({key: SPACEBAR_CHARCODE}); Controller.keyPressEvent.connect(keyPressEvent); Controller.keyReleaseEvent.connect(keyReleaseEvent); From 19eec811731f5fd7c8e5ccacf8edeb29a4d0d0b0 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 7 Jan 2015 20:46:39 +0100 Subject: [PATCH 013/103] moved goTo.js and virtualKeyboardTextEntityExample.js to the right category folder --- examples/{ => controllers/oculus}/goTo.js | 0 .../{ => controllers/oculus}/virtualKeyboardTextEntityExample.js | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename examples/{ => controllers/oculus}/goTo.js (100%) rename examples/{ => controllers/oculus}/virtualKeyboardTextEntityExample.js (100%) diff --git a/examples/goTo.js b/examples/controllers/oculus/goTo.js similarity index 100% rename from examples/goTo.js rename to examples/controllers/oculus/goTo.js diff --git a/examples/virtualKeyboardTextEntityExample.js b/examples/controllers/oculus/virtualKeyboardTextEntityExample.js similarity index 100% rename from examples/virtualKeyboardTextEntityExample.js rename to examples/controllers/oculus/virtualKeyboardTextEntityExample.js From ff6cae738b5ba26d43b25cb58c54b8c5291fb783 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 7 Jan 2015 20:47:59 +0100 Subject: [PATCH 014/103] fixed library paths --- examples/controllers/oculus/goTo.js | 2 +- examples/controllers/oculus/virtualKeyboardTextEntityExample.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/controllers/oculus/goTo.js b/examples/controllers/oculus/goTo.js index ef93bc9268..50d44d0a28 100644 --- a/examples/controllers/oculus/goTo.js +++ b/examples/controllers/oculus/goTo.js @@ -16,7 +16,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("libraries/virtualKeyboard.js"); +Script.include("../../libraries/virtualKeyboard.js"); var windowDimensions = Controller.getViewportDimensions(); var cursor = null; diff --git a/examples/controllers/oculus/virtualKeyboardTextEntityExample.js b/examples/controllers/oculus/virtualKeyboardTextEntityExample.js index a6960d209a..9c5ba6dfe5 100644 --- a/examples/controllers/oculus/virtualKeyboardTextEntityExample.js +++ b/examples/controllers/oculus/virtualKeyboardTextEntityExample.js @@ -15,7 +15,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("libraries/virtualKeyboard.js"); +Script.include("../../libraries/virtualKeyboard.js"); const SPAWN_DISTANCE = 1; const DEFAULT_TEXT_DIMENSION_Z = 0.02; From 4fdcdf095c9af35f2f77e22340eb771dbe440860 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 7 Jan 2015 21:27:14 +0100 Subject: [PATCH 015/103] trying to fix url --- examples/libraries/virtualKeyboard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/libraries/virtualKeyboard.js b/examples/libraries/virtualKeyboard.js index 492b49a4aa..aab590e63f 100644 --- a/examples/libraries/virtualKeyboard.js +++ b/examples/libraries/virtualKeyboard.js @@ -13,7 +13,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("libraries/globals.js"); +Script.include("globals.js"); // experimental 3dmode THREE_D_MODE = false; From 6771252eab69c000631d82c48ff02a603eb0bb76 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 7 Jan 2015 21:34:34 +0100 Subject: [PATCH 016/103] seems like you need to offset the include from the script that uses it --- examples/libraries/virtualKeyboard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/libraries/virtualKeyboard.js b/examples/libraries/virtualKeyboard.js index aab590e63f..893ed929d6 100644 --- a/examples/libraries/virtualKeyboard.js +++ b/examples/libraries/virtualKeyboard.js @@ -13,7 +13,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("globals.js"); +Script.include("../../libraries/globals.js"); // experimental 3dmode THREE_D_MODE = false; From 527576eebad6a0ec63b1b2bd081afa72d32ae6c1 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 7 Jan 2015 21:38:31 +0100 Subject: [PATCH 017/103] or not... --- examples/libraries/virtualKeyboard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/libraries/virtualKeyboard.js b/examples/libraries/virtualKeyboard.js index 893ed929d6..aab590e63f 100644 --- a/examples/libraries/virtualKeyboard.js +++ b/examples/libraries/virtualKeyboard.js @@ -13,7 +13,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("../../libraries/globals.js"); +Script.include("globals.js"); // experimental 3dmode THREE_D_MODE = false; From 40b4a17ba803de674993a1777b27b93564776f35 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 7 Jan 2015 23:14:31 +0100 Subject: [PATCH 018/103] include globals.js from runnable scripts for now. --- examples/controllers/oculus/goTo.js | 1 + examples/controllers/oculus/virtualKeyboardTextEntityExample.js | 1 + examples/libraries/virtualKeyboard.js | 2 -- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/controllers/oculus/goTo.js b/examples/controllers/oculus/goTo.js index 50d44d0a28..3423716698 100644 --- a/examples/controllers/oculus/goTo.js +++ b/examples/controllers/oculus/goTo.js @@ -16,6 +16,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("../../libraries/globals.js"); Script.include("../../libraries/virtualKeyboard.js"); var windowDimensions = Controller.getViewportDimensions(); diff --git a/examples/controllers/oculus/virtualKeyboardTextEntityExample.js b/examples/controllers/oculus/virtualKeyboardTextEntityExample.js index 9c5ba6dfe5..a5f5b2bf95 100644 --- a/examples/controllers/oculus/virtualKeyboardTextEntityExample.js +++ b/examples/controllers/oculus/virtualKeyboardTextEntityExample.js @@ -15,6 +15,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("../../libraries/globals.js"); Script.include("../../libraries/virtualKeyboard.js"); const SPAWN_DISTANCE = 1; diff --git a/examples/libraries/virtualKeyboard.js b/examples/libraries/virtualKeyboard.js index aab590e63f..854ca58d1d 100644 --- a/examples/libraries/virtualKeyboard.js +++ b/examples/libraries/virtualKeyboard.js @@ -13,8 +13,6 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("globals.js"); - // experimental 3dmode THREE_D_MODE = false; From c791422fabf1ce844434242967b7e5ef3ab85eef Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Thu, 8 Jan 2015 02:22:08 +0100 Subject: [PATCH 019/103] make gamepads and A (select key) and B (delete character) button function --- examples/controllers/oculus/goTo.js | 9 ++++++++- .../oculus/virtualKeyboardTextEntityExample.js | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/examples/controllers/oculus/goTo.js b/examples/controllers/oculus/goTo.js index 3423716698..ba1ee1eb81 100644 --- a/examples/controllers/oculus/goTo.js +++ b/examples/controllers/oculus/goTo.js @@ -123,12 +123,14 @@ function scriptEnding() { } function reportButtonValue(button, newValue, oldValue) { - if (button == Joysticks.BUTTON_FACE_LEFT) { + if (button == Joysticks.BUTTON_FACE_BOTTOM) { if (newValue) { keyboard.pressFocussedKey(); } else { keyboard.releaseKeys(); } + } else if (button == Joysticks.BUTTON_FACE_RIGHT && newValue) { + deleteChar(); } } @@ -136,6 +138,11 @@ function addJoystick(gamepad) { gamepad.buttonStateChanged.connect(reportButtonValue); } +var allJoysticks = Joysticks.getAllJoysticks(); +for (var i = 0; i < allJoysticks.length; i++) { + addJoystick(allJoysticks[i]); +} + Joysticks.joystickAdded.connect(addJoystick); Controller.captureKeyEvents({key: RETURN_CHARCODE}); Controller.captureKeyEvents({key: ENTER_CHARCODE}); diff --git a/examples/controllers/oculus/virtualKeyboardTextEntityExample.js b/examples/controllers/oculus/virtualKeyboardTextEntityExample.js index a5f5b2bf95..794b659bcb 100644 --- a/examples/controllers/oculus/virtualKeyboardTextEntityExample.js +++ b/examples/controllers/oculus/virtualKeyboardTextEntityExample.js @@ -154,12 +154,14 @@ function scriptEnding() { } function reportButtonValue(button, newValue, oldValue) { - if (button == Joysticks.BUTTON_FACE_LEFT) { + if (button == Joysticks.BUTTON_FACE_BOTTOM) { if (newValue) { keyboard.pressFocussedKey(); } else { keyboard.releaseKeys(); } + } else if (button == Joysticks.BUTTON_FACE_RIGHT && newValue) { + deleteChar(); } } @@ -167,6 +169,11 @@ function addJoystick(gamepad) { gamepad.buttonStateChanged.connect(reportButtonValue); } +var allJoysticks = Joysticks.getAllJoysticks(); +for (var i = 0; i < allJoysticks.length; i++) { + addJoystick(allJoysticks[i]); +} + Joysticks.joystickAdded.connect(addJoystick); Controller.captureKeyEvents({key: SPACEBAR_CHARCODE}); Controller.keyPressEvent.connect(keyPressEvent); From 3da5677aafadbb6961951db3118f274412a87257 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Tue, 13 Jan 2015 00:43:16 +0100 Subject: [PATCH 020/103] added HMD interface to toggle magnifier --- interface/src/Application.cpp | 3 ++ .../src/scripting/HMDScriptingInterface.cpp | 17 ++++++++++ .../src/scripting/HMDScriptingInterface.h | 32 +++++++++++++++++++ interface/src/ui/ApplicationOverlay.cpp | 3 +- interface/src/ui/ApplicationOverlay.h | 6 +++- 5 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 interface/src/scripting/HMDScriptingInterface.cpp create mode 100644 interface/src/scripting/HMDScriptingInterface.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1364e1b05b..6260634e25 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -101,6 +101,7 @@ #include "scripting/AccountScriptingInterface.h" #include "scripting/AudioDeviceScriptingInterface.h" #include "scripting/ClipboardScriptingInterface.h" +#include "scripting/HMDScriptingInterface.h" #include "scripting/JoystickScriptingInterface.h" #include "scripting/GlobalServicesScriptingInterface.h" #include "scripting/LocationScriptingInterface.h" @@ -3445,6 +3446,8 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri scriptEngine->registerGlobalObject("UndoStack", &_undoStackScriptingInterface); + scriptEngine->registerGlobalObject("HMD", &HMDScriptingInterface::getInstance()); + #ifdef HAVE_RTMIDI scriptEngine->registerGlobalObject("MIDI", &MIDIManager::getInstance()); #endif diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp new file mode 100644 index 0000000000..b9b9b103e4 --- /dev/null +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -0,0 +1,17 @@ +// +// HMDScriptingInterface.cpp +// interface/src/scripting +// +// Created by Thijs Wenker on 1/12/15. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "HMDScriptingInterface.h" + +HMDScriptingInterface& HMDScriptingInterface::getInstance() { + static HMDScriptingInterface sharedInstance; + return sharedInstance; +} diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h new file mode 100644 index 0000000000..4852d9ae6e --- /dev/null +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -0,0 +1,32 @@ +// +// HMDScriptingInterface.h +// interface/src/scripting +// +// Created by Thijs Wenker on 1/12/15. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_HMDScriptingInterface_h +#define hifi_HMDScriptingInterface_h + +#include "Application.h" + +class HMDScriptingInterface : public QObject { + Q_OBJECT + Q_PROPERTY(bool magnifier READ getMagnifier) +public: + static HMDScriptingInterface& getInstance(); + +public slots: + void toggleMagnifier() { Application::getInstance()->getApplicationOverlay().toggleMagnifier(); }; + +private: + HMDScriptingInterface() {}; + bool getMagnifier() const { return Application::getInstance()->getApplicationOverlay().hasMagnifier(); }; + +}; + +#endif // hifi_HMDScriptingInterface_h diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 1d710f29d4..b2bf821af8 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -131,6 +131,7 @@ ApplicationOverlay::ApplicationOverlay() : _alpha(1.0f), _oculusUIRadius(1.0f), _crosshairTexture(0), + _magnifier(true), _previousBorderWidth(-1), _previousBorderHeight(-1), _previousMagnifierBottomLeft(), @@ -555,7 +556,7 @@ void ApplicationOverlay::renderPointers() { _reticlePosition[MOUSE] = position; _reticleActive[MOUSE] = true; - _magActive[MOUSE] = true; + _magActive[MOUSE] = _magnifier; _reticleActive[LEFT_CONTROLLER] = false; _reticleActive[RIGHT_CONTROLLER] = false; } else if (application->getLastMouseMoveWasSimulated() && Menu::getInstance()->isOptionChecked(MenuOption::SixenseMouseInput)) { diff --git a/interface/src/ui/ApplicationOverlay.h b/interface/src/ui/ApplicationOverlay.h index e2094f2a8e..554dd5152e 100644 --- a/interface/src/ui/ApplicationOverlay.h +++ b/interface/src/ui/ApplicationOverlay.h @@ -34,6 +34,9 @@ public: QPoint getPalmClickLocation(const PalmData *palm) const; bool calculateRayUICollisionPoint(const glm::vec3& position, const glm::vec3& direction, glm::vec3& result) const; + bool hasMagnifier() const { return _magnifier; } + void toggleMagnifier() { _magnifier = !_magnifier; } + // Converter from one frame of reference to another. // Frame of reference: // Screen: Position on the screen (x,y) @@ -101,7 +104,8 @@ private: bool _magActive[NUMBER_OF_RETICLES]; float _magSizeMult[NUMBER_OF_RETICLES]; quint64 _lastMouseMove; - + bool _magnifier; + float _alpha; float _oculusUIRadius; float _trailingAudioLoudness; From ca4d493ec9b831c9b816e45b51af5e1a3c19326d Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 14 Jan 2015 00:01:50 +0100 Subject: [PATCH 021/103] added HMD.VRMode to HMDScriptingInterface --- interface/src/scripting/HMDScriptingInterface.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index 4852d9ae6e..e2ffc514cd 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -13,10 +13,12 @@ #define hifi_HMDScriptingInterface_h #include "Application.h" +#include "devices/OculusManager.h" class HMDScriptingInterface : public QObject { Q_OBJECT Q_PROPERTY(bool magnifier READ getMagnifier) + Q_PROPERTY(bool VRMode READ getVRMode) public: static HMDScriptingInterface& getInstance(); @@ -26,6 +28,7 @@ public slots: private: HMDScriptingInterface() {}; bool getMagnifier() const { return Application::getInstance()->getApplicationOverlay().hasMagnifier(); }; + bool getVRMode() const { return OculusManager::isConnected(); } }; From 0f6ad4eba02c55447b7e70332e854d16a24687d1 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 14 Jan 2015 00:07:15 +0100 Subject: [PATCH 022/103] HMD.VRMode -> HMD.active , and hooked it to a function which isn't dependent on HMD type, since there will be more HMD's than Oculus supported in the near future. --- interface/src/scripting/HMDScriptingInterface.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index e2ffc514cd..2c485195e5 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -13,12 +13,11 @@ #define hifi_HMDScriptingInterface_h #include "Application.h" -#include "devices/OculusManager.h" class HMDScriptingInterface : public QObject { Q_OBJECT Q_PROPERTY(bool magnifier READ getMagnifier) - Q_PROPERTY(bool VRMode READ getVRMode) + Q_PROPERTY(bool active READ isHMDMode) public: static HMDScriptingInterface& getInstance(); @@ -28,7 +27,7 @@ public slots: private: HMDScriptingInterface() {}; bool getMagnifier() const { return Application::getInstance()->getApplicationOverlay().hasMagnifier(); }; - bool getVRMode() const { return OculusManager::isConnected(); } + bool isHMDMode() const { return Application::getInstance()->isHMDMode(); } }; From 38d49854cbfa8254fbdf79de0274bdcac7609383 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 14 Jan 2015 01:06:44 +0100 Subject: [PATCH 023/103] hide cursor --- examples/controllers/oculus/goTo.js | 7 +++-- examples/libraries/virtualKeyboard.js | 38 +++++++++++++++++++-------- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/examples/controllers/oculus/goTo.js b/examples/controllers/oculus/goTo.js index ba1ee1eb81..3966c28a5c 100644 --- a/examples/controllers/oculus/goTo.js +++ b/examples/controllers/oculus/goTo.js @@ -20,7 +20,7 @@ Script.include("../../libraries/globals.js"); Script.include("../../libraries/virtualKeyboard.js"); var windowDimensions = Controller.getViewportDimensions(); -var cursor = null; +var cursor = new Cursor({visible: false}); var keyboard = new Keyboard({visible: false}); var textFontSize = 9; var text = null; @@ -91,7 +91,7 @@ keyboard.onFullyLoaded = function() { }); updateTextOverlay(); // the cursor is being loaded after the keyboard, else it will be on the background of the keyboard - cursor = new Cursor(); + cursor.updateVisibility(keyboard.visible); cursor.onUpdate = function(position) { keyboard.setFocusPosition(position.x, position.y); }; @@ -102,6 +102,9 @@ function keyPressEvent(event) { keyboard.pressFocussedKey(); } else if (event.key === ENTER_CHARCODE || event.key === RETURN_CHARCODE) { keyboard.toggle(); + if (cursor !== undefined) { + cursor.updateVisibility(keyboard.visible); + } Overlays.editOverlay(text, {visible: keyboard.visible}); } } diff --git a/examples/libraries/virtualKeyboard.js b/examples/libraries/virtualKeyboard.js index 854ca58d1d..d93e569af5 100644 --- a/examples/libraries/virtualKeyboard.js +++ b/examples/libraries/virtualKeyboard.js @@ -184,7 +184,7 @@ Keyboard = (function(params) { this.focussed_key = -1; this.scale = (windowDimensions.x / KEYBOARD_WIDTH) * KEYBOARD_SCALE_MULTIPLIER; this.shift = false; - this.visible = params.visible != undefined ? params.visible :true; + this.visible = params.visible != undefined ? params.visible : true; this.width = function() { return KEYBOARD_WIDTH * tthis.scale; }; @@ -320,21 +320,19 @@ Keyboard = (function(params) { }; this.show = function() { - tthis.visible = true; - tthis.updateVisibility(); + tthis.updateVisibility(true); }; this.hide = function() { - tthis.visible = false; - tthis.updateVisibility(); + tthis.updateVisibility(false); }; this.toggle = function() { - tthis.visible = !tthis.visible; - tthis.updateVisibility(); + tthis.updateVisibility(!tthis.visible); }; - - this.updateVisibility = function() { + + this.updateVisibility = function(visible) { + tthis.visible = visible; Overlays.editOverlay(tthis.background, { visible: tthis.visible }); for (var i = 0; i < this.keys.length; i++) { this.keys[i].updateVisibility(); @@ -454,8 +452,12 @@ Keyboard = (function(params) { this.keyboardTextureLoaded_timer = Script.setInterval(this.keyboardTextureLoaded, 250); }); -Cursor = (function() { +Cursor = (function(params) { + if (params === undefined) { + params = {}; + } var tthis = this; + this.visible = params.visible != undefined ? params.visible : true; this.x = windowDimensions.x / 2; this.y = windowDimensions.y / 2; this.overlay = Overlays.addOverlay("image", { @@ -464,7 +466,8 @@ Cursor = (function() { width: CURSOR_WIDTH, height: CURSOR_HEIGHT, imageURL: CURSOR_URL, - alpha: 1 + alpha: 1, + visible: this.visible }); this.remove = function() { Overlays.deleteOverlay(this.overlay); @@ -478,6 +481,19 @@ Cursor = (function() { this.getY = function() { return tthis.y; }; + this.show = function() { + tthis.updateVisibility(true); + }; + this.hide = function() { + tthis.updateVisibility(false); + }; + this.toggle = function() { + tthis.updateVisibility(!tthis.visible); + }; + this.updateVisibility = function(visible) { + tthis.visible = visible; + Overlays.editOverlay(this.overlay, { visible: tthis.visible }); + }; this.onUpdate = null; this.update = function() { var newWindowDimensions = Controller.getViewportDimensions(); From e3c55584702da79509f897601bdbb52843e0ddc2 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 14 Jan 2015 01:18:53 +0100 Subject: [PATCH 024/103] toggle magnifier when keyboard visibility changes --- examples/libraries/virtualKeyboard.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/libraries/virtualKeyboard.js b/examples/libraries/virtualKeyboard.js index d93e569af5..2671871fac 100644 --- a/examples/libraries/virtualKeyboard.js +++ b/examples/libraries/virtualKeyboard.js @@ -333,6 +333,9 @@ Keyboard = (function(params) { this.updateVisibility = function(visible) { tthis.visible = visible; + if (HMD.magnifier == visible) { + HMD.toggleMagnifier(); + } Overlays.editOverlay(tthis.background, { visible: tthis.visible }); for (var i = 0; i < this.keys.length; i++) { this.keys[i].updateVisibility(); From 12136e5305e9756e1770c6753339b140cb92c7d9 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Thu, 15 Jan 2015 22:25:59 +0100 Subject: [PATCH 025/103] cursor follows look at rotation now --- examples/controllers/oculus/goTo.js | 5 +- examples/libraries/virtualKeyboard.js | 134 +++++++++--------- .../src/scripting/HMDScriptingInterface.h | 20 +++ 3 files changed, 91 insertions(+), 68 deletions(-) diff --git a/examples/controllers/oculus/goTo.js b/examples/controllers/oculus/goTo.js index 3966c28a5c..5038253e17 100644 --- a/examples/controllers/oculus/goTo.js +++ b/examples/controllers/oculus/goTo.js @@ -20,7 +20,7 @@ Script.include("../../libraries/globals.js"); Script.include("../../libraries/virtualKeyboard.js"); var windowDimensions = Controller.getViewportDimensions(); -var cursor = new Cursor({visible: false}); +var cursor = new Cursor({visible: false});; var keyboard = new Keyboard({visible: false}); var textFontSize = 9; var text = null; @@ -66,7 +66,7 @@ keyboard.onKeyRelease = function(event) { print("going to hifi://" + locationURL); location = "hifi://" + locationURL; locationURL = ""; - keyboard.hide(); + keyboard.hide(); updateTextOverlay(); } } @@ -91,6 +91,7 @@ keyboard.onFullyLoaded = function() { }); updateTextOverlay(); // the cursor is being loaded after the keyboard, else it will be on the background of the keyboard + cursor.initialize(); cursor.updateVisibility(keyboard.visible); cursor.onUpdate = function(position) { keyboard.setFocusPosition(position.x, position.y); diff --git a/examples/libraries/virtualKeyboard.js b/examples/libraries/virtualKeyboard.js index 2671871fac..8035f9d701 100644 --- a/examples/libraries/virtualKeyboard.js +++ b/examples/libraries/virtualKeyboard.js @@ -460,71 +460,73 @@ Cursor = (function(params) { params = {}; } var tthis = this; - this.visible = params.visible != undefined ? params.visible : true; - this.x = windowDimensions.x / 2; - this.y = windowDimensions.y / 2; - this.overlay = Overlays.addOverlay("image", { - x: this.x, - y: this.y, - width: CURSOR_WIDTH, - height: CURSOR_HEIGHT, - imageURL: CURSOR_URL, - alpha: 1, - visible: this.visible - }); - this.remove = function() { - Overlays.deleteOverlay(this.overlay); + this.initialize = function() { + this.visible = params.visible != undefined ? params.visible : true; + this.x = windowDimensions.x / 2; + this.y = windowDimensions.y / 2; + this.overlay = Overlays.addOverlay("image", { + x: this.x, + y: this.y, + width: CURSOR_WIDTH, + height: CURSOR_HEIGHT, + imageURL: CURSOR_URL, + alpha: 1, + visible: this.visible + }); + this.remove = function() { + Overlays.deleteOverlay(this.overlay); + }; + this.getPosition = function() { + return {x: tthis.getX(), y: tthis.getY()}; + }; + this.getX = function() { + return tthis.x; + }; + this.getY = function() { + return tthis.y; + }; + this.show = function() { + tthis.updateVisibility(true); + }; + this.hide = function() { + tthis.updateVisibility(false); + }; + this.toggle = function() { + tthis.updateVisibility(!tthis.visible); + }; + this.updateVisibility = function(visible) { + tthis.visible = visible; + Overlays.editOverlay(this.overlay, { visible: tthis.visible }); + }; + this.onUpdate = null; + this.update = function() { + var newWindowDimensions = Controller.getViewportDimensions(); + if (newWindowDimensions.x != windowDimensions.x || newWindowDimensions.y != windowDimensions.y) { + windowDimensions = newWindowDimensions; + keyboard.rescale(); + Overlays.editOverlay(text, { + y: windowDimensions.y - keyboard.height() - 260, + width: windowDimensions.x + }); + } + var editobject = {}; + //if (MyAvatar.getHeadFinalYaw() <= VIEW_ANGLE_BY_TWO && MyAvatar.getHeadFinalYaw() >= -1 * VIEW_ANGLE_BY_TWO) { + //angle = ((-1 * MyAvatar.getHeadFinalYaw()) + VIEW_ANGLE_BY_TWO) / VIEW_ANGLE; + tthis.x = HMD.getHUDLookAtPositionX;//angle * windowDimensions.x; + editobject.x = tthis.x - (CURSOR_WIDTH / 2); + // } + // if (MyAvatar.getHeadFinalPitch() <= VIEW_ANGLE_BY_TWO && MyAvatar.getHeadFinalPitch() >= -1 * VIEW_ANGLE_BY_TWO) { + // angle = ((-1 * MyAvatar.getHeadFinalPitch()) + VIEW_ANGLE_BY_TWO) / VIEW_ANGLE; + tthis.y = HMD.getHUDLookAtPositionY;//angle * windowDimensions.y; + editobject.y = tthis.y - (CURSOR_HEIGHT / 2); + // } + if (Object.keys(editobject).length > 0) { + Overlays.editOverlay(tthis.overlay, editobject); + if (tthis.onUpdate != null) { + tthis.onUpdate(tthis.getPosition()); + } + } + }; + Script.update.connect(this.update); }; - this.getPosition = function() { - return {x: tthis.getX(), y: tthis.getY()}; - }; - this.getX = function() { - return tthis.x; - }; - this.getY = function() { - return tthis.y; - }; - this.show = function() { - tthis.updateVisibility(true); - }; - this.hide = function() { - tthis.updateVisibility(false); - }; - this.toggle = function() { - tthis.updateVisibility(!tthis.visible); - }; - this.updateVisibility = function(visible) { - tthis.visible = visible; - Overlays.editOverlay(this.overlay, { visible: tthis.visible }); - }; - this.onUpdate = null; - this.update = function() { - var newWindowDimensions = Controller.getViewportDimensions(); - if (newWindowDimensions.x != windowDimensions.x || newWindowDimensions.y != windowDimensions.y) { - windowDimensions = newWindowDimensions; - keyboard.rescale(); - Overlays.editOverlay(text, { - y: windowDimensions.y - keyboard.height() - 260, - width: windowDimensions.x - }); - } - var editobject = {}; - if (MyAvatar.getHeadFinalYaw() <= VIEW_ANGLE_BY_TWO && MyAvatar.getHeadFinalYaw() >= -1 * VIEW_ANGLE_BY_TWO) { - angle = ((-1 * MyAvatar.getHeadFinalYaw()) + VIEW_ANGLE_BY_TWO) / VIEW_ANGLE; - tthis.x = angle * windowDimensions.x; - editobject.x = tthis.x - (CURSOR_WIDTH / 2); - } - if (MyAvatar.getHeadFinalPitch() <= VIEW_ANGLE_BY_TWO && MyAvatar.getHeadFinalPitch() >= -1 * VIEW_ANGLE_BY_TWO) { - angle = ((-1 * MyAvatar.getHeadFinalPitch()) + VIEW_ANGLE_BY_TWO) / VIEW_ANGLE; - tthis.y = angle * windowDimensions.y; - editobject.y = tthis.y - (CURSOR_HEIGHT / 2); - } - if (Object.keys(editobject).length > 0) { - Overlays.editOverlay(tthis.overlay, editobject); - if (tthis.onUpdate != null) { - tthis.onUpdate(tthis.getPosition()); - } - } - }; - Script.update.connect(this.update); }); diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index 2c485195e5..a4950008eb 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -12,12 +12,17 @@ #ifndef hifi_HMDScriptingInterface_h #define hifi_HMDScriptingInterface_h +#include + #include "Application.h" +#include "devices/OculusManager.h" class HMDScriptingInterface : public QObject { Q_OBJECT Q_PROPERTY(bool magnifier READ getMagnifier) Q_PROPERTY(bool active READ isHMDMode) + Q_PROPERTY(float getHUDLookAtPositionX READ getHUDLookAtPositionX) + Q_PROPERTY(float getHUDLookAtPositionY READ getHUDLookAtPositionY) public: static HMDScriptingInterface& getInstance(); @@ -28,6 +33,21 @@ private: HMDScriptingInterface() {}; bool getMagnifier() const { return Application::getInstance()->getApplicationOverlay().hasMagnifier(); }; bool isHMDMode() const { return Application::getInstance()->isHMDMode(); } + float getHUDLookAtPositionX() const { + float pitch, yaw, roll; + OculusManager::getEulerAngles(yaw, pitch, roll); + glm::vec3 relativePos = OculusManager::getRelativePosition(); + glm::quat rotation = ::rotationBetween(glm::vec3(), relativePos); + glm::vec2 screenPos = Application::getInstance()->getApplicationOverlay().sphericalToOverlay(glm::vec2(yaw, -pitch)); + + return screenPos.x; + } + float getHUDLookAtPositionY() const { + float pitch, yaw, roll; + OculusManager::getEulerAngles(yaw, pitch, roll); + glm::vec2 screenPos = Application::getInstance()->getApplicationOverlay().sphericalToOverlay(glm::vec2(yaw, -pitch)); + return screenPos.y; + } }; From 9e51bece6325c7cc5660fd741bd6fd73ae73c2cc Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 21 Jan 2015 15:07:32 +0100 Subject: [PATCH 026/103] More accurate HMD-cursor on virtual keyboard, thanks Simon and @ctrlaltdavid for the help on this! --- examples/libraries/virtualKeyboard.js | 14 +++++----- interface/src/devices/OculusManager.cpp | 2 +- .../src/scripting/HMDScriptingInterface.cpp | 27 +++++++++++++++++++ .../src/scripting/HMDScriptingInterface.h | 21 +++------------ 4 files changed, 38 insertions(+), 26 deletions(-) diff --git a/examples/libraries/virtualKeyboard.js b/examples/libraries/virtualKeyboard.js index 8035f9d701..0b6ff49d71 100644 --- a/examples/libraries/virtualKeyboard.js +++ b/examples/libraries/virtualKeyboard.js @@ -510,16 +510,14 @@ Cursor = (function(params) { }); } var editobject = {}; - //if (MyAvatar.getHeadFinalYaw() <= VIEW_ANGLE_BY_TWO && MyAvatar.getHeadFinalYaw() >= -1 * VIEW_ANGLE_BY_TWO) { - //angle = ((-1 * MyAvatar.getHeadFinalYaw()) + VIEW_ANGLE_BY_TWO) / VIEW_ANGLE; - tthis.x = HMD.getHUDLookAtPositionX;//angle * windowDimensions.x; + if (tthis.x !== HMD.getHUDLookAtPosition2D.x) { + tthis.x = HMD.getHUDLookAtPosition2D.x; editobject.x = tthis.x - (CURSOR_WIDTH / 2); - // } - // if (MyAvatar.getHeadFinalPitch() <= VIEW_ANGLE_BY_TWO && MyAvatar.getHeadFinalPitch() >= -1 * VIEW_ANGLE_BY_TWO) { - // angle = ((-1 * MyAvatar.getHeadFinalPitch()) + VIEW_ANGLE_BY_TWO) / VIEW_ANGLE; - tthis.y = HMD.getHUDLookAtPositionY;//angle * windowDimensions.y; + } + if (tthis.y !== HMD.getHUDLookAtPosition2D.y) { + tthis.y = HMD.getHUDLookAtPosition2D.y; editobject.y = tthis.y - (CURSOR_HEIGHT / 2); - // } + } if (Object.keys(editobject).length > 0) { Overlays.editOverlay(tthis.overlay, editobject); if (tthis.onUpdate != null) { diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index 256c09f602..47279a40f9 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -685,7 +685,7 @@ void OculusManager::getEulerAngles(float& yaw, float& pitch, float& roll) { roll = 0.0f; #endif } - + glm::vec3 OculusManager::getRelativePosition() { #if (defined(__APPLE__) || defined(_WIN32)) && HAVE_LIBOVR ovrTrackingState trackingState = ovrHmd_GetTrackingState(_ovrHmd, ovr_GetTimeInSeconds()); diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index b9b9b103e4..caf37e27be 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -15,3 +15,30 @@ HMDScriptingInterface& HMDScriptingInterface::getInstance() { static HMDScriptingInterface sharedInstance; return sharedInstance; } + +glm::vec3 HMDScriptingInterface::getHUDLookAtPosition3D() const { + Camera* camera = Application::getInstance()->getCamera(); + glm::vec3 position = camera->getPosition(); + glm::quat orientation = camera->getOrientation(); + + glm::vec3 direction = orientation * glm::vec3(0.0f, 0.0f, -1.0f); + + ApplicationOverlay& applicationOverlay = Application::getInstance()->getApplicationOverlay(); + + glm::vec3 result; + applicationOverlay.calculateRayUICollisionPoint(position, direction, result); + return result; +} + +glm::vec2 HMDScriptingInterface::getHUDLookAtPosition2D() const { + MyAvatar* myAvatar = Application::getInstance()->getAvatar(); + glm::vec3 sphereCenter = myAvatar->getDefaultEyePosition(); + + glm::vec3 hudIntersection = getHUDLookAtPosition3D(); + + glm::vec3 direction = glm::inverse(myAvatar->getOrientation()) * (hudIntersection - sphereCenter); + glm::quat rotation = ::rotationBetween(glm::vec3(0.0f, 0.0f, -1.0f), direction); + glm::vec3 eulers = ::safeEulerAngles(rotation); + + return Application::getInstance()->getApplicationOverlay().sphericalToOverlay(glm::vec2(eulers.y, -eulers.x));; +} diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index a4950008eb..cc148d5d5d 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -21,8 +21,8 @@ class HMDScriptingInterface : public QObject { Q_OBJECT Q_PROPERTY(bool magnifier READ getMagnifier) Q_PROPERTY(bool active READ isHMDMode) - Q_PROPERTY(float getHUDLookAtPositionX READ getHUDLookAtPositionX) - Q_PROPERTY(float getHUDLookAtPositionY READ getHUDLookAtPositionY) + Q_PROPERTY(glm::vec3 HUDLookAtPosition3D READ getHUDLookAtPosition3D) + Q_PROPERTY(glm::vec2 HUDLookAtPosition2D READ getHUDLookAtPosition2D) public: static HMDScriptingInterface& getInstance(); @@ -33,22 +33,9 @@ private: HMDScriptingInterface() {}; bool getMagnifier() const { return Application::getInstance()->getApplicationOverlay().hasMagnifier(); }; bool isHMDMode() const { return Application::getInstance()->isHMDMode(); } - float getHUDLookAtPositionX() const { - float pitch, yaw, roll; - OculusManager::getEulerAngles(yaw, pitch, roll); - glm::vec3 relativePos = OculusManager::getRelativePosition(); - glm::quat rotation = ::rotationBetween(glm::vec3(), relativePos); - glm::vec2 screenPos = Application::getInstance()->getApplicationOverlay().sphericalToOverlay(glm::vec2(yaw, -pitch)); - - return screenPos.x; - } - float getHUDLookAtPositionY() const { - float pitch, yaw, roll; - OculusManager::getEulerAngles(yaw, pitch, roll); - glm::vec2 screenPos = Application::getInstance()->getApplicationOverlay().sphericalToOverlay(glm::vec2(yaw, -pitch)); - return screenPos.y; - } + glm::vec3 getHUDLookAtPosition3D() const; + glm::vec2 getHUDLookAtPosition2D() const; }; #endif // hifi_HMDScriptingInterface_h From 87b2c362fc02aa6a86a125d865e33f7c34612460 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 21 Jan 2015 17:19:51 +0100 Subject: [PATCH 027/103] style --- interface/src/scripting/HMDScriptingInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index caf37e27be..e2d150e390 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -40,5 +40,5 @@ glm::vec2 HMDScriptingInterface::getHUDLookAtPosition2D() const { glm::quat rotation = ::rotationBetween(glm::vec3(0.0f, 0.0f, -1.0f), direction); glm::vec3 eulers = ::safeEulerAngles(rotation); - return Application::getInstance()->getApplicationOverlay().sphericalToOverlay(glm::vec2(eulers.y, -eulers.x));; + return Application::getInstance()->getApplicationOverlay().sphericalToOverlay(glm::vec2(eulers.y, -eulers.x)); } From 724b56ed8c1eb63929f7ccdd9826435d6a11eaee Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Thu, 22 Jan 2015 01:09:16 +0100 Subject: [PATCH 028/103] HMD.getHUDLookAtPosition2D -> HMD.HUDLookAtPosition2D --- examples/libraries/virtualKeyboard.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/libraries/virtualKeyboard.js b/examples/libraries/virtualKeyboard.js index 0b6ff49d71..c62498685c 100644 --- a/examples/libraries/virtualKeyboard.js +++ b/examples/libraries/virtualKeyboard.js @@ -510,12 +510,12 @@ Cursor = (function(params) { }); } var editobject = {}; - if (tthis.x !== HMD.getHUDLookAtPosition2D.x) { - tthis.x = HMD.getHUDLookAtPosition2D.x; + if (tthis.x !== HMD.HUDLookAtPosition2D.x) { + tthis.x = HMD.HUDLookAtPosition2D.x; editobject.x = tthis.x - (CURSOR_WIDTH / 2); } - if (tthis.y !== HMD.getHUDLookAtPosition2D.y) { - tthis.y = HMD.getHUDLookAtPosition2D.y; + if (tthis.y !== HMD.HUDLookAtPosition2D.y) { + tthis.y = HMD.HUDLookAtPosition2D.y; editobject.y = tthis.y - (CURSOR_HEIGHT / 2); } if (Object.keys(editobject).length > 0) { From 3e4f4ecc6b97dd050a43c052842daa90bca9e781 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 28 Jan 2015 00:39:19 +0100 Subject: [PATCH 029/103] addOverlay rather than cloneOverlay now that we have a TextureCache for the ImageOverlay --- examples/libraries/virtualKeyboard.js | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/examples/libraries/virtualKeyboard.js b/examples/libraries/virtualKeyboard.js index c62498685c..42185138e3 100644 --- a/examples/libraries/virtualKeyboard.js +++ b/examples/libraries/virtualKeyboard.js @@ -147,9 +147,13 @@ KeyboardKey = (function(keyboard, keyProperties) { return true; }; for (var i = 0; i < this.bounds.length; i++) { - var newOverlay = Overlays.cloneOverlay(this.keyboard.background); if (THREE_D_MODE) { - Overlays.editOverlay(newOverlay, { + this.overlays.push(Overlays.addOverlay("billboard", { + scale: 1, + rotation: MyAvatar.rotation, + isFacingAvatar: false, + url: KEYBOARD_URL, + alpha: 1, position: { x: MyAvatar.position.x,// + this.bounds[i][BOUND_X] * 0.01,// /*+ this.keyboard.getX()*/ + this.bounds[i][BOUND_X] * keyboard.scale, y: MyAvatar.position.y,// - this.bounds[i][BOUND_Y] * 0.01,// /*+ this.keyboard.getY()*/ + this.bounds[i][BOUND_Y] * keyboard.scale, @@ -160,9 +164,10 @@ KeyboardKey = (function(keyboard, keyProperties) { subImage: {width: this.bounds[i][BOUND_W], height: this.bounds[i][BOUND_H], x: this.bounds[i][BOUND_X], y: (KEYBOARD_HEIGHT * this.keyState) + this.bounds[i][BOUND_Y]}, alpha: 1, visible: tthis.keyboard.visible - }); + })); } else { - Overlays.editOverlay(newOverlay, { + this.overlays.push(Overlays.addOverlay("image", { + imageURL: KEYBOARD_URL, x: this.keyboard.getX() + this.bounds[i][BOUND_X] * keyboard.scale, y: this.keyboard.getY() + this.bounds[i][BOUND_Y] * keyboard.scale, width: this.bounds[i][BOUND_W] * keyboard.scale, @@ -170,9 +175,8 @@ KeyboardKey = (function(keyboard, keyProperties) { subImage: {width: this.bounds[i][BOUND_W], height: this.bounds[i][BOUND_H], x: this.bounds[i][BOUND_X], y: (KEYBOARD_HEIGHT * this.keyState) + this.bounds[i][BOUND_Y]}, alpha: 1, visible: tthis.keyboard.visible - }); + })); } - this.overlays.push(newOverlay); } }); @@ -440,13 +444,12 @@ Keyboard = (function(params) { {bounds: [[899, 355, 263, 67]], event: 'submit'} ]; - + for (var i = 0; i < keyProperties.length; i++) { + this.keys.push(new KeyboardKey(this, keyProperties[i])); + } this.keyboardTextureLoaded = function() { if (Overlays.isLoaded(tthis.background)) { Script.clearInterval(tthis.keyboardTextureLoaded_timer); - for (var i = 0; i < keyProperties.length; i++) { - tthis.keys.push(new KeyboardKey(tthis, keyProperties[i])); - } if (keyboard.onFullyLoaded != null) { tthis.onFullyLoaded(); } From ae3233b11918904aa57bccd56165be44082537f0 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 27 Jan 2015 15:44:10 -0800 Subject: [PATCH 030/103] in the middle of something --- libraries/model/src/model/Geometry.h | 3 +- libraries/model/src/model/Material.h | 1 - .../render-utils/src/DeferredLighting.slh | 2 +- .../src/DeferredLightingEffect.cpp | 103 ++++++++++++++---- .../render-utils/src/DeferredLightingEffect.h | 13 ++- libraries/render-utils/src/point_light.slf | 11 +- libraries/render-utils/src/spot_light.slf | 16 ++- libraries/shared/src/Transform.h | 9 ++ 8 files changed, 130 insertions(+), 28 deletions(-) diff --git a/libraries/model/src/model/Geometry.h b/libraries/model/src/model/Geometry.h index 0beaa20a83..fbd485e6a0 100755 --- a/libraries/model/src/model/Geometry.h +++ b/libraries/model/src/model/Geometry.h @@ -23,6 +23,7 @@ typedef gpu::BufferView::Index Index; typedef gpu::BufferView BufferView; typedef AABox Box; typedef std::vector< Box > Boxes; +typedef glm::vec3 Vec3; class Mesh { public: @@ -35,7 +36,7 @@ public: typedef gpu::Stream::Format VertexFormat; typedef std::map< Slot, BufferView > BufferViewMap; - typedef glm::vec3 Vec3; + typedef model::Vec3 Vec3; Mesh(); Mesh(const Mesh& mesh); diff --git a/libraries/model/src/model/Material.h b/libraries/model/src/model/Material.h index efd2f35968..57e0f68a9c 100755 --- a/libraries/model/src/model/Material.h +++ b/libraries/model/src/model/Material.h @@ -100,7 +100,6 @@ public: void setTextureView(MapChannel channel, const TextureView& texture); const TextureMap& getTextureMap() const { return _textureMap; } - const Schema* getSchema() const { return &_schemaBuffer.get(); } protected: Flags _flags; diff --git a/libraries/render-utils/src/DeferredLighting.slh b/libraries/render-utils/src/DeferredLighting.slh index 9e421c03c9..cd65fd1053 100755 --- a/libraries/render-utils/src/DeferredLighting.slh +++ b/libraries/render-utils/src/DeferredLighting.slh @@ -59,7 +59,7 @@ vec3 evalDirectionalColor(float shadowAttenuation, vec3 position, vec3 normal, v // Diffuse Lighting float diffuseDot = dot(normal, gl_LightSource[0].position.xyz); float facingLight = step(0.0, diffuseDot) * shadowAttenuation; - vec3 diffuseColor = diffuse * (/*gl_FrontLightModelProduct.sceneColor.rgb +*/ gl_FrontLightProduct[0].diffuse.rgb * (diffuseDot * facingLight)); + vec3 diffuseColor = diffuse * (gl_FrontLightProduct[0].diffuse.rgb * (diffuseDot * facingLight)); // compute the specular multiplier (sans exponent) float specularPower = facingLight * max(0.0, diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 5cbdd04f64..58e90f57d1 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -25,6 +25,9 @@ #include "RenderUtil.h" #include "TextureCache.h" +#include "gpu/Batch.h" +#include "gpu/GLBackend.h" + #include "simple_vert.h" #include "simple_frag.h" @@ -269,7 +272,14 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu light.specular = glm::vec4(specular, 1.0f); light.constantAttenuation = constantAttenuation; light.linearAttenuation = linearAttenuation; - _pointLights.append(light); + + model::LightPointer lp = model::LightPointer(new model::Light()); + lp->setPosition(position); + lp->setAttenuationRadius(radius); + lp->setColor(diffuse); + lp->setIntensity(1.0f); + lp->setType(model::Light::POINT); + _pointLights.push_back(lp); } else { SpotLight light; @@ -283,7 +293,17 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu light.direction = direction; light.exponent = exponent; light.cutoff = cutoff; - _spotLights.append(light); + + model::LightPointer ls = model::LightPointer(new model::Light()); + ls->setPosition(position); + ls->setDirection(direction); + ls->setAttenuationRadius(radius); + ls->setSpotCone(cutoff); + ls->setColor(diffuse); + ls->setIntensity(1.0f); + ls->setType(model::Light::SPOT); + + _spotLights.push_back(ls); } } @@ -436,14 +456,24 @@ void DeferredLightingEffect::render() { auto geometryCache = DependencyManager::get(); - if (!_pointLights.isEmpty()) { + if (!_pointLights.empty()) { _pointLight.bind(); _pointLight.setUniformValue(_pointLightLocations.nearLocation, nearVal); _pointLight.setUniformValue(_pointLightLocations.depthScale, depthScale); _pointLight.setUniformValue(_pointLightLocations.depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT); _pointLight.setUniformValue(_pointLightLocations.depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT); - foreach (const PointLight& light, _pointLights) { + for (auto light : _pointLights) { + // foreach (const PointLight& light, _pointLights) { + if (_pointLightLocations.lightBufferUnit >= 0) { + gpu::Batch batch; + batch.setUniformBuffer(_pointLightLocations.lightBufferUnit, light->getSchemaBuffer()); + gpu::GLBackend::renderBatch(batch); + } + _spotLight.setUniformValue(_pointLightLocations.radius, light->getAttenuationRadius()); + + +/* _pointLight.setUniformValue(_pointLightLocations.radius, light.radius); glLightfv(GL_LIGHT1, GL_AMBIENT, (const GLfloat*)&light.ambient); glLightfv(GL_LIGHT1, GL_DIFFUSE, (const GLfloat*)&light.diffuse); @@ -452,11 +482,11 @@ void DeferredLightingEffect::render() { glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, (light.constantAttenuation > 0.0f ? light.constantAttenuation : 0.0f)); glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, (light.linearAttenuation > 0.0f ? light.linearAttenuation : 0.0f)); glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, (light.quadraticAttenuation > 0.0f ? light.quadraticAttenuation : 0.0f)); - + */ glPushMatrix(); - float expandedRadius = light.radius * (1.0f + SCALE_EXPANSION); - if (glm::distance(eyePoint, glm::vec3(light.position)) < expandedRadius + nearRadius) { + float expandedRadius = light->getAttenuationRadius() * (1.0f + SCALE_EXPANSION); + if (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius) { glLoadIdentity(); glTranslatef(0.0f, 0.0f, -1.0f); @@ -470,7 +500,7 @@ void DeferredLightingEffect::render() { glMatrixMode(GL_MODELVIEW); } else { - glTranslatef(light.position.x, light.position.y, light.position.z); + glTranslatef(light->getPosition().x, light->getPosition().y, light->getPosition().z); geometryCache->renderSphere(expandedRadius, 32, 32); } @@ -481,15 +511,24 @@ void DeferredLightingEffect::render() { _pointLight.release(); } - if (!_spotLights.isEmpty()) { + if (!_spotLights.empty()) { _spotLight.bind(); _spotLight.setUniformValue(_spotLightLocations.nearLocation, nearVal); _spotLight.setUniformValue(_spotLightLocations.depthScale, depthScale); _spotLight.setUniformValue(_spotLightLocations.depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT); _spotLight.setUniformValue(_spotLightLocations.depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT); - foreach (const SpotLight& light, _spotLights) { - _spotLight.setUniformValue(_spotLightLocations.radius, light.radius); + for (auto light : _spotLights) { + // foreach (const SpotLight& light, _spotLights) { + if (_spotLightLocations.lightBufferUnit >= 0) { + gpu::Batch batch; + batch.setUniformBuffer(_spotLightLocations.lightBufferUnit, light->getSchemaBuffer()); + gpu::GLBackend::renderBatch(batch); + } + _spotLight.setUniformValue(_spotLightLocations.radius, light->getAttenuationRadius()); + + /* + _spotLight.setUniformValue(_spotLightLocations.radius, light.radius); glLightfv(GL_LIGHT1, GL_AMBIENT, (const GLfloat*)&light.ambient); glLightfv(GL_LIGHT1, GL_DIFFUSE, (const GLfloat*)&light.diffuse); glLightfv(GL_LIGHT1, GL_SPECULAR, (const GLfloat*)&light.specular); @@ -500,12 +539,13 @@ void DeferredLightingEffect::render() { glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, (const GLfloat*)&light.direction); glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, light.exponent); glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, glm::degrees(light.cutoff)); - + */ + glPushMatrix(); - float expandedRadius = light.radius * (1.0f + SCALE_EXPANSION); - float edgeRadius = expandedRadius / glm::cos(light.cutoff); - if (glm::distance(eyePoint, glm::vec3(light.position)) < edgeRadius + nearRadius) { + float expandedRadius = light->getAttenuationRadius() * (1.0f + SCALE_EXPANSION); + float edgeRadius = expandedRadius / glm::cos(light->getSpotConeAngle()); + if (glm::distance(eyePoint, glm::vec3(light->getPosition())) < edgeRadius + nearRadius) { glLoadIdentity(); glTranslatef(0.0f, 0.0f, -1.0f); @@ -519,12 +559,12 @@ void DeferredLightingEffect::render() { glMatrixMode(GL_MODELVIEW); } else { - glTranslatef(light.position.x, light.position.y, light.position.z); - glm::quat spotRotation = rotationBetween(glm::vec3(0.0f, 0.0f, -1.0f), light.direction); + glTranslatef(light->getPosition().x, light->getPosition().y, light->getPosition().z); + glm::quat spotRotation = rotationBetween(glm::vec3(0.0f, 0.0f, -1.0f), light->getDirection()); glm::vec3 axis = glm::axis(spotRotation); glRotatef(glm::degrees(glm::angle(spotRotation)), axis.x, axis.y, axis.z); - glTranslatef(0.0f, 0.0f, -light.radius * (1.0f + SCALE_EXPANSION * 0.5f)); - geometryCache->renderCone(expandedRadius * glm::tan(light.cutoff), + glTranslatef(0.0f, 0.0f, -light->getAttenuationRadius() * (1.0f + SCALE_EXPANSION * 0.5f)); + geometryCache->renderCone(expandedRadius * glm::tan(light->getSpotConeAngle()), expandedRadius, 32, 1); } @@ -609,6 +649,31 @@ void DeferredLightingEffect::loadLightProgram(const char* fragSource, bool limit locations.depthTexCoordScale = program.uniformLocation("depthTexCoordScale"); locations.radius = program.uniformLocation("radius"); locations.ambientSphere = program.uniformLocation("ambientSphere.L00"); + + GLint loc = -1; +#if defined(Q_OS_MAC) + loc = program.uniformLocation("lightBuffer"); + if (loc >= 0) { + locations.lightBufferUnit = loc; + } else { + locations.lightBufferUnit = -1; + } +#elif defined(Q_OS_WIN) + loc = glGetUniformBlockIndex(program.programId(), "lightBuffer"); + if (loc >= 0) { + glUniformBlockBinding(program.programId(), loc, 1); + locations.lightBufferUnit = 1; + } else { + locations.lightBufferUnit = -1; + } +#else + loc = program.uniformLocation("lightBuffer"); + if (loc >= 0) { + locations.lightBufferUnit = loc; + } else { + locations.lightBufferUnit = -1; + } +#endif program.release(); } diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index cd8585eade..5c39c3041e 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -19,6 +19,8 @@ #include "ProgramObject.h" +#include "model/Light.h" + class AbstractViewStateInterface; class PostLightingRenderable; @@ -102,6 +104,7 @@ private: int depthTexCoordScale; int radius; int ambientSphere; + int lightBufferUnit; }; static void loadLightProgram(const char* fragSource, bool limited, ProgramObject& program, LightLocations& locations); @@ -146,9 +149,13 @@ private: float exponent; float cutoff; }; - - QVector _pointLights; - QVector _spotLights; + + typedef std::vector< model::LightPointer > Lights; + + Lights _pointLights; + Lights _spotLights; + // QVector _pointLights; + // QVector _spotLights; QVector _postLightingRenderables; AbstractViewStateInterface* _viewState; diff --git a/libraries/render-utils/src/point_light.slf b/libraries/render-utils/src/point_light.slf index e5142b25ce..9d9aecda95 100644 --- a/libraries/render-utils/src/point_light.slf +++ b/libraries/render-utils/src/point_light.slf @@ -15,16 +15,23 @@ // Everything about deferred buffer <@include DeferredBuffer.slh@> +// Everything about light +<@include Light.slh@> + // the radius (hard cutoff) of the light effect uniform float radius; void main(void) { // get the depth and exit early if it doesn't pass the test vec2 texCoord = gl_TexCoord[0].st / gl_TexCoord[0].q; - float depth = texture2D(depthMap, texCoord).r; + + DeferredFragment frag = unpackDeferredFragment(texCoord); + + float depth = frag.depthVal; if (depth < gl_FragCoord.z) { discard; } + // compute the view space position using the depth float z = near / (depth * depthScale - 1.0); vec4 position = vec4((depthTexCoordOffset + texCoord * depthTexCoordScale) * z, z, 1.0); @@ -52,4 +59,6 @@ void main(void) { normalizedNormal)); vec4 specularColor = texture2D(specularMap, texCoord); gl_FragColor = vec4((baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb) * attenuation, 0.0); + + gl_FragColor = vec4(frag.normal, 0.0); } diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf index f987760eb8..48e8ab0d61 100644 --- a/libraries/render-utils/src/spot_light.slf +++ b/libraries/render-utils/src/spot_light.slf @@ -15,20 +15,30 @@ // Everything about deferred buffer <@include DeferredBuffer.slh@> +// Everything about light +<@include Light.slh@> + // the radius (hard cutoff) of the light effect uniform float radius; void main(void) { - // get the depth and exit early if it doesn't pass the test vec2 texCoord = gl_TexCoord[0].st / gl_TexCoord[0].q; - float depth = texture2D(depthMap, texCoord).r; + + DeferredFragment frag = unpackDeferredFragment(texCoord); + + // get the depth and exit early if it doesn't pass the test + float depth = frag.depthVal; if (depth < gl_FragCoord.z) { discard; } + + + // compute the view space position using the depth float z = near / (depth * depthScale - 1.0); vec4 position = vec4((depthTexCoordOffset + texCoord * depthTexCoordScale) * z, z, 1.0); + // get the normal from the map vec4 normal = texture2D(normalMap, texCoord); vec4 normalizedNormal = normalize(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0)); @@ -54,4 +64,6 @@ void main(void) { normalizedNormal)); vec4 specularColor = texture2D(specularMap, texCoord); gl_FragColor = vec4((baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb) * attenuation, 0.0); + + gl_FragColor = vec4(frag.normal, 0.0); } diff --git a/libraries/shared/src/Transform.h b/libraries/shared/src/Transform.h index e08f00c0ac..346a82a3b0 100644 --- a/libraries/shared/src/Transform.h +++ b/libraries/shared/src/Transform.h @@ -100,6 +100,8 @@ public: // Left will be inversed before the multiplication static Transform& inverseMult(Transform& result, const Transform& left, const Transform& right); + Vec4 transform(const Vec4& pos) const; + protected: enum Flag { @@ -414,6 +416,13 @@ inline Transform& Transform::inverseMult( Transform& result, const Transform& le return result; } +inline Transform::Vec4 Transform::transform(const Vec4& pos) const { + Mat4 m; + getMatrix(m); + return m * pos; +} + + inline Transform::Mat4& Transform::getCachedMatrix(Transform::Mat4& result) const { updateCache(); result = (*_matrix); From db427cdf5e3553088786c29db1254938ece763e1 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 27 Jan 2015 15:45:10 -0800 Subject: [PATCH 031/103] adding Light class in model and the shader in render utils --- libraries/model/src/model/Light.cpp | 94 ++++++++++++++++++++ libraries/model/src/model/Light.h | 124 +++++++++++++++++++++++++++ libraries/render-utils/src/Light.slh | 88 +++++++++++++++++++ 3 files changed, 306 insertions(+) create mode 100755 libraries/model/src/model/Light.cpp create mode 100755 libraries/model/src/model/Light.h create mode 100755 libraries/render-utils/src/Light.slh diff --git a/libraries/model/src/model/Light.cpp b/libraries/model/src/model/Light.cpp new file mode 100755 index 0000000000..ea62a564d5 --- /dev/null +++ b/libraries/model/src/model/Light.cpp @@ -0,0 +1,94 @@ +// +// Light.cpp +// libraries/model/src/model +// +// Created by Sam Gateau on 1/26/2014. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#include "Light.h" + +using namespace model; + +Light::Light() : + _flags(0), + _schemaBuffer(), + _transform() { + // only if created from nothing shall we create the Buffer to store the properties + Schema schema; + _schemaBuffer = gpu::BufferView(new gpu::Buffer(sizeof(Schema), (const gpu::Buffer::Byte*) &schema)); +} + +Light::Light(const Light& light) : + _flags(light._flags), + _schemaBuffer(light._schemaBuffer), + _transform(light._transform) { +} + +Light& Light::operator= (const Light& light) { + _flags = (light._flags); + _schemaBuffer = (light._schemaBuffer); + _transform = (light._transform); + + return (*this); +} + +Light::~Light() { +} + +void Light::setPosition(const Vec3& position) { + _transform.setTranslation(position); + _transform.getMatrix(editSchema()._transform); +} + +void Light::setOrientation(const glm::quat& orientation) { + _transform.setRotation(orientation); + _transform.getMatrix(editSchema()._transform); +} + +void Light::setDirection(const Vec3& direction) { + glm::mat3 rotation( + Vec3(1.0f, 0.0f, 0.0f), + Vec3(0.0f, 1.0f, 0.0f), + -direction); + + setOrientation(glm::quat(rotation)); +} + +const Vec3& Light::getDirection() const { + return Vec3(_transform.transform(Vec4(0.0f, 0.0f, 1.0f, 0.0f))); +} + +void Light::setColor(const Color& color) { + editSchema()._color = color; +} + +void Light::setIntensity(float intensity) { + editSchema()._intensity = intensity; +} + +void Light::setAttenuationRadius(float radius) { + if (radius <= 0.f) { + radius = 1.0f; + } + editSchema()._attenuation = Vec4(1.0f, 2.0f/radius, 1.0f/(radius*radius), radius); +} + +void Light::setSpotCone(float angle) { + if (angle <= 0.f) { + angle = 0.0f; + } + editSchema()._spot.x = cos(angle); + editSchema()._spot.z = angle; +} + +void Light::setSpotConeExponent(float exponent) { + if (exponent <= 0.f) { + exponent = 1.0f; + } + editSchema()._spot.y = exponent; + editSchema()._spot.w = exponent; +} + diff --git a/libraries/model/src/model/Light.h b/libraries/model/src/model/Light.h new file mode 100755 index 0000000000..f731255f8e --- /dev/null +++ b/libraries/model/src/model/Light.h @@ -0,0 +1,124 @@ +// +// Light.h +// libraries/model/src/model +// +// Created by Sam Gateau on 12/10/2014. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#ifndef hifi_model_Light_h +#define hifi_model_Light_h + +#include +#include + +#include +#include "Transform.h" +#include "gpu/Resource.h" +#include "gpu/Texture.h" + +namespace model { +typedef gpu::BufferView UniformBufferView; +typedef gpu::TextureView TextureView; +typedef glm::vec3 Vec3; +typedef glm::vec4 Vec4; +typedef glm::quat Quat; + +class Light { +public: + enum Type { + SUN = 0, + POINT, + SPOT, + + NUM_TYPES, + }; + + typedef Vec3 Color; + + enum FlagBit { + COLOR_BIT = 0, + INTENSITY_BIT, + RANGE_BIT, + SPOT_BIT, + TRANSFORM_BIT, + + NUM_FLAGS, + }; + typedef std::bitset Flags; + + Light(); + Light(const Light& light); + Light& operator= (const Light& light); + virtual ~Light(); + + void setType(Type type) { editSchema()._control.x = float(type); } + Type getType() const { return Type((int) getSchema()._control.x); } + + void setPosition(const Vec3& position); + const Vec3& getPosition() const { return _transform.getTranslation(); } + + void setDirection(const Vec3& direction); + const Vec3& getDirection() const; + + void setOrientation(const Quat& orientation); + const glm::quat& getOrientation() const { return _transform.getRotation(); } + + const Color& getColor() const { return getSchema()._color; } + void setColor(const Color& color); + + float getIntensity() const { return getSchema()._intensity; } + void setIntensity(float intensity); + + bool isRanged() const { return (getType() == POINT) || (getType() == SPOT ); } + + void setAttenuationRadius(float radius); + float getAttenuationRadius() const { return getSchema()._attenuation.w; } + + // Spot properties + bool isSpot() const { return getType() == SPOT; } + void setSpotCone(float angle); + void setSpotConeExponent(float exponent); + float getSpotConeAngle() const { return getSchema()._spot.z; } + float getSpotConeExponent() const { return getSchema()._spot.w; } + + // Schema to access the attribute values of the light + class Schema { + public: + glm::mat4 _transform; + Color _color; + float _intensity; + Vec4 _attenuation; + Vec4 _spot; + Vec4 _shadow; + + Vec4 _control; + + Schema() : + _transform(), + _color(1.0f), + _intensity(1.0f), + _attenuation(1.0f, 2.0f, 1.0f, 1.0f), + _spot(0.0f, 0.0f, 0.0f, 0.0f), + _control(0.0f) + {} + }; + + const UniformBufferView& getSchemaBuffer() const { return _schemaBuffer; } + +protected: + + Flags _flags; + UniformBufferView _schemaBuffer; + Transform _transform; + + const Schema& getSchema() const { return _schemaBuffer.get(); } + Schema& editSchema() { return _schemaBuffer.edit(); } +}; +typedef QSharedPointer< Light > LightPointer; + +}; + +#endif diff --git a/libraries/render-utils/src/Light.slh b/libraries/render-utils/src/Light.slh new file mode 100755 index 0000000000..e91d1d93cb --- /dev/null +++ b/libraries/render-utils/src/Light.slh @@ -0,0 +1,88 @@ + +<@if not LIGHT_SLH@> +<@def LIGHT_SLH@> + +struct Light { + mat4 _transform; + + vec4 _color; + vec4 _attenuation; + vec4 _spot; + + vec4 _shadow; + + vec4 _control; +}; + +vec3 getLightPosition(Light l) { return l._transform[3].xyz; } +vec3 getLightDirection(Light l) { return -l._transform[2].xyz; } // direction is -Z axis + +vec3 getLightColor(Light l) { return l._color.rgb; } +float getLightIntensity(Light l) { return l._color.w; } + +float evalLightAttenuation(Light l, float r) { + return clamp(1.0/(l._attenuation.x + l._attenuation.y * r + l._attenuation.z * r * r), 0.0, 1.0); +} + +float evalLightSpotAttenuation(Light l, float cosA) { + if (cosA > l._spot.x) { + return 0.0; + } + return clamp(pow(cosA / l._spot.x, l._spot.w), 0.0, 1.0); +} + + + +<@if GLPROFILE == PC_GL@> +uniform lightBuffer { + Light light; +}; +Light getLight() { + return light; +} +<@elif GLPROFILE == MAC_GL@> +uniform vec4 lightBuffer[9]; +Light getLight() { + Light light; + light._transform[0] = lightBuffer[0]; + light._transform[1] = lightBuffer[1]; + light._transform[2] = lightBuffer[2]; + light._transform[3] = lightBuffer[3]; + light._color = lightBuffer[4]; + light._range = lightBuffer[5]; + light._spot = lightBuffer[6]; + light._shadow = lightBuffer[7]; + light._control = lightBuffer[8]; + + return light; +} +<@else@> +uniform vec4 lightBuffer[9]; +Light getLight() { + Light light; + light._transform[0] = lightBuffer[0]; + light._transform[1] = lightBuffer[1]; + light._transform[2] = lightBuffer[2]; + light._transform[3] = lightBuffer[3]; + light._color = lightBuffer[4]; + light._range = lightBuffer[5]; + light._spot = lightBuffer[6]; + light._shadow = lightBuffer[7]; + light._control = lightBuffer[8]; + + return light; +} +<@endif@> + + + +<@endif@> From b6836af0711d0cfbdbd8694fc347f92d131e2e5b Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 28 Jan 2015 00:09:15 -0800 Subject: [PATCH 032/103] improving on the poin light attenuatiion formula --- libraries/model/src/model/Light.cpp | 18 ++++------ libraries/model/src/model/Light.h | 14 ++++---- .../src/DeferredLightingEffect.cpp | 23 +++++++----- .../render-utils/src/DeferredLightingEffect.h | 1 + libraries/render-utils/src/Light.slh | 17 ++++++--- libraries/render-utils/src/point_light.slf | 35 ++++++++++++------- 6 files changed, 64 insertions(+), 44 deletions(-) diff --git a/libraries/model/src/model/Light.cpp b/libraries/model/src/model/Light.cpp index ea62a564d5..201144622f 100755 --- a/libraries/model/src/model/Light.cpp +++ b/libraries/model/src/model/Light.cpp @@ -40,25 +40,19 @@ Light::~Light() { void Light::setPosition(const Vec3& position) { _transform.setTranslation(position); - _transform.getMatrix(editSchema()._transform); + editSchema()._position = Vec4(position, 1.f); } void Light::setOrientation(const glm::quat& orientation) { _transform.setRotation(orientation); - _transform.getMatrix(editSchema()._transform); } void Light::setDirection(const Vec3& direction) { - glm::mat3 rotation( - Vec3(1.0f, 0.0f, 0.0f), - Vec3(0.0f, 1.0f, 0.0f), - -direction); - - setOrientation(glm::quat(rotation)); + editSchema()._direction = Vec4(direction, 0.f); } const Vec3& Light::getDirection() const { - return Vec3(_transform.transform(Vec4(0.0f, 0.0f, 1.0f, 0.0f))); + return Vec3(getSchema()._direction); } void Light::setColor(const Color& color) { @@ -69,11 +63,13 @@ void Light::setIntensity(float intensity) { editSchema()._intensity = intensity; } -void Light::setAttenuationRadius(float radius) { +void Light::setMaximumRadius(float radius) { if (radius <= 0.f) { radius = 1.0f; } - editSchema()._attenuation = Vec4(1.0f, 2.0f/radius, 1.0f/(radius*radius), radius); + float CutOffIntensityRatio = 0.01f; + float surfaceRadius = radius / (sqrt(1.0f / CutOffIntensityRatio) - 1.f); + editSchema()._attenuation = Vec4(surfaceRadius, 1.0f/surfaceRadius, CutOffIntensityRatio, radius); } void Light::setSpotCone(float angle) { diff --git a/libraries/model/src/model/Light.h b/libraries/model/src/model/Light.h index f731255f8e..107d30fb5e 100755 --- a/libraries/model/src/model/Light.h +++ b/libraries/model/src/model/Light.h @@ -73,9 +73,9 @@ public: void setIntensity(float intensity); bool isRanged() const { return (getType() == POINT) || (getType() == SPOT ); } - - void setAttenuationRadius(float radius); - float getAttenuationRadius() const { return getSchema()._attenuation.w; } + + void setMaximumRadius(float radius); + float getMaximumRadius() const { return getSchema()._attenuation.w; } // Spot properties bool isSpot() const { return getType() == SPOT; } @@ -87,7 +87,8 @@ public: // Schema to access the attribute values of the light class Schema { public: - glm::mat4 _transform; + Vec4 _position; + Vec4 _direction; Color _color; float _intensity; Vec4 _attenuation; @@ -97,10 +98,11 @@ public: Vec4 _control; Schema() : - _transform(), + _position(0.0f, 0.0f, 0.0f, 1.0f), + _direction(0.0f, 0.0f, -1.0f, 0.f), _color(1.0f), _intensity(1.0f), - _attenuation(1.0f, 2.0f, 1.0f, 1.0f), + _attenuation(1.0f, 1.0f, 1.0f, 1.0f), _spot(0.0f, 0.0f, 0.0f, 0.0f), _control(0.0f) {} diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 58e90f57d1..6899a47c99 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -275,7 +275,7 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu model::LightPointer lp = model::LightPointer(new model::Light()); lp->setPosition(position); - lp->setAttenuationRadius(radius); + lp->setMaximumRadius(radius); lp->setColor(diffuse); lp->setIntensity(1.0f); lp->setType(model::Light::POINT); @@ -297,7 +297,7 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu model::LightPointer ls = model::LightPointer(new model::Light()); ls->setPosition(position); ls->setDirection(direction); - ls->setAttenuationRadius(radius); + ls->setMaximumRadius(radius); ls->setSpotCone(cutoff); ls->setColor(diffuse); ls->setIntensity(1.0f); @@ -453,6 +453,8 @@ void DeferredLightingEffect::render() { const glm::vec3& eyePoint = _viewState->getCurrentViewFrustum()->getPosition(); float nearRadius = glm::distance(eyePoint, _viewState->getCurrentViewFrustum()->getNearTopLeft()); + glm::mat4 invViewMat; + _viewState->getViewTransform().getMatrix(invViewMat); auto geometryCache = DependencyManager::get(); @@ -470,7 +472,9 @@ void DeferredLightingEffect::render() { batch.setUniformBuffer(_pointLightLocations.lightBufferUnit, light->getSchemaBuffer()); gpu::GLBackend::renderBatch(batch); } - _spotLight.setUniformValue(_pointLightLocations.radius, light->getAttenuationRadius()); + glUniformMatrix4fv(_pointLightLocations.invViewMat, 1, false, reinterpret_cast< const GLfloat* >(&invViewMat)); + // _pointLight.setUniformValue(_pointLightLocations.viewMat, reinterpret_cast< const GLfloat* >(&viewMat)); + // _spotLight.setUniformValue(_pointLightLocations.radius, light->getAttenuationRadius()); /* @@ -485,7 +489,7 @@ void DeferredLightingEffect::render() { */ glPushMatrix(); - float expandedRadius = light->getAttenuationRadius() * (1.0f + SCALE_EXPANSION); + float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION); if (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius) { glLoadIdentity(); glTranslatef(0.0f, 0.0f, -1.0f); @@ -525,7 +529,7 @@ void DeferredLightingEffect::render() { batch.setUniformBuffer(_spotLightLocations.lightBufferUnit, light->getSchemaBuffer()); gpu::GLBackend::renderBatch(batch); } - _spotLight.setUniformValue(_spotLightLocations.radius, light->getAttenuationRadius()); + // _spotLight.setUniformValue(_spotLightLocations.radius, light->getAttenuationRadius()); /* _spotLight.setUniformValue(_spotLightLocations.radius, light.radius); @@ -543,7 +547,7 @@ void DeferredLightingEffect::render() { glPushMatrix(); - float expandedRadius = light->getAttenuationRadius() * (1.0f + SCALE_EXPANSION); + float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION); float edgeRadius = expandedRadius / glm::cos(light->getSpotConeAngle()); if (glm::distance(eyePoint, glm::vec3(light->getPosition())) < edgeRadius + nearRadius) { glLoadIdentity(); @@ -563,7 +567,7 @@ void DeferredLightingEffect::render() { glm::quat spotRotation = rotationBetween(glm::vec3(0.0f, 0.0f, -1.0f), light->getDirection()); glm::vec3 axis = glm::axis(spotRotation); glRotatef(glm::degrees(glm::angle(spotRotation)), axis.x, axis.y, axis.z); - glTranslatef(0.0f, 0.0f, -light->getAttenuationRadius() * (1.0f + SCALE_EXPANSION * 0.5f)); + glTranslatef(0.0f, 0.0f, -light->getMaximumRadius() * (1.0f + SCALE_EXPANSION * 0.5f)); geometryCache->renderCone(expandedRadius * glm::tan(light->getSpotConeAngle()), expandedRadius, 32, 1); } @@ -649,6 +653,7 @@ void DeferredLightingEffect::loadLightProgram(const char* fragSource, bool limit locations.depthTexCoordScale = program.uniformLocation("depthTexCoordScale"); locations.radius = program.uniformLocation("radius"); locations.ambientSphere = program.uniformLocation("ambientSphere.L00"); + locations.invViewMat = program.uniformLocation("invViewMat"); GLint loc = -1; #if defined(Q_OS_MAC) @@ -661,8 +666,8 @@ void DeferredLightingEffect::loadLightProgram(const char* fragSource, bool limit #elif defined(Q_OS_WIN) loc = glGetUniformBlockIndex(program.programId(), "lightBuffer"); if (loc >= 0) { - glUniformBlockBinding(program.programId(), loc, 1); - locations.lightBufferUnit = 1; + glUniformBlockBinding(program.programId(), loc, 0); + locations.lightBufferUnit = 0; } else { locations.lightBufferUnit = -1; } diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 5c39c3041e..60596dd86f 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -105,6 +105,7 @@ private: int radius; int ambientSphere; int lightBufferUnit; + int invViewMat; }; static void loadLightProgram(const char* fragSource, bool limited, ProgramObject& program, LightLocations& locations); diff --git a/libraries/render-utils/src/Light.slh b/libraries/render-utils/src/Light.slh index e91d1d93cb..a48f7da81d 100755 --- a/libraries/render-utils/src/Light.slh +++ b/libraries/render-utils/src/Light.slh @@ -12,8 +12,8 @@ <@def LIGHT_SLH@> struct Light { - mat4 _transform; - + vec4 _position; + vec4 _direction; vec4 _color; vec4 _attenuation; vec4 _spot; @@ -23,14 +23,18 @@ struct Light { vec4 _control; }; -vec3 getLightPosition(Light l) { return l._transform[3].xyz; } -vec3 getLightDirection(Light l) { return -l._transform[2].xyz; } // direction is -Z axis +vec3 getLightPosition(Light l) { return l._position.xyz; } +vec3 getLightDirection(Light l) { return l._direction.xyz; } // direction is -Z axis vec3 getLightColor(Light l) { return l._color.rgb; } float getLightIntensity(Light l) { return l._color.w; } float evalLightAttenuation(Light l, float r) { - return clamp(1.0/(l._attenuation.x + l._attenuation.y * r + l._attenuation.z * r * r), 0.0, 1.0); + float d = max(r - l._attenuation.x, 0.0); + float denom = d * l._attenuation.y + 1.0; + float attenuation = 1.0 / (denom * denom); + return max((attenuation - l._attenuation.z)/(1.0 - l._attenuation.z), 0.0); + // return clamp(1.0/(l._attenuation.x + l._attenuation.y * r + l._attenuation.z * r * r), 0.0, 1.0); } float evalLightSpotAttenuation(Light l, float cosA) { @@ -40,6 +44,9 @@ float evalLightSpotAttenuation(Light l, float cosA) { return clamp(pow(cosA / l._spot.x, l._spot.w), 0.0, 1.0); } +float getLightSquareRadius(Light l) { + return l._attenuation.w * l._attenuation.w; +} <@if GLPROFILE == PC_GL@> diff --git a/libraries/render-utils/src/point_light.slf b/libraries/render-utils/src/point_light.slf index 9d9aecda95..599d10fbdb 100644 --- a/libraries/render-utils/src/point_light.slf +++ b/libraries/render-utils/src/point_light.slf @@ -21,29 +21,38 @@ // the radius (hard cutoff) of the light effect uniform float radius; +uniform mat4 invViewMat; + void main(void) { // get the depth and exit early if it doesn't pass the test vec2 texCoord = gl_TexCoord[0].st / gl_TexCoord[0].q; DeferredFragment frag = unpackDeferredFragment(texCoord); - + float depth = frag.depthVal; if (depth < gl_FragCoord.z) { discard; } - // compute the view space position using the depth - float z = near / (depth * depthScale - 1.0); - vec4 position = vec4((depthTexCoordOffset + texCoord * depthTexCoordScale) * z, z, 1.0); - - // get the normal from the map - vec4 normal = texture2D(normalMap, texCoord); - vec4 normalizedNormal = normalize(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0)); - - // compute the base color based on OpenGL lighting model - vec4 lightVector = gl_LightSource[1].position - position; + vec4 wPos; + wPos = invViewMat * frag.position; + Light light = getLight(); + gl_FragColor = vec4(frag.normal, 0.0); + + vec3 lightVector = getLightPosition(light) - wPos.xyz; + if (dot(lightVector, lightVector) > getLightSquareRadius(light)) { + discard; + } + float lightDistance = length(lightVector); lightVector = lightVector / lightDistance; + + float lightAttenuation = evalLightAttenuation(light, lightDistance); + gl_FragColor.xyz *= lightAttenuation; +/* + float diffuse = dot(frag.normal, lightVector); + + float diffuse = dot(normalizedNormal, lightVector); float facingLight = step(0.0, diffuse); vec4 baseColor = texture2D(diffuseMap, texCoord) * (gl_FrontLightProduct[1].ambient + @@ -59,6 +68,6 @@ void main(void) { normalizedNormal)); vec4 specularColor = texture2D(specularMap, texCoord); gl_FragColor = vec4((baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb) * attenuation, 0.0); - - gl_FragColor = vec4(frag.normal, 0.0); + */ + // gl_FragColor = vec4(frag.normal, 0.0); } From 471da3935d0ea3d37b86b13257b6a66070ce101c Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 29 Jan 2015 17:11:50 -0800 Subject: [PATCH 033/103] working on the lighting --- .../render-utils/src/DeferredLighting.slh | 1 - libraries/render-utils/src/point_light.slf | 42 +++++++++---------- 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/libraries/render-utils/src/DeferredLighting.slh b/libraries/render-utils/src/DeferredLighting.slh index cd65fd1053..62d2e1e00f 100755 --- a/libraries/render-utils/src/DeferredLighting.slh +++ b/libraries/render-utils/src/DeferredLighting.slh @@ -92,5 +92,4 @@ vec3 evalLightmappedColor(float shadowAttenuation, vec3 normal, vec3 diffuse, ve return diffuse * (ambientLight + diffuseLight); } - <@endif@> diff --git a/libraries/render-utils/src/point_light.slf b/libraries/render-utils/src/point_light.slf index 599d10fbdb..e91a559eba 100644 --- a/libraries/render-utils/src/point_light.slf +++ b/libraries/render-utils/src/point_light.slf @@ -23,6 +23,8 @@ uniform float radius; uniform mat4 invViewMat; + + void main(void) { // get the depth and exit early if it doesn't pass the test vec2 texCoord = gl_TexCoord[0].st / gl_TexCoord[0].q; @@ -37,7 +39,6 @@ void main(void) { vec4 wPos; wPos = invViewMat * frag.position; Light light = getLight(); - gl_FragColor = vec4(frag.normal, 0.0); vec3 lightVector = getLightPosition(light) - wPos.xyz; if (dot(lightVector, lightVector) > getLightSquareRadius(light)) { @@ -45,29 +46,24 @@ void main(void) { } float lightDistance = length(lightVector); - lightVector = lightVector / lightDistance; + vec3 lightDir = lightVector / lightDistance; float lightAttenuation = evalLightAttenuation(light, lightDistance); - gl_FragColor.xyz *= lightAttenuation; -/* - float diffuse = dot(frag.normal, lightVector); - - float diffuse = dot(normalizedNormal, lightVector); - float facingLight = step(0.0, diffuse); - vec4 baseColor = texture2D(diffuseMap, texCoord) * (gl_FrontLightProduct[1].ambient + - gl_FrontLightProduct[1].diffuse * (diffuse * facingLight)); - - // compute attenuation based on distance, etc. - float attenuation = step(lightDistance, radius) / dot(vec3(gl_LightSource[1].constantAttenuation, - gl_LightSource[1].linearAttenuation, gl_LightSource[1].quadraticAttenuation), - vec3(1.0, lightDistance, lightDistance * lightDistance)); - - // add base to specular, modulate by attenuation - float specular = facingLight * max(0.0, dot(normalize(lightVector - normalize(vec4(position.xyz, 0.0))), - normalizedNormal)); - vec4 specularColor = texture2D(specularMap, texCoord); - gl_FragColor = vec4((baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb) * attenuation, 0.0); - */ - // gl_FragColor = vec4(frag.normal, 0.0); + vec4 wNor = invViewMat * vec4(frag.normal, 0.0); + vec4 wEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); + vec3 eyeDir = normalize(wEyeVector.xyz); + vec3 wHalfDir = normalize(eyeDir + lightDir); + // Diffuse Lighting + float diffuseDot = dot(wNor.xyz, lightDir); + float facingLight = step(0.0, diffuseDot); + vec3 diffuseColor = frag.diffuse * diffuseDot * facingLight; + + // compute the specular multiplier (sans exponent) + float specularPower = facingLight * max(0.0, + dot(eyeDir, wHalfDir)); + vec3 specularColor = pow(specularPower, frag.gloss * 128.0) * frag.specular; + + // add specular contribution + gl_FragColor = vec4((diffuseColor + specularColor) * lightAttenuation * getLightColor(light) * getLightIntensity(light), 0.0); } From 228e629856ec37e9184a72858094bf7a03b5ebad Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 30 Jan 2015 11:40:44 -0800 Subject: [PATCH 034/103] working on the spot light now --- .../src/DeferredLightingEffect.cpp | 2 + libraries/render-utils/src/Light.slh | 4 ++ libraries/render-utils/src/Model.cpp | 2 - libraries/render-utils/src/point_light.slf | 2 - libraries/render-utils/src/spot_light.slf | 64 +++++++++++++++++++ 5 files changed, 70 insertions(+), 4 deletions(-) diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 6899a47c99..b626a1a191 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -529,6 +529,8 @@ void DeferredLightingEffect::render() { batch.setUniformBuffer(_spotLightLocations.lightBufferUnit, light->getSchemaBuffer()); gpu::GLBackend::renderBatch(batch); } + glUniformMatrix4fv(_spotLightLocations.invViewMat, 1, false, reinterpret_cast< const GLfloat* >(&invViewMat)); + // _spotLight.setUniformValue(_spotLightLocations.radius, light->getAttenuationRadius()); /* diff --git a/libraries/render-utils/src/Light.slh b/libraries/render-utils/src/Light.slh index a48f7da81d..97fa415a0c 100755 --- a/libraries/render-utils/src/Light.slh +++ b/libraries/render-utils/src/Light.slh @@ -37,6 +37,10 @@ float evalLightAttenuation(Light l, float r) { // return clamp(1.0/(l._attenuation.x + l._attenuation.y * r + l._attenuation.z * r * r), 0.0, 1.0); } +float getLightSpotAngleCos(Light l) { + return l._spot.x; +} + float evalLightSpotAttenuation(Light l, float cosA) { if (cosA > l._spot.x) { return 0.0; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 79f938e7f6..afcab0bc9a 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -2437,11 +2437,9 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod } static bool showDiffuse = true; if (showDiffuse && diffuseMap) { - // GLBATCH(glBindTexture)(GL_TEXTURE_2D, diffuseMap->getID()); batch.setUniformTexture(0, diffuseMap->getGPUTexture()); } else { - // GLBATCH(glBindTexture)(GL_TEXTURE_2D, textureCache->getWhiteTextureID()); batch.setUniformTexture(0, textureCache->getWhiteTexture()); } diff --git a/libraries/render-utils/src/point_light.slf b/libraries/render-utils/src/point_light.slf index e91a559eba..225b975911 100644 --- a/libraries/render-utils/src/point_light.slf +++ b/libraries/render-utils/src/point_light.slf @@ -18,8 +18,6 @@ // Everything about light <@include Light.slh@> -// the radius (hard cutoff) of the light effect -uniform float radius; uniform mat4 invViewMat; diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf index 48e8ab0d61..0f33d30f35 100644 --- a/libraries/render-utils/src/spot_light.slf +++ b/libraries/render-utils/src/spot_light.slf @@ -18,6 +18,69 @@ // Everything about light <@include Light.slh@> +uniform mat4 invViewMat; + +void main(void) { + // get the depth and exit early if it doesn't pass the test + vec2 texCoord = gl_TexCoord[0].st / gl_TexCoord[0].q; + + DeferredFragment frag = unpackDeferredFragment(texCoord); + + float depth = frag.depthVal; + if (depth < gl_FragCoord.z) { + discard; + } + + vec4 wPos; + wPos = invViewMat * frag.position; + Light light = getLight(); + + vec3 lightVector = getLightPosition(light) - wPos.xyz; + if (dot(lightVector, lightVector) > getLightSquareRadius(light)) { + discard; + } + + float lightDistance = length(lightVector); + vec3 lightDir = lightVector / lightDistance; + + vec3 lightSpotDir = getLightDirection(light); + + // compute attenuation based on spot angle, distance, etc. + float cosSpotAngle = max(-dot(lightDir, lightSpotDir), 0.0); + if (cosSpotAngle < getLightSpotAngleCos(light)) { + discard; + } +/* + float attenuation = step(lightDistance, radius) * step(gl_LightSource[1].spotCosCutoff, cosSpotAngle) * + pow(cosSpotAngle, gl_LightSource[1].spotExponent) / dot(vec3(gl_LightSource[1].constantAttenuation, + gl_LightSource[1].linearAttenuation, gl_LightSource[1].quadraticAttenuation), + vec3(1.0, lightDistance, lightDistance * lightDistance)); + + + + float lightAttenuation = evalLightAttenuation(light, lightDistance); + + vec4 wNor = invViewMat * vec4(frag.normal, 0.0); + vec4 wEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); + vec3 eyeDir = normalize(wEyeVector.xyz); + vec3 wHalfDir = normalize(eyeDir + lightDir); + // Diffuse Lighting + float diffuseDot = dot(wNor.xyz, lightDir); + float facingLight = step(0.0, diffuseDot); + vec3 diffuseColor = frag.diffuse * diffuseDot * facingLight; + + // compute the specular multiplier (sans exponent) + float specularPower = facingLight * max(0.0, + dot(eyeDir, wHalfDir)); + vec3 specularColor = pow(specularPower, frag.gloss * 128.0) * frag.specular; + + // add specular contribution + gl_FragColor = vec4((diffuseColor + specularColor) * lightAttenuation * getLightColor(light) * getLightIntensity(light), 0.0); + */ + gl_FragColor = vec4(frag.normal, 0.0); + +} +/* // the radius (hard cutoff) of the light effect uniform float radius; @@ -67,3 +130,4 @@ void main(void) { gl_FragColor = vec4(frag.normal, 0.0); } +*/ \ No newline at end of file From 6eca52e4f2ba24621fe4f3c8eabe2c6ad4a1cbb0 Mon Sep 17 00:00:00 2001 From: dev Date: Fri, 30 Jan 2015 17:01:46 -0800 Subject: [PATCH 035/103] point light is working with Mac --- libraries/render-utils/src/Light.slh | 32 ++++++++++++---------------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/libraries/render-utils/src/Light.slh b/libraries/render-utils/src/Light.slh index 97fa415a0c..169699b89a 100755 --- a/libraries/render-utils/src/Light.slh +++ b/libraries/render-utils/src/Light.slh @@ -64,15 +64,13 @@ Light getLight() { uniform vec4 lightBuffer[9]; Light getLight() { Light light; - light._transform[0] = lightBuffer[0]; - light._transform[1] = lightBuffer[1]; - light._transform[2] = lightBuffer[2]; - light._transform[3] = lightBuffer[3]; - light._color = lightBuffer[4]; - light._range = lightBuffer[5]; - light._spot = lightBuffer[6]; - light._shadow = lightBuffer[7]; - light._control = lightBuffer[8]; + light._position = lightBuffer[0]; + light._direction = lightBuffer[1]; + light._color = lightBuffer[2]; + light._attenuation = lightBuffer[3]; + light._spot = lightBuffer[4]; + light._shadow = lightBuffer[5]; + light._control = lightBuffer[6]; return light; } @@ -80,15 +78,13 @@ Light getLight() { uniform vec4 lightBuffer[9]; Light getLight() { Light light; - light._transform[0] = lightBuffer[0]; - light._transform[1] = lightBuffer[1]; - light._transform[2] = lightBuffer[2]; - light._transform[3] = lightBuffer[3]; - light._color = lightBuffer[4]; - light._range = lightBuffer[5]; - light._spot = lightBuffer[6]; - light._shadow = lightBuffer[7]; - light._control = lightBuffer[8]; + light._position = lightBuffer[0]; + light._direction = lightBuffer[1]; + light._color = lightBuffer[2]; + light._attenuation = lightBuffer[3]; + light._spot = lightBuffer[4]; + light._shadow = lightBuffer[5]; + light._control = lightBuffer[6]; return light; } From c3e1311ed113b788064413e3531b43c48afa9396 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 30 Jan 2015 17:03:28 -0800 Subject: [PATCH 036/103] avoid recreating lights every frame, just have a pool of lights edited each frames --- .../src/DeferredLightingEffect.cpp | 40 +++++++++++-------- .../render-utils/src/DeferredLightingEffect.h | 5 ++- libraries/render-utils/src/GeometryCache.cpp | 6 +-- libraries/render-utils/src/point_light.slf | 7 ++++ 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index d0a77f9174..fee3b4c947 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -263,6 +263,13 @@ void DeferredLightingEffect::addPointLight(const glm::vec3& position, float radi void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radius, const glm::vec3& ambient, const glm::vec3& diffuse, const glm::vec3& specular, float constantAttenuation, float linearAttenuation, float quadraticAttenuation, const glm::vec3& direction, float exponent, float cutoff) { + + int lightID = _pointLights.size() + _spotLights.size(); + if (lightID >= _allocatedLights.size()) { + _allocatedLights.push_back(model::LightPointer(new model::Light())); + } + model::LightPointer lp = _allocatedLights[lightID]; + if (exponent == 0.0f && cutoff == PI) { PointLight light; light.position = glm::vec4(position, 1.0f); @@ -273,13 +280,12 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu light.constantAttenuation = constantAttenuation; light.linearAttenuation = linearAttenuation; - model::LightPointer lp = model::LightPointer(new model::Light()); lp->setPosition(position); lp->setMaximumRadius(radius); lp->setColor(diffuse); lp->setIntensity(1.0f); lp->setType(model::Light::POINT); - _pointLights.push_back(lp); + _pointLights.push_back(lightID); } else { SpotLight light; @@ -294,16 +300,15 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu light.exponent = exponent; light.cutoff = cutoff; - model::LightPointer ls = model::LightPointer(new model::Light()); - ls->setPosition(position); - ls->setDirection(direction); - ls->setMaximumRadius(radius); - ls->setSpotCone(cutoff); - ls->setColor(diffuse); - ls->setIntensity(1.0f); - ls->setType(model::Light::SPOT); + lp->setPosition(position); + lp->setDirection(direction); + lp->setMaximumRadius(radius); + lp->setSpotCone(cutoff); + lp->setColor(diffuse); + lp->setIntensity(1.0f); + lp->setType(model::Light::SPOT); - _spotLights.push_back(ls); + _spotLights.push_back(lightID); } } @@ -337,7 +342,7 @@ void DeferredLightingEffect::render() { QOpenGLFramebufferObject* freeFBO = DependencyManager::get()->getFreeFramebufferObject(); freeFBO->bind(); glClear(GL_COLOR_BUFFER_BIT); - glEnable(GL_FRAMEBUFFER_SRGB); + // glEnable(GL_FRAMEBUFFER_SRGB); glBindTexture(GL_TEXTURE_2D, primaryFBO->texture()); @@ -463,7 +468,8 @@ void DeferredLightingEffect::render() { _pointLight.setUniformValue(_pointLightLocations.depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT); _pointLight.setUniformValue(_pointLightLocations.depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT); - for (auto light : _pointLights) { + for (auto lightID : _pointLights) { + auto light = _allocatedLights[lightID]; // foreach (const PointLight& light, _pointLights) { if (_pointLightLocations.lightBufferUnit >= 0) { gpu::Batch batch; @@ -471,8 +477,6 @@ void DeferredLightingEffect::render() { gpu::GLBackend::renderBatch(batch); } glUniformMatrix4fv(_pointLightLocations.invViewMat, 1, false, reinterpret_cast< const GLfloat* >(&invViewMat)); - // _pointLight.setUniformValue(_pointLightLocations.viewMat, reinterpret_cast< const GLfloat* >(&viewMat)); - // _spotLight.setUniformValue(_pointLightLocations.radius, light->getAttenuationRadius()); /* @@ -520,7 +524,9 @@ void DeferredLightingEffect::render() { _spotLight.setUniformValue(_spotLightLocations.depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT); _spotLight.setUniformValue(_spotLightLocations.depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT); - for (auto light : _spotLights) { + for (auto lightID : _spotLights) { + auto light = _allocatedLights[lightID]; + // foreach (const SpotLight& light, _spotLights) { if (_spotLightLocations.lightBufferUnit >= 0) { gpu::Batch batch; @@ -591,7 +597,7 @@ void DeferredLightingEffect::render() { glBindTexture(GL_TEXTURE_2D, 0); freeFBO->release(); - glDisable(GL_FRAMEBUFFER_SRGB); + // glDisable(GL_FRAMEBUFFER_SRGB); glDisable(GL_CULL_FACE); diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 8c0288f2df..8e6606506a 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -153,8 +153,9 @@ private: typedef std::vector< model::LightPointer > Lights; - Lights _pointLights; - Lights _spotLights; + Lights _allocatedLights; + std::vector _pointLights; + std::vector _spotLights; // QVector _pointLights; // QVector _spotLights; QVector _postLightingRenderables; diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index c32b8ff757..cb44ecae5c 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -1152,7 +1152,7 @@ void GeometryCache::renderQuad(const glm::vec2& minCorner, const glm::vec2& maxC gpu::Batch batch; - glEnable(GL_TEXTURE_2D); +// glEnable(GL_TEXTURE_2D); //glBindTexture(GL_TEXTURE_2D, _currentTextureID); // this is quad specific... batch.setInputFormat(details.streamFormat); @@ -1166,8 +1166,8 @@ void GeometryCache::renderQuad(const glm::vec2& minCorner, const glm::vec2& maxC glDisableClientState(GL_COLOR_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindTexture(GL_TEXTURE_2D, 0); - glDisable(GL_TEXTURE_2D); + // glBindTexture(GL_TEXTURE_2D, 0); + // glDisable(GL_TEXTURE_2D); } void GeometryCache::renderQuad(const glm::vec3& minCorner, const glm::vec3& maxCorner, const glm::vec4& color, int id) { diff --git a/libraries/render-utils/src/point_light.slf b/libraries/render-utils/src/point_light.slf index 225b975911..5445d3576e 100644 --- a/libraries/render-utils/src/point_light.slf +++ b/libraries/render-utils/src/point_light.slf @@ -36,6 +36,7 @@ void main(void) { vec4 wPos; wPos = invViewMat * frag.position; + Light light = getLight(); vec3 lightVector = getLightPosition(light) - wPos.xyz; @@ -43,9 +44,14 @@ void main(void) { discard; } + + float lightDistance = length(lightVector); vec3 lightDir = lightVector / lightDistance; + vec4 wNor = invViewMat * vec4(frag.normal, 0.0); + gl_FragColor = vec4(wNor.xyz, 0.0); +/* float lightAttenuation = evalLightAttenuation(light, lightDistance); vec4 wNor = invViewMat * vec4(frag.normal, 0.0); @@ -64,4 +70,5 @@ void main(void) { // add specular contribution gl_FragColor = vec4((diffuseColor + specularColor) * lightAttenuation * getLightColor(light) * getLightIntensity(light), 0.0); + */ } From 0da38c103f38ae6252a88a8c8897b93d02be6ae0 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 2 Feb 2015 11:17:35 -0800 Subject: [PATCH 037/103] working on the spot light shader --- libraries/render-utils/src/Light.slh | 3 ++ libraries/render-utils/src/point_light.slf | 32 +++++++------ libraries/render-utils/src/spot_light.slf | 56 ++++++++++++++++++---- 3 files changed, 67 insertions(+), 24 deletions(-) diff --git a/libraries/render-utils/src/Light.slh b/libraries/render-utils/src/Light.slh index 169699b89a..647708b376 100755 --- a/libraries/render-utils/src/Light.slh +++ b/libraries/render-utils/src/Light.slh @@ -52,6 +52,9 @@ float getLightSquareRadius(Light l) { return l._attenuation.w * l._attenuation.w; } +float getLightAttenuationCutoff(Light l) { + return l._attenuation.z; +} <@if GLPROFILE == PC_GL@> uniform lightBuffer { diff --git a/libraries/render-utils/src/point_light.slf b/libraries/render-utils/src/point_light.slf index 5445d3576e..86cdb047ec 100644 --- a/libraries/render-utils/src/point_light.slf +++ b/libraries/render-utils/src/point_light.slf @@ -18,46 +18,44 @@ // Everything about light <@include Light.slh@> - +// The view Matrix uniform mat4 invViewMat; - - void main(void) { // get the depth and exit early if it doesn't pass the test vec2 texCoord = gl_TexCoord[0].st / gl_TexCoord[0].q; DeferredFragment frag = unpackDeferredFragment(texCoord); + // Kill if in front of the light volume float depth = frag.depthVal; if (depth < gl_FragCoord.z) { discard; } - vec4 wPos; - wPos = invViewMat * frag.position; - + // Need the light now Light light = getLight(); + // Make the Light vector going from fragment to light center in world space + vec4 wPos; + wPos = invViewMat * frag.position; vec3 lightVector = getLightPosition(light) - wPos.xyz; + + // Kill if too far from the light center if (dot(lightVector, lightVector) > getLightSquareRadius(light)) { discard; } - - + // Allright we re valid in the volume float lightDistance = length(lightVector); - vec3 lightDir = lightVector / lightDistance; - vec4 wNor = invViewMat * vec4(frag.normal, 0.0); - - gl_FragColor = vec4(wNor.xyz, 0.0); -/* float lightAttenuation = evalLightAttenuation(light, lightDistance); + vec3 lightDir = lightVector / lightDistance; vec4 wNor = invViewMat * vec4(frag.normal, 0.0); vec4 wEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); vec3 eyeDir = normalize(wEyeVector.xyz); vec3 wHalfDir = normalize(eyeDir + lightDir); + // Diffuse Lighting float diffuseDot = dot(wNor.xyz, lightDir); float facingLight = step(0.0, diffuseDot); @@ -69,6 +67,10 @@ void main(void) { vec3 specularColor = pow(specularPower, frag.gloss * 128.0) * frag.specular; // add specular contribution - gl_FragColor = vec4((diffuseColor + specularColor) * lightAttenuation * getLightColor(light) * getLightIntensity(light), 0.0); - */ + float ring = (lightAttenuation / (0.2 * getLightAttenuationCutoff(light))) - 1; + if (ring < 1) { + gl_FragColor = vec4(ring * ring * getLightColor(light), 0.0); + } else { + gl_FragColor = vec4((diffuseColor + specularColor) * lightAttenuation * getLightColor(light) * getLightIntensity(light), 0.0); + } } diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf index 0f33d30f35..e5688718f6 100644 --- a/libraries/render-utils/src/spot_light.slf +++ b/libraries/render-utils/src/spot_light.slf @@ -18,6 +18,7 @@ // Everything about light <@include Light.slh@> +// The view Matrix uniform mat4 invViewMat; void main(void) { @@ -26,30 +27,67 @@ void main(void) { DeferredFragment frag = unpackDeferredFragment(texCoord); + // Kill if in front of the light volume float depth = frag.depthVal; if (depth < gl_FragCoord.z) { discard; } - vec4 wPos; - wPos = invViewMat * frag.position; + // Need the light now Light light = getLight(); - vec3 lightVector = getLightPosition(light) - wPos.xyz; + // Make the Light vector going from fragment to light center in world space + vec4 wPos; + wPos = invViewMat * frag.position; + vec3 lightVector = wPos.xyz - getLightPosition(light); + + // Kill if too far from the light center if (dot(lightVector, lightVector) > getLightSquareRadius(light)) { discard; } + // Allright we re valid in the volume float lightDistance = length(lightVector); + float lightAttenuation = evalLightAttenuation(light, lightDistance); + vec3 lightDir = lightVector / lightDistance; + + gl_FragColor = vec4(getLightColor(light), 0.0); + // Kill if not in the spot light (ah ah !) vec3 lightSpotDir = getLightDirection(light); - - // compute attenuation based on spot angle, distance, etc. float cosSpotAngle = max(-dot(lightDir, lightSpotDir), 0.0); if (cosSpotAngle < getLightSpotAngleCos(light)) { - discard; + // discard; + gl_FragColor = vec4(vec3(1.0, 0.0, 0.0), 0.0); } + + /* + vec4 wNor = invViewMat * vec4(frag.normal, 0.0); + vec4 wEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); + vec3 eyeDir = normalize(wEyeVector.xyz); + vec3 wHalfDir = normalize(eyeDir + lightDir); + + // Diffuse Lighting + float diffuseDot = dot(wNor.xyz, lightDir); + float facingLight = step(0.0, diffuseDot); + vec3 diffuseColor = frag.diffuse * diffuseDot * facingLight; + + // compute the specular multiplier (sans exponent) + float specularPower = facingLight * max(0.0, + dot(eyeDir, wHalfDir)); + vec3 specularColor = pow(specularPower, frag.gloss * 128.0) * frag.specular; + + // add specular contribution + /* float ring = (lightAttenuation / (0.2 * getLightAttenuationCutoff(light))) - 1; + if (ring < 1) { + gl_FragColor = vec4(ring * ring * getLightColor(light), 0.0); + } else { + gl_FragColor = vec4((diffuseColor + specularColor) * lightAttenuation * getLightColor(light) * getLightIntensity(light), 0.0); + }*/ +} + + /* float attenuation = step(lightDistance, radius) * step(gl_LightSource[1].spotCosCutoff, cosSpotAngle) * pow(cosSpotAngle, gl_LightSource[1].spotExponent) / dot(vec3(gl_LightSource[1].constantAttenuation, @@ -77,9 +115,9 @@ void main(void) { // add specular contribution gl_FragColor = vec4((diffuseColor + specularColor) * lightAttenuation * getLightColor(light) * getLightIntensity(light), 0.0); */ - gl_FragColor = vec4(frag.normal, 0.0); +// gl_FragColor = vec4(frag.normal, 0.0); -} +//} /* // the radius (hard cutoff) of the light effect uniform float radius; @@ -130,4 +168,4 @@ void main(void) { gl_FragColor = vec4(frag.normal, 0.0); } -*/ \ No newline at end of file +*/ From 16f12dd2673189288f4117d0a339cef45a3c8cc3 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 2 Feb 2015 16:31:36 -0800 Subject: [PATCH 038/103] working on the point light shader edge representation --- libraries/model/src/model/Light.cpp | 4 ++-- libraries/model/src/model/Light.h | 6 ++++-- libraries/render-utils/src/Light.slh | 4 ++++ libraries/render-utils/src/point_light.slf | 10 ++++++---- libraries/render-utils/src/spot_light.slf | 16 ++++++++-------- 5 files changed, 24 insertions(+), 16 deletions(-) diff --git a/libraries/model/src/model/Light.cpp b/libraries/model/src/model/Light.cpp index 201144622f..6348ffbcc7 100755 --- a/libraries/model/src/model/Light.cpp +++ b/libraries/model/src/model/Light.cpp @@ -48,11 +48,11 @@ void Light::setOrientation(const glm::quat& orientation) { } void Light::setDirection(const Vec3& direction) { - editSchema()._direction = Vec4(direction, 0.f); + editSchema()._direction = direction; } const Vec3& Light::getDirection() const { - return Vec3(getSchema()._direction); + return getSchema()._direction; } void Light::setColor(const Color& color) { diff --git a/libraries/model/src/model/Light.h b/libraries/model/src/model/Light.h index 107d30fb5e..5e3bda5e1d 100755 --- a/libraries/model/src/model/Light.h +++ b/libraries/model/src/model/Light.h @@ -88,7 +88,8 @@ public: class Schema { public: Vec4 _position; - Vec4 _direction; + Vec3 _direction; + float _spare0; Color _color; float _intensity; Vec4 _attenuation; @@ -99,7 +100,8 @@ public: Schema() : _position(0.0f, 0.0f, 0.0f, 1.0f), - _direction(0.0f, 0.0f, -1.0f, 0.f), + _direction(0.0f, 0.0f, -1.0f), + _spare0(0.f), _color(1.0f), _intensity(1.0f), _attenuation(1.0f, 1.0f, 1.0f, 1.0f), diff --git a/libraries/render-utils/src/Light.slh b/libraries/render-utils/src/Light.slh index 647708b376..ccf6e52836 100755 --- a/libraries/render-utils/src/Light.slh +++ b/libraries/render-utils/src/Light.slh @@ -52,6 +52,10 @@ float getLightSquareRadius(Light l) { return l._attenuation.w * l._attenuation.w; } +float getLightRadius(Light l) { + return l._attenuation.w; +} + float getLightAttenuationCutoff(Light l) { return l._attenuation.z; } diff --git a/libraries/render-utils/src/point_light.slf b/libraries/render-utils/src/point_light.slf index 86cdb047ec..3ba6e8d2bc 100644 --- a/libraries/render-utils/src/point_light.slf +++ b/libraries/render-utils/src/point_light.slf @@ -66,10 +66,12 @@ void main(void) { dot(eyeDir, wHalfDir)); vec3 specularColor = pow(specularPower, frag.gloss * 128.0) * frag.specular; - // add specular contribution - float ring = (lightAttenuation / (0.2 * getLightAttenuationCutoff(light))) - 1; - if (ring < 1) { - gl_FragColor = vec4(ring * ring * getLightColor(light), 0.0); + // Show edge + float maxRadius = getLightRadius(light); + float edge = abs(2.0 * ((maxRadius - lightDistance) / (0.1)) - 1.0); + if (edge < 1) { + float edgeCoord = exp2(-8.0*edge*edge); + gl_FragColor = vec4(edgeCoord * edgeCoord * getLightColor(light), 0.0); } else { gl_FragColor = vec4((diffuseColor + specularColor) * lightAttenuation * getLightColor(light) * getLightIntensity(light), 0.0); } diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf index e5688718f6..cb309ea762 100644 --- a/libraries/render-utils/src/spot_light.slf +++ b/libraries/render-utils/src/spot_light.slf @@ -39,27 +39,27 @@ void main(void) { // Make the Light vector going from fragment to light center in world space vec4 wPos; wPos = invViewMat * frag.position; - vec3 lightVector = wPos.xyz - getLightPosition(light); + vec3 fragLightVec = getLightPosition(light) - wPos.xyz; // Kill if too far from the light center - if (dot(lightVector, lightVector) > getLightSquareRadius(light)) { + if (dot(fragLightVec, fragLightVec) > getLightSquareRadius(light)) { discard; } // Allright we re valid in the volume - float lightDistance = length(lightVector); - float lightAttenuation = evalLightAttenuation(light, lightDistance); + float fragLightDistance = length(fragLightVec); + float lightAttenuation = evalLightAttenuation(light, fragLightDistance); - vec3 lightDir = lightVector / lightDistance; + vec3 fragLightDir = fragLightVec / fragLightDistance; gl_FragColor = vec4(getLightColor(light), 0.0); // Kill if not in the spot light (ah ah !) vec3 lightSpotDir = getLightDirection(light); - float cosSpotAngle = max(-dot(lightDir, lightSpotDir), 0.0); + float cosSpotAngle = max(-dot(fragLightDir, lightSpotDir), 0.0); if (cosSpotAngle < getLightSpotAngleCos(light)) { - // discard; - gl_FragColor = vec4(vec3(1.0, 0.0, 0.0), 0.0); + discard; + //gl_FragColor = vec4(vec3(1.0, 0.0, 0.0), 0.0); } /* From 5c4a8a5cda754a25cf287745a51ffa58bf24a3d7 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 2 Feb 2015 17:24:26 -0800 Subject: [PATCH 039/103] Fixing the spotlight --- libraries/render-utils/src/point_light.slf | 22 ++-- libraries/render-utils/src/spot_light.slf | 123 ++++----------------- 2 files changed, 32 insertions(+), 113 deletions(-) diff --git a/libraries/render-utils/src/point_light.slf b/libraries/render-utils/src/point_light.slf index 3ba6e8d2bc..da2d708f06 100644 --- a/libraries/render-utils/src/point_light.slf +++ b/libraries/render-utils/src/point_light.slf @@ -39,36 +39,36 @@ void main(void) { // Make the Light vector going from fragment to light center in world space vec4 wPos; wPos = invViewMat * frag.position; - vec3 lightVector = getLightPosition(light) - wPos.xyz; + vec3 fragLightVec = getLightPosition(light) - wPos.xyz; // Kill if too far from the light center - if (dot(lightVector, lightVector) > getLightSquareRadius(light)) { + if (dot(fragLightVec, fragLightVec) > getLightSquareRadius(light)) { discard; } // Allright we re valid in the volume - float lightDistance = length(lightVector); - float lightAttenuation = evalLightAttenuation(light, lightDistance); + float fragLightDistance = length(fragLightVec); + float lightAttenuation = evalLightAttenuation(light, fragLightDistance); - vec3 lightDir = lightVector / lightDistance; + vec3 fragLightDir = fragLightVec / fragLightDistance; vec4 wNor = invViewMat * vec4(frag.normal, 0.0); - vec4 wEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); - vec3 eyeDir = normalize(wEyeVector.xyz); - vec3 wHalfDir = normalize(eyeDir + lightDir); + vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); + vec3 fragEyeDir = normalize(fragEyeVector.xyz); + vec3 wHalfDir = normalize(fragEyeDir + fragLightDir); // Diffuse Lighting - float diffuseDot = dot(wNor.xyz, lightDir); + float diffuseDot = dot(wNor.xyz, fragLightDir); float facingLight = step(0.0, diffuseDot); vec3 diffuseColor = frag.diffuse * diffuseDot * facingLight; // compute the specular multiplier (sans exponent) float specularPower = facingLight * max(0.0, - dot(eyeDir, wHalfDir)); + dot(fragEyeDir, wHalfDir)); vec3 specularColor = pow(specularPower, frag.gloss * 128.0) * frag.specular; // Show edge float maxRadius = getLightRadius(light); - float edge = abs(2.0 * ((maxRadius - lightDistance) / (0.1)) - 1.0); + float edge = abs(2.0 * ((maxRadius - fragLightDistance) / (0.1)) - 1.0); if (edge < 1) { float edgeCoord = exp2(-8.0*edge*edge); gl_FragColor = vec4(edgeCoord * edgeCoord * getLightColor(light), 0.0); diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf index cb309ea762..d8bedc2bea 100644 --- a/libraries/render-utils/src/spot_light.slf +++ b/libraries/render-utils/src/spot_light.slf @@ -37,8 +37,7 @@ void main(void) { Light light = getLight(); // Make the Light vector going from fragment to light center in world space - vec4 wPos; - wPos = invViewMat * frag.position; + vec4 wPos = invViewMat * frag.position; vec3 fragLightVec = getLightPosition(light) - wPos.xyz; // Kill if too far from the light center @@ -49,123 +48,43 @@ void main(void) { // Allright we re valid in the volume float fragLightDistance = length(fragLightVec); float lightAttenuation = evalLightAttenuation(light, fragLightDistance); - vec3 fragLightDir = fragLightVec / fragLightDistance; - - gl_FragColor = vec4(getLightColor(light), 0.0); // Kill if not in the spot light (ah ah !) vec3 lightSpotDir = getLightDirection(light); float cosSpotAngle = max(-dot(fragLightDir, lightSpotDir), 0.0); if (cosSpotAngle < getLightSpotAngleCos(light)) { discard; - //gl_FragColor = vec4(vec3(1.0, 0.0, 0.0), 0.0); } - /* vec4 wNor = invViewMat * vec4(frag.normal, 0.0); - vec4 wEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); - vec3 eyeDir = normalize(wEyeVector.xyz); - vec3 wHalfDir = normalize(eyeDir + lightDir); + vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); + vec3 fragEyeDir = normalize(fragEyeVector.xyz); + vec3 wHalfDir = normalize(fragEyeDir + fragLightDir); // Diffuse Lighting - float diffuseDot = dot(wNor.xyz, lightDir); + float diffuseDot = dot(wNor.xyz, fragLightDir); float facingLight = step(0.0, diffuseDot); vec3 diffuseColor = frag.diffuse * diffuseDot * facingLight; - + // compute the specular multiplier (sans exponent) - float specularPower = facingLight * max(0.0, - dot(eyeDir, wHalfDir)); + float specularPower = facingLight * max(0.0, dot(fragEyeDir, wHalfDir)); vec3 specularColor = pow(specularPower, frag.gloss * 128.0) * frag.specular; - // add specular contribution - /* float ring = (lightAttenuation / (0.2 * getLightAttenuationCutoff(light))) - 1; - if (ring < 1) { - gl_FragColor = vec4(ring * ring * getLightColor(light), 0.0); + // Eval angular attenuation + float lightAngularAttenuation = clamp((cosSpotAngle - getLightSpotAngleCos(light)) / (1.0 - getLightSpotAngleCos(light)), 0.0, 1.0); + + // Show edge + float maxRadius = getLightRadius(light); + float edge = abs(2.0 * ((maxRadius - fragLightDistance) / (0.1)) - 1.0); + if (cosSpotAngle < 1.01 * getLightSpotAngleCos(light)) { + edge = 0; + } + if (edge < 1) { + float edgeCoord = exp2(-8.0*edge*edge); + gl_FragColor = vec4(edgeCoord * edgeCoord * getLightColor(light), 0.0); } else { - gl_FragColor = vec4((diffuseColor + specularColor) * lightAttenuation * getLightColor(light) * getLightIntensity(light), 0.0); - }*/ -} - - -/* - float attenuation = step(lightDistance, radius) * step(gl_LightSource[1].spotCosCutoff, cosSpotAngle) * - pow(cosSpotAngle, gl_LightSource[1].spotExponent) / dot(vec3(gl_LightSource[1].constantAttenuation, - gl_LightSource[1].linearAttenuation, gl_LightSource[1].quadraticAttenuation), - vec3(1.0, lightDistance, lightDistance * lightDistance)); - - - - float lightAttenuation = evalLightAttenuation(light, lightDistance); - - vec4 wNor = invViewMat * vec4(frag.normal, 0.0); - vec4 wEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); - vec3 eyeDir = normalize(wEyeVector.xyz); - vec3 wHalfDir = normalize(eyeDir + lightDir); - // Diffuse Lighting - float diffuseDot = dot(wNor.xyz, lightDir); - float facingLight = step(0.0, diffuseDot); - vec3 diffuseColor = frag.diffuse * diffuseDot * facingLight; - - // compute the specular multiplier (sans exponent) - float specularPower = facingLight * max(0.0, - dot(eyeDir, wHalfDir)); - vec3 specularColor = pow(specularPower, frag.gloss * 128.0) * frag.specular; - - // add specular contribution - gl_FragColor = vec4((diffuseColor + specularColor) * lightAttenuation * getLightColor(light) * getLightIntensity(light), 0.0); - */ -// gl_FragColor = vec4(frag.normal, 0.0); - -//} -/* -// the radius (hard cutoff) of the light effect -uniform float radius; - -void main(void) { - vec2 texCoord = gl_TexCoord[0].st / gl_TexCoord[0].q; - - DeferredFragment frag = unpackDeferredFragment(texCoord); - - // get the depth and exit early if it doesn't pass the test - float depth = frag.depthVal; - if (depth < gl_FragCoord.z) { - discard; + gl_FragColor = vec4((diffuseColor + specularColor) * lightAngularAttenuation * lightAttenuation * getLightColor(light) * getLightIntensity(light), 0.0); } - - - - // compute the view space position using the depth - float z = near / (depth * depthScale - 1.0); - vec4 position = vec4((depthTexCoordOffset + texCoord * depthTexCoordScale) * z, z, 1.0); - - - // get the normal from the map - vec4 normal = texture2D(normalMap, texCoord); - vec4 normalizedNormal = normalize(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0)); - - // compute the base color based on OpenGL lighting model - vec4 lightVector = gl_LightSource[1].position - position; - float lightDistance = length(lightVector); - lightVector = lightVector / lightDistance; - float diffuse = dot(normalizedNormal, lightVector); - float facingLight = step(0.0, diffuse); - vec4 baseColor = texture2D(diffuseMap, texCoord) * (gl_FrontLightProduct[1].ambient + - gl_FrontLightProduct[1].diffuse * (diffuse * facingLight)); - - // compute attenuation based on spot angle, distance, etc. - float cosSpotAngle = max(-dot(lightVector.xyz, gl_LightSource[1].spotDirection), 0.0); - float attenuation = step(lightDistance, radius) * step(gl_LightSource[1].spotCosCutoff, cosSpotAngle) * - pow(cosSpotAngle, gl_LightSource[1].spotExponent) / dot(vec3(gl_LightSource[1].constantAttenuation, - gl_LightSource[1].linearAttenuation, gl_LightSource[1].quadraticAttenuation), - vec3(1.0, lightDistance, lightDistance * lightDistance)); - - // add base to specular, modulate by attenuation - float specular = facingLight * max(0.0, dot(normalize(lightVector - normalize(vec4(position.xyz, 0.0))), - normalizedNormal)); - vec4 specularColor = texture2D(specularMap, texCoord); - gl_FragColor = vec4((baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb) * attenuation, 0.0); - - gl_FragColor = vec4(frag.normal, 0.0); } -*/ + From d8d0a28d0f11cc43f42d7b8b5fc05b6913fd1c18 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 3 Feb 2015 14:34:11 -0800 Subject: [PATCH 040/103] FInd a solution for lightmap without 2nd uvset --- libraries/fbx/src/FBXReader.cpp | 3 ++- libraries/render-utils/src/GeometryCache.cpp | 9 ++++++++- libraries/render-utils/src/model_lightmap.slv | 3 ++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 3015de52ff..e0487ec76e 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -1179,7 +1179,7 @@ FBXTexture getTexture(const QString& textureID, texture.transform.setTranslation(p.translation); texture.transform.setRotation(glm::quat(glm::radians(p.rotation))); texture.transform.setScale(p.scaling); - if ((p.UVSet != "map1") || (p.UVSet != "UVSet0")) { + if ((p.UVSet != "map1") && (p.UVSet != "UVSet0")) { texture.texcoordSet = 1; } texture.texcoordSetName = p.UVSet; @@ -1605,6 +1605,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping, if (property.name == propertyName) { QString v = property.properties.at(0).toString(); if (property.properties.at(0) == "UVSet") { + std::string uvName = property.properties.at(index).toString().toStdString(); tex.assign(tex.UVSet, property.properties.at(index).toString()); } else if (property.properties.at(0) == "CurrentTextureBlendMode") { tex.assign(tex.currentTextureBlendMode, property.properties.at(index).value()); diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index cb44ecae5c..678f0b2484 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -2120,6 +2120,7 @@ void NetworkGeometry::setGeometry(const FBXGeometry& geometry) { NetworkMesh networkMesh; int totalIndices = 0; + bool checkForTexcoordLightmap = false; foreach (const FBXMeshPart& part, mesh.parts) { NetworkMeshPart networkPart; if (!part.diffuseTexture.filename.isEmpty()) { @@ -2149,6 +2150,7 @@ void NetworkGeometry::setGeometry(const FBXGeometry& geometry) { false, part.emissiveTexture.content); networkPart.emissiveTextureName = part.emissiveTexture.name; networkPart.emissiveTexture->setLoadPriorities(_loadPriorities); + checkForTexcoordLightmap = true; } networkMesh.parts.append(networkPart); @@ -2215,7 +2217,12 @@ void NetworkGeometry::setGeometry(const FBXGeometry& geometry) { if (mesh.tangents.size()) networkMesh._vertexFormat->setAttribute(gpu::Stream::TANGENT, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); if (mesh.colors.size()) networkMesh._vertexFormat->setAttribute(gpu::Stream::COLOR, channelNum++, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RGB)); if (mesh.texCoords.size()) networkMesh._vertexFormat->setAttribute(gpu::Stream::TEXCOORD, channelNum++, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV)); - if (mesh.texCoords1.size()) networkMesh._vertexFormat->setAttribute(gpu::Stream::TEXCOORD1, channelNum++, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV)); + if (mesh.texCoords1.size()) { + networkMesh._vertexFormat->setAttribute(gpu::Stream::TEXCOORD1, channelNum++, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV)); + } else if (checkForTexcoordLightmap && mesh.texCoords.size()) { + // need lightmap texcoord UV but doesn't have uv#1 so just reuse the same channel + networkMesh._vertexFormat->setAttribute(gpu::Stream::TEXCOORD1, channelNum - 1, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV)); + } if (mesh.clusterIndices.size()) networkMesh._vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, channelNum++, gpu::Element(gpu::VEC4, gpu::NFLOAT, gpu::XYZW)); if (mesh.clusterWeights.size()) networkMesh._vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, channelNum++, gpu::Element(gpu::VEC4, gpu::NFLOAT, gpu::XYZW)); } diff --git a/libraries/render-utils/src/model_lightmap.slv b/libraries/render-utils/src/model_lightmap.slv index 23d99b399a..1ea5b7b68a 100755 --- a/libraries/render-utils/src/model_lightmap.slv +++ b/libraries/render-utils/src/model_lightmap.slv @@ -33,8 +33,9 @@ void main(void) { // and the texture coordinates gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0); + // interpolatedTexcoord1 = vec2(texcoordMatrices[1] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0)).xy; interpolatedTexcoord1 = vec2(texcoordMatrices[1] * vec4(texcoord1.xy, 0.0, 1.0)).xy; - + // use standard pipeline transform gl_Position = ftransform(); } From 1029af140ee67ac881cf43c385bc3d83ac422db1 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 3 Feb 2015 18:15:20 -0800 Subject: [PATCH 041/103] tiny bit different... --- libraries/render-utils/src/directional_ambient_light.slf | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libraries/render-utils/src/directional_ambient_light.slf b/libraries/render-utils/src/directional_ambient_light.slf index 803bd5ac30..059c0e150f 100755 --- a/libraries/render-utils/src/directional_ambient_light.slf +++ b/libraries/render-utils/src/directional_ambient_light.slf @@ -22,12 +22,13 @@ void main(void) { // Light mapped or not ? if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { - gl_FragColor = vec4( evalLightmappedColor( + vec3 color = evalLightmappedColor( 1.0, frag.normal, frag.diffuse, - frag.specularVal.xyz), - 1.0); + frag.specularVal.xyz); + + gl_FragColor = vec4(color, 1.0); } else { vec3 color = evalAmbientSphereColor(frag.normal, frag.diffuse, frag.specular, frag.gloss) + evalDirectionalColor(1.0, From 7d6161598b8e4202467d50daee9a74aff27dfcd6 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 4 Feb 2015 13:31:39 -0800 Subject: [PATCH 042/103] REvisiting the shaders for lighting on deferred pass --- .../render-utils/src/DeferredLighting.slh | 33 ++++++++++++------- .../src/directional_ambient_light.slf | 1 + libraries/render-utils/src/spot_light.slf | 12 ++++--- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/libraries/render-utils/src/DeferredLighting.slh b/libraries/render-utils/src/DeferredLighting.slh index 62d2e1e00f..1c9f77c2e0 100755 --- a/libraries/render-utils/src/DeferredLighting.slh +++ b/libraries/render-utils/src/DeferredLighting.slh @@ -45,6 +45,9 @@ vec4 evalSphericalLight(SphericalHarmonics sh, vec3 direction ) { uniform SphericalHarmonics ambientSphere; +// Everything about light +<@include Light.slh@> + vec3 evalAmbientColor(vec3 normal, vec3 diffuse, vec3 specular, float gloss) { return diffuse.rgb * gl_FrontLightProduct[0].ambient.rgb; } @@ -55,19 +58,27 @@ vec3 evalAmbientSphereColor(vec3 normal, vec3 diffuse, vec3 specular, float glos return diffuse.rgb * ambientLight; } -vec3 evalDirectionalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { +// Frag Shading returns the diffuse amount as W and the specular rgb as xyz +vec4 evalFragShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 specular, float gloss) { // Diffuse Lighting - float diffuseDot = dot(normal, gl_LightSource[0].position.xyz); - float facingLight = step(0.0, diffuseDot) * shadowAttenuation; - vec3 diffuseColor = diffuse * (gl_FrontLightProduct[0].diffuse.rgb * (diffuseDot * facingLight)); - - // compute the specular multiplier (sans exponent) - float specularPower = facingLight * max(0.0, - dot(normalize(gl_LightSource[0].position.xyz - normalize(position)), normal)); - vec3 specularColor = pow(specularPower, gloss * 128.0) * specular; + float diffuseDot = dot(fragNormal, fragLightDir); + float facingLight = step(0.0, diffuseDot); + float diffuse = diffuseDot * facingLight; + + // Specular Lighting depends on the half vector and the gloss + vec3 halfDir = normalize(fragEyeDir + fragLightDir); - // add specular contribution - return vec3(diffuseColor + specularColor); + float specularPower = facingLight * max(0.0, dot(fragEyeDir, halfDir)); + vec3 reflect = pow(specularPower, gloss * 128.0) * specular; + + return vec4(reflect, diffuse); +} + +vec3 evalDirectionalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { + + vec4 shading = evalFragShading(normal, gl_LightSource[0].position.xyz, normalize(position), specular, gloss); + + return vec3(diffuse + shading.rgb) * shading.w * shadowAttenuation * gl_FrontLightProduct[0].diffuse.rgb; } diff --git a/libraries/render-utils/src/directional_ambient_light.slf b/libraries/render-utils/src/directional_ambient_light.slf index 059c0e150f..a0b850e925 100755 --- a/libraries/render-utils/src/directional_ambient_light.slf +++ b/libraries/render-utils/src/directional_ambient_light.slf @@ -20,6 +20,7 @@ void main(void) { DeferredFragment frag = unpackDeferredFragment(gl_TexCoord[0].st); + // Light mapped or not ? if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { vec3 color = evalLightmappedColor( diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf index d8bedc2bea..75c09508ae 100644 --- a/libraries/render-utils/src/spot_light.slf +++ b/libraries/render-utils/src/spot_light.slf @@ -57,10 +57,14 @@ void main(void) { discard; } - vec4 wNor = invViewMat * vec4(frag.normal, 0.0); + vec4 fragNormal = invViewMat * vec4(frag.normal, 0.0); vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); vec3 fragEyeDir = normalize(fragEyeVector.xyz); - vec3 wHalfDir = normalize(fragEyeDir + fragLightDir); + + vec4 shading = evalFragShading(fragNormal, fragLightDir, fragEyeDir, frag.specular, frag.gloss); + + vec3 fragColor = shading.w * (frag.diffuse + shading.xyz); + /* vec3 wHalfDir = normalize(fragEyeDir + fragLightDir); // Diffuse Lighting float diffuseDot = dot(wNor.xyz, fragLightDir); @@ -70,7 +74,7 @@ void main(void) { // compute the specular multiplier (sans exponent) float specularPower = facingLight * max(0.0, dot(fragEyeDir, wHalfDir)); vec3 specularColor = pow(specularPower, frag.gloss * 128.0) * frag.specular; - + */ // Eval angular attenuation float lightAngularAttenuation = clamp((cosSpotAngle - getLightSpotAngleCos(light)) / (1.0 - getLightSpotAngleCos(light)), 0.0, 1.0); @@ -84,7 +88,7 @@ void main(void) { float edgeCoord = exp2(-8.0*edge*edge); gl_FragColor = vec4(edgeCoord * edgeCoord * getLightColor(light), 0.0); } else { - gl_FragColor = vec4((diffuseColor + specularColor) * lightAngularAttenuation * lightAttenuation * getLightColor(light) * getLightIntensity(light), 0.0); + gl_FragColor = vec4(fragColor * lightAngularAttenuation * lightAttenuation * getLightColor(light) * getLightIntensity(light), 0.0); } } From 6c00f29f2b69130583f91ad502aa77ffb7c828ec Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 4 Feb 2015 14:01:16 -0800 Subject: [PATCH 043/103] REvisiting the shaders for lighting on deferred pass --- libraries/render-utils/src/spot_light.slf | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf index 75c09508ae..bbe4107a4d 100644 --- a/libraries/render-utils/src/spot_light.slf +++ b/libraries/render-utils/src/spot_light.slf @@ -15,6 +15,9 @@ // Everything about deferred buffer <@include DeferredBuffer.slh@> +//Everything about deferred lighting +<@include DeferredLighting.slh@> + // Everything about light <@include Light.slh@> @@ -57,7 +60,7 @@ void main(void) { discard; } - vec4 fragNormal = invViewMat * vec4(frag.normal, 0.0); + vec3 fragNormal = vec3(invViewMat * vec4(frag.normal, 0.0)); vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); vec3 fragEyeDir = normalize(fragEyeVector.xyz); From d270979f95c373e39cdac000bfabd667da32cb0b Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 4 Feb 2015 23:19:56 +0100 Subject: [PATCH 044/103] Instructions initial --- examples/controllers/oculus/goTo.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/examples/controllers/oculus/goTo.js b/examples/controllers/oculus/goTo.js index 5038253e17..ea3d12417d 100644 --- a/examples/controllers/oculus/goTo.js +++ b/examples/controllers/oculus/goTo.js @@ -19,6 +19,23 @@ Script.include("../../libraries/globals.js"); Script.include("../../libraries/virtualKeyboard.js"); +function Instructions(imageURL) { + this.overlay = Overlays.addOverlay("image", { + imageURL: HIFI_PUBLIC_BUCKET + "images/tutorial-goTo.svg", + x: 0, + y: 0, + alpha: 1, + visible: true + }); + this.remove = function() { + Overlays.deleteOverlay(this.overlay); + }; +}; + +var theInstruction = new Instructions(); + + + var windowDimensions = Controller.getViewportDimensions(); var cursor = new Cursor({visible: false});; var keyboard = new Keyboard({visible: false}); @@ -124,6 +141,7 @@ function scriptEnding() { Controller.releaseKeyEvents({key: SPACEBAR_CHARCODE}); Controller.releaseKeyEvents({key: RETURN_CHARCODE}); Controller.releaseKeyEvents({key: ENTER_CHARCODE}); + theInstruction.remove(); } function reportButtonValue(button, newValue, oldValue) { From 8e1eebbbd4063b8979c17643a4f935021d8693c8 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 4 Feb 2015 17:24:23 -0800 Subject: [PATCH 045/103] FInally getting the angular attenuation --- libraries/model/src/model/Light.cpp | 11 +++-- libraries/model/src/model/Light.h | 5 ++- .../src/DeferredLightingEffect.cpp | 31 +------------ libraries/render-utils/src/Light.slh | 9 ++-- libraries/render-utils/src/point_light.slf | 42 +++++++++--------- libraries/render-utils/src/spot_light.slf | 44 +++++++------------ 6 files changed, 54 insertions(+), 88 deletions(-) diff --git a/libraries/model/src/model/Light.cpp b/libraries/model/src/model/Light.cpp index 6348ffbcc7..a658c57be9 100755 --- a/libraries/model/src/model/Light.cpp +++ b/libraries/model/src/model/Light.cpp @@ -31,6 +31,7 @@ Light& Light::operator= (const Light& light) { _flags = (light._flags); _schemaBuffer = (light._schemaBuffer); _transform = (light._transform); + _spotConeAngle = (light._spotConeAngle); return (*this); } @@ -67,7 +68,7 @@ void Light::setMaximumRadius(float radius) { if (radius <= 0.f) { radius = 1.0f; } - float CutOffIntensityRatio = 0.01f; + float CutOffIntensityRatio = 0.05f; float surfaceRadius = radius / (sqrt(1.0f / CutOffIntensityRatio) - 1.f); editSchema()._attenuation = Vec4(surfaceRadius, 1.0f/surfaceRadius, CutOffIntensityRatio, radius); } @@ -76,15 +77,17 @@ void Light::setSpotCone(float angle) { if (angle <= 0.f) { angle = 0.0f; } - editSchema()._spot.x = cos(angle); - editSchema()._spot.z = angle; + float cosAngle = cos(angle); + editSchema()._spot.x = cosAngle; + editSchema()._spot.y = sin(angle); + editSchema()._spot.z = 1.0f / cosAngle; + _spotConeAngle = angle; } void Light::setSpotConeExponent(float exponent) { if (exponent <= 0.f) { exponent = 1.0f; } - editSchema()._spot.y = exponent; editSchema()._spot.w = exponent; } diff --git a/libraries/model/src/model/Light.h b/libraries/model/src/model/Light.h index 5e3bda5e1d..c1b8a351e5 100755 --- a/libraries/model/src/model/Light.h +++ b/libraries/model/src/model/Light.h @@ -81,7 +81,7 @@ public: bool isSpot() const { return getType() == SPOT; } void setSpotCone(float angle); void setSpotConeExponent(float exponent); - float getSpotConeAngle() const { return getSchema()._spot.z; } + float getSpotConeAngle() const { return _spotConeAngle; } float getSpotConeExponent() const { return getSchema()._spot.w; } // Schema to access the attribute values of the light @@ -105,7 +105,7 @@ public: _color(1.0f), _intensity(1.0f), _attenuation(1.0f, 1.0f, 1.0f, 1.0f), - _spot(0.0f, 0.0f, 0.0f, 0.0f), + _spot(0.0f, 0.0f, 0.0f, 3.0f), _control(0.0f) {} }; @@ -117,6 +117,7 @@ protected: Flags _flags; UniformBufferView _schemaBuffer; Transform _transform; + float _spotConeAngle = 0.0f; const Schema& getSchema() const { return _schemaBuffer.get(); } Schema& editSchema() { return _schemaBuffer.edit(); } diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index fee3b4c947..e0fd3787f6 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -304,6 +304,7 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu lp->setDirection(direction); lp->setMaximumRadius(radius); lp->setSpotCone(cutoff); + lp->setSpotConeExponent(exponent); lp->setColor(diffuse); lp->setIntensity(1.0f); lp->setType(model::Light::SPOT); @@ -470,25 +471,14 @@ void DeferredLightingEffect::render() { for (auto lightID : _pointLights) { auto light = _allocatedLights[lightID]; - // foreach (const PointLight& light, _pointLights) { + if (_pointLightLocations.lightBufferUnit >= 0) { gpu::Batch batch; batch.setUniformBuffer(_pointLightLocations.lightBufferUnit, light->getSchemaBuffer()); gpu::GLBackend::renderBatch(batch); } glUniformMatrix4fv(_pointLightLocations.invViewMat, 1, false, reinterpret_cast< const GLfloat* >(&invViewMat)); - -/* - _pointLight.setUniformValue(_pointLightLocations.radius, light.radius); - glLightfv(GL_LIGHT1, GL_AMBIENT, (const GLfloat*)&light.ambient); - glLightfv(GL_LIGHT1, GL_DIFFUSE, (const GLfloat*)&light.diffuse); - glLightfv(GL_LIGHT1, GL_SPECULAR, (const GLfloat*)&light.specular); - glLightfv(GL_LIGHT1, GL_POSITION, (const GLfloat*)&light.position); - glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, (light.constantAttenuation > 0.0f ? light.constantAttenuation : 0.0f)); - glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, (light.linearAttenuation > 0.0f ? light.linearAttenuation : 0.0f)); - glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, (light.quadraticAttenuation > 0.0f ? light.quadraticAttenuation : 0.0f)); - */ glPushMatrix(); float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION); @@ -527,7 +517,6 @@ void DeferredLightingEffect::render() { for (auto lightID : _spotLights) { auto light = _allocatedLights[lightID]; - // foreach (const SpotLight& light, _spotLights) { if (_spotLightLocations.lightBufferUnit >= 0) { gpu::Batch batch; batch.setUniformBuffer(_spotLightLocations.lightBufferUnit, light->getSchemaBuffer()); @@ -535,22 +524,6 @@ void DeferredLightingEffect::render() { } glUniformMatrix4fv(_spotLightLocations.invViewMat, 1, false, reinterpret_cast< const GLfloat* >(&invViewMat)); - // _spotLight.setUniformValue(_spotLightLocations.radius, light->getAttenuationRadius()); - - /* - _spotLight.setUniformValue(_spotLightLocations.radius, light.radius); - glLightfv(GL_LIGHT1, GL_AMBIENT, (const GLfloat*)&light.ambient); - glLightfv(GL_LIGHT1, GL_DIFFUSE, (const GLfloat*)&light.diffuse); - glLightfv(GL_LIGHT1, GL_SPECULAR, (const GLfloat*)&light.specular); - glLightfv(GL_LIGHT1, GL_POSITION, (const GLfloat*)&light.position); - glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, (light.constantAttenuation > 0.0f ? light.constantAttenuation : 0.0f)); - glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, (light.linearAttenuation > 0.0f ? light.linearAttenuation : 0.0f)); - glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, (light.quadraticAttenuation > 0.0f ? light.quadraticAttenuation : 0.0f)); - glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, (const GLfloat*)&light.direction); - glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, light.exponent); - glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, glm::degrees(light.cutoff)); - */ - glPushMatrix(); float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION); diff --git a/libraries/render-utils/src/Light.slh b/libraries/render-utils/src/Light.slh index ccf6e52836..ab9bf216de 100755 --- a/libraries/render-utils/src/Light.slh +++ b/libraries/render-utils/src/Light.slh @@ -41,11 +41,12 @@ float getLightSpotAngleCos(Light l) { return l._spot.x; } +vec2 getLightSpotOutsideNormal2(Light l) { + return vec2(-l._spot.y, l._spot.x); +} + float evalLightSpotAttenuation(Light l, float cosA) { - if (cosA > l._spot.x) { - return 0.0; - } - return clamp(pow(cosA / l._spot.x, l._spot.w), 0.0, 1.0); + return pow(cosA * l._spot.z, l._spot.w); } float getLightSquareRadius(Light l) { diff --git a/libraries/render-utils/src/point_light.slf b/libraries/render-utils/src/point_light.slf index da2d708f06..4a96f3ae3d 100644 --- a/libraries/render-utils/src/point_light.slf +++ b/libraries/render-utils/src/point_light.slf @@ -15,6 +15,9 @@ // Everything about deferred buffer <@include DeferredBuffer.slh@> +//Everything about deferred lighting +<@include DeferredLighting.slh@> + // Everything about light <@include Light.slh@> @@ -22,9 +25,8 @@ uniform mat4 invViewMat; void main(void) { - // get the depth and exit early if it doesn't pass the test + // Grab the fragment data from the uv vec2 texCoord = gl_TexCoord[0].st / gl_TexCoord[0].q; - DeferredFragment frag = unpackDeferredFragment(texCoord); // Kill if in front of the light volume @@ -37,9 +39,8 @@ void main(void) { Light light = getLight(); // Make the Light vector going from fragment to light center in world space - vec4 wPos; - wPos = invViewMat * frag.position; - vec3 fragLightVec = getLightPosition(light) - wPos.xyz; + vec4 fragPos = invViewMat * frag.position; + vec3 fragLightVec = getLightPosition(light) - fragPos.xyz; // Kill if too far from the light center if (dot(fragLightVec, fragLightVec) > getLightSquareRadius(light)) { @@ -48,31 +49,28 @@ void main(void) { // Allright we re valid in the volume float fragLightDistance = length(fragLightVec); - float lightAttenuation = evalLightAttenuation(light, fragLightDistance); - vec3 fragLightDir = fragLightVec / fragLightDistance; - vec4 wNor = invViewMat * vec4(frag.normal, 0.0); + + + // Eval shading + vec3 fragNormal = vec3(invViewMat * vec4(frag.normal, 0.0)); vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); vec3 fragEyeDir = normalize(fragEyeVector.xyz); - vec3 wHalfDir = normalize(fragEyeDir + fragLightDir); + vec4 shading = evalFragShading(fragNormal, fragLightDir, fragEyeDir, frag.specular, frag.gloss); - // Diffuse Lighting - float diffuseDot = dot(wNor.xyz, fragLightDir); - float facingLight = step(0.0, diffuseDot); - vec3 diffuseColor = frag.diffuse * diffuseDot * facingLight; - - // compute the specular multiplier (sans exponent) - float specularPower = facingLight * max(0.0, - dot(fragEyeDir, wHalfDir)); - vec3 specularColor = pow(specularPower, frag.gloss * 128.0) * frag.specular; + // Eval attenuation + float radialAttenuation = evalLightAttenuation(light, fragLightDistance); + // Final Lighting color + vec3 fragColor = shading.w * (frag.diffuse + shading.xyz); + gl_FragColor = vec4(fragColor * radialAttenuation * getLightColor(light) * getLightIntensity(light), 0.0); + +<@if SHOW_LIGHT_CONTOUR@> // Show edge - float maxRadius = getLightRadius(light); - float edge = abs(2.0 * ((maxRadius - fragLightDistance) / (0.1)) - 1.0); + float edge = abs(2.0 * ((getLightRadius(light) - fragLightDistance) / (0.1)) - 1.0); if (edge < 1) { float edgeCoord = exp2(-8.0*edge*edge); gl_FragColor = vec4(edgeCoord * edgeCoord * getLightColor(light), 0.0); - } else { - gl_FragColor = vec4((diffuseColor + specularColor) * lightAttenuation * getLightColor(light) * getLightIntensity(light), 0.0); } +<@endif@> } diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf index bbe4107a4d..aec1ce4b89 100644 --- a/libraries/render-utils/src/spot_light.slf +++ b/libraries/render-utils/src/spot_light.slf @@ -25,9 +25,8 @@ uniform mat4 invViewMat; void main(void) { - // get the depth and exit early if it doesn't pass the test + // Grab the fragment data from the uv vec2 texCoord = gl_TexCoord[0].st / gl_TexCoord[0].q; - DeferredFragment frag = unpackDeferredFragment(texCoord); // Kill if in front of the light volume @@ -40,8 +39,8 @@ void main(void) { Light light = getLight(); // Make the Light vector going from fragment to light center in world space - vec4 wPos = invViewMat * frag.position; - vec3 fragLightVec = getLightPosition(light) - wPos.xyz; + vec4 fragPos = invViewMat * frag.position; + vec3 fragLightVec = getLightPosition(light) - fragPos.xyz; // Kill if too far from the light center if (dot(fragLightVec, fragLightVec) > getLightSquareRadius(light)) { @@ -50,7 +49,6 @@ void main(void) { // Allright we re valid in the volume float fragLightDistance = length(fragLightVec); - float lightAttenuation = evalLightAttenuation(light, fragLightDistance); vec3 fragLightDir = fragLightVec / fragLightDistance; // Kill if not in the spot light (ah ah !) @@ -60,38 +58,30 @@ void main(void) { discard; } + // Eval shading vec3 fragNormal = vec3(invViewMat * vec4(frag.normal, 0.0)); vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); vec3 fragEyeDir = normalize(fragEyeVector.xyz); - vec4 shading = evalFragShading(fragNormal, fragLightDir, fragEyeDir, frag.specular, frag.gloss); + + // Eval attenuation + float radialAttenuation = evalLightAttenuation(light, fragLightDistance); + float angularAttenuation = evalLightSpotAttenuation(light, cosSpotAngle); + // Final Lighting color vec3 fragColor = shading.w * (frag.diffuse + shading.xyz); - /* vec3 wHalfDir = normalize(fragEyeDir + fragLightDir); + gl_FragColor = vec4(fragColor * angularAttenuation * radialAttenuation * getLightColor(light) * getLightIntensity(light), 0.0); - // Diffuse Lighting - float diffuseDot = dot(wNor.xyz, fragLightDir); - float facingLight = step(0.0, diffuseDot); - vec3 diffuseColor = frag.diffuse * diffuseDot * facingLight; - - // compute the specular multiplier (sans exponent) - float specularPower = facingLight * max(0.0, dot(fragEyeDir, wHalfDir)); - vec3 specularColor = pow(specularPower, frag.gloss * 128.0) * frag.specular; - */ - // Eval angular attenuation - float lightAngularAttenuation = clamp((cosSpotAngle - getLightSpotAngleCos(light)) / (1.0 - getLightSpotAngleCos(light)), 0.0, 1.0); - - // Show edge - float maxRadius = getLightRadius(light); - float edge = abs(2.0 * ((maxRadius - fragLightDistance) / (0.1)) - 1.0); - if (cosSpotAngle < 1.01 * getLightSpotAngleCos(light)) { - edge = 0; - } +<@if SHOW_LIGHT_CONTOUR@> + // Show edges + float edgeDistR = (getLightRadius(light) - fragLightDistance); + float edgeDistS = dot(fragLightDistance * vec2(cosSpotAngle, sqrt(1.0 - cosSpotAngle * cosSpotAngle)), -getLightSpotOutsideNormal2(light)); + float edgeDist = min(edgeDistR, edgeDistS); + float edge = abs(2.0 * (edgeDist / (0.1)) - 1.0); if (edge < 1) { float edgeCoord = exp2(-8.0*edge*edge); gl_FragColor = vec4(edgeCoord * edgeCoord * getLightColor(light), 0.0); - } else { - gl_FragColor = vec4(fragColor * lightAngularAttenuation * lightAttenuation * getLightColor(light) * getLightIntensity(light), 0.0); } +<@endif@> } From 00a9f55bc329b41aa41b1ff128dec10e6f0d2741 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 5 Feb 2015 10:20:19 -0800 Subject: [PATCH 046/103] lightings seems to work correctly now --- libraries/model/src/model/Light.cpp | 10 ++++------ libraries/model/src/model/Light.h | 9 ++++----- libraries/render-utils/src/DeferredLightingEffect.cpp | 8 ++++---- libraries/render-utils/src/Light.slh | 2 +- libraries/render-utils/src/point_light.slf | 1 - 5 files changed, 13 insertions(+), 17 deletions(-) diff --git a/libraries/model/src/model/Light.cpp b/libraries/model/src/model/Light.cpp index a658c57be9..d66c82ee16 100755 --- a/libraries/model/src/model/Light.cpp +++ b/libraries/model/src/model/Light.cpp @@ -31,7 +31,6 @@ Light& Light::operator= (const Light& light) { _flags = (light._flags); _schemaBuffer = (light._schemaBuffer); _transform = (light._transform); - _spotConeAngle = (light._spotConeAngle); return (*this); } @@ -73,18 +72,17 @@ void Light::setMaximumRadius(float radius) { editSchema()._attenuation = Vec4(surfaceRadius, 1.0f/surfaceRadius, CutOffIntensityRatio, radius); } -void Light::setSpotCone(float angle) { +void Light::setSpotAngle(float angle) { if (angle <= 0.f) { angle = 0.0f; } float cosAngle = cos(angle); - editSchema()._spot.x = cosAngle; + editSchema()._spot.x = cos(angle); editSchema()._spot.y = sin(angle); - editSchema()._spot.z = 1.0f / cosAngle; - _spotConeAngle = angle; + editSchema()._spot.z = angle; } -void Light::setSpotConeExponent(float exponent) { +void Light::setSpotExponent(float exponent) { if (exponent <= 0.f) { exponent = 1.0f; } diff --git a/libraries/model/src/model/Light.h b/libraries/model/src/model/Light.h index c1b8a351e5..c016d54491 100755 --- a/libraries/model/src/model/Light.h +++ b/libraries/model/src/model/Light.h @@ -79,10 +79,10 @@ public: // Spot properties bool isSpot() const { return getType() == SPOT; } - void setSpotCone(float angle); - void setSpotConeExponent(float exponent); - float getSpotConeAngle() const { return _spotConeAngle; } - float getSpotConeExponent() const { return getSchema()._spot.w; } + void setSpotAngle(float angle); + float getSpotAngle() const { return getSchema()._spot.z; } + void setSpotExponent(float exponent); + float getSpotExponent() const { return getSchema()._spot.w; } // Schema to access the attribute values of the light class Schema { @@ -117,7 +117,6 @@ protected: Flags _flags; UniformBufferView _schemaBuffer; Transform _transform; - float _spotConeAngle = 0.0f; const Schema& getSchema() const { return _schemaBuffer.get(); } Schema& editSchema() { return _schemaBuffer.edit(); } diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index e0fd3787f6..61330b8943 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -303,8 +303,8 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu lp->setPosition(position); lp->setDirection(direction); lp->setMaximumRadius(radius); - lp->setSpotCone(cutoff); - lp->setSpotConeExponent(exponent); + lp->setSpotAngle(cutoff); + lp->setSpotExponent(exponent); lp->setColor(diffuse); lp->setIntensity(1.0f); lp->setType(model::Light::SPOT); @@ -527,7 +527,7 @@ void DeferredLightingEffect::render() { glPushMatrix(); float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION); - float edgeRadius = expandedRadius / glm::cos(light->getSpotConeAngle()); + float edgeRadius = expandedRadius / glm::cos(light->getSpotAngle()); if (glm::distance(eyePoint, glm::vec3(light->getPosition())) < edgeRadius + nearRadius) { glLoadIdentity(); glTranslatef(0.0f, 0.0f, -1.0f); @@ -547,7 +547,7 @@ void DeferredLightingEffect::render() { glm::vec3 axis = glm::axis(spotRotation); glRotatef(glm::degrees(glm::angle(spotRotation)), axis.x, axis.y, axis.z); glTranslatef(0.0f, 0.0f, -light->getMaximumRadius() * (1.0f + SCALE_EXPANSION * 0.5f)); - geometryCache->renderCone(expandedRadius * glm::tan(light->getSpotConeAngle()), + geometryCache->renderCone(expandedRadius * glm::tan(light->getSpotAngle()), expandedRadius, 32, 1); } diff --git a/libraries/render-utils/src/Light.slh b/libraries/render-utils/src/Light.slh index ab9bf216de..0560898d09 100755 --- a/libraries/render-utils/src/Light.slh +++ b/libraries/render-utils/src/Light.slh @@ -46,7 +46,7 @@ vec2 getLightSpotOutsideNormal2(Light l) { } float evalLightSpotAttenuation(Light l, float cosA) { - return pow(cosA * l._spot.z, l._spot.w); + return pow(cosA, l._spot.w); } float getLightSquareRadius(Light l) { diff --git a/libraries/render-utils/src/point_light.slf b/libraries/render-utils/src/point_light.slf index 4a96f3ae3d..3d3d922203 100644 --- a/libraries/render-utils/src/point_light.slf +++ b/libraries/render-utils/src/point_light.slf @@ -51,7 +51,6 @@ void main(void) { float fragLightDistance = length(fragLightVec); vec3 fragLightDir = fragLightVec / fragLightDistance; - // Eval shading vec3 fragNormal = vec3(invViewMat * vec4(frag.normal, 0.0)); vec4 fragEyeVector = invViewMat * vec4(-frag.position.xyz, 0.0); From 9b0036d010474d4466e9e2e07f7a9d863cf73162 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 5 Feb 2015 14:10:06 -0800 Subject: [PATCH 047/103] adding Light and replace glLights also for the first deferred pass --- libraries/model/src/model/Light.cpp | 10 +- libraries/model/src/model/Light.h | 4 + .../render-utils/src/DeferredGlobalLight.slh | 122 ++++++++++++++++++ .../render-utils/src/DeferredLighting.slh | 76 ----------- .../src/DeferredLightingEffect.cpp | 66 +++++----- .../render-utils/src/DeferredLightingEffect.h | 5 +- libraries/render-utils/src/Light.slh | 4 + .../src/directional_ambient_light.slf | 5 +- ...onal_ambient_light_cascaded_shadow_map.slf | 5 +- .../directional_ambient_light_shadow_map.slf | 5 +- .../render-utils/src/directional_light.slf | 5 +- .../directional_light_cascaded_shadow_map.slf | 5 +- .../src/directional_light_shadow_map.slf | 5 +- libraries/render-utils/src/point_light.slf | 14 +- libraries/render-utils/src/spot_light.slf | 20 +-- 15 files changed, 202 insertions(+), 149 deletions(-) create mode 100755 libraries/render-utils/src/DeferredGlobalLight.slh diff --git a/libraries/model/src/model/Light.cpp b/libraries/model/src/model/Light.cpp index d66c82ee16..30e873ea30 100755 --- a/libraries/model/src/model/Light.cpp +++ b/libraries/model/src/model/Light.cpp @@ -48,7 +48,7 @@ void Light::setOrientation(const glm::quat& orientation) { } void Light::setDirection(const Vec3& direction) { - editSchema()._direction = direction; + editSchema()._direction = glm::normalize(direction); } const Vec3& Light::getDirection() const { @@ -56,7 +56,7 @@ const Vec3& Light::getDirection() const { } void Light::setColor(const Color& color) { - editSchema()._color = color; + editSchema()._color = glm::normalize(color); } void Light::setIntensity(float intensity) { @@ -89,3 +89,9 @@ void Light::setSpotExponent(float exponent) { editSchema()._spot.w = exponent; } +void Light::setShowVolumeContour(float show) { + if (show <= 0.f) { + show = 0.0f; + } + editSchema()._control.w = show; +} \ No newline at end of file diff --git a/libraries/model/src/model/Light.h b/libraries/model/src/model/Light.h index c016d54491..4640711f4d 100755 --- a/libraries/model/src/model/Light.h +++ b/libraries/model/src/model/Light.h @@ -84,6 +84,10 @@ public: void setSpotExponent(float exponent); float getSpotExponent() const { return getSchema()._spot.w; } + // For editing purpose, show the light volume contour + void setShowVolumeContour(float show); + float getShowVolumeContour() const { return getSchema()._control.w; } + // Schema to access the attribute values of the light class Schema { public: diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh new file mode 100755 index 0000000000..bb33a124dc --- /dev/null +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -0,0 +1,122 @@ + +<@if not DEFERRED_GLOBAL_LIGHT_SLH@> +<@def DEFERRED_GLOBAL_LIGHT_SLH@> + +<@include DeferredLighting.slh@> + +struct SphericalHarmonics { + vec4 L00; + vec4 L1m1; + vec4 L10; + vec4 L11; + vec4 L2m2; + vec4 L2m1; + vec4 L20; + vec4 L21; + vec4 L22; +}; + +vec4 evalSphericalLight(SphericalHarmonics sh, vec3 direction ) { + + const float C1 = 0.429043; + const float C2 = 0.511664; + const float C3 = 0.743125; + const float C4 = 0.886227; + const float C5 = 0.247708; + + vec4 value = C1 * sh.L22 * (direction.x * direction.x - direction.y * direction.y) + + C3 * sh.L20 * direction.z * direction.z + + C4 * sh.L00 - C5 * sh.L20 + + 2.0 * C1 * ( sh.L2m2 * direction.x * direction.y + + sh.L21 * direction.x * direction.z + + sh.L2m1 * direction.y * direction.z ) + + 2.0 * C2 * ( sh.L11 * direction.x + + sh.L1m1 * direction.y + + sh.L10 * direction.z ) ; + return value; +} + +// Need one SH +uniform SphericalHarmonics ambientSphere; + +// Everything about light +<@include Light.slh@> + +// The view Matrix +uniform mat4 invViewMat; + +vec3 evalAmbientColor(vec3 normal, vec3 diffuse, vec3 specular, float gloss) { + return diffuse.rgb * gl_FrontLightProduct[0].ambient.rgb; +} + +vec3 evalAmbientSphereColor(vec3 normal, vec3 diffuse, vec3 specular, float gloss) { + vec3 ambientLight = 0.5 * evalSphericalLight(ambientSphere, normal).xyz; + + return diffuse.rgb * ambientLight; +} + + + + +vec3 evalDirectionalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { + + // Need the light now + Light light = getLight(); + vec4 shading = evalFragShading(normal, getLightDirection(light), normalize(position), specular, gloss); + return vec3(diffuse + shading.rgb) * shading.w * shadowAttenuation * getLightColor(light) * getLightIntensity(light); + // return vec3(diffuse + shading.rgb) * shading.w * shadowAttenuation * gl_FrontLightProduct[0].diffuse.rgb; +} + +vec3 evalAmbienGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { + vec3 color = evalAmbientColor(normal, diffuse, specular, gloss) + + evalDirectionalColor(shadowAttenuation, + position, + normal, + diffuse, + specular, + gloss); + return color; +} +vec3 evalAmbienSphereGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { + vec3 color = evalAmbientSphereColor(normal, diffuse, specular, gloss) + + evalDirectionalColor(shadowAttenuation, + position, + normal, + diffuse, + specular, + gloss); + return color; +} + +vec3 evalLightmappedColor(float shadowAttenuation, vec3 normal, vec3 diffuse, vec3 lightmap) { + + Light light = getLight(); + float diffuseDot = dot(normal, getLightDirection(light)); + + // need to catch normals perpendicular to the projection plane hence the magic number for the threshold + // it should be just 0, but we have innacurracy so we need to overshoot + const float PERPENDICULAR_THRESHOLD = -0.005; + float facingLight = step(PERPENDICULAR_THRESHOLD, diffuseDot); + + // evaluate the shadow test but only relevant for light facing fragments + float lightAttenuation = (1 - facingLight) + facingLight * shadowAttenuation; + + // diffuse light is the lightmap dimmed by shadow + vec3 diffuseLight = lightAttenuation * lightmap; + + // ambient is a tiny percentage of the lightmap and only when in the shadow + vec3 ambientLight = (1 - lightAttenuation) * 0.5 * lightmap; + + return diffuse * (ambientLight + diffuseLight); +} + +<@endif@> diff --git a/libraries/render-utils/src/DeferredLighting.slh b/libraries/render-utils/src/DeferredLighting.slh index 1c9f77c2e0..f6845fbccb 100755 --- a/libraries/render-utils/src/DeferredLighting.slh +++ b/libraries/render-utils/src/DeferredLighting.slh @@ -11,53 +11,6 @@ <@if not DEFERRED_LIGHTING_SLH@> <@def DEFERRED_LIGHTING_SLH@> -struct SphericalHarmonics { - vec4 L00; - vec4 L1m1; - vec4 L10; - vec4 L11; - vec4 L2m2; - vec4 L2m1; - vec4 L20; - vec4 L21; - vec4 L22; -}; - -vec4 evalSphericalLight(SphericalHarmonics sh, vec3 direction ) { - - const float C1 = 0.429043; - const float C2 = 0.511664; - const float C3 = 0.743125; - const float C4 = 0.886227; - const float C5 = 0.247708; - - vec4 value = C1 * sh.L22 * (direction.x * direction.x - direction.y * direction.y) + - C3 * sh.L20 * direction.z * direction.z + - C4 * sh.L00 - C5 * sh.L20 + - 2.0 * C1 * ( sh.L2m2 * direction.x * direction.y + - sh.L21 * direction.x * direction.z + - sh.L2m1 * direction.y * direction.z ) + - 2.0 * C2 * ( sh.L11 * direction.x + - sh.L1m1 * direction.y + - sh.L10 * direction.z ) ; - return value; -} - -uniform SphericalHarmonics ambientSphere; - -// Everything about light -<@include Light.slh@> - -vec3 evalAmbientColor(vec3 normal, vec3 diffuse, vec3 specular, float gloss) { - return diffuse.rgb * gl_FrontLightProduct[0].ambient.rgb; -} - -vec3 evalAmbientSphereColor(vec3 normal, vec3 diffuse, vec3 specular, float gloss) { - vec3 ambientLight = 0.5 * evalSphericalLight(ambientSphere, normal).xyz; - - return diffuse.rgb * ambientLight; -} - // Frag Shading returns the diffuse amount as W and the specular rgb as xyz vec4 evalFragShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 specular, float gloss) { // Diffuse Lighting @@ -74,33 +27,4 @@ vec4 evalFragShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 s return vec4(reflect, diffuse); } -vec3 evalDirectionalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { - - vec4 shading = evalFragShading(normal, gl_LightSource[0].position.xyz, normalize(position), specular, gloss); - - return vec3(diffuse + shading.rgb) * shading.w * shadowAttenuation * gl_FrontLightProduct[0].diffuse.rgb; -} - - -vec3 evalLightmappedColor(float shadowAttenuation, vec3 normal, vec3 diffuse, vec3 lightmap) { - - float diffuseDot = dot(normal, gl_LightSource[0].position.xyz); - - // need to catch normals perpendicular to the projection plane hence the magic number for the threshold - // it should be just 0, but we have innacurracy so we need to overshoot - const float PERPENDICULAR_THRESHOLD = -0.005; - float facingLight = step(PERPENDICULAR_THRESHOLD, diffuseDot); - - // evaluate the shadow test but only relevant for light facing fragments - float lightAttenuation = (1 - facingLight) + facingLight * shadowAttenuation; - - // diffuse light is the lightmap dimmed by shadow - vec3 diffuseLight = lightAttenuation * lightmap; - - // ambient is a tiny percentage of the lightmap and only when in the shadow - vec3 ambientLight = (1 - lightAttenuation) * 0.5 * lightmap; - - return diffuse * (ambientLight + diffuseLight); -} - <@endif@> diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 61330b8943..1241845675 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -209,6 +209,17 @@ void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) { loadLightProgram(point_light_frag, true, _pointLight, _pointLightLocations); loadLightProgram(spot_light_frag, true, _spotLight, _spotLightLocations); + + // Allocate 2 global lights representing the GLobal Directional light casting shadow (the sun) and the ambient light + _globalLights.push_back(0); + _allocatedLights.push_back(model::LightPointer(new model::Light())); + + model::LightPointer lp = _allocatedLights[0]; + + lp->setDirection(-glm::vec3(1.0f, 1.0f, 1.0f)); + lp->setColor(glm::vec3(1.0f)); + lp->setIntensity(1.0f); + lp->setType(model::Light::SUN); } void DeferredLightingEffect::bindSimpleProgram() { @@ -264,51 +275,27 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu const glm::vec3& diffuse, const glm::vec3& specular, float constantAttenuation, float linearAttenuation, float quadraticAttenuation, const glm::vec3& direction, float exponent, float cutoff) { - int lightID = _pointLights.size() + _spotLights.size(); + int lightID = _pointLights.size() + _spotLights.size() + _globalLights.size(); if (lightID >= _allocatedLights.size()) { _allocatedLights.push_back(model::LightPointer(new model::Light())); } model::LightPointer lp = _allocatedLights[lightID]; - if (exponent == 0.0f && cutoff == PI) { - PointLight light; - light.position = glm::vec4(position, 1.0f); - light.radius = radius; - light.ambient = glm::vec4(ambient, 1.0f); - light.diffuse = glm::vec4(diffuse, 1.0f); - light.specular = glm::vec4(specular, 1.0f); - light.constantAttenuation = constantAttenuation; - light.linearAttenuation = linearAttenuation; + lp->setPosition(position); + lp->setMaximumRadius(radius); + lp->setColor(diffuse); + lp->setIntensity(1.0f); + lp->setShowVolumeContour(quadraticAttenuation); - lp->setPosition(position); - lp->setMaximumRadius(radius); - lp->setColor(diffuse); - lp->setIntensity(1.0f); + if (exponent == 0.0f && cutoff == PI) { lp->setType(model::Light::POINT); _pointLights.push_back(lightID); } else { - SpotLight light; - light.position = glm::vec4(position, 1.0f); - light.radius = radius; - light.ambient = glm::vec4(ambient, 1.0f); - light.diffuse = glm::vec4(diffuse, 1.0f); - light.specular = glm::vec4(specular, 1.0f); - light.constantAttenuation = constantAttenuation; - light.linearAttenuation = linearAttenuation; - light.direction = direction; - light.exponent = exponent; - light.cutoff = cutoff; - - lp->setPosition(position); lp->setDirection(direction); - lp->setMaximumRadius(radius); lp->setSpotAngle(cutoff); lp->setSpotExponent(exponent); - lp->setColor(diffuse); - lp->setIntensity(1.0f); lp->setType(model::Light::SPOT); - _spotLights.push_back(lightID); } } @@ -368,6 +355,10 @@ void DeferredLightingEffect::render() { float tMin = viewport[VIEWPORT_Y_INDEX] / (float)primaryFBO->height(); float tHeight = viewport[VIEWPORT_HEIGHT_INDEX] / (float)primaryFBO->height(); + // Fetch the ViewMatrix; + glm::mat4 invViewMat; + _viewState->getViewTransform().getMatrix(invViewMat); + ProgramObject* program = &_directionalLight; const LightLocations* locations = &_directionalLightLocations; bool shadowsEnabled = _viewState->getShadowsEnabled(); @@ -418,6 +409,17 @@ void DeferredLightingEffect::render() { } } + { + auto light = _allocatedLights[_globalLights.front()]; + + if (locations->lightBufferUnit >= 0) { + gpu::Batch batch; + batch.setUniformBuffer(locations->lightBufferUnit, light->getSchemaBuffer()); + gpu::GLBackend::renderBatch(batch); + } + glUniformMatrix4fv(locations->invViewMat, 1, false, reinterpret_cast< const GLfloat* >(&invViewMat)); + } + float left, right, bottom, top, nearVal, farVal; glm::vec4 nearClipPlane, farClipPlane; _viewState->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); @@ -457,8 +459,6 @@ void DeferredLightingEffect::render() { const glm::vec3& eyePoint = _viewState->getCurrentViewFrustum()->getPosition(); float nearRadius = glm::distance(eyePoint, _viewState->getCurrentViewFrustum()->getNearTopLeft()); - glm::mat4 invViewMat; - _viewState->getViewTransform().getMatrix(invViewMat); auto geometryCache = DependencyManager::get(); diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 8e6606506a..ad4231a0b7 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -91,7 +91,7 @@ public: void setAmbientLightMode(int preset); private: - DeferredLightingEffect() { } + DeferredLightingEffect() {} virtual ~DeferredLightingEffect() { } class LightLocations { @@ -154,10 +154,9 @@ private: typedef std::vector< model::LightPointer > Lights; Lights _allocatedLights; + std::vector _globalLights; std::vector _pointLights; std::vector _spotLights; - // QVector _pointLights; - // QVector _spotLights; QVector _postLightingRenderables; AbstractViewStateInterface* _viewState; diff --git a/libraries/render-utils/src/Light.slh b/libraries/render-utils/src/Light.slh index 0560898d09..abb9fb6c2a 100755 --- a/libraries/render-utils/src/Light.slh +++ b/libraries/render-utils/src/Light.slh @@ -61,6 +61,10 @@ float getLightAttenuationCutoff(Light l) { return l._attenuation.z; } +float getLightShowContour(Light l) { + return l._control.w; +} + <@if GLPROFILE == PC_GL@> uniform lightBuffer { Light light; diff --git a/libraries/render-utils/src/directional_ambient_light.slf b/libraries/render-utils/src/directional_ambient_light.slf index a0b850e925..308a8a73a7 100755 --- a/libraries/render-utils/src/directional_ambient_light.slf +++ b/libraries/render-utils/src/directional_ambient_light.slf @@ -15,7 +15,7 @@ // Everything about deferred buffer <@include DeferredBuffer.slh@> -<@include DeferredLighting.slh@> +<@include DeferredGlobalLight.slh@> void main(void) { DeferredFragment frag = unpackDeferredFragment(gl_TexCoord[0].st); @@ -31,8 +31,7 @@ void main(void) { gl_FragColor = vec4(color, 1.0); } else { - vec3 color = evalAmbientSphereColor(frag.normal, frag.diffuse, frag.specular, frag.gloss) - + evalDirectionalColor(1.0, + vec3 color = evalAmbienSphereGlobalColor(1.0, frag.position.xyz, frag.normal, frag.diffuse, diff --git a/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf b/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf index 5f88c558d3..db017cf5ac 100755 --- a/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf +++ b/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf @@ -15,7 +15,7 @@ // Everything about deferred buffer <@include DeferredBuffer.slh@> -<@include DeferredLighting.slh@> +<@include DeferredGlobalLight.slh@> // Everything about shadow <@include Shadow.slh@> @@ -36,8 +36,7 @@ void main(void) { frag.specularVal.xyz), 1.0); } else { - vec3 color = evalAmbientSphereColor(frag.normal, frag.diffuse, frag.specular, frag.gloss) - + evalDirectionalColor(shadowAttenuation, + vec3 color = evalAmbienSphereGlobalColor(shadowAttenuation, frag.position.xyz, frag.normal, frag.diffuse, diff --git a/libraries/render-utils/src/directional_ambient_light_shadow_map.slf b/libraries/render-utils/src/directional_ambient_light_shadow_map.slf index 6c241853e3..43d3e91dbe 100755 --- a/libraries/render-utils/src/directional_ambient_light_shadow_map.slf +++ b/libraries/render-utils/src/directional_ambient_light_shadow_map.slf @@ -15,7 +15,7 @@ // Everything about deferred buffer <@include DeferredBuffer.slh@> -<@include DeferredLighting.slh@> +<@include DeferredGlobalLight.slh@> // Everything about shadow <@include Shadow.slh@> @@ -37,8 +37,7 @@ void main(void) { frag.specularVal.xyz), 1.0); } else { - vec3 color = evalAmbientSphereColor(frag.normal, frag.diffuse, frag.specular, frag.gloss) - + evalDirectionalColor(shadowAttenuation, + vec3 color = evalAmbienSphereGlobalColor(shadowAttenuation, frag.position.xyz, frag.normal, frag.diffuse, diff --git a/libraries/render-utils/src/directional_light.slf b/libraries/render-utils/src/directional_light.slf index 8ff6cd6c87..3e708f849e 100644 --- a/libraries/render-utils/src/directional_light.slf +++ b/libraries/render-utils/src/directional_light.slf @@ -15,7 +15,7 @@ // Everything about deferred buffer <@include DeferredBuffer.slh@> -<@include DeferredLighting.slh@> +<@include DeferredGlobalLight.slh@> void main(void) { DeferredFragment frag = unpackDeferredFragment(gl_TexCoord[0].st); @@ -29,8 +29,7 @@ void main(void) { frag.specularVal.xyz), 1.0); } else { - vec3 color = evalAmbientColor(frag.normal, frag.diffuse, frag.specular, frag.gloss) - + evalDirectionalColor(1.0, + vec3 color = evalAmbienGlobalColor(1.0, frag.position.xyz, frag.normal, frag.diffuse, diff --git a/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf b/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf index ccf8909b64..90b3bf1d2b 100644 --- a/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf +++ b/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf @@ -15,7 +15,7 @@ // Everything about deferred buffer <@include DeferredBuffer.slh@> -<@include DeferredLighting.slh@> +<@include DeferredGlobalLight.slh@> // Everything about shadow <@include Shadow.slh@> @@ -36,8 +36,7 @@ void main(void) { frag.specularVal.xyz), 1.0); } else { - vec3 color = evalAmbientColor(frag.normal, frag.diffuse, frag.specular, frag.gloss) - + evalDirectionalColor(shadowAttenuation, + vec3 color = evalAmbienGlobalColor(shadowAttenuation, frag.position.xyz, frag.normal, frag.diffuse, diff --git a/libraries/render-utils/src/directional_light_shadow_map.slf b/libraries/render-utils/src/directional_light_shadow_map.slf index 13435e9101..5029b57020 100644 --- a/libraries/render-utils/src/directional_light_shadow_map.slf +++ b/libraries/render-utils/src/directional_light_shadow_map.slf @@ -15,7 +15,7 @@ // Everything about deferred buffer <@include DeferredBuffer.slh@> -<@include DeferredLighting.slh@> +<@include DeferredGlobalLight.slh@> // Everything about shadow <@include Shadow.slh@> @@ -37,8 +37,7 @@ void main(void) { frag.specularVal.xyz), 1.0); } else { - vec3 color = evalAmbientColor(frag.normal, frag.diffuse, frag.specular, frag.gloss) - + evalDirectionalColor(shadowAttenuation, + vec3 color = evalAmbienGlobalColor(shadowAttenuation, frag.position.xyz, frag.normal, frag.diffuse, diff --git a/libraries/render-utils/src/point_light.slf b/libraries/render-utils/src/point_light.slf index 3d3d922203..abe904ecce 100644 --- a/libraries/render-utils/src/point_light.slf +++ b/libraries/render-utils/src/point_light.slf @@ -64,12 +64,12 @@ void main(void) { vec3 fragColor = shading.w * (frag.diffuse + shading.xyz); gl_FragColor = vec4(fragColor * radialAttenuation * getLightColor(light) * getLightIntensity(light), 0.0); -<@if SHOW_LIGHT_CONTOUR@> - // Show edge - float edge = abs(2.0 * ((getLightRadius(light) - fragLightDistance) / (0.1)) - 1.0); - if (edge < 1) { - float edgeCoord = exp2(-8.0*edge*edge); - gl_FragColor = vec4(edgeCoord * edgeCoord * getLightColor(light), 0.0); + if (getLightShowContour(light) > 0.0) { + // Show edge + float edge = abs(2.0 * ((getLightRadius(light) - fragLightDistance) / (0.1)) - 1.0); + if (edge < 1) { + float edgeCoord = exp2(-8.0*edge*edge); + gl_FragColor = vec4(edgeCoord * edgeCoord * getLightShowContour(light) * getLightColor(light), 0.0); + } } -<@endif@> } diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf index aec1ce4b89..95fabae3ed 100644 --- a/libraries/render-utils/src/spot_light.slf +++ b/libraries/render-utils/src/spot_light.slf @@ -72,16 +72,16 @@ void main(void) { vec3 fragColor = shading.w * (frag.diffuse + shading.xyz); gl_FragColor = vec4(fragColor * angularAttenuation * radialAttenuation * getLightColor(light) * getLightIntensity(light), 0.0); -<@if SHOW_LIGHT_CONTOUR@> - // Show edges - float edgeDistR = (getLightRadius(light) - fragLightDistance); - float edgeDistS = dot(fragLightDistance * vec2(cosSpotAngle, sqrt(1.0 - cosSpotAngle * cosSpotAngle)), -getLightSpotOutsideNormal2(light)); - float edgeDist = min(edgeDistR, edgeDistS); - float edge = abs(2.0 * (edgeDist / (0.1)) - 1.0); - if (edge < 1) { - float edgeCoord = exp2(-8.0*edge*edge); - gl_FragColor = vec4(edgeCoord * edgeCoord * getLightColor(light), 0.0); + if (getLightShowContour(light) > 0.0) { + // Show edges + float edgeDistR = (getLightRadius(light) - fragLightDistance); + float edgeDistS = dot(fragLightDistance * vec2(cosSpotAngle, sqrt(1.0 - cosSpotAngle * cosSpotAngle)), -getLightSpotOutsideNormal2(light)); + float edgeDist = min(edgeDistR, edgeDistS); + float edge = abs(2.0 * (edgeDist / (0.1)) - 1.0); + if (edge < 1) { + float edgeCoord = exp2(-8.0*edge*edge); + gl_FragColor = vec4(edgeCoord * edgeCoord * getLightColor(light), 0.0); + } } -<@endif@> } From 1b22a3ef36a8d851346753319f067468cfaa99cf Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 5 Feb 2015 17:30:57 -0800 Subject: [PATCH 048/103] connecting the globalLight info to the DeferredLightingEffect --- interface/src/Application.cpp | 6 +- libraries/model/src/model/Light.cpp | 4 +- libraries/model/src/model/Light.h | 168 +++++++++++++++- .../render-utils/src/DeferredGlobalLight.slh | 61 +++--- .../src/DeferredLightingEffect.cpp | 180 +++--------------- .../render-utils/src/DeferredLightingEffect.h | 17 +- 6 files changed, 222 insertions(+), 214 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3c1806b00b..e7afd5ac3d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2585,6 +2585,9 @@ const GLfloat WORLD_AMBIENT_COLOR[] = { 0.525f, 0.525f, 0.6f }; const GLfloat WORLD_DIFFUSE_COLOR[] = { 0.6f, 0.525f, 0.525f }; const GLfloat WORLD_SPECULAR_COLOR[] = { 0.94f, 0.94f, 0.737f, 1.0f }; +const glm::vec3 GLOBAL_LIGHT_COLOR = { 0.6f, 0.525f, 0.525f }; +const float GLOBAL_LIGHT_INTENSITY = 1.0f; + void Application::setupWorldLight() { // Setup 3D lights (after the camera transform, so that they are positioned in world space) @@ -2599,6 +2602,7 @@ void Application::setupWorldLight() { glLightfv(GL_LIGHT0, GL_SPECULAR, WORLD_SPECULAR_COLOR); glMaterialfv(GL_FRONT, GL_SPECULAR, WORLD_SPECULAR_COLOR); glMateriali(GL_FRONT, GL_SHININESS, 96); + } bool Application::shouldRenderMesh(float largestDimension, float distanceToCamera) { @@ -2805,7 +2809,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs { DependencyManager::get()->setAmbientLightMode(getRenderAmbientLight()); - + DependencyManager::get()->setGlobalLight(getSunDirection(), GLOBAL_LIGHT_COLOR, GLOBAL_LIGHT_INTENSITY); PROFILE_RANGE("DeferredLighting"); PerformanceTimer perfTimer("lighting"); DependencyManager::get()->render(); diff --git a/libraries/model/src/model/Light.cpp b/libraries/model/src/model/Light.cpp index 30e873ea30..003a05eb2f 100755 --- a/libraries/model/src/model/Light.cpp +++ b/libraries/model/src/model/Light.cpp @@ -56,7 +56,7 @@ const Vec3& Light::getDirection() const { } void Light::setColor(const Color& color) { - editSchema()._color = glm::normalize(color); + editSchema()._color = color; } void Light::setIntensity(float intensity) { @@ -89,7 +89,7 @@ void Light::setSpotExponent(float exponent) { editSchema()._spot.w = exponent; } -void Light::setShowVolumeContour(float show) { +void Light::setShowContour(float show) { if (show <= 0.f) { show = 0.0f; } diff --git a/libraries/model/src/model/Light.h b/libraries/model/src/model/Light.h index 4640711f4d..2ef2bf3036 100755 --- a/libraries/model/src/model/Light.h +++ b/libraries/model/src/model/Light.h @@ -26,6 +26,161 @@ typedef glm::vec3 Vec3; typedef glm::vec4 Vec4; typedef glm::quat Quat; +class SphericalHarmonics { +public: + glm::vec3 L00 ; float spare0; + glm::vec3 L1m1 ; float spare1; + glm::vec3 L10 ; float spare2; + glm::vec3 L11 ; float spare3; + glm::vec3 L2m2 ; float spare4; + glm::vec3 L2m1 ; float spare5; + glm::vec3 L20 ; float spare6; + glm::vec3 L21 ; float spare7; + glm::vec3 L22 ; float spare8; + + static const int NUM_COEFFICIENTS = 9; + + enum Preset { + OLD_TOWN_SQUARE = 0, + GRACE_CATHEDRAL, + EUCALYPTUS_GROVE, + ST_PETERS_BASILICA, + UFFIZI_GALLERY, + GALILEOS_TOMB, + VINE_STREET_KITCHEN, + BREEZEWAY, + CAMPUS_SUNSET, + FUNSTON_BEACH_SUNSET, + + NUM_PRESET, + }; + + void assignPreset(int p) { + switch (p) { + case OLD_TOWN_SQUARE: { + L00 = glm::vec3( 0.871297f, 0.875222f, 0.864470f); + L1m1 = glm::vec3( 0.175058f, 0.245335f, 0.312891f); + L10 = glm::vec3( 0.034675f, 0.036107f, 0.037362f); + L11 = glm::vec3(-0.004629f,-0.029448f,-0.048028f); + L2m2 = glm::vec3(-0.120535f,-0.121160f,-0.117507f); + L2m1 = glm::vec3( 0.003242f, 0.003624f, 0.007511f); + L20 = glm::vec3(-0.028667f,-0.024926f,-0.020998f); + L21 = glm::vec3(-0.077539f,-0.086325f,-0.091591f); + L22 = glm::vec3(-0.161784f,-0.191783f,-0.219152f); + } + break; + case GRACE_CATHEDRAL: { + L00 = glm::vec3( 0.79f, 0.44f, 0.54f); + L1m1 = glm::vec3( 0.39f, 0.35f, 0.60f); + L10 = glm::vec3(-0.34f, -0.18f, -0.27f); + L11 = glm::vec3(-0.29f, -0.06f, 0.01f); + L2m2 = glm::vec3(-0.11f, -0.05f, -0.12f); + L2m1 = glm::vec3(-0.26f, -0.22f, -0.47f); + L20 = glm::vec3(-0.16f, -0.09f, -0.15f); + L21 = glm::vec3( 0.56f, 0.21f, 0.14f); + L22 = glm::vec3( 0.21f, -0.05f, -0.30f); + } + break; + case EUCALYPTUS_GROVE: { + L00 = glm::vec3( 0.38f, 0.43f, 0.45f); + L1m1 = glm::vec3( 0.29f, 0.36f, 0.41f); + L10 = glm::vec3( 0.04f, 0.03f, 0.01f); + L11 = glm::vec3(-0.10f, -0.10f, -0.09f); + L2m2 = glm::vec3(-0.06f, -0.06f, -0.04f); + L2m1 = glm::vec3( 0.01f, -0.01f, -0.05f); + L20 = glm::vec3(-0.09f, -0.13f, -0.15f); + L21 = glm::vec3(-0.06f, -0.05f, -0.04f); + L22 = glm::vec3( 0.02f, 0.00f, -0.05f); + } + break; + case ST_PETERS_BASILICA: { + L00 = glm::vec3( 0.36f, 0.26f, 0.23f); + L1m1 = glm::vec3( 0.18f, 0.14f, 0.13f); + L10 = glm::vec3(-0.02f, -0.01f, 0.00f); + L11 = glm::vec3( 0.03f, 0.02f, -0.00f); + L2m2 = glm::vec3( 0.02f, 0.01f, -0.00f); + L2m1 = glm::vec3(-0.05f, -0.03f, -0.01f); + L20 = glm::vec3(-0.09f, -0.08f, -0.07f); + L21 = glm::vec3( 0.01f, 0.00f, 0.00f); + L22 = glm::vec3(-0.08f, -0.03f, -0.00f); + } + break; + case UFFIZI_GALLERY: { + L00 = glm::vec3( 0.32f, 0.31f, 0.35f); + L1m1 = glm::vec3( 0.37f, 0.37f, 0.43f); + L10 = glm::vec3( 0.00f, 0.00f, 0.00f); + L11 = glm::vec3(-0.01f, -0.01f, -0.01f); + L2m2 = glm::vec3(-0.02f, -0.02f, -0.03f); + L2m1 = glm::vec3(-0.01f, -0.01f, -0.01f); + L20 = glm::vec3(-0.28f, -0.28f, -0.32f); + L21 = glm::vec3( 0.00f, 0.00f, 0.00f); + L22 = glm::vec3(-0.24f, -0.24f, -0.28f); + } + break; + case GALILEOS_TOMB: { + L00 = glm::vec3( 1.04f, 0.76f, 0.71f); + L1m1 = glm::vec3( 0.44f, 0.34f, 0.34f); + L10 = glm::vec3(-0.22f, -0.18f, -0.17f); + L11 = glm::vec3( 0.71f, 0.54f, 0.56f); + L2m2 = glm::vec3( 0.64f, 0.50f, 0.52f); + L2m1 = glm::vec3(-0.12f, -0.09f, -0.08f); + L20 = glm::vec3(-0.37f, -0.28f, -0.32f); + L21 = glm::vec3(-0.17f, -0.13f, -0.13f); + L22 = glm::vec3( 0.55f, 0.42f, 0.42f); + } + break; + case VINE_STREET_KITCHEN: { + L00 = glm::vec3( 0.64f, 0.67f, 0.73f); + L1m1 = glm::vec3( 0.28f, 0.32f, 0.33f); + L10 = glm::vec3( 0.42f, 0.60f, 0.77f); + L11 = glm::vec3(-0.05f, -0.04f, -0.02f); + L2m2 = glm::vec3(-0.10f, -0.08f, -0.05f); + L2m1 = glm::vec3( 0.25f, 0.39f, 0.53f); + L20 = glm::vec3( 0.38f, 0.54f, 0.71f); + L21 = glm::vec3( 0.06f, 0.01f, -0.02f); + L22 = glm::vec3(-0.03f, -0.02f, -0.03f); + } + break; + case BREEZEWAY: { + L00 = glm::vec3( 0.32f, 0.36f, 0.38f); + L1m1 = glm::vec3( 0.37f, 0.41f, 0.45f); + L10 = glm::vec3(-0.01f, -0.01f, -0.01f); + L11 = glm::vec3(-0.10f, -0.12f, -0.12f); + L2m2 = glm::vec3(-0.13f, -0.15f, -0.17f); + L2m1 = glm::vec3(-0.01f, -0.02f, 0.02f); + L20 = glm::vec3(-0.07f, -0.08f, -0.09f); + L21 = glm::vec3( 0.02f, 0.03f, 0.03f); + L22 = glm::vec3(-0.29f, -0.32f, -0.36f); + } + break; + case CAMPUS_SUNSET: { + L00 = glm::vec3( 0.79f, 0.94f, 0.98f); + L1m1 = glm::vec3( 0.44f, 0.56f, 0.70f); + L10 = glm::vec3(-0.10f, -0.18f, -0.27f); + L11 = glm::vec3( 0.45f, 0.38f, 0.20f); + L2m2 = glm::vec3( 0.18f, 0.14f, 0.05f); + L2m1 = glm::vec3(-0.14f, -0.22f, -0.31f); + L20 = glm::vec3(-0.39f, -0.40f, -0.36f); + L21 = glm::vec3( 0.09f, 0.07f, 0.04f); + L22 = glm::vec3( 0.67f, 0.67f, 0.52f); + } + break; + case FUNSTON_BEACH_SUNSET: { + L00 = glm::vec3( 0.68f, 0.69f, 0.70f); + L1m1 = glm::vec3( 0.32f, 0.37f, 0.44f); + L10 = glm::vec3(-0.17f, -0.17f, -0.17f); + L11 = glm::vec3(-0.45f, -0.42f, -0.34f); + L2m2 = glm::vec3(-0.17f, -0.17f, -0.15f); + L2m1 = glm::vec3(-0.08f, -0.09f, -0.10f); + L20 = glm::vec3(-0.03f, -0.02f, -0.01f); + L21 = glm::vec3( 0.16f, 0.14f, 0.10f); + L22 = glm::vec3( 0.37f, 0.31f, 0.20f); + } + break; + } + } +}; + class Light { public: enum Type { @@ -84,9 +239,15 @@ public: void setSpotExponent(float exponent); float getSpotExponent() const { return getSchema()._spot.w; } - // For editing purpose, show the light volume contour - void setShowVolumeContour(float show); - float getShowVolumeContour() const { return getSchema()._control.w; } + // For editing purpose, show the light volume contour. + // Set to non 0 to show it, the value is used as the intensity of the contour color + void setShowContour(float show); + float getShowContour() const { return getSchema()._control.w; } + + // Spherical Harmonics storing the Ambien lighting approximation used for the Sun typed light + void setAmbientSphere(const SphericalHarmonics& sphere) { _ambientSphere = sphere; } + const SphericalHarmonics& getAmbientSphere() const { return _ambientSphere; } + void setAmbientSpherePreset(SphericalHarmonics::Preset preset) { _ambientSphere.assignPreset(preset); } // Schema to access the attribute values of the light class Schema { @@ -121,6 +282,7 @@ protected: Flags _flags; UniformBufferView _schemaBuffer; Transform _transform; + SphericalHarmonics _ambientSphere; const Schema& getSchema() const { return _schemaBuffer.get(); } Schema& editSchema() { return _schemaBuffer.edit(); } diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index bb33a124dc..7ca416a616 100755 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -54,47 +54,38 @@ uniform SphericalHarmonics ambientSphere; // The view Matrix uniform mat4 invViewMat; -vec3 evalAmbientColor(vec3 normal, vec3 diffuse, vec3 specular, float gloss) { - return diffuse.rgb * gl_FrontLightProduct[0].ambient.rgb; -} +vec3 evalAmbienGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { -vec3 evalAmbientSphereColor(vec3 normal, vec3 diffuse, vec3 specular, float gloss) { - vec3 ambientLight = 0.5 * evalSphericalLight(ambientSphere, normal).xyz; - - return diffuse.rgb * ambientLight; -} - - - - -vec3 evalDirectionalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { - // Need the light now Light light = getLight(); - vec4 shading = evalFragShading(normal, getLightDirection(light), normalize(position), specular, gloss); - return vec3(diffuse + shading.rgb) * shading.w * shadowAttenuation * getLightColor(light) * getLightIntensity(light); - // return vec3(diffuse + shading.rgb) * shading.w * shadowAttenuation * gl_FrontLightProduct[0].diffuse.rgb; -} -vec3 evalAmbienGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { - vec3 color = evalAmbientColor(normal, diffuse, specular, gloss) - + evalDirectionalColor(shadowAttenuation, - position, - normal, - diffuse, - specular, - gloss); - return color; + vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0)); + vec4 fragEyeVector = invViewMat * vec4(-position, 0.0); + vec3 fragEyeDir = normalize(fragEyeVector.xyz); + + vec3 color = diffuse.rgb * getLightColor(light) * getLightIntensity(light); + + vec4 shading = evalFragShading(fragNormal, getLightDirection(light), fragEyeDir, specular, gloss); + + color += vec3(diffuse + shading.rgb) * shading.w * shadowAttenuation * getLightColor(light) * getLightIntensity(light); + + return color; } vec3 evalAmbienSphereGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { - vec3 color = evalAmbientSphereColor(normal, diffuse, specular, gloss) - + evalDirectionalColor(shadowAttenuation, - position, - normal, - diffuse, - specular, - gloss); - return color; + // Need the light now + Light light = getLight(); + + vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0)); + vec4 fragEyeVector = invViewMat * vec4(-position, 0.0); + vec3 fragEyeDir = normalize(fragEyeVector.xyz); + + vec3 color = diffuse.rgb * 0.5 * evalSphericalLight(ambientSphere, fragNormal).xyz; + + vec4 shading = evalFragShading(fragNormal, getLightDirection(light), fragEyeDir, specular, gloss); + + color += vec3(diffuse + shading.rgb) * shading.w * shadowAttenuation * getLightColor(light) * getLightIntensity(light); + + return color; } vec3 evalLightmappedColor(float shadowAttenuation, vec3 normal, vec3 diffuse, vec3 lightmap) { diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 1241845675..58f599be97 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -45,146 +45,6 @@ #include "point_light_frag.h" #include "spot_light_frag.h" -class SphericalHarmonics { -public: - glm::vec3 L00 ; float spare0; - glm::vec3 L1m1 ; float spare1; - glm::vec3 L10 ; float spare2; - glm::vec3 L11 ; float spare3; - glm::vec3 L2m2 ; float spare4; - glm::vec3 L2m1 ; float spare5; - glm::vec3 L20 ; float spare6; - glm::vec3 L21 ; float spare7; - glm::vec3 L22 ; float spare8; - - static const int NUM_COEFFICIENTS = 9; - - void assignPreset(int p) { - switch (p) { - case DeferredLightingEffect::OLD_TOWN_SQUARE: { - L00 = glm::vec3( 0.871297f, 0.875222f, 0.864470f); - L1m1 = glm::vec3( 0.175058f, 0.245335f, 0.312891f); - L10 = glm::vec3( 0.034675f, 0.036107f, 0.037362f); - L11 = glm::vec3(-0.004629f,-0.029448f,-0.048028f); - L2m2 = glm::vec3(-0.120535f,-0.121160f,-0.117507f); - L2m1 = glm::vec3( 0.003242f, 0.003624f, 0.007511f); - L20 = glm::vec3(-0.028667f,-0.024926f,-0.020998f); - L21 = glm::vec3(-0.077539f,-0.086325f,-0.091591f); - L22 = glm::vec3(-0.161784f,-0.191783f,-0.219152f); - } - break; - case DeferredLightingEffect::GRACE_CATHEDRAL: { - L00 = glm::vec3( 0.79f, 0.44f, 0.54f); - L1m1 = glm::vec3( 0.39f, 0.35f, 0.60f); - L10 = glm::vec3(-0.34f, -0.18f, -0.27f); - L11 = glm::vec3(-0.29f, -0.06f, 0.01f); - L2m2 = glm::vec3(-0.11f, -0.05f, -0.12f); - L2m1 = glm::vec3(-0.26f, -0.22f, -0.47f); - L20 = glm::vec3(-0.16f, -0.09f, -0.15f); - L21 = glm::vec3( 0.56f, 0.21f, 0.14f); - L22 = glm::vec3( 0.21f, -0.05f, -0.30f); - } - break; - case DeferredLightingEffect::EUCALYPTUS_GROVE: { - L00 = glm::vec3( 0.38f, 0.43f, 0.45f); - L1m1 = glm::vec3( 0.29f, 0.36f, 0.41f); - L10 = glm::vec3( 0.04f, 0.03f, 0.01f); - L11 = glm::vec3(-0.10f, -0.10f, -0.09f); - L2m2 = glm::vec3(-0.06f, -0.06f, -0.04f); - L2m1 = glm::vec3( 0.01f, -0.01f, -0.05f); - L20 = glm::vec3(-0.09f, -0.13f, -0.15f); - L21 = glm::vec3(-0.06f, -0.05f, -0.04f); - L22 = glm::vec3( 0.02f, 0.00f, -0.05f); - } - break; - case DeferredLightingEffect::ST_PETERS_BASILICA: { - L00 = glm::vec3( 0.36f, 0.26f, 0.23f); - L1m1 = glm::vec3( 0.18f, 0.14f, 0.13f); - L10 = glm::vec3(-0.02f, -0.01f, 0.00f); - L11 = glm::vec3( 0.03f, 0.02f, -0.00f); - L2m2 = glm::vec3( 0.02f, 0.01f, -0.00f); - L2m1 = glm::vec3(-0.05f, -0.03f, -0.01f); - L20 = glm::vec3(-0.09f, -0.08f, -0.07f); - L21 = glm::vec3( 0.01f, 0.00f, 0.00f); - L22 = glm::vec3(-0.08f, -0.03f, -0.00f); - } - break; - case DeferredLightingEffect::UFFIZI_GALLERY: { - L00 = glm::vec3( 0.32f, 0.31f, 0.35f); - L1m1 = glm::vec3( 0.37f, 0.37f, 0.43f); - L10 = glm::vec3( 0.00f, 0.00f, 0.00f); - L11 = glm::vec3(-0.01f, -0.01f, -0.01f); - L2m2 = glm::vec3(-0.02f, -0.02f, -0.03f); - L2m1 = glm::vec3(-0.01f, -0.01f, -0.01f); - L20 = glm::vec3(-0.28f, -0.28f, -0.32f); - L21 = glm::vec3( 0.00f, 0.00f, 0.00f); - L22 = glm::vec3(-0.24f, -0.24f, -0.28f); - } - break; - case DeferredLightingEffect::GALILEOS_TOMB: { - L00 = glm::vec3( 1.04f, 0.76f, 0.71f); - L1m1 = glm::vec3( 0.44f, 0.34f, 0.34f); - L10 = glm::vec3(-0.22f, -0.18f, -0.17f); - L11 = glm::vec3( 0.71f, 0.54f, 0.56f); - L2m2 = glm::vec3( 0.64f, 0.50f, 0.52f); - L2m1 = glm::vec3(-0.12f, -0.09f, -0.08f); - L20 = glm::vec3(-0.37f, -0.28f, -0.32f); - L21 = glm::vec3(-0.17f, -0.13f, -0.13f); - L22 = glm::vec3( 0.55f, 0.42f, 0.42f); - } - break; - case DeferredLightingEffect::VINE_STREET_KITCHEN: { - L00 = glm::vec3( 0.64f, 0.67f, 0.73f); - L1m1 = glm::vec3( 0.28f, 0.32f, 0.33f); - L10 = glm::vec3( 0.42f, 0.60f, 0.77f); - L11 = glm::vec3(-0.05f, -0.04f, -0.02f); - L2m2 = glm::vec3(-0.10f, -0.08f, -0.05f); - L2m1 = glm::vec3( 0.25f, 0.39f, 0.53f); - L20 = glm::vec3( 0.38f, 0.54f, 0.71f); - L21 = glm::vec3( 0.06f, 0.01f, -0.02f); - L22 = glm::vec3(-0.03f, -0.02f, -0.03f); - } - break; - case DeferredLightingEffect::BREEZEWAY: { - L00 = glm::vec3( 0.32f, 0.36f, 0.38f); - L1m1 = glm::vec3( 0.37f, 0.41f, 0.45f); - L10 = glm::vec3(-0.01f, -0.01f, -0.01f); - L11 = glm::vec3(-0.10f, -0.12f, -0.12f); - L2m2 = glm::vec3(-0.13f, -0.15f, -0.17f); - L2m1 = glm::vec3(-0.01f, -0.02f, 0.02f); - L20 = glm::vec3(-0.07f, -0.08f, -0.09f); - L21 = glm::vec3( 0.02f, 0.03f, 0.03f); - L22 = glm::vec3(-0.29f, -0.32f, -0.36f); - } - break; - case DeferredLightingEffect::CAMPUS_SUNSET: { - L00 = glm::vec3( 0.79f, 0.94f, 0.98f); - L1m1 = glm::vec3( 0.44f, 0.56f, 0.70f); - L10 = glm::vec3(-0.10f, -0.18f, -0.27f); - L11 = glm::vec3( 0.45f, 0.38f, 0.20f); - L2m2 = glm::vec3( 0.18f, 0.14f, 0.05f); - L2m1 = glm::vec3(-0.14f, -0.22f, -0.31f); - L20 = glm::vec3(-0.39f, -0.40f, -0.36f); - L21 = glm::vec3( 0.09f, 0.07f, 0.04f); - L22 = glm::vec3( 0.67f, 0.67f, 0.52f); - } - break; - case DeferredLightingEffect::FUNSTON_BEACH_SUNSET: { - L00 = glm::vec3( 0.68f, 0.69f, 0.70f); - L1m1 = glm::vec3( 0.32f, 0.37f, 0.44f); - L10 = glm::vec3(-0.17f, -0.17f, -0.17f); - L11 = glm::vec3(-0.45f, -0.42f, -0.34f); - L2m2 = glm::vec3(-0.17f, -0.17f, -0.15f); - L2m1 = glm::vec3(-0.08f, -0.09f, -0.10f); - L20 = glm::vec3(-0.03f, -0.02f, -0.01f); - L21 = glm::vec3( 0.16f, 0.14f, 0.10f); - L22 = glm::vec3( 0.37f, 0.31f, 0.20f); - } - break; - } - } -}; - void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) { _viewState = viewState; _simpleProgram.addShaderFromSourceCode(QGLShader::Vertex, simple_vert); @@ -220,6 +80,7 @@ void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) { lp->setColor(glm::vec3(1.0f)); lp->setIntensity(1.0f); lp->setType(model::Light::SUN); + lp->setAmbientSpherePreset(model::SphericalHarmonics::Preset(_ambientLightMode % model::SphericalHarmonics::NUM_PRESET)); } void DeferredLightingEffect::bindSimpleProgram() { @@ -285,7 +146,7 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu lp->setMaximumRadius(radius); lp->setColor(diffuse); lp->setIntensity(1.0f); - lp->setShowVolumeContour(quadraticAttenuation); + //lp->setShowContour(quadraticAttenuation); if (exponent == 0.0f && cutoff == PI) { lp->setType(model::Light::POINT); @@ -396,25 +257,19 @@ void DeferredLightingEffect::render() { program->bind(); } - if (locations->ambientSphere >= 0) { - SphericalHarmonics sh; - if (_ambientLightMode < NUM_PRESET) { - sh.assignPreset(_ambientLightMode); - } else { - sh.assignPreset(0); - } - - for (int i =0; i setUniformValue(locations->ambientSphere + i, *(((QVector4D*) &sh) + i)); - } - } - { - auto light = _allocatedLights[_globalLights.front()]; - + auto globalLight = _allocatedLights[_globalLights.front()]; + + if (locations->ambientSphere >= 0) { + auto sh = globalLight->getAmbientSphere(); + for (int i =0; i setUniformValue(locations->ambientSphere + i, *(((QVector4D*) &sh) + i)); + } + } + if (locations->lightBufferUnit >= 0) { gpu::Batch batch; - batch.setUniformBuffer(locations->lightBufferUnit, light->getSchemaBuffer()); + batch.setUniformBuffer(locations->lightBufferUnit, globalLight->getSchemaBuffer()); gpu::GLBackend::renderBatch(batch); } glUniformMatrix4fv(locations->invViewMat, 1, false, reinterpret_cast< const GLfloat* >(&invViewMat)); @@ -662,7 +517,16 @@ void DeferredLightingEffect::loadLightProgram(const char* fragSource, bool limit } void DeferredLightingEffect::setAmbientLightMode(int preset) { - if ((preset >= -1) && (preset < NUM_PRESET)) { + if ((preset >= -1) && (preset < model::SphericalHarmonics::NUM_PRESET)) { _ambientLightMode = preset; + auto light = _allocatedLights.front(); + light->setAmbientSpherePreset(model::SphericalHarmonics::Preset(preset % model::SphericalHarmonics::NUM_PRESET)); } } + +void DeferredLightingEffect::setGlobalLight(const glm::vec3& direction, const glm::vec3& diffuse, float intensity) { + auto light = _allocatedLights.front(); + light->setDirection(direction); + light->setColor(diffuse); + light->setIntensity(intensity); +} diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index ad4231a0b7..eeb92f19c7 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -73,22 +73,9 @@ public: void prepare(); void render(); - enum AmbientLightPreset { - OLD_TOWN_SQUARE = 0, - GRACE_CATHEDRAL, - EUCALYPTUS_GROVE, - ST_PETERS_BASILICA, - UFFIZI_GALLERY, - GALILEOS_TOMB, - VINE_STREET_KITCHEN, - BREEZEWAY, - CAMPUS_SUNSET, - FUNSTON_BEACH_SUNSET, - - NUM_PRESET, - }; - + // update global lighting void setAmbientLightMode(int preset); + void setGlobalLight(const glm::vec3& direction, const glm::vec3& diffuse, float intensity); private: DeferredLightingEffect() {} From bdf9164c7b1993c004630d53d097d27848a93567 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 6 Feb 2015 16:30:07 -0800 Subject: [PATCH 049/103] debugging the new global light pass --- interface/src/Application.cpp | 2 +- libraries/gpu/src/gpu/Texture.cpp | 7 +++++-- libraries/render-utils/src/DeferredGlobalLight.slh | 6 +++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e7afd5ac3d..3049fb7c8e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2809,7 +2809,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs { DependencyManager::get()->setAmbientLightMode(getRenderAmbientLight()); - DependencyManager::get()->setGlobalLight(getSunDirection(), GLOBAL_LIGHT_COLOR, GLOBAL_LIGHT_INTENSITY); + DependencyManager::get()->setGlobalLight(-getSunDirection(), GLOBAL_LIGHT_COLOR, GLOBAL_LIGHT_INTENSITY); PROFILE_RANGE("DeferredLighting"); PerformanceTimer perfTimer("lighting"); DependencyManager::get()->render(); diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index 33df50042e..b5191b29c7 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -76,8 +76,11 @@ bool Texture::Storage::allocateMip(uint16 level) { bool Texture::Storage::assignMipData(uint16 level, const Element& format, Size size, const Byte* bytes) { // Ok we should be able to do that... allocateMip(level); - _mips[level]->_format = format; - Size allocated = _mips[level]->_sysmem.setData(size, bytes); + auto mip = _mips[level]; + mip->_format = format; + Size allocated = mip->_sysmem.setData(size, bytes); + mip->_isGPULoaded = false; + return allocated == size; } diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index 7ca416a616..e3788bb325 100755 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -63,9 +63,9 @@ vec3 evalAmbienGlobalColor(float shadowAttenuation, vec3 position, vec3 normal, vec4 fragEyeVector = invViewMat * vec4(-position, 0.0); vec3 fragEyeDir = normalize(fragEyeVector.xyz); - vec3 color = diffuse.rgb * getLightColor(light) * getLightIntensity(light); + vec3 color = diffuse.rgb * getLightColor(light) * 0.5; - vec4 shading = evalFragShading(fragNormal, getLightDirection(light), fragEyeDir, specular, gloss); + vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss); color += vec3(diffuse + shading.rgb) * shading.w * shadowAttenuation * getLightColor(light) * getLightIntensity(light); @@ -81,7 +81,7 @@ vec3 evalAmbienSphereGlobalColor(float shadowAttenuation, vec3 position, vec3 no vec3 color = diffuse.rgb * 0.5 * evalSphericalLight(ambientSphere, fragNormal).xyz; - vec4 shading = evalFragShading(fragNormal, getLightDirection(light), fragEyeDir, specular, gloss); + vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss); color += vec3(diffuse + shading.rgb) * shading.w * shadowAttenuation * getLightColor(light) * getLightIntensity(light); From 0e663054564016f2ff5d7b0766922b2b6805c07c Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Sat, 7 Feb 2015 13:37:33 +0100 Subject: [PATCH 050/103] changed HMDScriptingInterface MyAvatar to new way of retrieving this object --- interface/src/scripting/HMDScriptingInterface.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index e2d150e390..7b5d4ddac6 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -11,6 +11,8 @@ #include "HMDScriptingInterface.h" +#include + HMDScriptingInterface& HMDScriptingInterface::getInstance() { static HMDScriptingInterface sharedInstance; return sharedInstance; @@ -31,7 +33,7 @@ glm::vec3 HMDScriptingInterface::getHUDLookAtPosition3D() const { } glm::vec2 HMDScriptingInterface::getHUDLookAtPosition2D() const { - MyAvatar* myAvatar = Application::getInstance()->getAvatar(); + MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); glm::vec3 sphereCenter = myAvatar->getDefaultEyePosition(); glm::vec3 hudIntersection = getHUDLookAtPosition3D(); From 0a41033c8568ad4b6f1ca0dc365ae60ee71a81df Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Sat, 7 Feb 2015 13:58:11 +0100 Subject: [PATCH 051/103] - set cursor invisible when virtual-keyboard is shown. - get rid of the invisible cursor/magnifier states when cleaning up keyboard. --- examples/libraries/virtualKeyboard.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/libraries/virtualKeyboard.js b/examples/libraries/virtualKeyboard.js index 42185138e3..7d7d72ae12 100644 --- a/examples/libraries/virtualKeyboard.js +++ b/examples/libraries/virtualKeyboard.js @@ -321,6 +321,8 @@ Keyboard = (function(params) { for (var i = 0; i < this.keys.length; i++) { this.keys[i].remove(); } + // resets the cursor and magnifier + this.updateVisibility(false); }; this.show = function() { @@ -340,6 +342,7 @@ Keyboard = (function(params) { if (HMD.magnifier == visible) { HMD.toggleMagnifier(); } + Window.cursorVisible = !visible; Overlays.editOverlay(tthis.background, { visible: tthis.visible }); for (var i = 0; i < this.keys.length; i++) { this.keys[i].updateVisibility(); From 8251542b786da7d2e2a908120a496ad061122862 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Sat, 7 Feb 2015 14:35:14 +0100 Subject: [PATCH 052/103] show instructions whenever the first gamepad is plugged since the script is loaded --- examples/controllers/oculus/goTo.js | 30 ++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/examples/controllers/oculus/goTo.js b/examples/controllers/oculus/goTo.js index ea3d12417d..2d2c80e661 100644 --- a/examples/controllers/oculus/goTo.js +++ b/examples/controllers/oculus/goTo.js @@ -20,21 +20,30 @@ Script.include("../../libraries/globals.js"); Script.include("../../libraries/virtualKeyboard.js"); function Instructions(imageURL) { + var tthis = this; + this.visible = false; this.overlay = Overlays.addOverlay("image", { imageURL: HIFI_PUBLIC_BUCKET + "images/tutorial-goTo.svg", x: 0, y: 0, + width: 200, + height: 200, alpha: 1, - visible: true + visible: this.visible }); + this.show = function() { + tthis.visible = true; + Overlays.editOverlay(tthis.overlay, {visible: tthis.visible}); + } this.remove = function() { Overlays.deleteOverlay(this.overlay); + this.visible = false; }; }; var theInstruction = new Instructions(); - +var firstControllerPlugged = false; var windowDimensions = Controller.getViewportDimensions(); var cursor = new Cursor({visible: false});; @@ -84,6 +93,7 @@ keyboard.onKeyRelease = function(event) { location = "hifi://" + locationURL; locationURL = ""; keyboard.hide(); + cursor.hide(); updateTextOverlay(); } } @@ -116,6 +126,9 @@ keyboard.onFullyLoaded = function() { }; function keyPressEvent(event) { + if (theInstruction.visible) { + return; + } if (event.key === SPACEBAR_CHARCODE) { keyboard.pressFocussedKey(); } else if (event.key === ENTER_CHARCODE || event.key === RETURN_CHARCODE) { @@ -128,6 +141,9 @@ function keyPressEvent(event) { } function keyReleaseEvent(event) { + if (theInstruction.visible) { + return; + } if (event.key === SPACEBAR_CHARCODE) { keyboard.releaseKeys(); } @@ -145,7 +161,11 @@ function scriptEnding() { } function reportButtonValue(button, newValue, oldValue) { - if (button == Joysticks.BUTTON_FACE_BOTTOM) { + if (theInstruction.visible) { + if (button == Joysticks.BUTTON_FACE_BOTTOM && newValue) { + theInstruction.remove(); + } + } else if (button == Joysticks.BUTTON_FACE_BOTTOM) { if (newValue) { keyboard.pressFocussedKey(); } else { @@ -158,6 +178,10 @@ function reportButtonValue(button, newValue, oldValue) { function addJoystick(gamepad) { gamepad.buttonStateChanged.connect(reportButtonValue); + if (!firstControllerPlugged) { + firstControllerPlugged = true; + theInstruction.show(); + } } var allJoysticks = Joysticks.getAllJoysticks(); From 48fca4c11d0e15c106b5ced2fd13040e4954c22e Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Sun, 8 Feb 2015 23:22:14 -0800 Subject: [PATCH 053/103] introducing PBR shading --- libraries/render-utils/src/DeferredGlobalLight.slh | 8 +++++++- libraries/render-utils/src/DeferredLighting.slh | 11 +++++++++-- libraries/render-utils/src/DeferredLightingEffect.cpp | 2 +- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index e3788bb325..2dad20e4d3 100755 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -79,12 +79,18 @@ vec3 evalAmbienSphereGlobalColor(float shadowAttenuation, vec3 position, vec3 no vec4 fragEyeVector = invViewMat * vec4(-position, 0.0); vec3 fragEyeDir = normalize(fragEyeVector.xyz); - vec3 color = diffuse.rgb * 0.5 * evalSphericalLight(ambientSphere, fragNormal).xyz; + vec3 ambientNormal = normal; + + vec3 color = diffuse.rgb * 0.5 * evalSphericalLight(ambientSphere, ambientNormal).xyz; vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss); color += vec3(diffuse + shading.rgb) * shading.w * shadowAttenuation * getLightColor(light) * getLightIntensity(light); + if (gl_FragCoord.x > 1000) { + return vec3(shading.rgb); + } + return color; } diff --git a/libraries/render-utils/src/DeferredLighting.slh b/libraries/render-utils/src/DeferredLighting.slh index f6845fbccb..44667bb530 100755 --- a/libraries/render-utils/src/DeferredLighting.slh +++ b/libraries/render-utils/src/DeferredLighting.slh @@ -21,8 +21,15 @@ vec4 evalFragShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 s // Specular Lighting depends on the half vector and the gloss vec3 halfDir = normalize(fragEyeDir + fragLightDir); - float specularPower = facingLight * max(0.0, dot(fragEyeDir, halfDir)); - vec3 reflect = pow(specularPower, gloss * 128.0) * specular; + float specularPower = pow(facingLight * max(0.0, dot(halfDir, fragNormal)), gloss * 128.0); + specularPower *= (gloss * 128.0 * 0.125 + 0.25); + + float shlickPower = (1.0 - dot(fragLightDir,halfDir)); + float shlickPower2 = shlickPower * shlickPower; + float shlickPower5 = shlickPower2 * shlickPower2 * shlickPower; + // vec3 schlick = specular * (1.0 - shlickPower5) + vec3(shlickPower5); + vec3 schlick = vec3(0.21) * (1.0 - shlickPower5) + vec3(shlickPower5); + vec3 reflect = specularPower * schlick; return vec4(reflect, diffuse); } diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 58f599be97..6569e3a018 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -425,7 +425,7 @@ void DeferredLightingEffect::render() { glBindTexture(GL_TEXTURE_2D, 0); freeFBO->release(); - // glDisable(GL_FRAMEBUFFER_SRGB); + // glDisable(GL_FRAMEBUFFER_SRGB); glDisable(GL_CULL_FACE); From d810283d5a006550b8d1f380928fdff25d76b6e4 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Mon, 9 Feb 2015 16:47:00 +0100 Subject: [PATCH 054/103] just show the instructions the first 2 times --- examples/controllers/oculus/goTo.js | 50 ++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/examples/controllers/oculus/goTo.js b/examples/controllers/oculus/goTo.js index 2d2c80e661..9f3daaea42 100644 --- a/examples/controllers/oculus/goTo.js +++ b/examples/controllers/oculus/goTo.js @@ -19,34 +19,62 @@ Script.include("../../libraries/globals.js"); Script.include("../../libraries/virtualKeyboard.js"); -function Instructions(imageURL) { +const MAX_SHOW_INSTRUCTION_TIMES = 2; +const INSTRUCTIONS_SETTING = "GoToInstructionsShowCounter" + +var windowDimensions = Controller.getViewportDimensions(); + +function Instructions(imageURL, originalWidth, originalHeight) { var tthis = this; + this.originalSize = {w: originalWidth, h: originalHeight}; this.visible = false; this.overlay = Overlays.addOverlay("image", { - imageURL: HIFI_PUBLIC_BUCKET + "images/tutorial-goTo.svg", + imageURL: imageURL, x: 0, y: 0, - width: 200, - height: 200, + width: originalWidth, + height: originalHeight, alpha: 1, visible: this.visible }); + this.show = function() { - tthis.visible = true; - Overlays.editOverlay(tthis.overlay, {visible: tthis.visible}); + var timesShown = Settings.getValue(INSTRUCTIONS_SETTING); + timesShown = timesShown === "" ? 0 : parseInt(timesShown); + print(timesShown); + if (timesShown < MAX_SHOW_INSTRUCTION_TIMES) { + Settings.setValue(INSTRUCTIONS_SETTING, timesShown + 1); + tthis.visible = true; + tthis.rescale(); + Overlays.editOverlay(tthis.overlay, {visible: tthis.visible}); + return; + } + tthis.remove(); } this.remove = function() { - Overlays.deleteOverlay(this.overlay); - this.visible = false; + Overlays.deleteOverlay(tthis.overlay); + tthis.visible = false; }; + this.rescale = function() { + var scale = Math.min(windowDimensions.x / tthis.originalSize.w, windowDimensions.y / tthis.originalSize.h); + var newWidth = tthis.originalSize.w * scale; + var newHeight = tthis.originalSize.h * scale; + Overlays.editOverlay(tthis.overlay, { + x: (windowDimensions.x / 2) - (newWidth / 2), + y: (windowDimensions.y / 2) - (newHeight / 2), + width: newWidth, + height: newHeight + }); + }; + this.rescale(); }; -var theInstruction = new Instructions(); +var theInstruction = new Instructions(HIFI_PUBLIC_BUCKET + "images/tutorial-goTo.svg", 457, 284.1); var firstControllerPlugged = false; -var windowDimensions = Controller.getViewportDimensions(); -var cursor = new Cursor({visible: false});; + +var cursor = new Cursor({visible: false}); var keyboard = new Keyboard({visible: false}); var textFontSize = 9; var text = null; From e53b38e497a5a8547edbedfbee5af5718b065d8f Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Mon, 9 Feb 2015 17:16:54 +0100 Subject: [PATCH 055/103] style / make sure the magnifier isn't rendered when we don't want it --- examples/controllers/oculus/goTo.js | 62 +++++++++++++++++-------- interface/src/ui/ApplicationOverlay.cpp | 3 ++ 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/examples/controllers/oculus/goTo.js b/examples/controllers/oculus/goTo.js index 9f3daaea42..c991d97fda 100644 --- a/examples/controllers/oculus/goTo.js +++ b/examples/controllers/oculus/goTo.js @@ -51,10 +51,12 @@ function Instructions(imageURL, originalWidth, originalHeight) { } tthis.remove(); } + this.remove = function() { Overlays.deleteOverlay(tthis.overlay); tthis.visible = false; }; + this.rescale = function() { var scale = Math.min(windowDimensions.x / tthis.originalSize.w, windowDimensions.y / tthis.originalSize.h); var newWidth = tthis.originalSize.w * scale; @@ -115,14 +117,14 @@ keyboard.onKeyRelease = function(event) { // you can cancel a key by releasing its focusing before releasing it if (event.focus) { if (event.event == 'delete') { - deleteChar(); + deleteChar(); } else if (event.event == 'submit' || event.event == 'enter') { - print("going to hifi://" + locationURL); - location = "hifi://" + locationURL; - locationURL = ""; - keyboard.hide(); - cursor.hide(); - updateTextOverlay(); + print("going to hifi://" + locationURL); + location = "hifi://" + locationURL; + locationURL = ""; + keyboard.hide(); + cursor.hide(); + updateTextOverlay(); } } }; @@ -131,18 +133,18 @@ keyboard.onFullyLoaded = function() { print("Virtual-keyboard fully loaded."); var dimensions = Controller.getViewportDimensions(); text = Overlays.addOverlay("text", { - x: 0, - y: dimensions.y - keyboard.height() - 260, - width: dimensions.x, - height: 250, - backgroundColor: { red: 255, green: 255, blue: 255}, - color: { red: 0, green: 0, blue: 0}, - topMargin: 5, - leftMargin: 0, - font: {size: textFontSize}, - text: "", - alpha: 0.8, - visible: keyboard.visible + x: 0, + y: dimensions.y - keyboard.height() - 260, + width: dimensions.x, + height: 250, + backgroundColor: { red: 255, green: 255, blue: 255}, + color: { red: 0, green: 0, blue: 0}, + topMargin: 5, + leftMargin: 0, + font: {size: textFontSize}, + text: "", + alpha: 0.8, + visible: keyboard.visible }); updateTextOverlay(); // the cursor is being loaded after the keyboard, else it will be on the background of the keyboard @@ -189,6 +191,7 @@ function scriptEnding() { } function reportButtonValue(button, newValue, oldValue) { + print(button); if (theInstruction.visible) { if (button == Joysticks.BUTTON_FACE_BOTTOM && newValue) { theInstruction.remove(); @@ -201,6 +204,27 @@ function reportButtonValue(button, newValue, oldValue) { } } else if (button == Joysticks.BUTTON_FACE_RIGHT && newValue) { deleteChar(); + } else if (button == Joysticks.BUTTON_FACE_LEFT && newValue) { + keyboard.hide(); + if (cursor !== undefined) { + cursor.hide(); + } + Overlays.editOverlay(text, {visible: false}); + } else if (button == Joysticks.BUTTON_RIGHT_SHOULDER && newValue) { + if (keyboard.visible) { + print("going to hifi://" + locationURL); + location = "hifi://" + locationURL; + locationURL = ""; + keyboard.hide(); + cursor.hide(); + updateTextOverlay(); + return; + } + keyboard.show(); + if (cursor !== undefined) { + cursor.show(); + } + Overlays.editOverlay(text, {visible: true}); } } diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index f80acf5801..8fc55921e7 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -719,6 +719,9 @@ void ApplicationOverlay::renderPointersOculus(const glm::vec3& eyePos) { //Renders a small magnification of the currently bound texture at the coordinates void ApplicationOverlay::renderMagnifier(glm::vec2 magPos, float sizeMult, bool showBorder) { + if (!_magnifier) { + return; + } auto glCanvas = DependencyManager::get(); const int widgetWidth = glCanvas->width(); From 1d5afba1fac11d7bae4bd8c591cf27ebce5bab51 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Mon, 9 Feb 2015 18:40:36 +0100 Subject: [PATCH 056/103] removed some console noise --- examples/controllers/oculus/goTo.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/controllers/oculus/goTo.js b/examples/controllers/oculus/goTo.js index c991d97fda..91ae8e6141 100644 --- a/examples/controllers/oculus/goTo.js +++ b/examples/controllers/oculus/goTo.js @@ -113,7 +113,6 @@ keyboard.onKeyPress = function(event) { }; keyboard.onKeyRelease = function(event) { - print("Key release event test"); // you can cancel a key by releasing its focusing before releasing it if (event.focus) { if (event.event == 'delete') { @@ -191,7 +190,6 @@ function scriptEnding() { } function reportButtonValue(button, newValue, oldValue) { - print(button); if (theInstruction.visible) { if (button == Joysticks.BUTTON_FACE_BOTTOM && newValue) { theInstruction.remove(); From c2761ac887ec18129d8369866bb711afe2807847 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 9 Feb 2015 15:26:14 -0800 Subject: [PATCH 057/103] CLean up the shader code for the blinn and the new PBR shading equation --- .../render-utils/src/DeferredGlobalLight.slh | 6 ++--- .../render-utils/src/DeferredLighting.slh | 27 ++++++++++++++++++- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index 2dad20e4d3..6868b96c24 100755 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -79,6 +79,8 @@ vec3 evalAmbienSphereGlobalColor(float shadowAttenuation, vec3 position, vec3 no vec4 fragEyeVector = invViewMat * vec4(-position, 0.0); vec3 fragEyeDir = normalize(fragEyeVector.xyz); + // TODO: The world space normal doesn;t seem to work properly with the current SH definitions + // FoOr now, we use the normal in view space vec3 ambientNormal = normal; vec3 color = diffuse.rgb * 0.5 * evalSphericalLight(ambientSphere, ambientNormal).xyz; @@ -87,10 +89,6 @@ vec3 evalAmbienSphereGlobalColor(float shadowAttenuation, vec3 position, vec3 no color += vec3(diffuse + shading.rgb) * shading.w * shadowAttenuation * getLightColor(light) * getLightIntensity(light); - if (gl_FragCoord.x > 1000) { - return vec3(shading.rgb); - } - return color; } diff --git a/libraries/render-utils/src/DeferredLighting.slh b/libraries/render-utils/src/DeferredLighting.slh index 44667bb530..dff24afdd9 100755 --- a/libraries/render-utils/src/DeferredLighting.slh +++ b/libraries/render-utils/src/DeferredLighting.slh @@ -12,7 +12,7 @@ <@def DEFERRED_LIGHTING_SLH@> // Frag Shading returns the diffuse amount as W and the specular rgb as xyz -vec4 evalFragShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 specular, float gloss) { +vec4 evalPBRShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 specular, float gloss) { // Diffuse Lighting float diffuseDot = dot(fragNormal, fragLightDir); float facingLight = step(0.0, diffuseDot); @@ -21,6 +21,7 @@ vec4 evalFragShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 s // Specular Lighting depends on the half vector and the gloss vec3 halfDir = normalize(fragEyeDir + fragLightDir); + // float specularPower = pow(facingLight * max(0.0, dot(halfDir, fragNormal)), gloss * 128.0); float specularPower = pow(facingLight * max(0.0, dot(halfDir, fragNormal)), gloss * 128.0); specularPower *= (gloss * 128.0 * 0.125 + 0.25); @@ -34,4 +35,28 @@ vec4 evalFragShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 s return vec4(reflect, diffuse); } +vec4 evalBlinnShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 specular, float gloss) { + // Diffuse Lighting + float diffuseDot = dot(fragNormal, fragLightDir); + float facingLight = step(0.0, diffuseDot); + float diffuse = diffuseDot * facingLight; + + // Specular Lighting depends on the half vector and the gloss + vec3 halfDir = normalize(fragEyeDir + fragLightDir); + + float specularPower = pow(facingLight * max(0.0, dot(halfDir, fragNormal)), gloss * 128.0); + vec3 reflect = specularPower * specular; + + return vec4(reflect, diffuse); +} + +vec4 evalFragShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 specular, float gloss) { + + /* if (gl_FragCoord.x > 1000) { + return evalBlinnShading(fragNormal, fragLightDir, fragEyeDir, specular, gloss); + } else { */ + return evalPBRShading(fragNormal, fragLightDir, fragEyeDir, specular, gloss); + // } +} + <@endif@> From 871f9a849a7d55d9a9bf85c6bbf3a4cc37ae32ca Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 9 Feb 2015 15:30:17 -0800 Subject: [PATCH 058/103] CLean up the shader code for the blinn and the new PBR shading equation --- libraries/render-utils/src/DeferredLighting.slh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/render-utils/src/DeferredLighting.slh b/libraries/render-utils/src/DeferredLighting.slh index dff24afdd9..73792f67ac 100755 --- a/libraries/render-utils/src/DeferredLighting.slh +++ b/libraries/render-utils/src/DeferredLighting.slh @@ -28,8 +28,7 @@ vec4 evalPBRShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 sp float shlickPower = (1.0 - dot(fragLightDir,halfDir)); float shlickPower2 = shlickPower * shlickPower; float shlickPower5 = shlickPower2 * shlickPower2 * shlickPower; - // vec3 schlick = specular * (1.0 - shlickPower5) + vec3(shlickPower5); - vec3 schlick = vec3(0.21) * (1.0 - shlickPower5) + vec3(shlickPower5); + vec3 schlick = specular * (1.0 - shlickPower5) + vec3(shlickPower5); vec3 reflect = specularPower * schlick; return vec4(reflect, diffuse); From 23a54b17ce8def25e82a937c20571114dd241729 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 9 Feb 2015 15:33:55 -0800 Subject: [PATCH 059/103] Clean up comments --- libraries/render-utils/src/DeferredLightingEffect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 6569e3a018..1f5d0ce4c3 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -70,7 +70,7 @@ void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) { loadLightProgram(point_light_frag, true, _pointLight, _pointLightLocations); loadLightProgram(spot_light_frag, true, _spotLight, _spotLightLocations); - // Allocate 2 global lights representing the GLobal Directional light casting shadow (the sun) and the ambient light + // Allocate a global light representing the Global Directional light casting shadow (the sun) and the ambient light _globalLights.push_back(0); _allocatedLights.push_back(model::LightPointer(new model::Light())); From 11beb51ec1fcefd7ce9a16615bebebd9d120ed00 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 9 Feb 2015 18:02:34 -0800 Subject: [PATCH 060/103] Clean up comments --- libraries/model/src/model/Light.cpp | 2 +- libraries/render-utils/src/DeferredLighting.slh | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/model/src/model/Light.cpp b/libraries/model/src/model/Light.cpp index 003a05eb2f..9616ed2106 100755 --- a/libraries/model/src/model/Light.cpp +++ b/libraries/model/src/model/Light.cpp @@ -94,4 +94,4 @@ void Light::setShowContour(float show) { show = 0.0f; } editSchema()._control.w = show; -} \ No newline at end of file +} diff --git a/libraries/render-utils/src/DeferredLighting.slh b/libraries/render-utils/src/DeferredLighting.slh index 73792f67ac..bb37a9e3e8 100755 --- a/libraries/render-utils/src/DeferredLighting.slh +++ b/libraries/render-utils/src/DeferredLighting.slh @@ -22,7 +22,7 @@ vec4 evalPBRShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 sp vec3 halfDir = normalize(fragEyeDir + fragLightDir); // float specularPower = pow(facingLight * max(0.0, dot(halfDir, fragNormal)), gloss * 128.0); - float specularPower = pow(facingLight * max(0.0, dot(halfDir, fragNormal)), gloss * 128.0); + float specularPower = pow(max(0.0, dot(halfDir, fragNormal)), gloss * 128.0); specularPower *= (gloss * 128.0 * 0.125 + 0.25); float shlickPower = (1.0 - dot(fragLightDir,halfDir)); @@ -51,11 +51,11 @@ vec4 evalBlinnShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 vec4 evalFragShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 specular, float gloss) { - /* if (gl_FragCoord.x > 1000) { + /*if (gl_FragCoord.x > 1000) { return evalBlinnShading(fragNormal, fragLightDir, fragEyeDir, specular, gloss); - } else { */ + } else {*/ return evalPBRShading(fragNormal, fragLightDir, fragEyeDir, specular, gloss); - // } + //} } <@endif@> From 8e0ac763eb8e43c37ebc517d75889c5a8d5bb84d Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Tue, 10 Feb 2015 22:41:43 +0000 Subject: [PATCH 061/103] Changed color of audio bar background Worklist mentions: Additionally, change the color of the bar to #4CC1B8 / 76,193,184 --- interface/src/ui/ApplicationOverlay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 18b9943e29..f558b5a2ad 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -847,7 +847,7 @@ void ApplicationOverlay::renderAudioMeter() { // Draw audio meter background Quad DependencyManager::get()->renderQuad(AUDIO_METER_X, audioMeterY, AUDIO_METER_WIDTH, AUDIO_METER_HEIGHT, - glm::vec4(0, 0, 0, 1)); + glm::vec4(0.298f, 0.757f, 0.722f, 1)); if (audioLevel > AUDIO_RED_START) { glm::vec4 quadColor; From e473661568f859ace26281d6f59f8f3cd4a449f7 Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Tue, 10 Feb 2015 23:55:56 +0000 Subject: [PATCH 062/103] Fix meter showing out of bounds add conditional check for exception when audioLevel is NAN. --- interface/src/ui/ApplicationOverlay.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index f558b5a2ad..3930b43fbd 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -883,17 +883,20 @@ void ApplicationOverlay::renderAudioMeter() { audioLevel = AUDIO_GREEN_START; } // Draw Blue Quad - glm::vec4 quadColor; - if (!isClipping) { - quadColor = AUDIO_METER_BLUE; - } else { - quadColor = glm::vec4(1, 1, 1, 1); - } - // Draw Blue (low level) quad - DependencyManager::get()->renderQuad(AUDIO_METER_X + AUDIO_METER_INSET, - audioMeterY + AUDIO_METER_INSET, - audioLevel, AUDIO_METER_HEIGHT - AUDIO_METER_INSET, quadColor, - _audioBlueQuad); + if (audioLevel > 0) { + glm::vec4 quadColor; + if (!isClipping) { + quadColor = AUDIO_METER_BLUE; + } + else { + quadColor = glm::vec4(1, 1, 1, 1); + } + // Draw Blue (low level) quad + DependencyManager::get()->renderQuad(AUDIO_METER_X + AUDIO_METER_INSET, + audioMeterY + AUDIO_METER_INSET, + audioLevel, AUDIO_METER_HEIGHT - AUDIO_METER_INSET, quadColor, + _audioBlueQuad); + } } void ApplicationOverlay::renderStatsAndLogs() { From d59ee7c561f3816ec6eca39ed578b5f5d23dcec7 Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Tue, 10 Feb 2015 23:57:09 +0000 Subject: [PATCH 063/103] Removed meter inset changes to bar color make the inset very visible --- interface/src/ui/ApplicationOverlay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 3930b43fbd..ecd524e496 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -788,7 +788,7 @@ void ApplicationOverlay::renderAudioMeter() { // Audio VU Meter and Mute Icon const int MUTE_ICON_SIZE = 24; - const int AUDIO_METER_INSET = 2; + const int AUDIO_METER_INSET = 0; const int MUTE_ICON_PADDING = 10; const int AUDIO_METER_WIDTH = MIRROR_VIEW_WIDTH - MUTE_ICON_SIZE - AUDIO_METER_INSET - MUTE_ICON_PADDING; const int AUDIO_METER_SCALE_WIDTH = AUDIO_METER_WIDTH - 2 * AUDIO_METER_INSET; From 93366e068f34be5e9c7bc9f336d91e036de36282 Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Wed, 11 Feb 2015 00:16:40 +0000 Subject: [PATCH 064/103] Remove all references to AUDIO_METER_INSET further cleaning --- interface/src/ui/ApplicationOverlay.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index ecd524e496..45fd4c7de4 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -788,13 +788,12 @@ void ApplicationOverlay::renderAudioMeter() { // Audio VU Meter and Mute Icon const int MUTE_ICON_SIZE = 24; - const int AUDIO_METER_INSET = 0; const int MUTE_ICON_PADDING = 10; - const int AUDIO_METER_WIDTH = MIRROR_VIEW_WIDTH - MUTE_ICON_SIZE - AUDIO_METER_INSET - MUTE_ICON_PADDING; - const int AUDIO_METER_SCALE_WIDTH = AUDIO_METER_WIDTH - 2 * AUDIO_METER_INSET; + const int AUDIO_METER_WIDTH = MIRROR_VIEW_WIDTH - MUTE_ICON_SIZE - MUTE_ICON_PADDING; + const int AUDIO_METER_SCALE_WIDTH = AUDIO_METER_WIDTH - 2 ; const int AUDIO_METER_HEIGHT = 8; const int AUDIO_METER_GAP = 5; - const int AUDIO_METER_X = MIRROR_VIEW_LEFT_PADDING + MUTE_ICON_SIZE + AUDIO_METER_INSET + AUDIO_METER_GAP; + const int AUDIO_METER_X = MIRROR_VIEW_LEFT_PADDING + MUTE_ICON_SIZE + AUDIO_METER_GAP; int audioMeterY; bool smallMirrorVisible = Menu::getInstance()->isOptionChecked(MenuOption::Mirror) && !OculusManager::isConnected(); @@ -857,10 +856,10 @@ void ApplicationOverlay::renderAudioMeter() { quadColor = glm::vec4(1, 1, 1, 1); } // Draw Red Quad - DependencyManager::get()->renderQuad(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_RED_START, - audioMeterY + AUDIO_METER_INSET, + DependencyManager::get()->renderQuad(AUDIO_METER_X +AUDIO_RED_START, + audioMeterY, audioLevel - AUDIO_RED_START, - AUDIO_METER_HEIGHT - AUDIO_METER_INSET, quadColor, + AUDIO_METER_HEIGHT, quadColor, _audioRedQuad); audioLevel = AUDIO_RED_START; @@ -874,10 +873,10 @@ void ApplicationOverlay::renderAudioMeter() { quadColor = glm::vec4(1, 1, 1, 1); } // Draw Green Quad - DependencyManager::get()->renderQuad(AUDIO_METER_X + AUDIO_METER_INSET + AUDIO_GREEN_START, - audioMeterY + AUDIO_METER_INSET, + DependencyManager::get()->renderQuad(AUDIO_METER_X + AUDIO_GREEN_START, + audioMeterY, audioLevel - AUDIO_GREEN_START, - AUDIO_METER_HEIGHT - AUDIO_METER_INSET, quadColor, + AUDIO_METER_HEIGHT, quadColor, _audioGreenQuad); audioLevel = AUDIO_GREEN_START; @@ -892,9 +891,9 @@ void ApplicationOverlay::renderAudioMeter() { quadColor = glm::vec4(1, 1, 1, 1); } // Draw Blue (low level) quad - DependencyManager::get()->renderQuad(AUDIO_METER_X + AUDIO_METER_INSET, - audioMeterY + AUDIO_METER_INSET, - audioLevel, AUDIO_METER_HEIGHT - AUDIO_METER_INSET, quadColor, + DependencyManager::get()->renderQuad(AUDIO_METER_X, + audioMeterY, + audioLevel, AUDIO_METER_HEIGHT, quadColor, _audioBlueQuad); } } From 84d7ae6b3a8566b234f8a55fb5b569ffce09f31e Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Wed, 11 Feb 2015 00:18:08 +0000 Subject: [PATCH 065/103] Change conditional limit to >= edge case --- interface/src/ui/ApplicationOverlay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 45fd4c7de4..407a9cb676 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -882,7 +882,7 @@ void ApplicationOverlay::renderAudioMeter() { audioLevel = AUDIO_GREEN_START; } // Draw Blue Quad - if (audioLevel > 0) { + if (audioLevel >= 0) { glm::vec4 quadColor; if (!isClipping) { quadColor = AUDIO_METER_BLUE; From 837f8d71a41a28080dec5da57a103d5798835a28 Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Wed, 11 Feb 2015 03:17:28 +0000 Subject: [PATCH 066/103] Coding standard fixes Coding standard fixes Indentation and space missing --- interface/src/ui/ApplicationOverlay.cpp | 26 ++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 407a9cb676..9f1ba8080f 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -856,7 +856,7 @@ void ApplicationOverlay::renderAudioMeter() { quadColor = glm::vec4(1, 1, 1, 1); } // Draw Red Quad - DependencyManager::get()->renderQuad(AUDIO_METER_X +AUDIO_RED_START, + DependencyManager::get()->renderQuad(AUDIO_METER_X + AUDIO_RED_START, audioMeterY, audioLevel - AUDIO_RED_START, AUDIO_METER_HEIGHT, quadColor, @@ -883,18 +883,18 @@ void ApplicationOverlay::renderAudioMeter() { } // Draw Blue Quad if (audioLevel >= 0) { - glm::vec4 quadColor; - if (!isClipping) { - quadColor = AUDIO_METER_BLUE; - } - else { - quadColor = glm::vec4(1, 1, 1, 1); - } - // Draw Blue (low level) quad - DependencyManager::get()->renderQuad(AUDIO_METER_X, - audioMeterY, - audioLevel, AUDIO_METER_HEIGHT, quadColor, - _audioBlueQuad); + glm::vec4 quadColor; + if (!isClipping) { + quadColor = AUDIO_METER_BLUE; + } + else { + quadColor = glm::vec4(1, 1, 1, 1); + } + // Draw Blue (low level) quad + DependencyManager::get()->renderQuad(AUDIO_METER_X, + audioMeterY, + audioLevel, AUDIO_METER_HEIGHT, quadColor, + _audioBlueQuad); } } From 260f960ccc22465e66e2792caa9fc07b4d966a19 Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Wed, 11 Feb 2015 03:49:28 +0000 Subject: [PATCH 067/103] Indentation correction Indention was still incorrect I believe. :cry: --- interface/src/ui/ApplicationOverlay.cpp | 28 ++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 9f1ba8080f..5f4493a08d 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -882,20 +882,20 @@ void ApplicationOverlay::renderAudioMeter() { audioLevel = AUDIO_GREEN_START; } // Draw Blue Quad - if (audioLevel >= 0) { - glm::vec4 quadColor; - if (!isClipping) { - quadColor = AUDIO_METER_BLUE; - } - else { - quadColor = glm::vec4(1, 1, 1, 1); - } - // Draw Blue (low level) quad - DependencyManager::get()->renderQuad(AUDIO_METER_X, - audioMeterY, - audioLevel, AUDIO_METER_HEIGHT, quadColor, - _audioBlueQuad); - } + if (audioLevel >= 0) { + glm::vec4 quadColor; + if (!isClipping) { + quadColor = AUDIO_METER_BLUE; + } + else { + quadColor = glm::vec4(1, 1, 1, 1); + } + // Draw Blue (low level) quad + DependencyManager::get()->renderQuad(AUDIO_METER_X, + audioMeterY, + audioLevel, AUDIO_METER_HEIGHT, quadColor, + _audioBlueQuad); + } } void ApplicationOverlay::renderStatsAndLogs() { From e2f942c02637ecf9cab12b1514e94d7c8717c72f Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Wed, 11 Feb 2015 06:11:38 +0000 Subject: [PATCH 068/103] Coding standard fixes Corrected else format, removed additional comment to fit other declarations and break block. --- interface/src/ui/ApplicationOverlay.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 5f4493a08d..f9437221e5 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -881,13 +881,12 @@ void ApplicationOverlay::renderAudioMeter() { audioLevel = AUDIO_GREEN_START; } - // Draw Blue Quad + if (audioLevel >= 0) { glm::vec4 quadColor; if (!isClipping) { quadColor = AUDIO_METER_BLUE; - } - else { + } else { quadColor = glm::vec4(1, 1, 1, 1); } // Draw Blue (low level) quad From 2c52c9c3c0d7b3965b98b3624ac8ea83599c02ea Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 11 Feb 2015 22:57:59 +0100 Subject: [PATCH 069/103] fixes for the virtualKeyboardTextEntityExample --- .../virtualKeyboardTextEntityExample.js | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/examples/controllers/oculus/virtualKeyboardTextEntityExample.js b/examples/controllers/oculus/virtualKeyboardTextEntityExample.js index 794b659bcb..c3cb3c6316 100644 --- a/examples/controllers/oculus/virtualKeyboardTextEntityExample.js +++ b/examples/controllers/oculus/virtualKeyboardTextEntityExample.js @@ -27,7 +27,7 @@ const TEXT_MARGIN_RIGHT = 0.17; const TEXT_MARGIN_BOTTOM = 0.17; var windowDimensions = Controller.getViewportDimensions(); -var cursor = null; +var cursor = new Cursor(); var keyboard = new Keyboard(); var textFontSize = 9; var text = null; @@ -70,7 +70,7 @@ keyboard.onKeyRelease = function(event) { // you can cancel a key by releasing its focusing before releasing it if (event.focus) { if (event.event == 'delete') { - deleteChar(); + deleteChar(); } else if (event.event == 'submit') { print(textText); @@ -83,12 +83,14 @@ keyboard.onKeyRelease = function(event) { if (maxLineWidth < usernameWidth) { maxLineWidth = usernameWidth; } else { - var spaceableWidth = maxLineWidth - usernameWidth; - var spaceWidth = Overlays.textSize(textSizeMeasureOverlay, " ").width; - var numberOfSpaces = Math.floor(spaceableWidth / spaceWidth); - for (var i = 0; i < numberOfSpaces; i++) { - usernameLine = " " + usernameLine; - } + var spaceableWidth = maxLineWidth - usernameWidth; + //TODO: WORKAROUND WARNING BELOW Fix this when spaces are not trimmed out of the textsize calculation anymore + var spaceWidth = Overlays.textSize(textSizeMeasureOverlay, "| |").width + - Overlays.textSize(textSizeMeasureOverlay, "||").width; + var numberOfSpaces = Math.floor(spaceableWidth / spaceWidth); + for (var i = 0; i < numberOfSpaces; i++) { + usernameLine = " " + usernameLine; + } } var dimension_x = maxLineWidth + TEXT_MARGIN_RIGHT + TEXT_MARGIN_LEFT; if (position.x > 0 && position.y > 0 && position.z > 0) { @@ -100,7 +102,7 @@ keyboard.onKeyRelease = function(event) { backgroundColor: { red: 0, green: 0, blue: 0 }, textColor: { red: 255, green: 255, blue: 255 }, text: textText + "\n" + usernameLine, - lineHeight: 0.1 + lineHeight: 0.1 }); } textText = ""; @@ -127,7 +129,7 @@ keyboard.onFullyLoaded = function() { }); updateTextOverlay(); // the cursor is being loaded after the keyboard, else it will be on the background of the keyboard - cursor = new Cursor(); + cursor.initialize(); cursor.onUpdate = function(position) { keyboard.setFocusPosition(position.x, position.y); }; From 51ce8c7100486db53bb57654706d44db465eb2e5 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 12 Feb 2015 13:09:37 -0800 Subject: [PATCH 070/103] Update editEntities to not select new entity when edit tools are off --- examples/editEntities.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/editEntities.js b/examples/editEntities.js index f25a873992..6938fc86b7 100644 --- a/examples/editEntities.js +++ b/examples/editEntities.js @@ -533,7 +533,9 @@ function highlightEntityUnderCursor(position, accurateRay) { function mouseReleaseEvent(event) { if (placingEntityID) { - selectionManager.setSelections([placingEntityID]); + if (isActive) { + selectionManager.setSelections([placingEntityID]); + } placingEntityID = null; } if (isActive && selectionManager.hasSelection()) { From ff6f8ea4a18b1f12c3e4bdaf668b19f6ad98b559 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 12 Feb 2015 13:14:30 -0800 Subject: [PATCH 071/103] cleaner cleanup of AudioClient from RenderingClient --- gvr-interface/src/Client.h | 3 +++ gvr-interface/src/GVRInterface.cpp | 7 +++++++ gvr-interface/src/GVRInterface.h | 1 + gvr-interface/src/RenderingClient.cpp | 16 ++++++---------- gvr-interface/src/RenderingClient.h | 3 ++- libraries/audio-client/src/AudioClient.cpp | 3 ++- libraries/audio-client/src/AudioClient.h | 4 ++++ 7 files changed, 25 insertions(+), 12 deletions(-) diff --git a/gvr-interface/src/Client.h b/gvr-interface/src/Client.h index 6eb3913ea9..31bc8be3bd 100644 --- a/gvr-interface/src/Client.h +++ b/gvr-interface/src/Client.h @@ -22,7 +22,10 @@ class Client : public QObject { Q_OBJECT public: Client(QObject* parent = 0); + + virtual void cleanupBeforeQuit() = 0; protected: + void setupNetworking(); virtual void processVerifiedPacket(const HifiSockAddr& senderSockAddr, const QByteArray& incomingPacket); private slots: diff --git a/gvr-interface/src/GVRInterface.cpp b/gvr-interface/src/GVRInterface.cpp index 7476bfc764..3d58396322 100644 --- a/gvr-interface/src/GVRInterface.cpp +++ b/gvr-interface/src/GVRInterface.cpp @@ -86,6 +86,13 @@ GVRInterface::GVRInterface(int argc, char* argv[]) : QTimer* idleTimer = new QTimer(this); connect(idleTimer, &QTimer::timeout, this, &GVRInterface::idle); idleTimer->start(0); + + // call our quit handler before we go down + connect(this, &QCoreApplication::aboutToQuit, this, &GVRInterface::handleApplicationQuit); +} + +void GVRInterface::handleApplicationQuit() { + _client->cleanupBeforeQuit(); } void GVRInterface::idle() { diff --git a/gvr-interface/src/GVRInterface.h b/gvr-interface/src/GVRInterface.h index 926c44da15..9ffbd52909 100644 --- a/gvr-interface/src/GVRInterface.h +++ b/gvr-interface/src/GVRInterface.h @@ -53,6 +53,7 @@ private slots: void handleApplicationStateChange(Qt::ApplicationState state); void idle(); private: + void handleApplicationQuit(); void enterVRMode(); void leaveVRMode(); diff --git a/gvr-interface/src/RenderingClient.cpp b/gvr-interface/src/RenderingClient.cpp index 9737263eee..1abf4bbc95 100644 --- a/gvr-interface/src/RenderingClient.cpp +++ b/gvr-interface/src/RenderingClient.cpp @@ -37,7 +37,7 @@ RenderingClient::RenderingClient(QObject *parent, const QString& launchURLString DependencyManager::set(); // get our audio client setup on its own thread - QThread* audioThread = new QThread(this); + QThread* audioThread = new QThread(); auto audioClient = DependencyManager::set(); audioClient->setPositionGetter(getPositionForAudio); @@ -45,6 +45,8 @@ RenderingClient::RenderingClient(QObject *parent, const QString& launchURLString audioClient->moveToThread(audioThread); connect(audioThread, &QThread::started, audioClient.data(), &AudioClient::start); + connect(audioClient.data(), &AudioClient::destroyed, audioThread, &QThread::quit); + connect(audioThread, &QThread::finished, audioThread, &QThread::deleteLater); audioThread->start(); @@ -68,15 +70,9 @@ void RenderingClient::sendAvatarPacket() { _fakeAvatar.sendIdentityPacket(); } -RenderingClient::~RenderingClient() { - auto audioClient = DependencyManager::get(); - - // stop the audio client - QMetaObject::invokeMethod(audioClient.data(), "stop", Qt::BlockingQueuedConnection); - - // ask the audio thread to quit and wait until it is done - audioClient->thread()->quit(); - audioClient->thread()->wait(); +void RenderingClient::cleanupBeforeQuit() { + // destroy the AudioClient so it and it's thread will safely go down + DependencyManager::destroy(); } void RenderingClient::processVerifiedPacket(const HifiSockAddr& senderSockAddr, const QByteArray& incomingPacket) { diff --git a/gvr-interface/src/RenderingClient.h b/gvr-interface/src/RenderingClient.h index 870bde748f..c4724bc086 100644 --- a/gvr-interface/src/RenderingClient.h +++ b/gvr-interface/src/RenderingClient.h @@ -26,7 +26,6 @@ class RenderingClient : public Client { Q_OBJECT public: RenderingClient(QObject* parent = 0, const QString& launchURLString = QString()); - ~RenderingClient(); const glm::vec3& getPosition() const { return _position; } const glm::quat& getOrientation() const { return _orientation; } @@ -35,6 +34,8 @@ public: static glm::vec3 getPositionForAudio() { return _instance->getPosition(); } static glm::quat getOrientationForAudio() { return _instance->getOrientation(); } + virtual void cleanupBeforeQuit(); + private slots: void goToLocation(const glm::vec3& newPosition, bool hasOrientationChange, const glm::quat& newOrientation, diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 1919f2bbe5..a45fae94dc 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -136,6 +136,8 @@ AudioClient::AudioClient() : } AudioClient::~AudioClient() { + stop(); + if (_gverbLocal) { gverb_free(_gverbLocal); } @@ -489,7 +491,6 @@ void AudioClient::start() { } void AudioClient::stop() { - _inputFrameBuffer.finalize(); _inputGain.finalize(); _sourceGain.finalize(); diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index e55a116e06..4f16500103 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -188,6 +188,10 @@ protected: AudioClient(); ~AudioClient(); + virtual void customDeleter() { + deleteLater(); + } + private: void outputFormatChanged(); From a3d09e6adcd4affc503df58f2d5c759036462136 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 12 Feb 2015 13:18:02 -0800 Subject: [PATCH 072/103] Fix edit grid not showing up --- examples/editEntities.js | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/editEntities.js b/examples/editEntities.js index f25a873992..a9b5bfeb16 100644 --- a/examples/editEntities.js +++ b/examples/editEntities.js @@ -190,6 +190,7 @@ var toolBar = (function () { cameraManager.enable(); entityListTool.setVisible(true); gridTool.setVisible(true); + grid.setEnabled(true); propertiesTool.setVisible(true); Window.setFocus(); } From 813673b720e958b7aeae65efe735281f3b69e10c Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 12 Feb 2015 13:18:17 -0800 Subject: [PATCH 073/103] Fix grid tool not showing minor grid width --- examples/html/gridControls.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/html/gridControls.html b/examples/html/gridControls.html index 7e354c5bec..941a4b5c2a 100644 --- a/examples/html/gridControls.html +++ b/examples/html/gridControls.html @@ -30,8 +30,8 @@ elPosY.value = origin.y.toFixed(2); } - if (data.minorGridSpacing !== undefined) { - elMinorSpacing.value = data.minorGridSpacing; + if (data.minorGridWidth !== undefined) { + elMinorSpacing.value = data.minorGridWidth; } if (data.majorGridEvery !== undefined) { @@ -57,7 +57,7 @@ origin: { y: elPosY.value, }, - minorGridSpacing: elMinorSpacing.value, + minorGridWidth: elMinorSpacing.value, majorGridEvery: elMajorSpacing.value, gridColor: gridColor, colorIndex: gridColorIndex, From 6c25205856cbace0494e306d22533db3c7efa145 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 12 Feb 2015 13:35:22 -0800 Subject: [PATCH 074/103] fix audio cleanup and close action in Application --- gvr-interface/src/RenderingClient.cpp | 4 +++ interface/src/Application.cpp | 35 +++++++++++-------- interface/src/Application.h | 2 ++ .../networking/src/UserActivityLogger.cpp | 10 +----- libraries/networking/src/UserActivityLogger.h | 2 +- 5 files changed, 28 insertions(+), 25 deletions(-) diff --git a/gvr-interface/src/RenderingClient.cpp b/gvr-interface/src/RenderingClient.cpp index 1abf4bbc95..8f7755a8c5 100644 --- a/gvr-interface/src/RenderingClient.cpp +++ b/gvr-interface/src/RenderingClient.cpp @@ -71,6 +71,10 @@ void RenderingClient::sendAvatarPacket() { } void RenderingClient::cleanupBeforeQuit() { + + QMetaObject::invokeMethod(DependencyManager::get().data(), + "stop", Qt::BlockingQueuedConnection); + // destroy the AudioClient so it and it's thread will safely go down DependencyManager::destroy(); } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 474913fefb..aad1d51ac0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -328,7 +328,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : connect(&nodeList->getNodeSocket(), SIGNAL(readyRead()), &_datagramProcessor, SLOT(processDatagrams())); // put the audio processing on a separate thread - QThread* audioThread = new QThread(this); + QThread* audioThread = new QThread(); audioThread->setObjectName("Audio Thread"); auto audioIO = DependencyManager::get(); @@ -338,7 +338,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : audioIO->moveToThread(audioThread); connect(audioThread, &QThread::started, audioIO.data(), &AudioClient::start); - connect(audioIO.data(), SIGNAL(muteToggled()), this, SLOT(audioMuteToggled())); + connect(audioIO.data(), &AudioClient::destroyed, audioThread, &QThread::quit); + connect(audioThread, &QThread::finished, audioThread, &QThread::deleteLater); + connect(audioIO.data(), &AudioClient::muteToggled, this, &Application::audioMuteToggled); audioThread->start(); @@ -516,21 +518,33 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : void Application::aboutToQuit() { _aboutToQuit = true; + + cleanupBeforeQuit(); } -Application::~Application() { +void Application::cleanupBeforeQuit() { QMetaObject::invokeMethod(&_settingsTimer, "stop", Qt::BlockingQueuedConnection); _settingsThread.quit(); saveSettings(); + // TODO: now that this is in cleanupBeforeQuit do we really need it to stop and force + // an event loop to send the packet? + UserActivityLogger::getInstance().close(); + + // stop the AudioClient + QMetaObject::invokeMethod(DependencyManager::get().data(), + "stop", Qt::BlockingQueuedConnection); + + // destroy the AudioClient so it and its thread have a chance to go down safely + DependencyManager::destroy(); +} + +Application::~Application() { _entities.getTree()->setSimulation(NULL); qInstallMessageHandler(NULL); _window->saveGeometry(); - int DELAY_TIME = 1000; - UserActivityLogger::getInstance().close(DELAY_TIME); - // make sure we don't call the idle timer any more delete idleTimer; @@ -541,15 +555,6 @@ Application::~Application() { _nodeThread->quit(); _nodeThread->wait(); - auto audioIO = DependencyManager::get(); - - // stop the audio process - QMetaObject::invokeMethod(audioIO.data(), "stop", Qt::BlockingQueuedConnection); - - // ask the audio thread to quit and wait until it is done - audioIO->thread()->quit(); - audioIO->thread()->wait(); - _octreeProcessor.terminate(); _entityEditSender.terminate(); diff --git a/interface/src/Application.h b/interface/src/Application.h index d015d09035..da29920ef9 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -410,6 +410,8 @@ private: void initDisplay(); void init(); + + void cleanupBeforeQuit(); void update(float deltaTime); diff --git a/libraries/networking/src/UserActivityLogger.cpp b/libraries/networking/src/UserActivityLogger.cpp index 4fc6905e3a..f2646369c1 100644 --- a/libraries/networking/src/UserActivityLogger.cpp +++ b/libraries/networking/src/UserActivityLogger.cpp @@ -86,17 +86,9 @@ void UserActivityLogger::launch(QString applicationVersion) { logAction(ACTION_NAME, actionDetails); } -void UserActivityLogger::close(int delayTime) { +void UserActivityLogger::close() { const QString ACTION_NAME = "close"; - - // In order to get the end of the session, we need to give the account manager enough time to send the packet. - QEventLoop loop; - QTimer timer; - connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit); - // Now we can log it logAction(ACTION_NAME, QJsonObject()); - timer.start(delayTime); - loop.exec(); } void UserActivityLogger::changedDisplayName(QString displayName) { diff --git a/libraries/networking/src/UserActivityLogger.h b/libraries/networking/src/UserActivityLogger.h index 9b100461ee..295ad5ee8d 100644 --- a/libraries/networking/src/UserActivityLogger.h +++ b/libraries/networking/src/UserActivityLogger.h @@ -30,7 +30,7 @@ public slots: void logAction(QString action, QJsonObject details = QJsonObject(), JSONCallbackParameters params = JSONCallbackParameters()); void launch(QString applicationVersion); - void close(int delayTime); + void close(); void changedDisplayName(QString displayName); void changedModel(QString typeOfModel, QString modelURL); void changedDomain(QString domainURL); From 4e71e128f3d6f8bf1ce0be722d1aa0f4a61021dd Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 12 Feb 2015 13:42:36 -0800 Subject: [PATCH 075/103] remove QThread not currently used in client --- gvr-interface/src/Client.cpp | 2 -- gvr-interface/src/Client.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/gvr-interface/src/Client.cpp b/gvr-interface/src/Client.cpp index e323ab96b5..65238ad784 100644 --- a/gvr-interface/src/Client.cpp +++ b/gvr-interface/src/Client.cpp @@ -9,8 +9,6 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include - #include #include #include diff --git a/gvr-interface/src/Client.h b/gvr-interface/src/Client.h index 31bc8be3bd..6fbe40f165 100644 --- a/gvr-interface/src/Client.h +++ b/gvr-interface/src/Client.h @@ -16,8 +16,6 @@ #include -class QThread; - class Client : public QObject { Q_OBJECT public: From 062c2cbcee34825cac95aa228c3638c7710b72d0 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Thu, 12 Feb 2015 22:55:44 +0100 Subject: [PATCH 076/103] HUD LookAt positions could be NULL now if whenever they're out of range HMD.HUDLookAtPosition2D -> HMD.getHUDLookAtPosition2D() HMD.HUDLookAtPosition3D -> HMD.getHUDLookAtPosition3D() --- examples/libraries/virtualKeyboard.js | 12 +++-- interface/src/Application.cpp | 4 +- .../src/scripting/HMDScriptingInterface.cpp | 44 ++++++++++++------- .../src/scripting/HMDScriptingInterface.h | 9 ++-- libraries/script-engine/src/ScriptEngine.cpp | 6 ++- libraries/script-engine/src/ScriptEngine.h | 2 + 6 files changed, 50 insertions(+), 27 deletions(-) diff --git a/examples/libraries/virtualKeyboard.js b/examples/libraries/virtualKeyboard.js index 7d7d72ae12..a1f952a5eb 100644 --- a/examples/libraries/virtualKeyboard.js +++ b/examples/libraries/virtualKeyboard.js @@ -516,12 +516,16 @@ Cursor = (function(params) { }); } var editobject = {}; - if (tthis.x !== HMD.HUDLookAtPosition2D.x) { - tthis.x = HMD.HUDLookAtPosition2D.x; + var hudLookatPosition = HMD.getHUDLookAtPosition2D(); + if (hudLookatPosition === null) { + return; + } + if (tthis.x !== hudLookatPosition.x) { + tthis.x = hudLookatPosition.x; editobject.x = tthis.x - (CURSOR_WIDTH / 2); } - if (tthis.y !== HMD.HUDLookAtPosition2D.y) { - tthis.y = HMD.HUDLookAtPosition2D.y; + if (tthis.y !== hudLookatPosition.y) { + tthis.y = hudLookatPosition.y; editobject.y = tthis.y - (CURSOR_HEIGHT / 2); } if (Object.keys(editobject).length > 0) { diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d9bd5ed807..22e52d8eaa 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3476,7 +3476,9 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri scriptEngine->registerGlobalObject("UndoStack", &_undoStackScriptingInterface); - scriptEngine->registerGlobalObject("HMD", &HMDScriptingInterface::getInstance()); + QScriptValue hmdInterface = scriptEngine->registerGlobalObject("HMD", &HMDScriptingInterface::getInstance()); + scriptEngine->registerFunction(hmdInterface, "getHUDLookAtPosition2D", HMDScriptingInterface::getHUDLookAtPosition2D, 0); + scriptEngine->registerFunction(hmdInterface, "getHUDLookAtPosition3D", HMDScriptingInterface::getHUDLookAtPosition3D, 0); #ifdef HAVE_RTMIDI scriptEngine->registerGlobalObject("MIDI", &MIDIManager::getInstance()); diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index 7b5d4ddac6..fe274b6878 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -1,4 +1,4 @@ -// +// // HMDScriptingInterface.cpp // interface/src/scripting // @@ -18,7 +18,7 @@ HMDScriptingInterface& HMDScriptingInterface::getInstance() { return sharedInstance; } -glm::vec3 HMDScriptingInterface::getHUDLookAtPosition3D() const { +bool HMDScriptingInterface::getHUDLookAtPosition3D(glm::vec3& result) const { Camera* camera = Application::getInstance()->getCamera(); glm::vec3 position = camera->getPosition(); glm::quat orientation = camera->getOrientation(); @@ -27,20 +27,30 @@ glm::vec3 HMDScriptingInterface::getHUDLookAtPosition3D() const { ApplicationOverlay& applicationOverlay = Application::getInstance()->getApplicationOverlay(); + return applicationOverlay.calculateRayUICollisionPoint(position, direction, result); +} + +QScriptValue HMDScriptingInterface::getHUDLookAtPosition2D(QScriptContext* context, QScriptEngine* engine) { + + glm::vec3 hudIntersection; + + if ((&HMDScriptingInterface::getInstance())->getHUDLookAtPosition3D(hudIntersection)) { + MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); + glm::vec3 sphereCenter = myAvatar->getDefaultEyePosition(); + glm::vec3 direction = glm::inverse(myAvatar->getOrientation()) * (hudIntersection - sphereCenter); + glm::quat rotation = ::rotationBetween(glm::vec3(0.0f, 0.0f, -1.0f), direction); + glm::vec3 eulers = ::safeEulerAngles(rotation); + return qScriptValueFromValue(engine, Application::getInstance()->getApplicationOverlay() + .sphericalToOverlay(glm::vec2(eulers.y, -eulers.x))); + } + return QScriptValue::NullValue; +} + +QScriptValue HMDScriptingInterface::getHUDLookAtPosition3D(QScriptContext* context, QScriptEngine* engine) { glm::vec3 result; - applicationOverlay.calculateRayUICollisionPoint(position, direction, result); - return result; -} - -glm::vec2 HMDScriptingInterface::getHUDLookAtPosition2D() const { - MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); - glm::vec3 sphereCenter = myAvatar->getDefaultEyePosition(); - - glm::vec3 hudIntersection = getHUDLookAtPosition3D(); - - glm::vec3 direction = glm::inverse(myAvatar->getOrientation()) * (hudIntersection - sphereCenter); - glm::quat rotation = ::rotationBetween(glm::vec3(0.0f, 0.0f, -1.0f), direction); - glm::vec3 eulers = ::safeEulerAngles(rotation); - - return Application::getInstance()->getApplicationOverlay().sphericalToOverlay(glm::vec2(eulers.y, -eulers.x)); + HMDScriptingInterface* hmdInterface = &HMDScriptingInterface::getInstance(); + if ((&HMDScriptingInterface::getInstance())->getHUDLookAtPosition3D(result)) { + return qScriptValueFromValue(engine, result); + } + return QScriptValue::NullValue; } diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index cc148d5d5d..bcd458ca5e 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -21,11 +21,12 @@ class HMDScriptingInterface : public QObject { Q_OBJECT Q_PROPERTY(bool magnifier READ getMagnifier) Q_PROPERTY(bool active READ isHMDMode) - Q_PROPERTY(glm::vec3 HUDLookAtPosition3D READ getHUDLookAtPosition3D) - Q_PROPERTY(glm::vec2 HUDLookAtPosition2D READ getHUDLookAtPosition2D) public: static HMDScriptingInterface& getInstance(); + static QScriptValue getHUDLookAtPosition2D(QScriptContext* context, QScriptEngine* engine); + static QScriptValue getHUDLookAtPosition3D(QScriptContext* context, QScriptEngine* engine); + public slots: void toggleMagnifier() { Application::getInstance()->getApplicationOverlay().toggleMagnifier(); }; @@ -34,8 +35,8 @@ private: bool getMagnifier() const { return Application::getInstance()->getApplicationOverlay().hasMagnifier(); }; bool isHMDMode() const { return Application::getInstance()->isHMDMode(); } - glm::vec3 getHUDLookAtPosition3D() const; - glm::vec2 getHUDLookAtPosition2D() const; + bool getHUDLookAtPosition3D(glm::vec3& result) const; + }; #endif // hifi_HMDScriptingInterface_h diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 353e215561..d40d3752d2 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -272,8 +272,12 @@ QScriptValue ScriptEngine::registerGlobalObject(const QString& name, QObject* ob } void ScriptEngine::registerFunction(const QString& name, QScriptEngine::FunctionSignature fun, int numArguments) { + registerFunction(globalObject(), name, fun, numArguments); +} + +void ScriptEngine::registerFunction(QScriptValue parent, const QString& name, QScriptEngine::FunctionSignature fun, int numArguments) { QScriptValue scriptFun = newFunction(fun, numArguments); - globalObject().setProperty(name, scriptFun); + parent.setProperty(name, scriptFun); } void ScriptEngine::registerGetterSetter(const QString& name, QScriptEngine::FunctionSignature getter, diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index f78a14bffa..7cb1fb59db 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -58,6 +58,8 @@ public: void registerGetterSetter(const QString& name, QScriptEngine::FunctionSignature getter, QScriptEngine::FunctionSignature setter, QScriptValue object = QScriptValue::NullValue); void registerFunction(const QString& name, QScriptEngine::FunctionSignature fun, int numArguments = -1); + void registerFunction(QScriptValue parent, const QString& name, QScriptEngine::FunctionSignature fun, + int numArguments = -1); Q_INVOKABLE void setIsAvatar(bool isAvatar); bool isAvatar() const { return _isAvatar; } From 30b371559dca50c963472d885b68befe4516bd53 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 12 Feb 2015 15:11:24 -0800 Subject: [PATCH 077/103] fix a typo in RenderingClient --- gvr-interface/src/RenderingClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gvr-interface/src/RenderingClient.cpp b/gvr-interface/src/RenderingClient.cpp index 8f7755a8c5..e6d2f6b585 100644 --- a/gvr-interface/src/RenderingClient.cpp +++ b/gvr-interface/src/RenderingClient.cpp @@ -75,7 +75,7 @@ void RenderingClient::cleanupBeforeQuit() { QMetaObject::invokeMethod(DependencyManager::get().data(), "stop", Qt::BlockingQueuedConnection); - // destroy the AudioClient so it and it's thread will safely go down + // destroy the AudioClient so it and its thread will safely go down DependencyManager::destroy(); } From f1a586520103301f0a733afe2a866690ed369d02 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 12 Feb 2015 15:17:48 -0800 Subject: [PATCH 078/103] added more logging to persist and backup, fixed bug in start up case for no models.svo and backup --- libraries/octree/src/OctreePersistThread.cpp | 30 ++++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/libraries/octree/src/OctreePersistThread.cpp b/libraries/octree/src/OctreePersistThread.cpp index f0612cc9b1..b247f88059 100644 --- a/libraries/octree/src/OctreePersistThread.cpp +++ b/libraries/octree/src/OctreePersistThread.cpp @@ -213,7 +213,9 @@ void OctreePersistThread::persist() { } _tree->unlock(); + qDebug() << "persist operation calling backup..."; backup(); // handle backup if requested + qDebug() << "persist operation DONE with backup..."; // create our "lock" file to indicate we're saving. @@ -347,6 +349,7 @@ void OctreePersistThread::rollOldBackupVersions(const BackupRule& rule) { void OctreePersistThread::backup() { + qDebug() << "backup operation wantBackup:" << _wantBackup; if (_wantBackup) { quint64 now = usecTimestampNow(); @@ -354,10 +357,12 @@ void OctreePersistThread::backup() { BackupRule& rule = _backupRules[i]; quint64 sinceLastBackup = now - rule.lastBackup; - quint64 SECS_TO_USECS = 1000 * 1000; quint64 intervalToBackup = rule.interval * SECS_TO_USECS; - + + qDebug() << "Checking [" << rule.name << "] - Time since last backup [" << sinceLastBackup << "] " << + "compared to backup interval [" << intervalToBackup << "]..."; + if (sinceLastBackup > intervalToBackup) { qDebug() << "Time since last backup [" << sinceLastBackup << "] for rule [" << rule.name << "] exceeds backup interval [" << intervalToBackup << "] doing backup now..."; @@ -379,15 +384,22 @@ void OctreePersistThread::backup() { } - qDebug() << "backing up persist file " << _filename << "to" << backupFileName << "..."; - bool result = QFile::copy(_filename, backupFileName); - if (result) { - qDebug() << "DONE backing up persist file..."; + QFile persistFile(_filename); + if (persistFile.exists()) { + qDebug() << "backing up persist file " << _filename << "to" << backupFileName << "..."; + bool result = QFile::copy(_filename, backupFileName); + if (result) { + qDebug() << "DONE backing up persist file..."; + rule.lastBackup = now; // only record successful backup in this case. + } else { + qDebug() << "ERROR in backing up persist file..."; + } } else { - qDebug() << "ERROR in backing up persist file..."; + qDebug() << "persist file " << _filename << " does not exist. " << + "nothing to backup for this rule ["<< rule.name << "]..."; } - - rule.lastBackup = now; + } else { + qDebug() << "Backup not needed for this rule ["<< rule.name << "]..."; } } } From 07a12f8b4c818bbb1a6575c930c5b961b233cd80 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 12 Feb 2015 16:55:14 -0800 Subject: [PATCH 079/103] remove a couple crash modes on shutdown --- interface/src/Application.cpp | 37 ++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c720ed7606..e33938d959 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -519,37 +519,31 @@ void Application::aboutToQuit() { } Application::~Application() { + // stop idle calls + delete idleTimer; + + // save settings QMetaObject::invokeMethod(&_settingsTimer, "stop", Qt::BlockingQueuedConnection); _settingsThread.quit(); saveSettings(); - - _entities.getTree()->setSimulation(NULL); - qInstallMessageHandler(NULL); - _window->saveGeometry(); - int DELAY_TIME = 1000; - UserActivityLogger::getInstance().close(DELAY_TIME); - - // make sure we don't call the idle timer any more - delete idleTimer; - // let the avatar mixer know we're out MyAvatar::sendKillAvatar(); + // log activity (sends data over HTTP) + // NOTE: there is still an occasional crash in UserActivitiyLogger::close() + int DELAY_TIME = 1000; + UserActivityLogger::getInstance().close(DELAY_TIME); + // ask the datagram processing thread to quit and wait until it is done _nodeThread->quit(); _nodeThread->wait(); - // kill any audio injectors that are still around + // kill audio AudioScriptingInterface::getInstance().stopAllInjectors(); - auto audioIO = DependencyManager::get(); - - // stop the audio process QMetaObject::invokeMethod(audioIO.data(), "stop", Qt::BlockingQueuedConnection); - - // ask the audio thread to quit and wait until it is done audioIO->thread()->quit(); audioIO->thread()->wait(); @@ -566,6 +560,17 @@ Application::~Application() { DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); + + EntityTree* tree = _entities.getTree(); + tree->lockForWrite(); + _entities.getTree()->setSimulation(NULL); + tree->unlock(); + + qInstallMessageHandler(NULL); + + // At this point we return all memory to the operating system ASAP + // and don't worry about proper cleanup of global variables. + exit(0); } void Application::initializeGL() { From c3b432c4b5be2780244ebbb59154b7941400fb93 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 12 Feb 2015 17:02:21 -0800 Subject: [PATCH 080/103] wrap explicit exit() in #ifndef DEBUG --- interface/src/Application.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e33938d959..57e7ffe065 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -568,9 +568,11 @@ Application::~Application() { qInstallMessageHandler(NULL); +#ifndef DEBUG // At this point we return all memory to the operating system ASAP // and don't worry about proper cleanup of global variables. exit(0); +#endif } void Application::initializeGL() { From 4b7d4d72901ed1b168595be63739f0a58f459c5c Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 13 Feb 2015 10:56:04 +0100 Subject: [PATCH 081/103] Don't use DataStream to write MuteEnv packet --- interface/src/DatagramProcessor.cpp | 4 ++-- libraries/audio-client/src/AudioClient.cpp | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/interface/src/DatagramProcessor.cpp b/interface/src/DatagramProcessor.cpp index 9c56f8bc8d..02d3c62765 100644 --- a/interface/src/DatagramProcessor.cpp +++ b/interface/src/DatagramProcessor.cpp @@ -129,12 +129,12 @@ void DatagramProcessor::processDatagrams() { if (incomingType == PacketTypeMuteEnvironment) { glm::vec3 position; - float radius, distance; + float radius; int headerSize = numBytesForPacketHeaderGivenPacketType(PacketTypeMuteEnvironment); memcpy(&position, incomingPacket.constData() + headerSize, sizeof(glm::vec3)); memcpy(&radius, incomingPacket.constData() + headerSize + sizeof(glm::vec3), sizeof(float)); - distance = glm::distance(DependencyManager::get()->getMyAvatar()->getPosition(), + float distance = glm::distance(DependencyManager::get()->getMyAvatar()->getPosition(), position); mute = mute && (distance < radius); diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 9f569c9893..dba24c6703 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -871,13 +871,14 @@ void AudioClient::processReceivedSamples(const QByteArray& inputBuffer, QByteArr void AudioClient::sendMuteEnvironmentPacket() { QByteArray mutePacket = byteArrayWithPopulatedHeader(PacketTypeMuteEnvironment); - QDataStream mutePacketStream(&mutePacket, QIODevice::Append); + int headerSize = mutePacket.size(); const float MUTE_RADIUS = 50; glm::vec3 currentSourcePosition = _positionGetter(); - mutePacketStream.writeBytes(reinterpret_cast(¤tSourcePosition), sizeof(glm::vec3)); - mutePacketStream.writeBytes(reinterpret_cast(&MUTE_RADIUS), sizeof(float)); + mutePacket.resize(mutePacket.size() + sizeof(glm::vec3) + sizeof(float)); + memcpy(mutePacket.data() + headerSize, ¤tSourcePosition, sizeof(glm::vec3)); + memcpy(mutePacket.data() + headerSize + sizeof(glm::vec3), &MUTE_RADIUS, sizeof(float)); // grab our audio mixer from the NodeList, if it exists auto nodelist = DependencyManager::get(); From 1ba85518fceadc0884971385b69d7d57ff633aca Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 13 Feb 2015 11:36:41 -0800 Subject: [PATCH 082/103] fix for playSound called from same thread --- .../src/AudioScriptingInterface.cpp | 39 +++++++++---------- .../src/AudioScriptingInterface.h | 3 -- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/libraries/script-engine/src/AudioScriptingInterface.cpp b/libraries/script-engine/src/AudioScriptingInterface.cpp index 32b9eb23e2..387852fe00 100644 --- a/libraries/script-engine/src/AudioScriptingInterface.cpp +++ b/libraries/script-engine/src/AudioScriptingInterface.cpp @@ -31,44 +31,41 @@ AudioScriptingInterface::AudioScriptingInterface() : } ScriptAudioInjector* AudioScriptingInterface::playSound(Sound* sound, const AudioInjectorOptions& injectorOptions) { - AudioInjector* injector = NULL; - QMetaObject::invokeMethod(this, "invokedPlaySound", Qt::BlockingQueuedConnection, - Q_RETURN_ARG(AudioInjector*, injector), - Q_ARG(Sound*, sound), Q_ARG(const AudioInjectorOptions&, injectorOptions)); - if (injector) { - return new ScriptAudioInjector(injector); - } else { - return NULL; + if (QThread::currentThread() != thread()) { + ScriptAudioInjector* injector = NULL; + + QMetaObject::invokeMethod(this, "playSound", Qt::BlockingQueuedConnection, + Q_RETURN_ARG(ScriptAudioInjector*, injector), + Q_ARG(Sound*, sound), Q_ARG(const AudioInjectorOptions&, injectorOptions)); + return injector; } -} - -AudioInjector* AudioScriptingInterface::invokedPlaySound(Sound* sound, const AudioInjectorOptions& injectorOptions) { + if (sound) { // stereo option isn't set from script, this comes from sound metadata or filename AudioInjectorOptions optionsCopy = injectorOptions; optionsCopy.stereo = sound->isStereo(); - + QThread* injectorThread = new QThread(); injectorThread->setObjectName("Audio Injector Thread"); - + AudioInjector* injector = new AudioInjector(sound, optionsCopy); injector->setLocalAudioInterface(_localAudioInterface); - + injector->moveToThread(injectorThread); - + // start injecting when the injector thread starts connect(injectorThread, &QThread::started, injector, &AudioInjector::injectAudio); - + // connect the right slots and signals for AudioInjector and thread cleanup connect(injector, &AudioInjector::destroyed, injectorThread, &QThread::quit); connect(injectorThread, &QThread::finished, injectorThread, &QThread::deleteLater); - + injectorThread->start(); - - return injector; - + + return new ScriptAudioInjector(injector); + } else { qDebug() << "AudioScriptingInterface::playSound called with null Sound object."; return NULL; } -} +} \ No newline at end of file diff --git a/libraries/script-engine/src/AudioScriptingInterface.h b/libraries/script-engine/src/AudioScriptingInterface.h index ed52d951ad..b74c520670 100644 --- a/libraries/script-engine/src/AudioScriptingInterface.h +++ b/libraries/script-engine/src/AudioScriptingInterface.h @@ -32,9 +32,6 @@ protected: signals: void mutedByMixer(); void environmentMuted(); - -private slots: - AudioInjector* invokedPlaySound(Sound* sound, const AudioInjectorOptions& injectorOptions); private: AudioScriptingInterface(); From 6ff4f8c2c04c01789adcbe7cba95b594c228088d Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 13 Feb 2015 11:52:23 -0800 Subject: [PATCH 083/103] give butterflies an initial velocity so that they are on the kinematics list --- examples/example/entities/butterflies.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/examples/example/entities/butterflies.js b/examples/example/entities/butterflies.js index 336e128d83..9cbe8f966c 100644 --- a/examples/example/entities/butterflies.js +++ b/examples/example/entities/butterflies.js @@ -13,6 +13,9 @@ // +print("BUTTERFLIES START"); + + var numButterflies = 25; @@ -109,7 +112,7 @@ function updateButterflies(deltaTime) { var properties = Entities.getEntityProperties(butterflies[i]); if (Vec3.length(Vec3.subtract(properties.position, flockPosition)) > range) { Entities.editEntity(butterflies[i], { position: flockPosition } ); - } else if (properties.velocity.y < 0.0) { + } else if (properties.velocity.y <= 0.0) { // If falling, Create a new direction and impulse var HORIZ_SCALE = 0.50; var VERT_SCALE = 0.50; @@ -139,3 +142,5 @@ Script.scriptEnding.connect(function() { Entities.deleteEntity(butterflies[i]); } }); + +print("BUTTERFLIES END"); From 28430d928a7cfa1f44bc8f935292aa11ec38124c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 13 Feb 2015 11:52:51 -0800 Subject: [PATCH 084/103] use direct connection to ensure injector is stopped --- libraries/script-engine/src/ScriptAudioInjector.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/script-engine/src/ScriptAudioInjector.cpp b/libraries/script-engine/src/ScriptAudioInjector.cpp index beb056468f..7bdf78be63 100644 --- a/libraries/script-engine/src/ScriptAudioInjector.cpp +++ b/libraries/script-engine/src/ScriptAudioInjector.cpp @@ -13,7 +13,9 @@ QScriptValue injectorToScriptValue(QScriptEngine* engine, ScriptAudioInjector* const& in) { // when the script goes down we want to cleanup the injector - QObject::connect(engine, &QScriptEngine::destroyed, in, &ScriptAudioInjector::stopInjectorImmediately); + + QObject::connect(engine, &QScriptEngine::destroyed, in, &ScriptAudioInjector::stopInjectorImmediately, + Qt::DirectConnection); return engine->newQObject(in, QScriptEngine::ScriptOwnership); } @@ -36,5 +38,6 @@ ScriptAudioInjector::~ScriptAudioInjector() { } void ScriptAudioInjector::stopInjectorImmediately() { + qDebug() << "ScriptAudioInjector::stopInjectorImmediately called to stop audio injector immediately."; _injector->stopAndDeleteLater(); } From 589077bce64ab3761b7e78db85d9372b03d6f093 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 13 Feb 2015 14:01:56 -0800 Subject: [PATCH 085/103] try again: move stuff around in ~Application --- interface/src/Application.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a99fcde7ee..1e94d79457 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -523,13 +523,21 @@ void Application::aboutToQuit() { } void Application::cleanupBeforeQuit() { + // make sure we don't call the idle timer any more + delete idleTimer; + + // save state QMetaObject::invokeMethod(&_settingsTimer, "stop", Qt::BlockingQueuedConnection); _settingsThread.quit(); saveSettings(); + _window->saveGeometry(); // TODO: now that this is in cleanupBeforeQuit do we really need it to stop and force // an event loop to send the packet? UserActivityLogger::getInstance().close(); + + // let the avatar mixer know we're out + MyAvatar::sendKillAvatar(); // stop the AudioClient QMetaObject::invokeMethod(DependencyManager::get().data(), @@ -540,13 +548,12 @@ void Application::cleanupBeforeQuit() { } Application::~Application() { - _window->saveGeometry(); - - // make sure we don't call the idle timer any more - delete idleTimer; - - // let the avatar mixer know we're out - MyAvatar::sendKillAvatar(); + EntityTree* tree = _entities.getTree(); + tree->lockForWrite(); + _entities.getTree()->setSimulation(NULL); + tree->unlock(); + + qInstallMessageHandler(NULL); // ask the datagram processing thread to quit and wait until it is done _nodeThread->quit(); @@ -565,13 +572,6 @@ Application::~Application() { DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); - - EntityTree* tree = _entities.getTree(); - tree->lockForWrite(); - _entities.getTree()->setSimulation(NULL); - tree->unlock(); - - qInstallMessageHandler(NULL); } void Application::initializeGL() { From bc5a1477e6bcd827b43daa5afddce72e6acc6609 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 13 Feb 2015 14:59:57 -0800 Subject: [PATCH 086/103] added logging of edit commands in the server --- .../src/entities/EntityServer.cpp | 11 ++++ assignment-client/src/entities/EntityServer.h | 1 + .../resources/describe-settings.json | 7 +++ libraries/entities/src/EntityItemProperties.h | 58 +++++++++++++++++-- .../entities/src/EntityItemPropertiesMacros.h | 4 ++ libraries/entities/src/EntityTree.cpp | 4 ++ libraries/entities/src/EntityTree.h | 5 ++ 7 files changed, 84 insertions(+), 6 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index d882ea19ac..85d0a7414c 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -147,3 +147,14 @@ void EntityServer::pruneDeletedEntities() { } } +void EntityServer::readAdditionalConfiguration(const QJsonObject& settingsSectionObject) { + bool wantEditLogging = false; + readOptionBool(QString("wantEditLogging"), settingsSectionObject, wantEditLogging); + qDebug("wantEditLogging=%s", debug::valueOf(wantEditLogging)); + + + EntityTree* tree = static_cast(_tree); + tree->setWantEditLogging(wantEditLogging); +} + + diff --git a/assignment-client/src/entities/EntityServer.h b/assignment-client/src/entities/EntityServer.h index d072d18cdf..d8c2e39f3b 100644 --- a/assignment-client/src/entities/EntityServer.h +++ b/assignment-client/src/entities/EntityServer.h @@ -41,6 +41,7 @@ public: virtual int sendSpecialPacket(const SharedNodePointer& node, OctreeQueryNode* queryNode, int& packetsSent); virtual void entityCreated(const EntityItem& newEntity, const SharedNodePointer& senderNode); + virtual void readAdditionalConfiguration(const QJsonObject& settingsSectionObject); public slots: void pruneDeletedEntities(); diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 1ff82f58eb..fdaede8c44 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -409,6 +409,13 @@ "default": "", "advanced": true }, + { + "name": "wantEditLogging", + "type": "checkbox", + "help": "Logging of all edits to entities", + "default": true, + "advanced": true + }, { "name": "verboseDebug", "type": "checkbox", diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 4db6cd5d79..51779d3f56 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -194,6 +194,7 @@ public: bool containsBoundsProperties() const { return (_positionChanged || _dimensionsChanged); } bool containsPositionChange() const { return _positionChanged; } bool containsDimensionsChange() const { return _dimensionsChanged; } + bool containsAnimationSettingsChange() const { return _animationSettingsChanged; } float getGlowLevel() const { return _glowLevel; } float getLocalRenderAlpha() const { return _localRenderAlpha; } @@ -256,12 +257,57 @@ inline void EntityItemProperties::setPosition(const glm::vec3& value) inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { - debug << "EntityItemProperties[" << "\n" - << " position:" << properties.getPosition() << "in meters" << "\n" - << " velocity:" << properties.getVelocity() << "in meters" << "\n" - << " last edited:" << properties.getLastEdited() << "\n" - << " edited ago:" << properties.getEditedAgo() << "\n" - << "]"; + debug << "EntityItemProperties[" << "\n"; + + // TODO: figure out why position and animationSettings don't seem to like the macro approach + if (properties.containsPositionChange()) { + debug << " position:" << properties.getPosition() << "in meters" << "\n"; + } + if (properties.containsAnimationSettingsChange()) { + debug << " animationSettings:" << properties.getAnimationSettings() << "\n"; + } + + DEBUG_PROPERTY_IF_CHANGED(debug, properties, Dimensions, dimensions, "in meters"); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, Velocity, velocity, "in meters"); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, Visible, visible, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, Rotation, rotation, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, Density, density, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, Gravity, gravity, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, Damping, damping, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, Lifetime, lifetime, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, Script, script, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, Color, color, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, ModelURL, modelURL, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, AnimationURL, animationURL, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, AnimationFPS, animationFPS, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, AnimationFrameIndex, animationFrameIndex, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, AnimationIsPlaying, animationIsPlaying, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, RegistrationPoint, registrationPoint, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, AngularVelocity, angularVelocity, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, AngularDamping, angularDamping, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, IgnoreForCollisions, ignoreForCollisions, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, CollisionsWillMove, collisionsWillMove, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, IsSpotlight, isSpotlight, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, DiffuseColor, diffuseColor, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, AmbientColor, ambientColor, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, SpecularColor, specularColor, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, ConstantAttenuation, constantAttenuation, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, LinearAttenuation, linearAttenuation, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, QuadraticAttenuation, quadraticAttenuation, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, Exponent, exponent, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, Cutoff, cutoff, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, Locked, locked, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, Textures, textures, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, UserData, userData, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, Text, text, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, LineHeight, lineHeight, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, TextColor, textColor, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, BackgroundColor, backgroundColor, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, ShapeType, shapeType, ""); + + debug << " last edited:" << properties.getLastEdited() << "\n"; + debug << " edited ago:" << properties.getEditedAgo() << "\n"; + debug << "]"; return debug; } diff --git a/libraries/entities/src/EntityItemPropertiesMacros.h b/libraries/entities/src/EntityItemPropertiesMacros.h index 518035c0d3..592f808e1a 100644 --- a/libraries/entities/src/EntityItemPropertiesMacros.h +++ b/libraries/entities/src/EntityItemPropertiesMacros.h @@ -321,6 +321,10 @@ T _##n; \ bool _##n##Changed; +#define DEBUG_PROPERTY_IF_CHANGED(D, P, N, n, x) \ + if (P.n##Changed()) { \ + D << " " << #n << ":" << P.get##N() << x << "\n"; \ + } #endif // hifi_EntityItemPropertiesMacros_h diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 95617b4944..8bb759c1b4 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -592,6 +592,10 @@ int EntityTree::processEditPacketData(PacketType packetType, const unsigned char // if the EntityItem exists, then update it if (existingEntity) { + if (wantEditLogging()) { + qDebug() << "User [" << senderNode->getUUID() << "] editing entity. ID:" << entityItemID; + qDebug() << " properties:" << properties; + } updateEntity(entityItemID, properties, senderNode->getCanAdjustLocks()); existingEntity->markAsChangedOnServer(); } else { diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 3bc0986799..d8b9b9f38f 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -151,6 +151,9 @@ public: void emitEntityScriptChanging(const EntityItemID& entityItemID); void setSimulation(EntitySimulation* simulation); + + bool wantEditLogging() const { return _wantEditLogging; } + void setWantEditLogging(bool value) { _wantEditLogging = value; } signals: void deletingEntity(const EntityItemID& entityID); @@ -180,6 +183,8 @@ private: QHash _entityToElementMap; EntitySimulation* _simulation; + + bool _wantEditLogging = false; }; #endif // hifi_EntityTree_h From 0495833ca6eb13b41373e67c9d4739541ada5d94 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 13 Feb 2015 15:00:37 -0800 Subject: [PATCH 087/103] Disallow entity models to be reset to natural dimensions if unknown --- examples/editEntities.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/examples/editEntities.js b/examples/editEntities.js index a9b5bfeb16..f0bb123e96 100644 --- a/examples/editEntities.js +++ b/examples/editEntities.js @@ -957,9 +957,18 @@ PropertiesTool = function(opts) { selectionManager.saveProperties(); for (var i = 0; i < selectionManager.selections.length; i++) { var properties = selectionManager.savedProperties[selectionManager.selections[i].id]; - Entities.editEntity(selectionManager.selections[i], { - dimensions: properties.naturalDimensions, - }); + var naturalDimensions = properties.naturalDimensions; + + // If any of the natural dimensions are not 0, resize + if (properties.type == "Model" && naturalDimensions.x == 0 + && naturalDimensions.y == 0 || naturalDimensions.z == 0) { + Window.alert("Cannot reset entity to its natural dimensions: Model URL" + + " is invalid or the model has not yet been loaded."); + } else { + Entities.editEntity(selectionManager.selections[i], { + dimensions: properties.naturalDimensions, + }); + } } pushCommandForSelections(); selectionManager._update(); From 2df850eb8d75bd88aed5eec157a41618566cb437 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 13 Feb 2015 15:02:16 -0800 Subject: [PATCH 088/103] Fix natural dimensions check --- examples/editEntities.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/editEntities.js b/examples/editEntities.js index f0bb123e96..b9e594a1c1 100644 --- a/examples/editEntities.js +++ b/examples/editEntities.js @@ -961,7 +961,7 @@ PropertiesTool = function(opts) { // If any of the natural dimensions are not 0, resize if (properties.type == "Model" && naturalDimensions.x == 0 - && naturalDimensions.y == 0 || naturalDimensions.z == 0) { + && naturalDimensions.y == 0 && naturalDimensions.z == 0) { Window.alert("Cannot reset entity to its natural dimensions: Model URL" + " is invalid or the model has not yet been loaded."); } else { From 98b445b22f9cac6e5a6e0ff86c3d8ad5d0a5e7e8 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 13 Feb 2015 15:21:03 -0800 Subject: [PATCH 089/103] the geometryCacheID for Rectangle3DOverlay wasn't being initialized (so was randomish). if they overlapped, some would be drawn looking like others --- interface/src/ui/overlays/Rectangle3DOverlay.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/ui/overlays/Rectangle3DOverlay.cpp b/interface/src/ui/overlays/Rectangle3DOverlay.cpp index 6ee90b11cc..99023d389b 100644 --- a/interface/src/ui/overlays/Rectangle3DOverlay.cpp +++ b/interface/src/ui/overlays/Rectangle3DOverlay.cpp @@ -20,6 +20,7 @@ #include "Rectangle3DOverlay.h" Rectangle3DOverlay::Rectangle3DOverlay() { + _geometryCacheID(DependencyManager::get()->allocateID()) } Rectangle3DOverlay::Rectangle3DOverlay(const Rectangle3DOverlay* rectangle3DOverlay) : From 42511f3b7f1ad65d997e23f3e77c147dd5d933e6 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 13 Feb 2015 15:23:22 -0800 Subject: [PATCH 090/103] M-x mangle buffer --- interface/src/ui/overlays/Rectangle3DOverlay.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/Rectangle3DOverlay.cpp b/interface/src/ui/overlays/Rectangle3DOverlay.cpp index 99023d389b..7a88b327d1 100644 --- a/interface/src/ui/overlays/Rectangle3DOverlay.cpp +++ b/interface/src/ui/overlays/Rectangle3DOverlay.cpp @@ -19,8 +19,9 @@ #include "Rectangle3DOverlay.h" -Rectangle3DOverlay::Rectangle3DOverlay() { +Rectangle3DOverlay::Rectangle3DOverlay() : _geometryCacheID(DependencyManager::get()->allocateID()) +{ } Rectangle3DOverlay::Rectangle3DOverlay(const Rectangle3DOverlay* rectangle3DOverlay) : From 1fc0225939fa516333a17febfa8335922440bd1e Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 13 Feb 2015 15:33:41 -0800 Subject: [PATCH 091/103] change ScriptCache and SoundCache to derive from Dependency --- assignment-client/src/Agent.cpp | 2 +- assignment-client/src/AssignmentClient.cpp | 2 +- interface/src/Application.cpp | 7 ++- interface/src/ui/CachesSizeDialog.cpp | 8 ++-- libraries/audio/src/SoundCache.cpp | 5 -- libraries/audio/src/SoundCache.h | 6 +-- libraries/metavoxels/src/Bitstream.cpp | 54 +++++++++++----------- libraries/metavoxels/src/MetavoxelUtil.cpp | 6 +-- libraries/metavoxels/src/ScriptCache.cpp | 9 +--- libraries/metavoxels/src/ScriptCache.h | 6 +-- tests/metavoxels/src/MetavoxelTests.cpp | 14 +++--- 11 files changed, 56 insertions(+), 63 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 08a510f32c..4755d9137a 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -208,7 +208,7 @@ void Agent::run() { _scriptEngine.init(); // must be done before we set up the viewers - _scriptEngine.registerGlobalObject("SoundCache", &SoundCache::getInstance()); + _scriptEngine.registerGlobalObject("SoundCache", DependencyManager::get().data()); _scriptEngine.registerGlobalObject("EntityViewer", &_entityViewer); _entityViewer.setJurisdictionListener(_scriptEngine.getEntityScriptingInterface()->getJurisdictionListener()); diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index 9eb2fad739..80f3cbab5e 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -136,7 +136,7 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : // Create Singleton objects on main thread NetworkAccessManager::getInstance(); - SoundCache::getInstance(); + auto soundCache = DependencyManager::get(); } void AssignmentClient::sendAssignmentRequest() { diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2011f9b82e..903cae413e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -211,6 +211,8 @@ bool setupEssentials(int& argc, char** argv) { auto addressManager = DependencyManager::set(); auto nodeList = DependencyManager::set(NodeType::Agent, listenPort); auto geometryCache = DependencyManager::set(); + auto scriptCache = DependencyManager::set(); + auto soundCache = DependencyManager::set(); auto glowEffect = DependencyManager::set(); auto faceshift = DependencyManager::set(); auto audio = DependencyManager::set(); @@ -563,11 +565,14 @@ Application::~Application() { _myAvatar = NULL; DependencyManager::destroy(); + + qDebug() << "start destroying ResourceCaches Application::~Application() line:" << __LINE__; DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); + qDebug() << "done destroying ResourceCaches Application::~Application() line:" << __LINE__; } void Application::initializeGL() { @@ -3466,7 +3471,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri scriptEngine->registerGlobalObject("Settings", SettingsScriptingInterface::getInstance()); scriptEngine->registerGlobalObject("AudioDevice", AudioDeviceScriptingInterface::getInstance()); scriptEngine->registerGlobalObject("AnimationCache", DependencyManager::get().data()); - scriptEngine->registerGlobalObject("SoundCache", &SoundCache::getInstance()); + scriptEngine->registerGlobalObject("SoundCache", DependencyManager::get().data()); scriptEngine->registerGlobalObject("Account", AccountScriptingInterface::getInstance()); scriptEngine->registerGlobalObject("Metavoxels", &_metavoxels); diff --git a/interface/src/ui/CachesSizeDialog.cpp b/interface/src/ui/CachesSizeDialog.cpp index 4d4457c922..d21d1c2db8 100644 --- a/interface/src/ui/CachesSizeDialog.cpp +++ b/interface/src/ui/CachesSizeDialog.cpp @@ -59,8 +59,8 @@ CachesSizeDialog::CachesSizeDialog(QWidget* parent) : void CachesSizeDialog::confirmClicked(bool checked) { DependencyManager::get()->setUnusedResourceCacheSize(_animations->value() * BYTES_PER_MEGABYTES); DependencyManager::get()->setUnusedResourceCacheSize(_geometries->value() * BYTES_PER_MEGABYTES); - ScriptCache::getInstance()->setUnusedResourceCacheSize(_scripts->value() * BYTES_PER_MEGABYTES); - SoundCache::getInstance().setUnusedResourceCacheSize(_sounds->value() * BYTES_PER_MEGABYTES); + DependencyManager::get()->setUnusedResourceCacheSize(_scripts->value() * BYTES_PER_MEGABYTES); + DependencyManager::get()->setUnusedResourceCacheSize(_sounds->value() * BYTES_PER_MEGABYTES); DependencyManager::get()->setUnusedResourceCacheSize(_textures->value() * BYTES_PER_MEGABYTES); QDialog::close(); @@ -69,8 +69,8 @@ void CachesSizeDialog::confirmClicked(bool checked) { void CachesSizeDialog::resetClicked(bool checked) { _animations->setValue(DependencyManager::get()->getUnusedResourceCacheSize() / BYTES_PER_MEGABYTES); _geometries->setValue(DependencyManager::get()->getUnusedResourceCacheSize() / BYTES_PER_MEGABYTES); - _scripts->setValue(ScriptCache::getInstance()->getUnusedResourceCacheSize() / BYTES_PER_MEGABYTES); - _sounds->setValue(SoundCache::getInstance().getUnusedResourceCacheSize() / BYTES_PER_MEGABYTES); + _scripts->setValue(DependencyManager::get()->getUnusedResourceCacheSize() / BYTES_PER_MEGABYTES); + _sounds->setValue(DependencyManager::get()->getUnusedResourceCacheSize() / BYTES_PER_MEGABYTES); _textures->setValue(DependencyManager::get()->getUnusedResourceCacheSize() / BYTES_PER_MEGABYTES); } diff --git a/libraries/audio/src/SoundCache.cpp b/libraries/audio/src/SoundCache.cpp index fe05372ce5..2949a6c70a 100644 --- a/libraries/audio/src/SoundCache.cpp +++ b/libraries/audio/src/SoundCache.cpp @@ -15,11 +15,6 @@ static int soundPointerMetaTypeId = qRegisterMetaType(); -SoundCache& SoundCache::getInstance() { - static SoundCache staticInstance; - return staticInstance; -} - SoundCache::SoundCache(QObject* parent) : ResourceCache(parent) { diff --git a/libraries/audio/src/SoundCache.h b/libraries/audio/src/SoundCache.h index f9fbf51c10..7942e16010 100644 --- a/libraries/audio/src/SoundCache.h +++ b/libraries/audio/src/SoundCache.h @@ -17,11 +17,11 @@ #include "Sound.h" /// Scriptable interface for sound loading. -class SoundCache : public ResourceCache { +class SoundCache : public ResourceCache, public Dependency { Q_OBJECT + SINGLETON_DEPENDENCY + public: - static SoundCache& getInstance(); - Q_INVOKABLE SharedSoundPointer getSound(const QUrl& url); protected: diff --git a/libraries/metavoxels/src/Bitstream.cpp b/libraries/metavoxels/src/Bitstream.cpp index 642562bfb5..9c672a415e 100644 --- a/libraries/metavoxels/src/Bitstream.cpp +++ b/libraries/metavoxels/src/Bitstream.cpp @@ -465,9 +465,9 @@ void Bitstream::writeRawDelta(const QScriptValue& value, const QScriptValue& ref } else if (reference.isArray()) { if (value.isArray()) { *this << false; - int length = value.property(ScriptCache::getInstance()->getLengthString()).toInt32(); + int length = value.property(DependencyManager::get()->getLengthString()).toInt32(); *this << length; - int referenceLength = reference.property(ScriptCache::getInstance()->getLengthString()).toInt32(); + int referenceLength = reference.property(DependencyManager::get()->getLengthString()).toInt32(); for (int i = 0; i < length; i++) { if (i < referenceLength) { writeDelta(value.property(i), reference.property(i)); @@ -555,7 +555,7 @@ void Bitstream::readRawDelta(QScriptValue& value, const QScriptValue& reference) } else { QVariant variant; readRawDelta(variant, reference.toVariant()); - value = ScriptCache::getInstance()->getEngine()->newVariant(variant); + value = DependencyManager::get()->getEngine()->newVariant(variant); } } else if (reference.isQObject()) { bool typeChanged; @@ -566,7 +566,7 @@ void Bitstream::readRawDelta(QScriptValue& value, const QScriptValue& reference) } else { QObject* object; readRawDelta(object, reference.toQObject()); - value = ScriptCache::getInstance()->getEngine()->newQObject(object, QScriptEngine::ScriptOwnership); + value = DependencyManager::get()->getEngine()->newQObject(object, QScriptEngine::ScriptOwnership); } } else if (reference.isQMetaObject()) { bool typeChanged; @@ -577,7 +577,7 @@ void Bitstream::readRawDelta(QScriptValue& value, const QScriptValue& reference) } else { const QMetaObject* metaObject; *this >> metaObject; - value = ScriptCache::getInstance()->getEngine()->newQMetaObject(metaObject); + value = DependencyManager::get()->getEngine()->newQMetaObject(metaObject); } } else if (reference.isDate()) { bool typeChanged; @@ -588,7 +588,7 @@ void Bitstream::readRawDelta(QScriptValue& value, const QScriptValue& reference) } else { QDateTime dateTime; *this >> dateTime; - value = ScriptCache::getInstance()->getEngine()->newDate(dateTime); + value = DependencyManager::get()->getEngine()->newDate(dateTime); } } else if (reference.isRegExp()) { bool typeChanged; @@ -599,7 +599,7 @@ void Bitstream::readRawDelta(QScriptValue& value, const QScriptValue& reference) } else { QRegExp regExp; *this >> regExp; - value = ScriptCache::getInstance()->getEngine()->newRegExp(regExp); + value = DependencyManager::get()->getEngine()->newRegExp(regExp); } } else if (reference.isArray()) { bool typeChanged; @@ -610,8 +610,8 @@ void Bitstream::readRawDelta(QScriptValue& value, const QScriptValue& reference) } else { int length; *this >> length; - value = ScriptCache::getInstance()->getEngine()->newArray(length); - int referenceLength = reference.property(ScriptCache::getInstance()->getLengthString()).toInt32(); + value = DependencyManager::get()->getEngine()->newArray(length); + int referenceLength = reference.property(DependencyManager::get()->getLengthString()).toInt32(); for (int i = 0; i < length; i++) { QScriptValue element; if (i < referenceLength) { @@ -630,7 +630,7 @@ void Bitstream::readRawDelta(QScriptValue& value, const QScriptValue& reference) } else { // start by shallow-copying the reference - value = ScriptCache::getInstance()->getEngine()->newObject(); + value = DependencyManager::get()->getEngine()->newObject(); for (QScriptValueIterator it(reference); it.hasNext(); ) { it.next(); value.setProperty(it.scriptName(), it.value()); @@ -1036,7 +1036,7 @@ Bitstream& Bitstream::operator<<(const QScriptValue& value) { } else if (value.isArray()) { writeScriptValueType(*this, ARRAY_SCRIPT_VALUE); - int length = value.property(ScriptCache::getInstance()->getLengthString()).toInt32(); + int length = value.property(DependencyManager::get()->getLengthString()).toInt32(); *this << length; for (int i = 0; i < length; i++) { *this << value.property(i); @@ -1087,37 +1087,37 @@ Bitstream& Bitstream::operator>>(QScriptValue& value) { case VARIANT_SCRIPT_VALUE: { QVariant variantValue; *this >> variantValue; - value = ScriptCache::getInstance()->getEngine()->newVariant(variantValue); + value = DependencyManager::get()->getEngine()->newVariant(variantValue); break; } case QOBJECT_SCRIPT_VALUE: { QObject* object; *this >> object; - ScriptCache::getInstance()->getEngine()->newQObject(object, QScriptEngine::ScriptOwnership); + DependencyManager::get()->getEngine()->newQObject(object, QScriptEngine::ScriptOwnership); break; } case QMETAOBJECT_SCRIPT_VALUE: { const QMetaObject* metaObject; *this >> metaObject; - ScriptCache::getInstance()->getEngine()->newQMetaObject(metaObject); + DependencyManager::get()->getEngine()->newQMetaObject(metaObject); break; } case DATE_SCRIPT_VALUE: { QDateTime dateTime; *this >> dateTime; - value = ScriptCache::getInstance()->getEngine()->newDate(dateTime); + value = DependencyManager::get()->getEngine()->newDate(dateTime); break; } case REGEXP_SCRIPT_VALUE: { QRegExp regExp; *this >> regExp; - value = ScriptCache::getInstance()->getEngine()->newRegExp(regExp); + value = DependencyManager::get()->getEngine()->newRegExp(regExp); break; } case ARRAY_SCRIPT_VALUE: { int length; *this >> length; - value = ScriptCache::getInstance()->getEngine()->newArray(length); + value = DependencyManager::get()->getEngine()->newArray(length); for (int i = 0; i < length; i++) { QScriptValue element; *this >> element; @@ -1126,7 +1126,7 @@ Bitstream& Bitstream::operator>>(QScriptValue& value) { break; } case OBJECT_SCRIPT_VALUE: { - value = ScriptCache::getInstance()->getEngine()->newObject(); + value = DependencyManager::get()->getEngine()->newObject(); forever { QScriptString name; *this >> name; @@ -1477,7 +1477,7 @@ Bitstream& Bitstream::operator>(QScriptString& string) { QString rawString; *this >> rawString; string = (rawString == INVALID_STRING) ? QScriptString() : - ScriptCache::getInstance()->getEngine()->toStringHandle(rawString); + DependencyManager::get()->getEngine()->toStringHandle(rawString); return *this; } @@ -1828,7 +1828,7 @@ QJsonValue JSONWriter::getData(const QScriptValue& value) { } else if (value.isArray()) { object.insert("type", QString("ARRAY")); QJsonArray array; - int length = value.property(ScriptCache::getInstance()->getLengthString()).toInt32(); + int length = value.property(DependencyManager::get()->getLengthString()).toInt32(); for (int i = 0; i < length; i++) { array.append(getData(value.property(i))); } @@ -2209,31 +2209,31 @@ void JSONReader::putData(const QJsonValue& data, QScriptValue& value) { } else if (type == "VARIANT") { QVariant variant; putData(object.value("value"), variant); - value = ScriptCache::getInstance()->getEngine()->newVariant(variant); + value = DependencyManager::get()->getEngine()->newVariant(variant); } else if (type == "QOBJECT") { QObject* qObject; putData(object.value("value"), qObject); - value = ScriptCache::getInstance()->getEngine()->newQObject(qObject, QScriptEngine::ScriptOwnership); + value = DependencyManager::get()->getEngine()->newQObject(qObject, QScriptEngine::ScriptOwnership); } else if (type == "QMETAOBJECT") { const QMetaObject* metaObject; putData(object.value("value"), metaObject); - value = ScriptCache::getInstance()->getEngine()->newQMetaObject(metaObject); + value = DependencyManager::get()->getEngine()->newQMetaObject(metaObject); } else if (type == "DATE") { QDateTime dateTime; putData(object.value("value"), dateTime); - value = ScriptCache::getInstance()->getEngine()->newDate(dateTime); + value = DependencyManager::get()->getEngine()->newDate(dateTime); } else if (type == "REGEXP") { QRegExp regExp; putData(object.value("value"), regExp); - value = ScriptCache::getInstance()->getEngine()->newRegExp(regExp); + value = DependencyManager::get()->getEngine()->newRegExp(regExp); } else if (type == "ARRAY") { QJsonArray array = object.value("value").toArray(); - value = ScriptCache::getInstance()->getEngine()->newArray(array.size()); + value = DependencyManager::get()->getEngine()->newArray(array.size()); for (int i = 0; i < array.size(); i++) { QScriptValue element; putData(array.at(i), element); @@ -2241,7 +2241,7 @@ void JSONReader::putData(const QJsonValue& data, QScriptValue& value) { } } else if (type == "OBJECT") { QJsonObject jsonObject = object.value("value").toObject(); - value = ScriptCache::getInstance()->getEngine()->newObject(); + value = DependencyManager::get()->getEngine()->newObject(); for (QJsonObject::const_iterator it = jsonObject.constBegin(); it != jsonObject.constEnd(); it++) { QScriptValue element; putData(it.value(), element); diff --git a/libraries/metavoxels/src/MetavoxelUtil.cpp b/libraries/metavoxels/src/MetavoxelUtil.cpp index 73900fdcbc..4e86e1c636 100644 --- a/libraries/metavoxels/src/MetavoxelUtil.cpp +++ b/libraries/metavoxels/src/MetavoxelUtil.cpp @@ -663,7 +663,7 @@ void ParameterizedURLEditor::updateURL() { QByteArray valuePropertyName = widget->property("valuePropertyName").toByteArray(); const QMetaObject* widgetMetaObject = widget->metaObject(); QMetaProperty widgetProperty = widgetMetaObject->property(widgetMetaObject->indexOfProperty(valuePropertyName)); - parameters.insert(ScriptCache::getInstance()->getEngine()->toStringHandle( + parameters.insert(DependencyManager::get()->getEngine()->toStringHandle( widget->property("parameterName").toString()), widgetProperty.read(widget)); } } @@ -677,7 +677,7 @@ void ParameterizedURLEditor::updateParameters() { if (_program) { _program->disconnect(this); } - _program = ScriptCache::getInstance()->getProgram(_url.getURL()); + _program = DependencyManager::get()->getProgram(_url.getURL()); if (_program->isLoaded()) { continueUpdatingParameters(); } else { @@ -698,7 +698,7 @@ void ParameterizedURLEditor::continueUpdatingParameters() { } delete form; } - QSharedPointer value = ScriptCache::getInstance()->getValue(_url.getURL()); + QSharedPointer value = DependencyManager::get()->getValue(_url.getURL()); const QList& parameters = static_cast(value.data())->getParameterInfo(); if (parameters.isEmpty()) { return; diff --git a/libraries/metavoxels/src/ScriptCache.cpp b/libraries/metavoxels/src/ScriptCache.cpp index 7e8dbc4bae..b7e81b5381 100644 --- a/libraries/metavoxels/src/ScriptCache.cpp +++ b/libraries/metavoxels/src/ScriptCache.cpp @@ -57,8 +57,8 @@ bool operator==(const QScriptValue& first, const QScriptValue& second) { if (!second.isArray()) { return false; } - int length = first.property(ScriptCache::getInstance()->getLengthString()).toInt32(); - if (second.property(ScriptCache::getInstance()->getLengthString()).toInt32() != length) { + int length = first.property(DependencyManager::get()->getLengthString()).toInt32(); + if (second.property(DependencyManager::get()->getLengthString()).toInt32() != length) { return false; } for (int i = 0; i < length; i++) { @@ -103,11 +103,6 @@ bool operator<(const QScriptValue& first, const QScriptValue& second) { return first.lessThan(second); } -ScriptCache* ScriptCache::getInstance() { - static ScriptCache cache; - return &cache; -} - ScriptCache::ScriptCache() : _engine(NULL) { diff --git a/libraries/metavoxels/src/ScriptCache.h b/libraries/metavoxels/src/ScriptCache.h index 5d29157b3d..b9294a7504 100644 --- a/libraries/metavoxels/src/ScriptCache.h +++ b/libraries/metavoxels/src/ScriptCache.h @@ -25,13 +25,11 @@ class NetworkProgram; class NetworkValue; /// Maintains a cache of loaded scripts. -class ScriptCache : public ResourceCache { +class ScriptCache : public ResourceCache, public Dependency { Q_OBJECT + SINGLETON_DEPENDENCY public: - - static ScriptCache* getInstance(); - ScriptCache(); void setEngine(QScriptEngine* engine); diff --git a/tests/metavoxels/src/MetavoxelTests.cpp b/tests/metavoxels/src/MetavoxelTests.cpp index 106c56b0fe..938b5470e8 100644 --- a/tests/metavoxels/src/MetavoxelTests.cpp +++ b/tests/metavoxels/src/MetavoxelTests.cpp @@ -219,14 +219,14 @@ static QScriptValue createRandomScriptValue(bool complex = false, bool ensureHas case 4: { int length = randIntInRange(2, 6); - QScriptValue value = ScriptCache::getInstance()->getEngine()->newArray(length); + QScriptValue value = DependencyManager::get()->getEngine()->newArray(length); for (int i = 0; i < length; i++) { value.setProperty(i, createRandomScriptValue()); } return value; } default: { - QScriptValue value = ScriptCache::getInstance()->getEngine()->newObject(); + QScriptValue value = DependencyManager::get()->getEngine()->newObject(); if (ensureHashOrder) { // we can't depend on the iteration order, so if we need it to be the same (as when comparing bytes), we // can only have one property @@ -747,7 +747,7 @@ static SharedObjectPointer mutate(const SharedObjectPointer& state) { case 3: { SharedObjectPointer newState = state->clone(true); QScriptValue oldValue = static_cast(newState.data())->getBizzle(); - QScriptValue newValue = ScriptCache::getInstance()->getEngine()->newObject(); + QScriptValue newValue = DependencyManager::get()->getEngine()->newObject(); for (QScriptValueIterator it(oldValue); it.hasNext(); ) { it.next(); newValue.setProperty(it.scriptName(), it.value()); @@ -755,8 +755,8 @@ static SharedObjectPointer mutate(const SharedObjectPointer& state) { switch (randIntInRange(0, 2)) { case 0: { QScriptValue oldArray = oldValue.property("foo"); - int oldLength = oldArray.property(ScriptCache::getInstance()->getLengthString()).toInt32(); - QScriptValue newArray = ScriptCache::getInstance()->getEngine()->newArray(oldLength); + int oldLength = oldArray.property(DependencyManager::get()->getLengthString()).toInt32(); + QScriptValue newArray = DependencyManager::get()->getEngine()->newArray(oldLength); for (int i = 0; i < oldLength; i++) { newArray.setProperty(i, oldArray.property(i)); } @@ -1203,8 +1203,8 @@ TestSharedObjectA::TestSharedObjectA(float foo, TestEnum baz, TestFlags bong) : _bong(bong) { sharedObjectsCreated++; - _bizzle = ScriptCache::getInstance()->getEngine()->newObject(); - _bizzle.setProperty("foo", ScriptCache::getInstance()->getEngine()->newArray(4)); + _bizzle = DependencyManager::get()->getEngine()->newObject(); + _bizzle.setProperty("foo", DependencyManager::get()->getEngine()->newArray(4)); } TestSharedObjectA::~TestSharedObjectA() { From cfbf8fdca763d812eb4bd52e121f7fcf03122c33 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 13 Feb 2015 16:19:10 -0800 Subject: [PATCH 092/103] explicit cleanup of loaded model animations in Application dtor --- interface/src/Application.cpp | 3 +++ libraries/entities/src/ModelEntityItem.cpp | 10 ---------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1e94d79457..cee5404287 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -65,6 +65,7 @@ #include #include #include +#include #include #include #include @@ -565,6 +566,8 @@ Application::~Application() { Menu::getInstance()->deleteLater(); _myAvatar = NULL; + + ModelEntityItem::cleanupLoadedAnimations() ; DependencyManager::destroy(); DependencyManager::destroy(); diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 4d8e741cc6..ed76b8c99f 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -163,16 +163,6 @@ void ModelEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit QMap ModelEntityItem::_loadedAnimations; // TODO: improve cleanup by leveraging the AnimationPointer(s) -// This class/instance will cleanup the animations once unloaded. -class EntityAnimationsBookkeeper { -public: - ~EntityAnimationsBookkeeper() { - ModelEntityItem::cleanupLoadedAnimations(); - } -}; - -EntityAnimationsBookkeeper modelAnimationsBookkeeperInstance; - void ModelEntityItem::cleanupLoadedAnimations() { foreach(AnimationPointer animation, _loadedAnimations) { animation.clear(); From 573d7971ac393a2aed2512984f1bfd26005c6129 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 13 Feb 2015 20:23:12 -0800 Subject: [PATCH 093/103] fix a couple of bugs in backup settings --- libraries/octree/src/OctreePersistThread.cpp | 92 +++++++++++++------- 1 file changed, 61 insertions(+), 31 deletions(-) diff --git a/libraries/octree/src/OctreePersistThread.cpp b/libraries/octree/src/OctreePersistThread.cpp index b247f88059..2a563dc50a 100644 --- a/libraries/octree/src/OctreePersistThread.cpp +++ b/libraries/octree/src/OctreePersistThread.cpp @@ -49,14 +49,32 @@ void OctreePersistThread::parseSettings(const QJsonObject& settings) { qDebug() << "BACKUP RULES:"; foreach (const QJsonValue& value, backupRules) { + QJsonObject obj = value.toObject(); + + int interval = 0; + int count = 0; + + QJsonValue intervalVal = obj["backupInterval"]; + if (intervalVal.isString()) { + interval = intervalVal.toString().toInt(); + } else { + interval = intervalVal.toInt(); + } + + QJsonValue countVal = obj["maxBackupVersions"]; + if (countVal.isString()) { + count = countVal.toString().toInt(); + } else { + count = countVal.toInt(); + } + qDebug() << " Name:" << obj["Name"].toString(); qDebug() << " format:" << obj["format"].toString(); - qDebug() << " interval:" << obj["backupInterval"].toInt(); - qDebug() << " count:" << obj["maxBackupVersions"].toInt(); + qDebug() << " interval:" << interval; + qDebug() << " count:" << count; - BackupRule newRule = { obj["Name"].toString(), obj["backupInterval"].toInt(), - obj["format"].toString(), obj["maxBackupVersions"].toInt(), 0}; + BackupRule newRule = { obj["Name"].toString(), interval, obj["format"].toString(), count, 0}; newRule.lastBackup = getMostRecentBackupTimeInUsecs(obj["format"].toString()); @@ -321,29 +339,35 @@ bool OctreePersistThread::getMostRecentBackup(const QString& format, void OctreePersistThread::rollOldBackupVersions(const BackupRule& rule) { if (rule.extensionFormat.contains("%N")) { - qDebug() << "Rolling old backup versions for rule" << rule.name << "..."; - for(int n = rule.maxBackupVersions - 1; n > 0; n--) { - QString backupExtensionN = rule.extensionFormat; - QString backupExtensionNplusOne = rule.extensionFormat; - backupExtensionN.replace(QString("%N"), QString::number(n)); - backupExtensionNplusOne.replace(QString("%N"), QString::number(n+1)); + if (rule.maxBackupVersions > 0) { + qDebug() << "Rolling old backup versions for rule" << rule.name << "..."; + for(int n = rule.maxBackupVersions - 1; n > 0; n--) { + QString backupExtensionN = rule.extensionFormat; + QString backupExtensionNplusOne = rule.extensionFormat; + backupExtensionN.replace(QString("%N"), QString::number(n)); + backupExtensionNplusOne.replace(QString("%N"), QString::number(n+1)); - QString backupFilenameN = _filename + backupExtensionN; - QString backupFilenameNplusOne = _filename + backupExtensionNplusOne; + QString backupFilenameN = _filename + backupExtensionN; + QString backupFilenameNplusOne = _filename + backupExtensionNplusOne; - QFile backupFileN(backupFilenameN); + QFile backupFileN(backupFilenameN); - if (backupFileN.exists()) { - qDebug() << "rolling backup file " << backupFilenameN << "to" << backupFilenameNplusOne << "..."; - int result = rename(qPrintable(backupFilenameN), qPrintable(backupFilenameNplusOne)); - if (result == 0) { - qDebug() << "DONE rolling backup file " << backupFilenameN << "to" << backupFilenameNplusOne << "..."; - } else { - qDebug() << "ERROR in rolling backup file " << backupFilenameN << "to" << backupFilenameNplusOne << "..."; + if (backupFileN.exists()) { + qDebug() << "rolling backup file " << backupFilenameN << "to" << backupFilenameNplusOne << "..."; + int result = rename(qPrintable(backupFilenameN), qPrintable(backupFilenameNplusOne)); + if (result == 0) { + qDebug() << "DONE rolling backup file " << backupFilenameN << "to" << backupFilenameNplusOne << "..."; + } else { + qDebug() << "ERROR in rolling backup file " << backupFilenameN << "to" << backupFilenameNplusOne << "..."; + } } } + qDebug() << "Done rolling old backup versions..."; + } else { + qDebug() << "Rolling backups for rule" << rule.name << "." + << " Max Rolled Backup Versions less than 1 [" << rule.maxBackupVersions << "]." + << " No need to roll backups..."; } - qDebug() << "Done rolling old backup versions..."; } } @@ -384,19 +408,25 @@ void OctreePersistThread::backup() { } - QFile persistFile(_filename); - if (persistFile.exists()) { - qDebug() << "backing up persist file " << _filename << "to" << backupFileName << "..."; - bool result = QFile::copy(_filename, backupFileName); - if (result) { - qDebug() << "DONE backing up persist file..."; - rule.lastBackup = now; // only record successful backup in this case. + if (rule.maxBackupVersions > 0) { + QFile persistFile(_filename); + if (persistFile.exists()) { + qDebug() << "backing up persist file " << _filename << "to" << backupFileName << "..."; + bool result = QFile::copy(_filename, backupFileName); + if (result) { + qDebug() << "DONE backing up persist file..."; + rule.lastBackup = now; // only record successful backup in this case. + } else { + qDebug() << "ERROR in backing up persist file..."; + } } else { - qDebug() << "ERROR in backing up persist file..."; + qDebug() << "persist file " << _filename << " does not exist. " << + "nothing to backup for this rule ["<< rule.name << "]..."; } } else { - qDebug() << "persist file " << _filename << " does not exist. " << - "nothing to backup for this rule ["<< rule.name << "]..."; + qDebug() << "This backup rule" << rule.name + << " has Max Rolled Backup Versions less than 1 [" << rule.maxBackupVersions << "]." + << " There are no backups to be done..."; } } else { qDebug() << "Backup not needed for this rule ["<< rule.name << "]..."; From 20b0dee80c0d5b219c5f009ee1a01fec743f308e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 16 Feb 2015 12:07:22 -0800 Subject: [PATCH 094/103] add a NULL initializer for the linked data create callback --- libraries/networking/src/LimitedNodeList.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 13bb2b1ad8..43f4dda565 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -39,6 +39,7 @@ const char SOLO_NODE_TYPES[2] = { const QUrl DEFAULT_NODE_AUTH_URL = QUrl("https://metaverse.highfidelity.io"); LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short dtlsListenPort) : + linkedDataCreateCallback(NULL), _sessionUUID(), _nodeHash(), _nodeMutex(QReadWriteLock::Recursive), From 42e4eee15e93db6797fbfacd443eeaab0f0c0c55 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Mon, 16 Feb 2015 23:14:27 +0100 Subject: [PATCH 095/103] audio meter background "back in black" / "paint it black" --- interface/src/ui/ApplicationOverlay.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index f9437221e5..0805373ba6 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -789,7 +789,7 @@ void ApplicationOverlay::renderAudioMeter() { // Audio VU Meter and Mute Icon const int MUTE_ICON_SIZE = 24; const int MUTE_ICON_PADDING = 10; - const int AUDIO_METER_WIDTH = MIRROR_VIEW_WIDTH - MUTE_ICON_SIZE - MUTE_ICON_PADDING; + const int AUDIO_METER_WIDTH = MIRROR_VIEW_WIDTH - MUTE_ICON_SIZE - MUTE_ICON_PADDING; const int AUDIO_METER_SCALE_WIDTH = AUDIO_METER_WIDTH - 2 ; const int AUDIO_METER_HEIGHT = 8; const int AUDIO_METER_GAP = 5; @@ -845,8 +845,8 @@ void ApplicationOverlay::renderAudioMeter() { audioMeterY += AUDIO_METER_HEIGHT; // Draw audio meter background Quad - DependencyManager::get()->renderQuad(AUDIO_METER_X, audioMeterY, AUDIO_METER_WIDTH, AUDIO_METER_HEIGHT, - glm::vec4(0.298f, 0.757f, 0.722f, 1)); + DependencyManager::get()->renderQuad(AUDIO_METER_X, audioMeterY, AUDIO_METER_WIDTH, AUDIO_METER_HEIGHT, + glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); if (audioLevel > AUDIO_RED_START) { glm::vec4 quadColor; From 4a3550ce0e5d428ba5f4fcd5a9c5e91b8a3d69aa Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Tue, 17 Feb 2015 02:27:07 +0100 Subject: [PATCH 096/103] toggleQAction(); in constructor to make the right initial button connection --- interface/src/ui/LoginDialog.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/src/ui/LoginDialog.cpp b/interface/src/ui/LoginDialog.cpp index 049e5bd1cd..99b60fc232 100644 --- a/interface/src/ui/LoginDialog.cpp +++ b/interface/src/ui/LoginDialog.cpp @@ -41,6 +41,9 @@ LoginDialog::LoginDialog(QWidget* parent) : this, &LoginDialog::handleLoginClicked); connect(_ui->closeButton, &QPushButton::clicked, this, &LoginDialog::close); + + // Initialize toggle connection + toggleQAction(); }; LoginDialog::~LoginDialog() { From d1f7a730ad87610a19e9976b151e2919a7e791c2 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 17 Feb 2015 08:23:11 -0800 Subject: [PATCH 097/103] Make add-model button non-selectable --- examples/editEntities.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/editEntities.js b/examples/editEntities.js index c6ec5a7f0a..8dbf64a7ae 100644 --- a/examples/editEntities.js +++ b/examples/editEntities.js @@ -127,7 +127,7 @@ var toolBar = (function () { height: toolHeight, alpha: 0.9, visible: true - }, true, false); + }); browseModelsButton = toolBar.addTool({ imageURL: toolIconUrl + "list-icon.svg", From 97e70920cefe2775f55c6e295294bd404f16d61d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 17 Feb 2015 08:23:39 -0800 Subject: [PATCH 098/103] Move handling of add model buttons to mouseRelease --- examples/editEntities.js | 48 +++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/examples/editEntities.js b/examples/editEntities.js index 8dbf64a7ae..61100b4556 100644 --- a/examples/editEntities.js +++ b/examples/editEntities.js @@ -262,6 +262,8 @@ var toolBar = (function () { toolBar.move(toolsX, toolsY); }; + var newModelButtonDown = false; + var browseModelsButtonDown = false; that.mousePressEvent = function (event) { var clickedOverlay, url, @@ -274,19 +276,14 @@ var toolBar = (function () { return true; } + // Handle these two buttons in the mouseRelease event handler so that we don't suppress a mouseRelease event from + // occurring when showing a modal dialog. if (newModelButton === toolBar.clicked(clickedOverlay)) { - url = Window.prompt("Model URL", modelURLs[Math.floor(Math.random() * modelURLs.length)]); - if (url !== null && url !== "") { - addModel(url); - } + newModelButtonDown = true; return true; } - if (browseModelsButton === toolBar.clicked(clickedOverlay)) { - url = Window.s3Browse(".*(fbx|FBX)"); - if (url !== null && url !== "") { - addModel(url); - } + browseModelsButtonDown = true; return true; } @@ -348,6 +345,7 @@ var toolBar = (function () { return true; } + if (newTextButton === toolBar.clicked(clickedOverlay)) { var position = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), SPAWN_DISTANCE)); @@ -367,10 +365,37 @@ var toolBar = (function () { return true; } - return false; }; + that.mouseReleaseEvent = function(event) { + var handled = false; + if (newModelButtonDown) { + var clickedOverlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y }); + if (newModelButton === toolBar.clicked(clickedOverlay)) { + url = Window.prompt("Model URL", modelURLs[Math.floor(Math.random() * modelURLs.length)]); + if (url !== null && url !== "") { + addModel(url); + } + handled = true; + } + } else if (browseModelsButtonDown) { + var clickedOverlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y }); + if (browseModelsButton === toolBar.clicked(clickedOverlay)) { + url = Window.s3Browse(".*(fbx|FBX)"); + if (url !== null && url !== "") { + addModel(url); + } + handled = true; + } + } + + newModelButtonDown = false; + browseModelsButtonDown = false; + + return handled; + } + that.cleanup = function () { toolBar.cleanup(); }; @@ -533,6 +558,9 @@ function highlightEntityUnderCursor(position, accurateRay) { function mouseReleaseEvent(event) { + if (toolBar.mouseReleaseEvent(event)) { + return true; + } if (placingEntityID) { if (isActive) { selectionManager.setSelections([placingEntityID]); From dd64eeb282d832d0e8425becb1ad2d47c70e23ca Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 17 Feb 2015 11:47:29 -0800 Subject: [PATCH 099/103] fix uninitialized geometry cache id in Line3DOverlay --- interface/src/ui/overlays/Line3DOverlay.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/Line3DOverlay.cpp b/interface/src/ui/overlays/Line3DOverlay.cpp index d2bfa1955b..6672a88e45 100644 --- a/interface/src/ui/overlays/Line3DOverlay.cpp +++ b/interface/src/ui/overlays/Line3DOverlay.cpp @@ -17,7 +17,9 @@ #include "Line3DOverlay.h" -Line3DOverlay::Line3DOverlay() { +Line3DOverlay::Line3DOverlay() : + _geometryCacheID(DependencyManager::get()->allocateID()) +{ } Line3DOverlay::Line3DOverlay(const Line3DOverlay* line3DOverlay) : From 9fcb7591e6df784a2cae1e44fea543ba5dc74885 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 17 Feb 2015 14:52:20 -0800 Subject: [PATCH 100/103] don't crash if font load fails --- libraries/render-utils/src/TextRenderer.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/libraries/render-utils/src/TextRenderer.cpp b/libraries/render-utils/src/TextRenderer.cpp index fb720b3040..ce694ec835 100644 --- a/libraries/render-utils/src/TextRenderer.cpp +++ b/libraries/render-utils/src/TextRenderer.cpp @@ -511,6 +511,9 @@ TextRenderer::TextRenderer(const char* family, float pointSize, int weight, bool italic, EffectType effect, int effectThickness, const QColor& color) : _effectType(effect), _effectThickness(effectThickness), _pointSize(pointSize), _color(color), _font(loadFont(family)) { + if (!_font) { + qWarning() << "Unable to load font with family " << family; + } if (1 != _effectThickness) { qWarning() << "Effect thickness not current supported"; } @@ -524,7 +527,10 @@ TextRenderer::~TextRenderer() { glm::vec2 TextRenderer::computeExtent(const QString & str) const { float scale = (_pointSize / DEFAULT_POINT_SIZE) * 0.25f; - return _font->computeExtent(str) * scale; + if (_font) { + return _font->computeExtent(str) * scale; + } + return glm::vec2(0.1f,0.1f); } float TextRenderer::draw(float x, float y, const QString & str, @@ -544,7 +550,9 @@ float TextRenderer::draw(float x, float y, const QString & str, // scale at all. mv.translate(glm::vec2(x, y)).scale(glm::vec3(scale, -scale, scale)); // The font does all the OpenGL work - result = _font->drawString(x, y, str, actualColor, _effectType, bounds / scale); + if (_font) { + result = _font->drawString(x, y, str, actualColor, _effectType, bounds / scale); + } }); return result.x; } From ef2d386c75569c56942fe2f452a10a8b7fae7ab2 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 17 Feb 2015 15:12:24 -0800 Subject: [PATCH 101/103] attempt to load Courier if the requested font-family fails to load --- libraries/render-utils/src/TextRenderer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/render-utils/src/TextRenderer.cpp b/libraries/render-utils/src/TextRenderer.cpp index ce694ec835..9238db91e3 100644 --- a/libraries/render-utils/src/TextRenderer.cpp +++ b/libraries/render-utils/src/TextRenderer.cpp @@ -513,6 +513,7 @@ TextRenderer::TextRenderer(const char* family, float pointSize, int weight, _effectType(effect), _effectThickness(effectThickness), _pointSize(pointSize), _color(color), _font(loadFont(family)) { if (!_font) { qWarning() << "Unable to load font with family " << family; + _font = loadFont("Courier"); } if (1 != _effectThickness) { qWarning() << "Effect thickness not current supported"; From 8c7e147b82423790ba0c6699eb5d963f878cf740 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 17 Feb 2015 15:16:03 -0800 Subject: [PATCH 102/103] include debug symbols --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b6eb3b935e..bc67d622de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,7 +40,7 @@ if (WIN32) elseif (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) #SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic") #SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-unknown-pragmas") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-strict-aliasing") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-strict-aliasing -ggdb") endif(WIN32) if (NOT MSVC12) From f7cc7ad7e7471165ef43c646b04475ae71da2f0b Mon Sep 17 00:00:00 2001 From: Grayson Stebbins Date: Tue, 17 Feb 2015 17:14:47 -0800 Subject: [PATCH 103/103] Added note about running inside visual studio --- BUILD_WIN.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BUILD_WIN.md b/BUILD_WIN.md index 6f26e8c809..f5bc3e09b5 100644 --- a/BUILD_WIN.md +++ b/BUILD_WIN.md @@ -163,6 +163,8 @@ We recommend you install it to %HIFI_LIB_DIR%\soxr. This will help our FindSoxr Extract the soxr archive wherever you like. Then, inside the extracted folder, create a directory called `build`. From that build directory, the following commands will build and then install soxr to `%HIFI_LIB_DIR%`. +(Make sure to run the following inside Visual Studio) + ``` cmake .. -G "NMake Makefiles" -DCMAKE_INSTALL_PREFIX=%HIFI_LIB_DIR%/soxr nmake