From 3aec67bb364ae5ecd6907fd23fc152e284fc2fd6 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 23 Apr 2016 16:05:34 +1200 Subject: [PATCH 01/10] 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 02/10] 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 d8a32c8329208c1ad9d689caf1766068578d16c1 Mon Sep 17 00:00:00 2001 From: Anthony Thibault Date: Sun, 24 Apr 2016 17:59:51 -0700 Subject: [PATCH 03/10] Avatar eye gaze fix for HMDs When no avatars are chosen for more detailed eye gaze tracking the eyes should look straight ahead. Before this fix, if you were in room scale or not aligned with the camera sensor your gaze could drift to the left or to the right of your head's forward direction. Now it should follow your head more closely. --- interface/src/Application.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4071043c87..fcf1425287 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3104,10 +3104,8 @@ void Application::updateMyAvatarLookAtPosition() { } else { // I am not looking at anyone else, so just look forward if (isHMD) { - glm::mat4 headPose = myAvatar->getHMDSensorMatrix(); - glm::quat headRotation = glm::quat_cast(headPose); - lookAtSpot = myAvatar->getPosition() + - myAvatar->getOrientation() * (headRotation * glm::vec3(0.0f, 0.0f, -TREE_SCALE)); + glm::mat4 worldHMDMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + lookAtSpot = transformPoint(worldHMDMat, glm::vec3(0.0f, 0.0f, -TREE_SCALE)); } else { lookAtSpot = myAvatar->getHead()->getEyePosition() + (myAvatar->getHead()->getFinalOrientationInWorldFrame() * glm::vec3(0.0f, 0.0f, -TREE_SCALE)); From 0da3fb8eeea646fa55bf674837f8423169dbbc58 Mon Sep 17 00:00:00 2001 From: Anthony Thibault Date: Sun, 24 Apr 2016 18:50:14 -0700 Subject: [PATCH 04/10] Eye contact improvements * After eyes change targets there is now a minimum 1/3rd second delay before they will again. * Changing gaze from eye to mouth is less likely then switching between eyes. --- interface/src/avatar/MyAvatar.cpp | 46 ++++++++++++++++++++----------- interface/src/avatar/MyAvatar.h | 3 ++ 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index b1107896a9..f61f64412c 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -317,6 +317,36 @@ void MyAvatar::update(float deltaTime) { } currentEnergy = max(0.0f, min(currentEnergy,1.0f)); emit energyChanged(currentEnergy); + + updateEyeContactTarget(deltaTime); +} + +void MyAvatar::updateEyeContactTarget(float deltaTime) { + + _eyeContactTargetTimer -= deltaTime; + if (_eyeContactTargetTimer < 0.0f) { + + const float CHANCE_OF_CHANGING_TARGET = 0.01f; + if (randFloat() < CHANCE_OF_CHANGING_TARGET) { + + float const FIFTY_FIFTY_CHANCE = 0.5f; + float const EYE_TO_MOUTH_CHANCE = 0.25f; + switch (_eyeContactTarget) { + case LEFT_EYE: + _eyeContactTarget = (randFloat() < EYE_TO_MOUTH_CHANCE) ? MOUTH : RIGHT_EYE; + break; + case RIGHT_EYE: + _eyeContactTarget = (randFloat() < EYE_TO_MOUTH_CHANCE) ? MOUTH : LEFT_EYE; + break; + case MOUTH: + _eyeContactTarget = (randFloat() < FIFTY_FIFTY_CHANCE) ? RIGHT_EYE : LEFT_EYE; + break; + } + + const float EYE_TARGET_DELAY_TIME = 0.33f; + _eyeContactTargetTimer = EYE_TARGET_DELAY_TIME; + } + } } extern QByteArray avatarStateToFrame(const AvatarData* _avatar); @@ -944,22 +974,6 @@ void MyAvatar::clearLookAtTargetAvatar() { } eyeContactTarget MyAvatar::getEyeContactTarget() { - float const CHANCE_OF_CHANGING_TARGET = 0.01f; - if (randFloat() < CHANCE_OF_CHANGING_TARGET) { - float const FIFTY_FIFTY_CHANCE = 0.5f; - switch (_eyeContactTarget) { - case LEFT_EYE: - _eyeContactTarget = (randFloat() < FIFTY_FIFTY_CHANCE) ? MOUTH : RIGHT_EYE; - break; - case RIGHT_EYE: - _eyeContactTarget = (randFloat() < FIFTY_FIFTY_CHANCE) ? LEFT_EYE : MOUTH; - break; - case MOUTH: - _eyeContactTarget = (randFloat() < FIFTY_FIFTY_CHANCE) ? RIGHT_EYE : LEFT_EYE; - break; - } - } - return _eyeContactTarget; } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 35caabe0f7..69bb7ea4c2 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -331,6 +331,8 @@ private: bool cameraInsideHead() const; + void updateEyeContactTarget(float deltaTime); + // These are made private for MyAvatar so that you will use the "use" methods instead virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override; @@ -371,6 +373,7 @@ private: float _oculusYawOffset; eyeContactTarget _eyeContactTarget; + float _eyeContactTargetTimer { 0.0f }; glm::vec3 _trackedHeadPosition; From 1066efc73754e074b7e850fb6cfbe272cc2d0d2d Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Mon, 25 Apr 2016 17:12:32 +0200 Subject: [PATCH 05/10] - 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 0c200e8c004719f1018b2e2f378468fba6fb820d Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Mon, 25 Apr 2016 09:27:43 -0700 Subject: [PATCH 06/10] MyAvatar: coding convention fix for updateEyeContactTarget() --- interface/src/avatar/MyAvatar.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index f61f64412c..9a61c00712 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -332,15 +332,16 @@ void MyAvatar::updateEyeContactTarget(float deltaTime) { float const FIFTY_FIFTY_CHANCE = 0.5f; float const EYE_TO_MOUTH_CHANCE = 0.25f; switch (_eyeContactTarget) { - case LEFT_EYE: - _eyeContactTarget = (randFloat() < EYE_TO_MOUTH_CHANCE) ? MOUTH : RIGHT_EYE; - break; - case RIGHT_EYE: - _eyeContactTarget = (randFloat() < EYE_TO_MOUTH_CHANCE) ? MOUTH : LEFT_EYE; - break; - case MOUTH: - _eyeContactTarget = (randFloat() < FIFTY_FIFTY_CHANCE) ? RIGHT_EYE : LEFT_EYE; - break; + case LEFT_EYE: + _eyeContactTarget = (randFloat() < EYE_TO_MOUTH_CHANCE) ? MOUTH : RIGHT_EYE; + break; + case RIGHT_EYE: + _eyeContactTarget = (randFloat() < EYE_TO_MOUTH_CHANCE) ? MOUTH : LEFT_EYE; + break; + case MOUTH: + default: + _eyeContactTarget = (randFloat() < FIFTY_FIFTY_CHANCE) ? RIGHT_EYE : LEFT_EYE; + break; } const float EYE_TARGET_DELAY_TIME = 0.33f; From f5fdc9e28f6ba35683c632875a0999415a821783 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 25 Apr 2016 09:53:41 -0700 Subject: [PATCH 07/10] 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 08/10] 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 09/10] 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 10/10] 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);