diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 4755d9137a..b66226e1a5 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -47,6 +47,7 @@ Agent::Agent(const QByteArray& packet) : _scriptEngine.getEntityScriptingInterface()->setPacketSender(&_entityEditSender); DependencyManager::set(); + DependencyManager::set(); } void Agent::readPendingDatagrams() { diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index 80f3cbab5e..bf67d4d597 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -136,7 +136,6 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : // Create Singleton objects on main thread NetworkAccessManager::getInstance(); - auto soundCache = DependencyManager::get(); } void AssignmentClient::sendAssignmentRequest() { diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index b862cd0c78..e865ab0035 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -479,10 +479,20 @@ void AudioMixer::sendAudioEnvironmentPacket(SharedNodePointer node) { for (int i = 0; i < _zoneReverbSettings.size(); ++i) { AudioMixerClientData* data = static_cast(node->getLinkedData()); glm::vec3 streamPosition = data->getAvatarAudioStream()->getPosition(); - if (_audioZones[_zoneReverbSettings[i].zone].contains(streamPosition)) { + AABox box = _audioZones[_zoneReverbSettings[i].zone]; + if (box.contains(streamPosition)) { hasReverb = true; reverbTime = _zoneReverbSettings[i].reverbTime; wetLevel = _zoneReverbSettings[i].wetLevel; + + // Modulate wet level with distance to wall + float MIN_ATTENUATION_DISTANCE = 2.0f; + float MAX_ATTENUATION = -12; // dB + glm::vec3 distanceToWalls = (box.getDimensions() / 2.0f) - glm::abs(streamPosition - box.calcCenter()); + float distanceToClosestWall = glm::min(distanceToWalls.x, distanceToWalls.z); + if (distanceToClosestWall < MIN_ATTENUATION_DISTANCE) { + wetLevel += MAX_ATTENUATION * (1.0f - distanceToClosestWall / MIN_ATTENUATION_DISTANCE); + } break; } } diff --git a/cmake/externals/gverb/CMakeLists.txt b/cmake/externals/gverb/CMakeLists.txt index 19a44781b1..a73b192fee 100644 --- a/cmake/externals/gverb/CMakeLists.txt +++ b/cmake/externals/gverb/CMakeLists.txt @@ -8,7 +8,7 @@ include(ExternalProject) ExternalProject_Add( ${EXTERNAL_NAME} PREFIX ${EXTERNAL_NAME} - GIT_REPOSITORY https://github.com/birarda/gverb.git + URL http://hifi-public.s3.amazonaws.com/dependencies/gverb-master.zip CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX:PATH= LOG_DOWNLOAD ON ) diff --git a/examples/controllers/oculus/goTo.js b/examples/controllers/oculus/goTo.js index 91ae8e6141..5a5c3429ed 100644 --- a/examples/controllers/oculus/goTo.js +++ b/examples/controllers/oculus/goTo.js @@ -18,6 +18,7 @@ Script.include("../../libraries/globals.js"); Script.include("../../libraries/virtualKeyboard.js"); +Script.include("../../libraries/soundArray.js"); const MAX_SHOW_INSTRUCTION_TIMES = 2; const INSTRUCTIONS_SETTING = "GoToInstructionsShowCounter" @@ -82,6 +83,12 @@ var textFontSize = 9; var text = null; var locationURL = ""; +var randomSounds = new SoundArray({}, true); +var numberOfSounds = 7; +for (var i = 1; i <= numberOfSounds; i++) { + randomSounds.addSound(HIFI_PUBLIC_BUCKET + "sounds/UI/virtualKeyboard-press" + i + ".raw"); +} + function appendChar(char) { locationURL += char; updateTextOverlay(); @@ -107,6 +114,7 @@ function updateTextOverlay() { } keyboard.onKeyPress = function(event) { + randomSounds.playRandom(); if (event.event == 'keypress') { appendChar(event.char); } diff --git a/examples/controllers/oculus/virtualKeyboardTextEntityExample.js b/examples/controllers/oculus/virtualKeyboardTextEntityExample.js index c3cb3c6316..cf36fdbffb 100644 --- a/examples/controllers/oculus/virtualKeyboardTextEntityExample.js +++ b/examples/controllers/oculus/virtualKeyboardTextEntityExample.js @@ -17,6 +17,7 @@ Script.include("../../libraries/globals.js"); Script.include("../../libraries/virtualKeyboard.js"); +Script.include("../../libraries/soundArray.js"); const SPAWN_DISTANCE = 1; const DEFAULT_TEXT_DIMENSION_Z = 0.02; @@ -34,6 +35,12 @@ var text = null; var textText = ""; var textSizeMeasureOverlay = Overlays.addOverlay("text3d", {visible: false}); +var randomSounds = new SoundArray({}, true); +var numberOfSounds = 7; +for (var i = 1; i <= numberOfSounds; i++) { + randomSounds.addSound(HIFI_PUBLIC_BUCKET + "sounds/UI/virtualKeyboard-press" + i + ".raw"); +} + function appendChar(char) { textText += char; updateTextOverlay(); @@ -58,6 +65,7 @@ function updateTextOverlay() { } keyboard.onKeyPress = function(event) { + randomSounds.playRandom(); if (event.event == 'keypress') { appendChar(event.char); } else if (event.event == 'enter') { diff --git a/examples/libraries/soundArray.js b/examples/libraries/soundArray.js new file mode 100644 index 0000000000..813621fb4b --- /dev/null +++ b/examples/libraries/soundArray.js @@ -0,0 +1,42 @@ +/** + * An array for sounds, allows you to randomly play a sound + * taken from the removed editVoxels.js + */ +SoundArray = function(audioOptions, autoUpdateAudioPosition) { + this.audioOptions = audioOptions !== undefined ? audioOptions : {}; + this.autoUpdateAudioPosition = autoUpdateAudioPosition !== undefined ? autoUpdateAudioPosition : false; + if (this.audioOptions.position === undefined) { + this.audioOptions.position = Vec3.sum(MyAvatar.position, { x: 0, y: 1, z: 0}), + } + if (this.audioOptions.volume === undefined) { + this.audioOptions.volume = 1.0; + } + this.sounds = new Array(); + this.addSound = function (soundURL) { + this.sounds[this.sounds.length] = SoundCache.getSound(soundURL); + }; + this.play = function (index) { + if (0 <= index && index < this.sounds.length) { + if (this.autoUpdateAudioPosition) { + this.updateAudioPosition(); + } + if (this.sounds[index].downloaded) { + Audio.playSound(this.sounds[index], this.audioOptions); + } + } else { + print("[ERROR] libraries/soundArray.js:play() : Index " + index + " out of range."); + } + }; + this.playRandom = function () { + if (this.sounds.length > 0) { + this.play(Math.floor(Math.random() * this.sounds.length)); + } else { + print("[ERROR] libraries/soundArray.js:playRandom() : Array is empty."); + } + }; + this.updateAudioPosition = function() { + var position = MyAvatar.position; + var forwardVector = Quat.getFront(MyAvatar.orientation); + this.audioOptions.position = Vec3.sum(position, forwardVector); + }; +}; diff --git a/examples/notifications.js b/examples/notifications.js index 1b512634d7..287bfd0b36 100644 --- a/examples/notifications.js +++ b/examples/notifications.js @@ -1,13 +1,13 @@ -// -// notifications.js -// Version 0.801 -// Created by Adrian +// +// notifications.js +// Version 0.801 +// Created by Adrian // // Adrian McCarlie 8-10-14 // This script demonstrates on-screen overlay type notifications. // 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 @@ -20,29 +20,29 @@ // CTRL/m for mic mute and unmute. // System generated notifications: -// Displays users online at startup. +// Displays users online at startup. // If Screen is resized. // Triggers notification if @MyUserName is mentioned in chat. // Announces existing user logging out. // Announces new user logging in. // If mic is muted for any reason. -// +// // To add a new System notification type: // -// 1. Set the Event Connector at the bottom of the script. -// example: +// 1. Set the Event Connector at the bottom of the script. +// example: // GlobalServices.incomingMessage.connect(onIncomingMessage); // -// 2. Create a new function to produce a text string, do not include new line returns. +// 2. Create a new function to produce a text string, do not include new line returns. // example: // function onIncomingMessage(user, message) { -// //do stuff here; +// //do stuff here; // var text = "This is a notification"; // wordWrap(text); // } // // This new function must call wordWrap(text) if the length of message is longer than 42 chars or unknown. -// wordWrap() will format the text to fit the notifications overlay and send it to createNotification(text). +// wordWrap() will format the text to fit the notifications overlay and send it to createNotification(text). // If the message is 42 chars or less you should bypass wordWrap() and call createNotification() directly. @@ -57,6 +57,8 @@ // var welcome = "There are " + GlobalServices.onlineUsers.length + " users online now."; // createNotification(welcome); // } +Script.include("./libraries/globals.js"); +Script.include("./libraries/soundArray.js"); var width = 340.0; //width of notification overlay var windowDimensions = Controller.getViewportDimensions(); // get the size of the interface window @@ -66,7 +68,7 @@ var locationY = 20.0; // position down from top of interface window var topMargin = 13.0; var leftMargin = 10.0; var textColor = { red: 228, green: 228, blue: 228}; // text color -var backColor = { red: 2, green: 2, blue: 2}; // background color was 38,38,38 +var backColor = { red: 2, green: 2, blue: 2}; // background color was 38,38,38 var backgroundAlpha = 0; var fontSize = 12.0; var PERSIST_TIME_2D = 10.0; // Time in seconds before notification fades @@ -81,6 +83,22 @@ var last_users = GlobalServices.onlineUsers; var users = []; var ctrlIsPressed = false; var ready = true; + +var randomSounds = new SoundArray({}, true); +var numberOfSounds = 2; +for (var i = 1; i <= numberOfSounds; i++) { + randomSounds.addSound(HIFI_PUBLIC_BUCKET + "sounds/UI/notification-general" + i + ".raw"); +} + +// When our script shuts down, we should clean up all of our overlays +function scriptEnding() { + for (i = 0; i < notifications.length; i++) { + Overlays.deleteOverlay(notifications[i]); + Overlays.deleteOverlay(buttons[i]); + } +} +Script.scriptEnding.connect(scriptEnding); + var notifications = []; var buttons = []; var times = []; @@ -193,6 +211,8 @@ function notify(notice, button, height) { positions, last; + randomSounds.playRandom(); + if (isOnHMD) { // Calculate 3D values from 2D overlay properties. @@ -454,7 +474,6 @@ function onOnlineUsersChanged(users) { if (last_users.indexOf(users[i]) === -1.0) { createNotification(users[i] + " has joined"); } - } for (i = 0; i < last_users.length; i += 1) { diff --git a/examples/progress.js b/examples/progress.js index 6ee53c55e6..55ea15f218 100644 --- a/examples/progress.js +++ b/examples/progress.js @@ -13,9 +13,13 @@ (function () { - var progress = 100, // % + var rawProgress = 100, // % raw value. + displayProgress = 100, // % smoothed value to display. + DISPLAY_PROGRESS_MINOR_MAXIMUM = 8, // % displayed progress bar goes up to while 0% raw progress. + DISPLAY_PROGRESS_MINOR_INCREMENT = 0.1, // % amount to increment display value each update when 0% raw progress. + DISPLAY_PROGRESS_MAJOR_INCREMENT = 5, // % maximum amount to increment display value when >0% raw progress. alpha = 0.0, - alphaDelta = 0.0, // > 0 if fading in; < 0 if fading out/ + alphaDelta = 0.0, // > 0 if fading in; < 0 if fading out. ALPHA_DELTA_IN = 0.15, ALPHA_DELTA_OUT = -0.02, fadeTimer = null, @@ -23,18 +27,18 @@ fadeWaitTimer = null, FADE_OUT_WAIT = 1000, // Wait before starting to fade out after progress 100%. visible = false, - BAR_WIDTH = 320, // Nominal dimension of SVG in pixels of visible portion (half) of the bar. - BAR_HEIGHT = 20, + BAR_WIDTH = 480, // Dimension of SVG in pixels of visible portion (half) of the bar. + BAR_HEIGHT = 30, BAR_URL = "http://hifi-public.s3.amazonaws.com/images/progress-bar.svg", - BACKGROUND_WIDTH = 360, - BACKGROUND_HEIGHT = 60, + BACKGROUND_WIDTH = 540, + BACKGROUND_HEIGHT = 90, BACKGROUND_URL = "http://hifi-public.s3.amazonaws.com/images/progress-bar-background.svg", isOnHMD = false, windowWidth = 0, windowHeight = 0, background2D = {}, bar2D = {}, - SCALE_2D = 0.55, // Scale the SVGs for 2D display. + SCALE_2D = 0.35, // Scale the SVGs for 2D display. background3D = {}, bar3D = {}, ENABLE_VR_MODE_MENU_ITEM = "Enable VR Mode", @@ -43,7 +47,7 @@ PROGRESS_3D_ELEVATION = -0.8, // Height of top middle of top notification relative to avatar eyes. PROGRESS_3D_YAW = 0.0, // Degrees relative to notifications direction. PROGRESS_3D_PITCH = -60.0, // Degrees from vertical. - SCALE_3D = 0.0017, // Scale the bar SVG for 3D display. + SCALE_3D = 0.0011, // Scale the bar SVG for 3D display. BACKGROUND_3D_SIZE = { x: 0.76, y: 0.08 }, // Match up with the 3D background with those of notifications.js notices. BACKGROUND_3D_COLOR = { red: 2, green: 2, blue: 2 }, BACKGROUND_3D_ALPHA = 0.7; @@ -89,56 +93,15 @@ function onDownloadInfoChanged(info) { var i; - // Calculate progress + // Update raw progress value if (info.downloading.length + info.pending === 0) { - progress = 100; + rawProgress = 100; } else { - progress = 0; + rawProgress = 0; for (i = 0; i < info.downloading.length; i += 1) { - progress += info.downloading[i]; + rawProgress += info.downloading[i]; } - progress = progress / (info.downloading.length + info.pending); - } - - // Update state - if (!visible) { // Not visible because no recent downloads - if (progress < 100) { // Have started downloading so fade in - visible = true; - alphaDelta = ALPHA_DELTA_IN; - fadeTimer = Script.setInterval(fade, FADE_INTERVAL); - } - } else if (alphaDelta !== 0.0) { // Fading in or out - if (alphaDelta > 0) { - if (progress === 100) { // Was donloading but now have finished so fade out - alphaDelta = ALPHA_DELTA_OUT; - } - } else { - if (progress < 100) { // Was finished downloading but have resumed so fade in - alphaDelta = ALPHA_DELTA_IN; - } - } - } else { // Fully visible because downloading or recently so - if (fadeWaitTimer === null) { - if (progress === 100) { // Was downloading but have finished so fade out soon - fadeWaitTimer = Script.setTimeout(function () { - alphaDelta = ALPHA_DELTA_OUT; - fadeTimer = Script.setInterval(fade, FADE_INTERVAL); - fadeWaitTimer = null; - }, FADE_OUT_WAIT); - } - } else { - if (progress < 100) { // Was finished and waiting to fade out but have resumed downloading so don't fade out - Script.clearInterval(fadeWaitTimer); - fadeWaitTimer = null; - } - } - } - - // Update progress bar - if (visible) { - Overlays.editOverlay(isOnHMD ? bar3D.overlay : bar2D.overlay, { - subImage: { x: BAR_WIDTH * (1 - progress / 100), y: 0, width: BAR_WIDTH, height: BAR_HEIGHT } - }); + rawProgress = rawProgress / (info.downloading.length + info.pending); } } @@ -200,7 +163,58 @@ createOverlays(); } + // Calculate progress value to display + if (rawProgress === 0 && displayProgress <= DISPLAY_PROGRESS_MINOR_MAXIMUM) { + displayProgress = Math.min(displayProgress + DISPLAY_PROGRESS_MINOR_INCREMENT, DISPLAY_PROGRESS_MINOR_MAXIMUM); + } else if (rawProgress < displayProgress) { + displayProgress = rawProgress; + } else if (rawProgress > displayProgress) { + displayProgress = Math.min(rawProgress, displayProgress + DISPLAY_PROGRESS_MAJOR_INCREMENT); + } // else (rawProgress === displayProgress); do nothing. + + // Update state + if (!visible) { // Not visible because no recent downloads + if (displayProgress < 100) { // Have started downloading so fade in + visible = true; + alphaDelta = ALPHA_DELTA_IN; + fadeTimer = Script.setInterval(fade, FADE_INTERVAL); + } + } else if (alphaDelta !== 0.0) { // Fading in or out + if (alphaDelta > 0) { + if (displayProgress === 100) { // Was downloading but now have finished so fade out + alphaDelta = ALPHA_DELTA_OUT; + } + } else { + if (displayProgress < 100) { // Was finished downloading but have resumed so fade in + alphaDelta = ALPHA_DELTA_IN; + } + } + } else { // Fully visible because downloading or recently so + if (fadeWaitTimer === null) { + if (displayProgress === 100) { // Was downloading but have finished so fade out soon + fadeWaitTimer = Script.setTimeout(function () { + alphaDelta = ALPHA_DELTA_OUT; + fadeTimer = Script.setInterval(fade, FADE_INTERVAL); + fadeWaitTimer = null; + }, FADE_OUT_WAIT); + } + } else { + if (displayProgress < 100) { // Was finished and waiting to fade out but have resumed so don't fade out + Script.clearInterval(fadeWaitTimer); + fadeWaitTimer = null; + } + } + } + if (visible) { + + // Update progress bar + Overlays.editOverlay(isOnHMD ? bar3D.overlay : bar2D.overlay, { + visible: visible, + subImage: { x: BAR_WIDTH * (1 - displayProgress / 100), y: 0, width: BAR_WIDTH, height: BAR_HEIGHT } + }); + + // Update position if (isOnHMD) { // Update 3D overlays to maintain positions relative to avatar eyePosition = MyAvatar.getDefaultEyePosition(); diff --git a/interface/resources/html/img/devices.png b/interface/resources/html/img/devices.png new file mode 100644 index 0000000000..fc4231e96e Binary files /dev/null and b/interface/resources/html/img/devices.png differ diff --git a/interface/resources/html/img/models.png b/interface/resources/html/img/models.png new file mode 100644 index 0000000000..b09c36011d Binary files /dev/null and b/interface/resources/html/img/models.png differ diff --git a/interface/resources/html/img/move.png b/interface/resources/html/img/move.png new file mode 100644 index 0000000000..4444ebbec5 Binary files /dev/null and b/interface/resources/html/img/move.png differ diff --git a/interface/resources/html/img/run-script.png b/interface/resources/html/img/run-script.png new file mode 100644 index 0000000000..941b8ee9f1 Binary files /dev/null and b/interface/resources/html/img/run-script.png differ diff --git a/interface/resources/html/img/talk.png b/interface/resources/html/img/talk.png new file mode 100644 index 0000000000..682e034ab0 Binary files /dev/null and b/interface/resources/html/img/talk.png differ diff --git a/interface/resources/html/img/write-script.png b/interface/resources/html/img/write-script.png new file mode 100644 index 0000000000..dae97e59b1 Binary files /dev/null and b/interface/resources/html/img/write-script.png differ diff --git a/interface/resources/html/interface-welcome-allsvg.html b/interface/resources/html/interface-welcome-allsvg.html deleted file mode 100644 index d025f8059b..0000000000 --- a/interface/resources/html/interface-welcome-allsvg.html +++ /dev/null @@ -1,628 +0,0 @@ - -
- - -Welcome to Interface -Created with Sketch (http://www.bohemiancoding.com/sketch) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Use your best headphones and microphone for high fidelity audio. Chat via text by pressing the Enter key. - -Use two fingers to look around. Turn this off by opening Running Scripts (Cmnd/Cntrl+J) and clicking the X next to lookWithTouch.js - -Move around with WASD & fly up or down with E & C.Cmnd/Cntrl+G will send you home. @ (Shift+2) will let you teleport to a user or location. - -Have an Oculus Rift, a Razer Hydra, or a PrimeSense 3D camera? We support them all. - -Use the editVoxels.js script to build with your mouse – use the tab key to toggle the tools on/off. - - - - - - - - - - - - - - - - - - -Write a script; we’re always adding new features. Cmnd/Cntrl+J will launch a Running Scripts dialog to help manage your scripts. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - A - C - D - S - - W - - - - - - - - - E - - - - - - - - - - - - - - -
diff --git a/interface/resources/html/interface-welcome.html b/interface/resources/html/interface-welcome.html new file mode 100644 index 0000000000..d632cb0e5c --- /dev/null +++ b/interface/resources/html/interface-welcome.html @@ -0,0 +1,190 @@ + + + + + + + Welcome to Interface + + + + + +
+
+

Move around

+ +

+ Move around with WASD & fly
+ up or down with E & C.
+ Cmnd/Ctrl+G will send you
+ home. Hitting Enter will let you
+ teleport to a user or location. +

+
+
+

Listen & talk

+ +

+ Use your best headphones
+ and microphone for high
+ fidelity audio. Chat via text by
+ pressing the \ key. +

+
+
+

Connect devices

+ +

+ Have an Oculus Rift, a Razer
+ Hydra, or a PrimeSense 3D
+ camera? We support them all. +

+
+
+

Run a script

+ +

+ Cmnd/Cntrl+J will launch a
+ Running Scripts dialog to help
+ manage your scripts and search
+ for new ones to run. +

+
+
+

Script something

+ +

+ Write a script; we're always
+ adding new features.
+ Cmnd/Cntrl+J will launch a
+ Running Scripts dialog to help
+ manage your scripts. +

+
+
+

Import models

+ +

+ Use the editEntitles.js script to
+ add FBX models in-world. You
+ can use grids and fine tune
+ placement-related parameters
+ with ease. +

+
+
+
+

Read the docs

+

+ We are writing documentation on
+ just about everything. Please,
+ devour all we've written and make
+ suggestions where necessary.
+ Documentation is always at
+ docs.highfidelity.io +

+
+
+
+
+ + + + + \ No newline at end of file diff --git a/interface/resources/icons/start-script.svg b/interface/resources/icons/start-script.svg index 86354a555d..1401853fe4 100644 --- a/interface/resources/icons/start-script.svg +++ b/interface/resources/icons/start-script.svg @@ -536,22 +536,5 @@ height="44.57473" x="84.498352" y="1050.0748" /> - - - - diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ce33b04777..1211df3727 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -140,6 +140,12 @@ static unsigned STARFIELD_SEED = 1; const qint64 MAXIMUM_CACHE_SIZE = 10737418240; // 10GB +static QTimer* locationUpdateTimer = NULL; +static QTimer* balanceUpdateTimer = NULL; +static QTimer* silentNodeTimer = NULL; +static QTimer* identityPacketTimer = NULL; +static QTimer* billboardPacketTimer = NULL; +static QTimer* checkFPStimer = NULL; static QTimer* idleTimer = NULL; const QString CHECK_VERSION_URL = "https://highfidelity.io/latestVersion.xml"; @@ -362,7 +368,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : // update our location every 5 seconds in the data-server, assuming that we are authenticated with one const qint64 DATA_SERVER_LOCATION_CHANGE_UPDATE_MSECS = 5 * 1000; - QTimer* locationUpdateTimer = new QTimer(this); + locationUpdateTimer = new QTimer(this); connect(locationUpdateTimer, &QTimer::timeout, this, &Application::updateLocationInServer); locationUpdateTimer->start(DATA_SERVER_LOCATION_CHANGE_UPDATE_MSECS); @@ -378,7 +384,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : const qint64 BALANCE_UPDATE_INTERVAL_MSECS = 5 * 1000; - QTimer* balanceUpdateTimer = new QTimer(this); + balanceUpdateTimer = new QTimer(this); connect(balanceUpdateTimer, &QTimer::timeout, &accountManager, &AccountManager::updateBalance); balanceUpdateTimer->start(BALANCE_UPDATE_INTERVAL_MSECS); @@ -417,18 +423,18 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : connect(&_entityEditSender, &EntityEditPacketSender::packetSent, this, &Application::packetSent); // move the silentNodeTimer to the _nodeThread - QTimer* silentNodeTimer = new QTimer(); + silentNodeTimer = new QTimer(); connect(silentNodeTimer, SIGNAL(timeout()), nodeList.data(), SLOT(removeSilentNodes())); silentNodeTimer->start(NODE_SILENCE_THRESHOLD_MSECS); silentNodeTimer->moveToThread(_nodeThread); // send the identity packet for our avatar each second to our avatar mixer - QTimer* identityPacketTimer = new QTimer(); + identityPacketTimer = new QTimer(); connect(identityPacketTimer, &QTimer::timeout, _myAvatar, &MyAvatar::sendIdentityPacket); identityPacketTimer->start(AVATAR_IDENTITY_PACKET_SEND_INTERVAL_MSECS); // send the billboard packet for our avatar every few seconds - QTimer* billboardPacketTimer = new QTimer(); + billboardPacketTimer = new QTimer(); connect(billboardPacketTimer, &QTimer::timeout, _myAvatar, &MyAvatar::sendBillboardPacket); billboardPacketTimer->start(AVATAR_BILLBOARD_PACKET_SEND_INTERVAL_MSECS); @@ -527,11 +533,28 @@ void Application::aboutToQuit() { } void Application::cleanupBeforeQuit() { - // make sure we don't call the idle timer any more + // first stop all timers directly or by invokeMethod + // depending on what thread they run in + locationUpdateTimer->stop(); + balanceUpdateTimer->stop(); + QMetaObject::invokeMethod(silentNodeTimer, "stop", Qt::BlockingQueuedConnection); + identityPacketTimer->stop(); + billboardPacketTimer->stop(); + checkFPStimer->stop(); + idleTimer->stop(); + QMetaObject::invokeMethod(&_settingsTimer, "stop", Qt::BlockingQueuedConnection); + + // and then delete those that got created by "new" + delete locationUpdateTimer; + delete balanceUpdateTimer; + delete silentNodeTimer; + delete identityPacketTimer; + delete billboardPacketTimer; + delete checkFPStimer; delete idleTimer; + // no need to delete _settingsTimer here as it is no pointer // save state - QMetaObject::invokeMethod(&_settingsTimer, "stop", Qt::BlockingQueuedConnection); _settingsThread.quit(); saveSettings(); _window->saveGeometry(); @@ -630,9 +653,9 @@ void Application::initializeGL() { _entityEditSender.initialize(_enableProcessOctreeThread); // call our timer function every second - QTimer* timer = new QTimer(this); - connect(timer, SIGNAL(timeout()), SLOT(timer())); - timer->start(1000); + checkFPStimer = new QTimer(this); + connect(checkFPStimer, SIGNAL(timeout()), SLOT(checkFPS())); + checkFPStimer->start(1000); // call our idle function whenever we can idleTimer = new QTimer(this); @@ -1428,7 +1451,7 @@ void Application::sendPingPackets() { } // Every second, check the frame rates and other stuff -void Application::timer() { +void Application::checkFPS() { if (Menu::getInstance()->isOptionChecked(MenuOption::TestPing)) { sendPingPackets(); } diff --git a/interface/src/Application.h b/interface/src/Application.h index da29920ef9..f7a71e1e7c 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -111,7 +111,7 @@ static const float MIRROR_FIELD_OF_VIEW = 30.0f; static const quint64 TOO_LONG_SINCE_LAST_SEND_DOWNSTREAM_AUDIO_STATS = 1 * USECS_PER_SECOND; -static const QString INFO_HELP_PATH = "html/interface-welcome-allsvg.html"; +static const QString INFO_HELP_PATH = "html/interface-welcome.html"; static const QString INFO_EDIT_ENTITIES_PATH = "html/edit-entities-commands.html"; #ifdef Q_OS_WIN @@ -368,7 +368,7 @@ public slots: private slots: void clearDomainOctreeDetails(); - void timer(); + void checkFPS(); void idle(); void aboutToQuit(); diff --git a/interface/src/audio/AudioScope.cpp b/interface/src/audio/AudioScope.cpp index 45820e2393..8cc27341d6 100644 --- a/interface/src/audio/AudioScope.cpp +++ b/interface/src/audio/AudioScope.cpp @@ -230,7 +230,7 @@ int AudioScope::addSilenceToScope(QByteArray* byteArray, int frameOffset, int si int samplesToBufferEnd = _samplesPerScope - frameOffset; if (silentSamples > samplesToBufferEnd) { memset(destination + frameOffset, 0, samplesToBufferEnd * sizeof(int16_t)); - memset(destination, 0, silentSamples - samplesToBufferEnd * sizeof(int16_t)); + memset(destination, 0, (silentSamples - samplesToBufferEnd) * sizeof(int16_t)); } else { memset(destination + frameOffset, 0, silentSamples * sizeof(int16_t)); } diff --git a/interface/src/ui/InfoView.cpp b/interface/src/ui/InfoView.cpp index 607b222207..b62b8f3f2d 100644 --- a/interface/src/ui/InfoView.cpp +++ b/interface/src/ui/InfoView.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -32,6 +33,9 @@ InfoView::InfoView(bool forced, QString path) : QString absPath = QFileInfo(PathUtils::resourcesPath() + path).absoluteFilePath(); QUrl url = QUrl::fromLocalFile(absPath); + page()->setLinkDelegationPolicy(QWebPage::DelegateExternalLinks); + connect(this, SIGNAL(linkClicked(QUrl)), this, SLOT(linkClickedInfoView(QUrl))); + load(url); connect(this, SIGNAL(loadFinished(bool)), this, SLOT(loaded(bool))); } @@ -83,3 +87,8 @@ void InfoView::loaded(bool ok) { setAttribute(Qt::WA_DeleteOnClose); show(); } + +void InfoView::linkClickedInfoView(QUrl url) { + close(); + QDesktopServices::openUrl(url); +} diff --git a/interface/src/ui/InfoView.h b/interface/src/ui/InfoView.h index 47d5dac9ce..1198a703e4 100644 --- a/interface/src/ui/InfoView.h +++ b/interface/src/ui/InfoView.h @@ -27,6 +27,7 @@ private: private slots: void loaded(bool ok); + void linkClickedInfoView(QUrl url); }; #endif // hifi_InfoView_h diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index b427d5ba42..e1410d3304 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -109,7 +109,6 @@ AudioClient::AudioClient() : _audioSourceInjectEnabled(false), _reverb(false), _reverbOptions(&_scriptReverbOptions), - _gverbLocal(NULL), _gverb(NULL), _inputToNetworkResampler(NULL), _networkToOutputResampler(NULL), @@ -126,26 +125,23 @@ AudioClient::AudioClient() : connect(&_receivedAudioStream, &MixedProcessedAudioStream::processSamples, this, &AudioClient::processReceivedSamples, Qt::DirectConnection); - - // Initialize GVerb - initGverb(); - - const qint64 DEVICE_CHECK_INTERVAL_MSECS = 2 * 1000; _inputDevices = getDeviceNames(QAudio::AudioInput); _outputDevices = getDeviceNames(QAudio::AudioOutput); + const qint64 DEVICE_CHECK_INTERVAL_MSECS = 2 * 1000; QTimer* updateTimer = new QTimer(this); connect(updateTimer, &QTimer::timeout, this, &AudioClient::checkDevices); updateTimer->start(DEVICE_CHECK_INTERVAL_MSECS); + + // create GVerb filter + _gverb = createGverbFilter(); + configureGverbFilter(_gverb); } AudioClient::~AudioClient() { stop(); - if (_gverbLocal) { - gverb_free(_gverbLocal); - } if (_gverb) { gverb_free(_gverb); } @@ -158,6 +154,8 @@ void AudioClient::reset() { _toneSource.reset(); _sourceGain.reset(); _inputGain.reset(); + + gverb_flush(_gverb); } void AudioClient::audioMixerKilled() { @@ -491,8 +489,8 @@ void AudioClient::start() { _sourceGain.initialize(); _noiseSource.initialize(); _toneSource.initialize(); - _sourceGain.setParameters(0.25f,0.0f); - _inputGain.setParameters(1.0f,0.0f); + _sourceGain.setParameters(0.25f, 0.0f); + _inputGain.setParameters(1.0f, 0.0f); } void AudioClient::stop() { @@ -535,38 +533,24 @@ bool AudioClient::switchOutputToAudioDevice(const QString& outputDeviceName) { return switchOutputToAudioDevice(getNamedAudioDeviceForMode(QAudio::AudioOutput, outputDeviceName)); } -void AudioClient::initGverb() { +ty_gverb* AudioClient::createGverbFilter() { // Initialize a new gverb instance - if (_gverbLocal) { - gverb_free(_gverbLocal); - } - _gverbLocal = gverb_new(_outputFormat.sampleRate(), _reverbOptions->getMaxRoomSize(), _reverbOptions->getRoomSize(), - _reverbOptions->getReverbTime(), _reverbOptions->getDamping(), _reverbOptions->getSpread(), - _reverbOptions->getInputBandwidth(), _reverbOptions->getEarlyLevel(), - _reverbOptions->getTailLevel()); - - if (_gverb) { - gverb_free(_gverb); - } - _gverb = gverb_new(_outputFormat.sampleRate(), _reverbOptions->getMaxRoomSize(), _reverbOptions->getRoomSize(), - _reverbOptions->getReverbTime(), _reverbOptions->getDamping(), _reverbOptions->getSpread(), - _reverbOptions->getInputBandwidth(), _reverbOptions->getEarlyLevel(), - _reverbOptions->getTailLevel()); + ty_gverb* filter = gverb_new(_outputFormat.sampleRate(), _reverbOptions->getMaxRoomSize(), _reverbOptions->getRoomSize(), + _reverbOptions->getReverbTime(), _reverbOptions->getDamping(), _reverbOptions->getSpread(), + _reverbOptions->getInputBandwidth(), _reverbOptions->getEarlyLevel(), + _reverbOptions->getTailLevel()); + return filter; +} + +void AudioClient::configureGverbFilter(ty_gverb* filter) { // Configure the instance (these functions are not super well named - they actually set several internal variables) - gverb_set_roomsize(_gverbLocal, _reverbOptions->getRoomSize()); - gverb_set_revtime(_gverbLocal, _reverbOptions->getReverbTime()); - gverb_set_damping(_gverbLocal, _reverbOptions->getDamping()); - gverb_set_inputbandwidth(_gverbLocal, _reverbOptions->getInputBandwidth()); - gverb_set_earlylevel(_gverbLocal, DB_CO(_reverbOptions->getEarlyLevel())); - gverb_set_taillevel(_gverbLocal, DB_CO(_reverbOptions->getTailLevel())); - - gverb_set_roomsize(_gverb, _reverbOptions->getRoomSize()); - gverb_set_revtime(_gverb, _reverbOptions->getReverbTime()); - gverb_set_damping(_gverb, _reverbOptions->getDamping()); - gverb_set_inputbandwidth(_gverb, _reverbOptions->getInputBandwidth()); - gverb_set_earlylevel(_gverb, DB_CO(_reverbOptions->getEarlyLevel())); - gverb_set_taillevel(_gverb, DB_CO(_reverbOptions->getTailLevel())); + gverb_set_roomsize(filter, _reverbOptions->getRoomSize()); + gverb_set_revtime(filter, _reverbOptions->getReverbTime()); + gverb_set_damping(filter, _reverbOptions->getDamping()); + gverb_set_inputbandwidth(filter, _reverbOptions->getInputBandwidth()); + gverb_set_earlylevel(filter, DB_CO(_reverbOptions->getEarlyLevel())); + gverb_set_taillevel(filter, DB_CO(_reverbOptions->getTailLevel())); } void AudioClient::updateGverbOptions() { @@ -579,7 +563,7 @@ void AudioClient::updateGverbOptions() { } if (_zoneReverbOptions.getWetLevel() != _receivedAudioStream.getWetLevel()) { _zoneReverbOptions.setWetLevel(_receivedAudioStream.getWetLevel()); - reverbChanged = true; + // Not part of actual filter config, no need to set reverbChanged to true } if (_reverbOptions != &_zoneReverbOptions) { @@ -592,7 +576,17 @@ void AudioClient::updateGverbOptions() { } if (reverbChanged) { - initGverb(); + gverb_free(_gverb); + _gverb = createGverbFilter(); + configureGverbFilter(_gverb); + } +} + +void AudioClient::setReverb(bool reverb) { + _reverb = reverb; + + if (!_reverb) { + gverb_flush(_gverb); } } @@ -611,14 +605,17 @@ void AudioClient::setReverbOptions(const AudioEffectOptions* options) { _scriptReverbOptions.setWetLevel(options->getWetLevel()); if (_reverbOptions == &_scriptReverbOptions) { - // Apply them to the reverb instance(s) - initGverb(); + // Apply them to the reverb instances + gverb_free(_gverb); + _gverb = createGverbFilter(); + configureGverbFilter(_gverb); } } -void AudioClient::addReverb(ty_gverb* gverb, int16_t* samplesData, int numSamples, QAudioFormat& audioFormat, bool noEcho) { +void AudioClient::addReverb(ty_gverb* gverb, int16_t* samplesData, int16_t* reverbAlone, int numSamples, + QAudioFormat& audioFormat, bool noEcho) { float wetFraction = DB_CO(_reverbOptions->getWetLevel()); - float dryFraction = (noEcho) ? 0.0f : (1.0f - wetFraction); + float dryFraction = 1.0f - wetFraction; float lValue,rValue; for (int sample = 0; sample < numSamples; sample += audioFormat.channelCount()) { @@ -633,11 +630,19 @@ void AudioClient::addReverb(ty_gverb* gverb, int16_t* samplesData, int numSample int lResult = glm::clamp((int)(samplesData[j] * dryFraction + lValue * wetFraction), AudioConstants::MIN_SAMPLE_VALUE, AudioConstants::MAX_SAMPLE_VALUE); samplesData[j] = (int16_t)lResult; + + if (noEcho) { + reverbAlone[j] = (int16_t)lValue * wetFraction; + } } else if (j == (sample + 1)) { // right channel int rResult = glm::clamp((int)(samplesData[j] * dryFraction + rValue * wetFraction), AudioConstants::MIN_SAMPLE_VALUE, AudioConstants::MAX_SAMPLE_VALUE); samplesData[j] = (int16_t)rResult; + + if (noEcho) { + reverbAlone[j] = (int16_t)rValue * wetFraction; + } } else { // ignore channels above 2 } @@ -647,9 +652,8 @@ void AudioClient::addReverb(ty_gverb* gverb, int16_t* samplesData, int numSample void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) { // If there is server echo, reverb will be applied to the recieved audio stream so no need to have it here. - bool hasLocalReverb = (_reverb || _receivedAudioStream.hasReverb()) && - !_shouldEchoToServer; - if (_muted || !_audioOutput || (!_shouldEchoLocally && !hasLocalReverb)) { + bool hasReverb = _reverb || _receivedAudioStream.hasReverb(); + if (_muted || !_audioOutput || (!_shouldEchoLocally && !hasReverb)) { return; } @@ -659,6 +663,10 @@ void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) { if (!_loopbackOutputDevice && _loopbackAudioOutput) { // we didn't have the loopback output device going so set that up now _loopbackOutputDevice = _loopbackAudioOutput->start(); + + if (!_loopbackOutputDevice) { + return; + } } // do we need to setup a resampler? @@ -671,26 +679,31 @@ void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) { } } + static QByteArray reverbAlone; // Intermediary for local reverb with no echo static QByteArray loopBackByteArray; - loopBackByteArray.resize(numDestinationSamplesRequired(_inputFormat, _outputFormat, - inputByteArray.size() / sizeof(int16_t)) * sizeof(int16_t)); + + int numInputSamples = inputByteArray.size() / sizeof(int16_t); + int numLoopbackSamples = numDestinationSamplesRequired(_inputFormat, _outputFormat, numInputSamples); + + reverbAlone.resize(numInputSamples * sizeof(int16_t)); + loopBackByteArray.resize(numLoopbackSamples * sizeof(int16_t)); + + int16_t* inputSamples = reinterpret_cast(inputByteArray.data()); + int16_t* reverbAloneSamples = reinterpret_cast(reverbAlone.data()); + int16_t* loopbackSamples = reinterpret_cast(loopBackByteArray.data()); + + if (hasReverb) { + updateGverbOptions(); + addReverb(_gverb, inputSamples, reverbAloneSamples, numInputSamples, + _inputFormat, !_shouldEchoLocally); + } possibleResampling(_loopbackResampler, - reinterpret_cast(inputByteArray.data()), - reinterpret_cast(loopBackByteArray.data()), - inputByteArray.size() / sizeof(int16_t), loopBackByteArray.size() / sizeof(int16_t), + (_shouldEchoLocally) ? inputSamples : reverbAloneSamples, loopbackSamples, + numInputSamples, numLoopbackSamples, _inputFormat, _outputFormat); - if (hasLocalReverb) { - int16_t* loopbackSamples = reinterpret_cast(loopBackByteArray.data()); - int numLoopbackSamples = loopBackByteArray.size() / sizeof(int16_t); - updateGverbOptions(); - addReverb(_gverbLocal, loopbackSamples, numLoopbackSamples, _outputFormat, !_shouldEchoLocally); - } - - if (_loopbackOutputDevice) { - _loopbackOutputDevice->write(loopBackByteArray); - } + _loopbackOutputDevice->write(loopBackByteArray); } void AudioClient::handleAudioInput() { @@ -884,11 +897,6 @@ void AudioClient::processReceivedSamples(const QByteArray& inputBuffer, QByteArr reinterpret_cast(outputBuffer.data()), numNetworkOutputSamples, numDeviceOutputSamples, _desiredOutputFormat, _outputFormat); - - if(_reverb || _receivedAudioStream.hasReverb()) { - updateGverbOptions(); - addReverb(_gverb, (int16_t*)outputBuffer.data(), numDeviceOutputSamples, _outputFormat); - } } void AudioClient::sendMuteEnvironmentPacket() { diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index 0095a885eb..f75843df5f 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -166,7 +166,7 @@ public slots: float getInputVolume() const { return (_audioInput) ? _audioInput->volume() : 0.0f; } void setInputVolume(float volume) { if (_audioInput) _audioInput->setVolume(volume); } - void setReverb(bool reverb) { _reverb = reverb; } + void setReverb(bool reverb); void setReverbOptions(const AudioEffectOptions* options); void outputNotify(); @@ -241,7 +241,6 @@ private: AudioEffectOptions _scriptReverbOptions; AudioEffectOptions _zoneReverbOptions; AudioEffectOptions* _reverbOptions; - ty_gverb* _gverbLocal; ty_gverb* _gverb; // possible soxr streams needed for resample @@ -250,9 +249,10 @@ private: soxr* _loopbackResampler; // Adds Reverb - void initGverb(); + ty_gverb* createGverbFilter(); + void configureGverbFilter(ty_gverb* filter); void updateGverbOptions(); - void addReverb(ty_gverb* gverb, int16_t* samples, int numSamples, QAudioFormat& format, bool noEcho = false); + void addReverb(ty_gverb* gverb, int16_t* samples, int16_t* reverbAlone, int numSamples, QAudioFormat& format, bool noEcho = false); void handleLocalEchoAndReverb(QByteArray& inputByteArray); diff --git a/libraries/audio/src/AudioEditBuffer.h b/libraries/audio/src/AudioEditBuffer.h index b773fedfb8..66639f20bb 100644 --- a/libraries/audio/src/AudioEditBuffer.h +++ b/libraries/audio/src/AudioEditBuffer.h @@ -23,8 +23,8 @@ public: bool getZeroCrossing(uint32_t start, bool direction, float32_t epsilon, uint32_t& zero); - void linearFade(uint32_t start, uint32_t stop, bool slope); - void exponentialFade(uint32_t start, uint32_t stop, bool slope); + void linearFade(uint32_t start, uint32_t stop, bool increasing); + void exponentialFade(uint32_t start, uint32_t stop, bool increasing); }; template< typename T > @@ -74,7 +74,7 @@ inline bool AudioEditBuffer::getZeroCrossing(uint32_t start, bool direction, } template< typename T > -inline void AudioEditBuffer::linearFade(uint32_t start, uint32_t stop, bool slope) { +inline void AudioEditBuffer::linearFade(uint32_t start, uint32_t stop, bool increasing) { if (start >= stop || start > this->_frameCount || stop > this->_frameCount ) { return; @@ -84,7 +84,7 @@ inline void AudioEditBuffer::linearFade(uint32_t start, uint32_t stop, bool s float32_t delta; float32_t gain; - if (slope) { // 0.0 to 1.0f in delta increments + if (increasing) { // 0.0 to 1.0f in delta increments delta = 1.0f / (float32_t)count; gain = 0.0f; } else { // 1.0f to 0.0f in delta increments @@ -95,13 +95,13 @@ inline void AudioEditBuffer::linearFade(uint32_t start, uint32_t stop, bool s for (uint32_t i = start; i < stop; ++i) { for (uint32_t j = 0; j < this->_channelCount; ++j) { this->_frameBuffer[j][i] *= gain; - gain += delta; } + gain += delta; } } template< typename T > -inline void AudioEditBuffer::exponentialFade(uint32_t start, uint32_t stop, bool slope) { +inline void AudioEditBuffer::exponentialFade(uint32_t start, uint32_t stop, bool increasing) { // TBD } diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 43f4dda565..c8c454ff14 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -310,20 +310,23 @@ int LimitedNodeList::updateNodeWithDataFromPacket(const SharedNodePointer& match matchingNode->setLastHeardMicrostamp(usecTimestampNow()); - if (!matchingNode->getLinkedData() && linkedDataCreateCallback) { + NodeData* linkedData = matchingNode->getLinkedData(); + if (!linkedData && linkedDataCreateCallback) { linkedDataCreateCallback(matchingNode.data()); } - - QMutexLocker linkedDataLocker(&matchingNode->getLinkedData()->getMutex()); - - return matchingNode->getLinkedData()->parseData(packet); + + if (linkedData) { + QMutexLocker linkedDataLocker(&linkedData->getMutex()); + return linkedData->parseData(packet); + } + return 0; } int LimitedNodeList::findNodeAndUpdateWithDataFromPacket(const QByteArray& packet) { SharedNodePointer matchingNode = sendingNodeForPacket(packet); if (matchingNode) { - updateNodeWithDataFromPacket(matchingNode, packet); + return updateNodeWithDataFromPacket(matchingNode, packet); } // we weren't able to match the sender address to the address we have for this node, unlock and don't parse diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index d35e11a1c3..f70c2d9b3c 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -347,7 +347,7 @@ void NodeList::handleICEConnectionToDomainServer() { qDebug() << "Sending ping packets to establish connectivity with domain-server with ID" << uuidStringWithoutCurlyBraces(_domainHandler.getICEDomainID()); - // send the ping packet to the local and public sockets for this nodfe + // send the ping packet to the local and public sockets for this node QByteArray localPingPacket = constructPingPacket(PingType::Local, false, _domainHandler.getICEClientID()); writeUnverifiedDatagram(localPingPacket, _domainHandler.getICEPeer().getLocalSocket()); diff --git a/libraries/octree/src/OctreeQuery.h b/libraries/octree/src/OctreeQuery.h index 66abe53931..1fefabdf68 100644 --- a/libraries/octree/src/OctreeQuery.h +++ b/libraries/octree/src/OctreeQuery.h @@ -95,7 +95,7 @@ protected: glm::vec3 _cameraPosition = glm::vec3(0.0f); glm::quat _cameraOrientation = glm::quat(); float _cameraFov = 0.0f; - float _cameraAspectRatio = 0.0f; + float _cameraAspectRatio = 1.0f; float _cameraNearClip = 0.0f; float _cameraFarClip = 0.0f; glm::vec3 _cameraEyeOffsetPosition = glm::vec3(0.0f);