From 3aec67bb364ae5ecd6907fd23fc152e284fc2fd6 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 23 Apr 2016 16:05:34 +1200 Subject: [PATCH 1/7] Position default toolbar buttons bottom center of screen Expand edit toolbar horizontally. --- examples/directory.js | 7 ++++--- examples/edit.js | 7 ++++--- examples/examples.js | 7 ++++--- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/examples/directory.js b/examples/directory.js index 243811c8d4..4af784d59e 100644 --- a/examples/directory.js +++ b/examples/directory.js @@ -27,6 +27,7 @@ var directoryWindow = new OverlayWebWindow({ var toolHeight = 50; var toolWidth = 50; +var TOOLBAR_MARGIN_Y = 25; function showDirectory() { @@ -53,10 +54,10 @@ var toolBar = (function() { browseDirectoryButton; function initialize() { - toolBar = new ToolBar(0, 0, ToolBar.VERTICAL, "highfidelity.directory.toolbar", function(windowDimensions, toolbar) { + toolBar = new ToolBar(0, 0, ToolBar.HORIZONTAL, "highfidelity.directory.toolbar", function(windowDimensions, toolbar) { return { - x: windowDimensions.x - 8 - toolbar.width, - y: 50 + x: windowDimensions.x / 2 - 3 * toolbar.height, // Use toolbar.height to match edit.js + y: windowDimensions.y - TOOLBAR_MARGIN_Y - toolHeight }; }); browseDirectoryButton = toolBar.addTool({ diff --git a/examples/edit.js b/examples/edit.js index f03915f5ad..929f8014dd 100644 --- a/examples/edit.js +++ b/examples/edit.js @@ -53,6 +53,7 @@ selectionManager.addEventListener(function() { var toolIconUrl = HIFI_PUBLIC_BUCKET + "images/tools/"; var toolHeight = 50; var toolWidth = 50; +var TOOLBAR_MARGIN_Y = 25; var DEGREES_TO_RADIANS = Math.PI / 180.0; var RADIANS_TO_DEGREES = 180.0 / Math.PI; @@ -179,10 +180,10 @@ var toolBar = (function() { newParticleButton function initialize() { - toolBar = new ToolBar(0, 0, ToolBar.VERTICAL, "highfidelity.edit.toolbar", function(windowDimensions, toolbar) { + toolBar = new ToolBar(0, 0, ToolBar.HORIZONTAL, "highfidelity.edit.toolbar", function(windowDimensions, toolbar) { return { - x: windowDimensions.x - 8 - toolbar.width, - y: (windowDimensions.y - toolbar.height) / 2 + x: windowDimensions.x / 2 + 2 * toolbar.height, // Use toolbar.height as a proxy for width of a single button + y: windowDimensions.y - TOOLBAR_MARGIN_Y - toolHeight }; }); diff --git a/examples/examples.js b/examples/examples.js index bfa85473de..1f764ebd8e 100644 --- a/examples/examples.js +++ b/examples/examples.js @@ -27,6 +27,7 @@ var examplesWindow = new OverlayWebWindow({ var toolHeight = 50; var toolWidth = 50; +var TOOLBAR_MARGIN_Y = 25; function showExamples(marketplaceID) { @@ -58,10 +59,10 @@ var toolBar = (function() { browseExamplesButton; function initialize() { - toolBar = new ToolBar(0, 0, ToolBar.VERTICAL, "highfidelity.examples.toolbar", function(windowDimensions, toolbar) { + toolBar = new ToolBar(0, 0, ToolBar.HORIXONTAL, "highfidelity.examples.toolbar", function(windowDimensions, toolbar) { return { - x: windowDimensions.x - 8 - toolbar.width, - y: 135 + x: windowDimensions.x / 2 - toolbar.height / 2, // Use toolbar.height to match edit.js + y: windowDimensions.y - TOOLBAR_MARGIN_Y - toolHeight }; }); browseExamplesButton = toolBar.addTool({ From 958c6f48c2665102d909e464f1893d1739356c8a Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 23 Apr 2016 18:16:20 +1200 Subject: [PATCH 2/7] Maintain relative spacing among toolbars as the window is resized --- examples/directory.js | 7 +++++-- examples/edit.js | 7 +++++-- examples/examples.js | 7 +++++-- examples/libraries/toolBars.js | 21 +++++++++++---------- 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/examples/directory.js b/examples/directory.js index 4af784d59e..ac426cafe7 100644 --- a/examples/directory.js +++ b/examples/directory.js @@ -56,9 +56,12 @@ var toolBar = (function() { function initialize() { toolBar = new ToolBar(0, 0, ToolBar.HORIZONTAL, "highfidelity.directory.toolbar", function(windowDimensions, toolbar) { return { - x: windowDimensions.x / 2 - 3 * toolbar.height, // Use toolbar.height to match edit.js - y: windowDimensions.y - TOOLBAR_MARGIN_Y - toolHeight + x: windowDimensions.x / 2, + y: windowDimensions.y }; + }, { + x: -2 * toolWidth, + y: -TOOLBAR_MARGIN_Y - toolHeight }); browseDirectoryButton = toolBar.addTool({ imageURL: toolIconUrl + "directory-01.svg", diff --git a/examples/edit.js b/examples/edit.js index 929f8014dd..c4c3b5a99b 100644 --- a/examples/edit.js +++ b/examples/edit.js @@ -182,9 +182,12 @@ var toolBar = (function() { function initialize() { toolBar = new ToolBar(0, 0, ToolBar.HORIZONTAL, "highfidelity.edit.toolbar", function(windowDimensions, toolbar) { return { - x: windowDimensions.x / 2 + 2 * toolbar.height, // Use toolbar.height as a proxy for width of a single button - y: windowDimensions.y - TOOLBAR_MARGIN_Y - toolHeight + x: windowDimensions.x / 2, + y: windowDimensions.y }; + }, { + x: toolWidth, + y: -TOOLBAR_MARGIN_Y - toolHeight }); activeButton = toolBar.addTool({ diff --git a/examples/examples.js b/examples/examples.js index 1f764ebd8e..90dca71f38 100644 --- a/examples/examples.js +++ b/examples/examples.js @@ -61,9 +61,12 @@ var toolBar = (function() { function initialize() { toolBar = new ToolBar(0, 0, ToolBar.HORIXONTAL, "highfidelity.examples.toolbar", function(windowDimensions, toolbar) { return { - x: windowDimensions.x / 2 - toolbar.height / 2, // Use toolbar.height to match edit.js - y: windowDimensions.y - TOOLBAR_MARGIN_Y - toolHeight + x: windowDimensions.x / 2, + y: windowDimensions.y }; + }, { + x: -toolWidth / 2, + y: -TOOLBAR_MARGIN_Y - toolHeight }); browseExamplesButton = toolBar.addTool({ imageURL: toolIconUrl + "examples-01.svg", diff --git a/examples/libraries/toolBars.js b/examples/libraries/toolBars.js index 6e54c0276c..4f560e6b8d 100644 --- a/examples/libraries/toolBars.js +++ b/examples/libraries/toolBars.js @@ -139,12 +139,13 @@ Tool.prototype = new Overlay2D; Tool.IMAGE_HEIGHT = 50; Tool.IMAGE_WIDTH = 50; -ToolBar = function(x, y, direction, optionalPersistenceKey, optionalInitialPositionFunction) { +ToolBar = function(x, y, direction, optionalPersistenceKey, optionalInitialPositionFunction, optionalOffset) { this.tools = new Array(); this.x = x; this.y = y; + this.offset = optionalOffset ? optionalOffset : { x: 0, y: 0 }; this.width = 0; - this.height = 0 + this.height = 0; this.backAlpha = 1.0; this.back = Overlays.addOverlay("rectangle", { color: { red: 255, green: 255, blue: 255 }, @@ -237,7 +238,7 @@ ToolBar = function(x, y, direction, optionalPersistenceKey, optionalInitialPosit } } - this.move = function(x, y) { + this.move = function (x, y) { var dx = x - this.x; var dy = y - this.y; this.x = x; @@ -370,14 +371,14 @@ ToolBar = function(x, y, direction, optionalPersistenceKey, optionalInitialPosit that.onResizeViewport = function (newSize) { // Can be overridden or extended by clients. var recommendedRect = Controller.getRecommendedOverlayRect(); var recommendedDimmensions = { x: recommendedRect.width, y: recommendedRect.height }; - var originRelativeX = (that.x - that.origin.x); - var originRelativeY = (that.y - that.origin.y); + var originRelativeX = (that.x - that.origin.x - that.offset.x); + var originRelativeY = (that.y - that.origin.y - that.offset.y); var fractionX = clamp(originRelativeX / that.windowDimensions.x, 0, 1); var fractionY = clamp(originRelativeY / that.windowDimensions.y, 0, 1); that.windowDimensions = newSize || recommendedDimmensions; that.origin = { x: recommendedRect.x, y: recommendedRect.y }; - var newX = (fractionX * that.windowDimensions.x) + recommendedRect.x; - var newY = (fractionY * that.windowDimensions.y) + recommendedRect.y; + var newX = (fractionX * that.windowDimensions.x) + recommendedRect.x + that.offset.x; + var newY = (fractionY * that.windowDimensions.y) + recommendedRect.y + that.offset.y; that.move(newX, newY); }; if (optionalPersistenceKey) { @@ -387,7 +388,7 @@ ToolBar = function(x, y, direction, optionalPersistenceKey, optionalInitialPosit var screenSize = { x: recommendedRect.width, y: recommendedRect.height }; if (screenSize.x > 0 && screenSize.y > 0) { // Guard against invalid screen size that can occur at shut-down. - var fraction = {x: that.x / screenSize.x, y: that.y / screenSize.y}; + var fraction = {x: (that.x - that.offset.x) / screenSize.x, y: (that.y - that.offset.y) / screenSize.y}; Settings.setValue(this.fractionKey, JSON.stringify(fraction)); } } @@ -456,7 +457,7 @@ ToolBar = function(x, y, direction, optionalPersistenceKey, optionalInitialPosit var screenSize = { x: recommendedRect.width, y: recommendedRect.height }; if (savedFraction) { // If we have saved data, keep the toolbar at the same proportion of the screen width/height. - that.move(savedFraction.x * screenSize.x, savedFraction.y * screenSize.y); + that.move(savedFraction.x * screenSize.x + that.offset.x, savedFraction.y * screenSize.y + that.offset.y); } else if (!optionalInitialPositionFunction) { print("No initPosition(screenSize, intializedToolbar) specified for ToolBar"); } else { @@ -464,7 +465,7 @@ ToolBar = function(x, y, direction, optionalPersistenceKey, optionalInitialPosit var that = this; Script.setTimeout(function () { var position = optionalInitialPositionFunction(screenSize, that); - that.move(position.x, position.y); + that.move(position.x + that.offset.x, position.y + that.offset.y); }, 0); } } From 1066efc73754e074b7e850fb6cfbe272cc2d0d2d Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Mon, 25 Apr 2016 17:12:32 +0200 Subject: [PATCH 3/7] - fix the settings window of Planky - set lifetime Planky blocks 60 minutes (per request of Ryan) --- examples/example/games/planky.js | 23 ++++++++++++++++------- examples/html/plankySettings.html | 22 +++++++++++++++------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/examples/example/games/planky.js b/examples/example/games/planky.js index 22388eba47..742cc3b7d0 100644 --- a/examples/example/games/planky.js +++ b/examples/example/games/planky.js @@ -10,9 +10,9 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; +HIFI_PUBLIC_BUCKET = 'http://s3.amazonaws.com/hifi-public/'; -Script.include("../../libraries/toolBars.js"); +Script.include('../../libraries/toolBars.js'); const DEFAULT_NUM_LAYERS = 16; const DEFAULT_BASE_DIMENSION = { x: 7, y: 2, z: 7 }; @@ -30,6 +30,8 @@ const DEFAULT_RESTITUTION = 0.0; const DEFAULT_SPAWN_DISTANCE = 3; const DEFAULT_BLOCK_YAW_OFFSET = 45; +const PLANKY_LIFETIME = 3600; // 1 hour (3600 seconds) + var editMode = false; const BUTTON_DIMENSIONS = {width: 49, height: 49}; @@ -51,13 +53,17 @@ SettingsWindow = function() { this.plankyStack = null; this.webWindow = null; this.init = function(plankyStack) { - _this.webWindow = new OverlayWebWindow('Planky', Script.resolvePath('../../html/plankySettings.html'), 255, 500, true); + _this.webWindow = new OverlayWebWindow({ + title: 'Planky', + source: Script.resolvePath('../../html/plankySettings.html'), + toolWindow: true + }); _this.webWindow.setVisible(false); - _this.webWindow.eventBridge.webEventReceived.connect(_this.onWebEventReceived); + _this.webWindow.webEventReceived.connect(_this.onWebEventReceived); _this.plankyStack = plankyStack; }; this.sendData = function(data) { - _this.webWindow.eventBridge.emitScriptEvent(JSON.stringify(data)); + _this.webWindow.emitScriptEvent(JSON.stringify(data)); }; this.onWebEventReceived = function(data) { data = JSON.parse(data); @@ -188,7 +194,8 @@ PlankyStack = function() { dimensions: _this.options.baseDimension, position: Vec3.sum(_this.basePosition, {y: -(_this.options.baseDimension.y / 2)}), rotation: _this.baseRotation, - shapeType: 'box' + shapeType: 'box', + lifetime: PLANKY_LIFETIME }); return; } @@ -254,7 +261,8 @@ PlankyStack = function() { density: _this.options.density, velocity: {x: 0, y: 0, z: 0}, angularVelocity: Quat.fromPitchYawRollDegrees(0, 0, 0), - collisionless: true + collisionless: true, + lifetime: PLANKY_LIFETIME }; _this.planks.forEach(function(plank, index, object) { if (plank.layer === layer && plank.row === row) { @@ -304,6 +312,7 @@ var settingsWindow = new SettingsWindow(); var plankyStack = new PlankyStack(); settingsWindow.init(plankyStack); +// This function is used to get the ideal y-location for a floor function grabLowestJointY() { var jointNames = MyAvatar.getJointNames(); var floorY = MyAvatar.position.y; diff --git a/examples/html/plankySettings.html b/examples/html/plankySettings.html index 0eea4948ad..836d5454b6 100644 --- a/examples/html/plankySettings.html +++ b/examples/html/plankySettings.html @@ -3,11 +3,15 @@ + +
- \ No newline at end of file + From f5fdc9e28f6ba35683c632875a0999415a821783 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 25 Apr 2016 09:53:41 -0700 Subject: [PATCH 4/7] change link on Sandbox splash screen --- server-console/src/splash.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-console/src/splash.html b/server-console/src/splash.html index b9947bcbaa..d93b742181 100644 --- a/server-console/src/splash.html +++ b/server-console/src/splash.html @@ -28,7 +28,7 @@ You can make your home yours by uploading your own models and scripts.

- To see how, check out 'The Basics' + To get started exploring and creating, check out our Quick-start Guide

From 49566c8f261a635e3fadf7880823a2e01b1e2293 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 25 Apr 2016 10:07:08 -0700 Subject: [PATCH 5/7] fix memory leak in AssetMappingModel --- interface/src/scripting/AssetMappingsScriptingInterface.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/scripting/AssetMappingsScriptingInterface.cpp b/interface/src/scripting/AssetMappingsScriptingInterface.cpp index 3f11bd1fd8..965b3a9e0c 100644 --- a/interface/src/scripting/AssetMappingsScriptingInterface.cpp +++ b/interface/src/scripting/AssetMappingsScriptingInterface.cpp @@ -292,6 +292,8 @@ void AssetMappingModel::refresh() { } else { emit errorGettingMappings(request->getErrorString()); } + + request->deleteLater(); }); request->start(); From 16bf59f8a63ea005f346e6bd9a5bfabd684b8382 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 25 Apr 2016 10:26:32 -0700 Subject: [PATCH 6/7] fix a crash in RenderableModelEntityItem::getModel --- libraries/entities/src/EntityTree.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 71b6f1364f..b4f0c484d5 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1459,10 +1459,12 @@ void EntityTree::trackIncomingEntityLastEdited(quint64 lastEditedTime, int bytes void EntityTree::callLoader(EntityItemID entityID) { // this is used to bounce from the networking thread to the main thread - EntityItemPointer entity = findEntityByEntityItemID(entityID); - if (entity) { - entity->loader(); - } + this->withWriteLock([&] { + EntityItemPointer entity = findEntityByEntityItemID(entityID); + if (entity) { + entity->loader(); + } + }); } int EntityTree::getJointIndex(const QUuid& entityID, const QString& name) const { From b7f157f4ff50d806a5df93334626a360055e79cd Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Mon, 25 Apr 2016 14:10:20 -0700 Subject: [PATCH 7/7] Reset avatar on exit of away-mode. Exposed MyAvatar.reset(bool) to script. away.js now calls this on exit of away-mode. --- examples/away.js | 1 + interface/src/avatar/MyAvatar.cpp | 9 +++++++-- interface/src/avatar/MyAvatar.h | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/examples/away.js b/examples/away.js index 9c5aed98fa..dee4f841b0 100644 --- a/examples/away.js +++ b/examples/away.js @@ -196,6 +196,7 @@ function goActive() { } MyAvatar.setEnableMeshVisible(true); // IWBNI we respected Developer->Avatar->Draw Mesh setting. stopAwayAnimation(); + MyAvatar.reset(true); hideOverlay(); // restore overlays state to what it was when we went "away" diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 9a61c00712..a357cd879d 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -235,7 +235,12 @@ QByteArray MyAvatar::toByteArray(bool cullSmallChanges, bool sendAll) { return AvatarData::toByteArray(cullSmallChanges, sendAll); } -void MyAvatar::reset(bool andReload) { +void MyAvatar::reset(bool andRecenter) { + + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "reset", Q_ARG(bool, andRecenter)); + return; + } // Reset dynamic state. _wasPushing = _isPushing = _isBraking = false; @@ -245,7 +250,7 @@ void MyAvatar::reset(bool andReload) { _targetVelocity = glm::vec3(0.0f); setThrust(glm::vec3(0.0f)); - if (andReload) { + if (andRecenter) { // derive the desired body orientation from the *old* hmd orientation, before the sensor reset. auto newBodySensorMatrix = deriveBodyFromHMDSensor(); // Based on current cached HMD position/rotation.. diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 69bb7ea4c2..e320c0e3de 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -93,7 +93,7 @@ public: AudioListenerMode getAudioListenerModeCamera() const { return FROM_CAMERA; } AudioListenerMode getAudioListenerModeCustom() const { return CUSTOM; } - void reset(bool andReload = false); + Q_INVOKABLE void reset(bool andRecenter = false); void update(float deltaTime); void preRender(RenderArgs* renderArgs);