diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index b7dfdd9b24..b862cd0c78 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -648,6 +648,7 @@ void AudioMixer::run() { // setup a QThread with us as parent that will house the AudioMixerDatagramProcessor _datagramProcessingThread = new QThread(this); + _datagramProcessingThread->setObjectName("Datagram Processor Thread"); // create an AudioMixerDatagramProcessor and move it to that thread AudioMixerDatagramProcessor* datagramProcessor = new AudioMixerDatagramProcessor(nodeList->getNodeSocket(), thread()); diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index aaf37c2beb..85d4749b27 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -879,6 +879,7 @@ void OctreeServer::setupDatagramProcessingThread() { // setup a QThread with us as parent that will house the OctreeServerDatagramProcessor _datagramProcessingThread = new QThread(this); + _datagramProcessingThread->setObjectName("Octree Datagram Processor"); // create an OctreeServerDatagramProcessor and move it to that thread OctreeServerDatagramProcessor* datagramProcessor = new OctreeServerDatagramProcessor(nodeList->getNodeSocket(), thread()); diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 7cfeed3331..d680bbf520 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -1925,7 +1925,7 @@ Headers DomainServer::setupCookieHeadersFromProfileReply(QNetworkReply* profileR // persist the cookie to settings file so we can get it back on DS relaunch QStringList path = QStringList() << DS_SETTINGS_SESSIONS_GROUP << cookieUUID.toString(); - SettingHandles::SettingHandle(path).set(QVariant::fromValue(sessionData)); + Setting::Handle(path).set(QVariant::fromValue(sessionData)); // setup expiry for cookie to 1 month from today QDateTime cookieExpiry = QDateTime::currentDateTimeUtc().addMonths(1); diff --git a/examples/defaultScripts.js b/examples/defaultScripts.js index a14958dd23..ea13694f0c 100644 --- a/examples/defaultScripts.js +++ b/examples/defaultScripts.js @@ -8,6 +8,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.load("progress.js"); Script.load("lookWithTouch.js"); Script.load("editEntities.js"); Script.load("selectAudioDevice.js"); diff --git a/examples/editEntities.js b/examples/editEntities.js index 3a70d2020e..c0c74b8f33 100644 --- a/examples/editEntities.js +++ b/examples/editEntities.js @@ -46,28 +46,8 @@ gridTool.setVisible(false); var entityListTool = EntityListTool(); -var hasShownPropertiesTool = false; - -var entityListVisible = false; - selectionManager.addEventListener(function() { selectionDisplay.updateHandles(); - if (selectionManager.hasSelection() && !hasShownPropertiesTool) { - // Open properties and model list, but force selection of model list tab - propertiesTool.setVisible(false); - entityListTool.setVisible(false); - gridTool.setVisible(false); - propertiesTool.setVisible(true); - entityListTool.setVisible(true); - gridTool.setVisible(true); - Window.setFocus(); - hasShownPropertiesTool = true; - } - if (!selectionManager.hasSelection()) { - toolBar.setActive(false); - } else { - toolBar.setActive(true); - } }); var windowDimensions = Controller.getViewportDimensions(); @@ -94,9 +74,11 @@ var DEFAULT_DIMENSIONS = { }; var MENU_INSPECT_TOOL_ENABLED = "Inspect Tool"; +var MENU_AUTO_FOCUS_ON_SELECT = "Auto Focus on Select"; var MENU_EASE_ON_FOCUS = "Ease Orientation on Focus"; var SETTING_INSPECT_TOOL_ENABLED = "inspectToolEnabled"; +var SETTING_AUTO_FOCUS_ON_SELECT = "autoFocusOnSelect"; var SETTING_EASE_ON_FOCUS = "cameraEaseOnFocus"; var modelURLs = [ @@ -138,10 +120,9 @@ var toolBar = (function () { // Hide active button for now - this may come back, so not deleting yet. activeButton = toolBar.addTool({ imageURL: toolIconUrl + "models-tool.svg", - // subImage: { x: 0, y: Tool.IMAGE_WIDTH, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, - subImage: { x: 0, y: Tool.IMAGE_WIDTH, width: 0, height: 0 }, - width: 0,//toolWidth, - height: 0,//toolHeight, + subImage: { x: 0, y: Tool.IMAGE_WIDTH, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, + width: toolWidth, + height: toolHeight, alpha: 0.9, visible: true }, true, false); @@ -253,7 +234,10 @@ var toolBar = (function () { } else { hasShownPropertiesTool = false; cameraManager.enable(); - grid.setEnabled(true); + entityListTool.setVisible(true); + gridTool.setVisible(true); + propertiesTool.setVisible(true); + Window.setFocus(); } } toolBar.selectTool(activeButton, active); @@ -535,7 +519,7 @@ function mousePressEvent(event) { if (result !== null) { var currentProperties = Entities.getEntityProperties(result.entityID); cameraManager.enable(); - cameraManager.focus(currentProperties.position, null, true); + cameraManager.focus(currentProperties.position, null, Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); cameraManager.mousePressEvent(event); } } else { @@ -551,6 +535,9 @@ var idleMouseTimerId = null; var IDLE_MOUSE_TIMEOUT = 200; function mouseMoveEvent(event) { + if (!isActive) { + return; + } if (idleMouseTimerId) { Script.clearTimeout(idleMouseTimerId); } @@ -618,7 +605,7 @@ function mouseReleaseEvent(event) { } function mouseClickEvent(event) { - if (!event.isRightButton) { + if (!event.isLeftButton || !isActive) { return; } @@ -681,9 +668,11 @@ function mouseClickEvent(event) { print("Model selected: " + foundEntity.id); selectionDisplay.select(selectedEntityID, event); - cameraManager.focus(selectionManager.worldPosition, - selectionManager.worldDimensions, - true); + if (Menu.isOptionChecked(MENU_AUTO_FOCUS_ON_SELECT)) { + cameraManager.focus(selectionManager.worldPosition, + selectionManager.worldDimensions, + Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); + } } } } @@ -725,7 +714,9 @@ function setupModelMenus() { Menu.addMenuItem({ menuName: "File", menuItemName: "Import Models", shortcutKey: "CTRL+META+I", afterItem: "Export Models" }); - Menu.addMenuItem({ menuName: "View", menuItemName: MENU_EASE_ON_FOCUS, afterItem: MENU_INSPECT_TOOL_ENABLED, + Menu.addMenuItem({ menuName: "View", menuItemName: MENU_AUTO_FOCUS_ON_SELECT, afterItem: MENU_INSPECT_TOOL_ENABLED, + isCheckable: true, isChecked: Settings.getValue(SETTING_AUTO_FOCUS_ON_SELECT) == "true" }); + Menu.addMenuItem({ menuName: "View", menuItemName: MENU_EASE_ON_FOCUS, afterItem: MENU_AUTO_FOCUS_ON_SELECT, isCheckable: true, isChecked: Settings.getValue(SETTING_EASE_ON_FOCUS) == "true" }); Entities.setLightsArePickable(false); @@ -751,11 +742,12 @@ function cleanupModelMenus() { Menu.removeMenuItem("File", "Import Models"); Menu.removeMenuItem("View", MENU_INSPECT_TOOL_ENABLED); + Menu.removeMenuItem("View", MENU_AUTO_FOCUS_ON_SELECT); Menu.removeMenuItem("View", MENU_EASE_ON_FOCUS); } Script.scriptEnding.connect(function() { - Settings.setValue(SETTING_INSPECT_TOOL_ENABLED, Menu.isOptionChecked(MENU_INSPECT_TOOL_ENABLED)); + Settings.setValue(SETTING_AUTO_FOCUS_ON_SELECT, Menu.isOptionChecked(MENU_AUTO_FOCUS_ON_SELECT)); Settings.setValue(SETTING_EASE_ON_FOCUS, Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); progressDialog.cleanup(); diff --git a/examples/libraries/entityCameraTool.js b/examples/libraries/entityCameraTool.js index bf5bf6b105..bbd28dd38a 100644 --- a/examples/libraries/entityCameraTool.js +++ b/examples/libraries/entityCameraTool.js @@ -15,11 +15,11 @@ var MOUSE_SENSITIVITY = 0.9; var SCROLL_SENSITIVITY = 0.05; var PAN_ZOOM_SCALE_RATIO = 0.4; -var KEY_ORBIT_SENSITIVITY = 40; -var KEY_ZOOM_SENSITIVITY = 10; +var KEY_ORBIT_SENSITIVITY = 90; +var KEY_ZOOM_SENSITIVITY = 3; -// Scaling applied based on the size of the object being focused -var FOCUS_ZOOM_SCALE = 1.3; +// Scaling applied based on the size of the object being focused (Larger values focus further away) +var FOCUS_ZOOM_SCALE = 2.3; // Minimum zoom level when focusing on an object var FOCUS_MIN_ZOOM = 0.5; @@ -433,8 +433,13 @@ CameraManager = function() { that.targetYaw += (actions.orbitRight - actions.orbitLeft) * dt * KEY_ORBIT_SENSITIVITY; that.targetPitch += (actions.orbitUp - actions.orbitDown) * dt * KEY_ORBIT_SENSITIVITY; that.targetPitch = clamp(that.targetPitch, -90, 90); - that.targetZoomDistance += (actions.orbitBackward - actions.orbitForward) * dt * KEY_ZOOM_SENSITIVITY; - that.targetZoomDistance = clamp(that.targetZoomDistance, MIN_ZOOM_DISTANCE, MAX_ZOOM_DISTANCE); + + var dZoom = actions.orbitBackward - actions.orbitForward; + if (dZoom) { + dZoom *= that.targetZoomDistance * dt * KEY_ZOOM_SENSITIVITY; + that.targetZoomDistance += dZoom; + that.targetZoomDistance = clamp(that.targetZoomDistance, MIN_ZOOM_DISTANCE, MAX_ZOOM_DISTANCE); + } if (easing) { diff --git a/examples/progress.js b/examples/progress.js new file mode 100644 index 0000000000..6ee53c55e6 --- /dev/null +++ b/examples/progress.js @@ -0,0 +1,265 @@ +// +// progress.js +// examples +// +// Created by David Rowe on 29 Jan 2015. +// Copyright 2015 High Fidelity, Inc. +// +// This script displays a progress download indicator when downloads are in progress. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +(function () { + + var progress = 100, // % + alpha = 0.0, + alphaDelta = 0.0, // > 0 if fading in; < 0 if fading out/ + ALPHA_DELTA_IN = 0.15, + ALPHA_DELTA_OUT = -0.02, + fadeTimer = null, + FADE_INTERVAL = 30, // ms between changes in alpha. + 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_URL = "http://hifi-public.s3.amazonaws.com/images/progress-bar.svg", + BACKGROUND_WIDTH = 360, + BACKGROUND_HEIGHT = 60, + 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. + background3D = {}, + bar3D = {}, + ENABLE_VR_MODE_MENU_ITEM = "Enable VR Mode", + PROGRESS_3D_DIRECTION = 0.0, // Degrees from avatar orientation. + PROGRESS_3D_DISTANCE = 0.602, // Horizontal distance from avatar position. + 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. + 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; + + function fade() { + + alpha = alpha + alphaDelta; + + if (alpha < 0) { + alpha = 0; + } + + if (alpha > 1) { + alpha = 1; + } + + if (alpha === 0 || alpha === 1) { // Finished fading in or out + alphaDelta = 0; + Script.clearInterval(fadeTimer); + } + + if (alpha === 0) { // Finished fading out + visible = false; + } + + if (isOnHMD) { + Overlays.editOverlay(background3D.overlay, { + backgroundAlpha: alpha * BACKGROUND_3D_ALPHA, + visible: visible + }); + } else { + Overlays.editOverlay(background2D.overlay, { + alpha: alpha, + visible: visible + }); + } + Overlays.editOverlay(isOnHMD ? bar3D.overlay : bar2D.overlay, { + alpha: alpha, + visible: visible + }); + } + + function onDownloadInfoChanged(info) { + var i; + + // Calculate progress + if (info.downloading.length + info.pending === 0) { + progress = 100; + } else { + progress = 0; + for (i = 0; i < info.downloading.length; i += 1) { + progress += 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 } + }); + } + } + + function createOverlays() { + if (isOnHMD) { + + background3D.overlay = Overlays.addOverlay("rectangle3d", { + size: BACKGROUND_3D_SIZE, + color: BACKGROUND_3D_COLOR, + alpha: BACKGROUND_3D_ALPHA, + solid: true, + isFacingAvatar: false, + visible: false, + ignoreRayIntersection: true + }); + bar3D.overlay = Overlays.addOverlay("billboard", { + url: BAR_URL, + subImage: { x: BAR_WIDTH, y: 0, width: BAR_WIDTH, height: BAR_HEIGHT }, + scale: SCALE_3D * BAR_WIDTH, + isFacingAvatar: false, + visible: false, + alpha: 0.0, + ignoreRayIntersection: true + }); + + } else { + + background2D.overlay = Overlays.addOverlay("image", { + imageURL: BACKGROUND_URL, + width: background2D.width, + height: background2D.height, + visible: false, + alpha: 0.0 + }); + bar2D.overlay = Overlays.addOverlay("image", { + imageURL: BAR_URL, + subImage: { x: BAR_WIDTH, y: 0, width: BAR_WIDTH, height: BAR_HEIGHT }, + width: bar2D.width, + height: bar2D.height, + visible: false, + alpha: 0.0 + }); + } + } + + function deleteOverlays() { + Overlays.deleteOverlay(isOnHMD ? background3D.overlay : background2D.overlay); + Overlays.deleteOverlay(isOnHMD ? bar3D.overlay : bar2D.overlay); + } + + function update() { + var viewport, + eyePosition, + avatarOrientation; + + if (isOnHMD !== Menu.isOptionChecked(ENABLE_VR_MODE_MENU_ITEM)) { + deleteOverlays(); + isOnHMD = !isOnHMD; + createOverlays(); + } + + if (visible) { + if (isOnHMD) { + // Update 3D overlays to maintain positions relative to avatar + eyePosition = MyAvatar.getDefaultEyePosition(); + avatarOrientation = MyAvatar.orientation; + + Overlays.editOverlay(background3D.overlay, { + position: Vec3.sum(eyePosition, Vec3.multiplyQbyV(avatarOrientation, background3D.offset)), + rotation: Quat.multiply(avatarOrientation, background3D.orientation) + }); + Overlays.editOverlay(bar3D.overlay, { + position: Vec3.sum(eyePosition, Vec3.multiplyQbyV(avatarOrientation, bar3D.offset)), + rotation: Quat.multiply(avatarOrientation, bar3D.orientation) + }); + + } else { + // Update 2D overlays to maintain positions at bottom middle of window + viewport = Controller.getViewportDimensions(); + + if (viewport.x !== windowWidth || viewport.y !== windowHeight) { + windowWidth = viewport.x; + windowHeight = viewport.y; + + Overlays.editOverlay(background2D.overlay, { + x: windowWidth / 2 - background2D.width / 2, + y: windowHeight - background2D.height - bar2D.height + }); + + Overlays.editOverlay(bar2D.overlay, { + x: windowWidth / 2 - bar2D.width / 2, + y: windowHeight - background2D.height - bar2D.height + (background2D.height - bar2D.height) / 2 + }); + } + } + } + } + + function setUp() { + background2D.width = SCALE_2D * BACKGROUND_WIDTH; + background2D.height = SCALE_2D * BACKGROUND_HEIGHT; + bar2D.width = SCALE_2D * BAR_WIDTH; + bar2D.height = SCALE_2D * BAR_HEIGHT; + + background3D.offset = Vec3.multiplyQbyV(Quat.fromPitchYawRollDegrees(0, PROGRESS_3D_DIRECTION, 0), + { x: 0, y: 0, z: -PROGRESS_3D_DISTANCE }); + background3D.offset.y += PROGRESS_3D_ELEVATION; + background3D.orientation = Quat.fromPitchYawRollDegrees(PROGRESS_3D_PITCH, PROGRESS_3D_DIRECTION + PROGRESS_3D_YAW, 0); + bar3D.offset = Vec3.sum(background3D.offset, { x: 0, y: 0, z: 0.001 }); // Just in front of background + bar3D.orientation = background3D.orientation; + + createOverlays(); + } + + function tearDown() { + deleteOverlays(); + } + + setUp(); + GlobalServices.downloadInfoChanged.connect(onDownloadInfoChanged); + GlobalServices.updateDownloadInfo(); + Script.update.connect(update); + Script.scriptEnding.connect(tearDown); +}()); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 90f0c65f60..f1ead1ac4f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -73,7 +73,7 @@ #include #include #include -#include +#include #include #include #include @@ -146,12 +146,6 @@ const QString SKIP_FILENAME = QStandardPaths::writableLocation(QStandardPaths::D const QString DEFAULT_SCRIPTS_JS_URL = "http://s3.amazonaws.com/hifi-public/scripts/defaultScripts.js"; -namespace SettingHandles { - const SettingHandle firstRun("firstRun", true); - const SettingHandle lastScriptLocation("LastScriptLocation"); - const SettingHandle scriptsLocation("scriptsLocation"); -} - void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) { QString logMessage = LogHandler::getInstance().printMessage((LogMsgType) type, context, message); @@ -167,16 +161,8 @@ bool setupEssentials(int& argc, char** argv) { if (portStr) { listenPort = atoi(portStr); } - - // read the ApplicationInfo.ini file for Name/Version/Domain information - QSettings::setDefaultFormat(QSettings::IniFormat); - QSettings applicationInfo(PathUtils::resourcesPath() + "info/ApplicationInfo.ini", QSettings::IniFormat); - // set the associated application properties - applicationInfo.beginGroup("INFO"); - QApplication::setApplicationName(applicationInfo.value("name").toString()); - QApplication::setApplicationVersion(BUILD_VERSION); - QApplication::setOrganizationName(applicationInfo.value("organizationName").toString()); - QApplication::setOrganizationDomain(applicationInfo.value("organizationDomain").toString()); + // Set build version + QCoreApplication::setApplicationVersion(BUILD_VERSION); DependencyManager::registerInheritance(); @@ -209,7 +195,6 @@ bool setupEssentials(int& argc, char** argv) { return true; } - Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : QApplication(argc, argv), _dependencyManagerIsSetup(setupEssentials(argc, argv)), @@ -230,6 +215,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _lastQueriedViewFrustum(), _lastQueriedTime(usecTimestampNow()), _mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)), + _firstRun("firstRun", true), + _previousScriptLocation("LastScriptLocation"), + _scriptsLocationHandle("scriptsLocation"), + _fieldOfView("fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES), _viewTransform(), _scaleMirror(1.0f), _rotateMirror(0.0f), @@ -243,7 +232,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _enableProcessOctreeThread(true), _octreeProcessor(), _nodeBoundsDisplay(this), - _previousScriptLocation(), _applicationOverlay(), _runningScriptsWidget(NULL), _runningScriptsWidgetWasVisible(false), @@ -251,7 +239,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _lastNackTime(usecTimestampNow()), _lastSendDownstreamAudioStats(usecTimestampNow()), _isVSyncOn(true), - _aboutToQuit(false) + _aboutToQuit(false), + _notifiedPacketVersionMismatchThisDomain(false) { _logger = new FileLogger(this); // After setting organization name in order to get correct directory qInstallMessageHandler(messageHandler); @@ -278,6 +267,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _runningScriptsWidget = new RunningScriptsWidget(_window); // start the nodeThread so its event loop is running + _nodeThread->setObjectName("Datagram Processor Thread"); _nodeThread->start(); // make sure the node thread is given highest priority @@ -292,6 +282,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : // put the audio processing on a separate thread QThread* audioThread = new QThread(this); + audioThread->setObjectName("Audio Thread"); auto audioIO = DependencyManager::get