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)); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index b1107896a9..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.. @@ -317,6 +322,37 @@ 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: + default: + _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 +980,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..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); @@ -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; 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(); 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 { diff --git a/script-archive/example/games/planky.js b/script-archive/example/games/planky.js index 22388eba47..742cc3b7d0 100644 --- a/script-archive/example/games/planky.js +++ b/script-archive/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/script-archive/html/plankySettings.html b/script-archive/html/plankySettings.html index 0eea4948ad..836d5454b6 100644 --- a/script-archive/html/plankySettings.html +++ b/script-archive/html/plankySettings.html @@ -3,11 +3,15 @@ + +
- \ No newline at end of file + diff --git a/scripts/system/away.js b/scripts/system/away.js index 2880bdcb04..687345a5e1 100644 --- a/scripts/system/away.js +++ b/scripts/system/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/scripts/system/directory.js b/scripts/system/directory.js index 1df982541c..cf9aa6aba7 100644 --- a/scripts/system/directory.js +++ b/scripts/system/directory.js @@ -26,6 +26,7 @@ var directoryWindow = new OverlayWebWindow({ var toolHeight = 50; var toolWidth = 50; +var TOOLBAR_MARGIN_Y = 25; function showDirectory() { @@ -52,11 +53,14 @@ 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, + y: windowDimensions.y }; + }, { + x: -2 * toolWidth, + y: -TOOLBAR_MARGIN_Y - toolHeight }); browseDirectoryButton = toolBar.addTool({ imageURL: toolIconUrl + "directory-01.svg", diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 6784c41100..2796297e40 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -53,6 +53,7 @@ selectionManager.addEventListener(function() { var toolIconUrl = Script.resolvePath("assets/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,11 +180,14 @@ 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, + y: windowDimensions.y }; + }, { + x: toolWidth, + y: -TOOLBAR_MARGIN_Y - toolHeight }); activeButton = toolBar.addTool({ diff --git a/scripts/system/examples.js b/scripts/system/examples.js index 9883de2582..9caedec70f 100644 --- a/scripts/system/examples.js +++ b/scripts/system/examples.js @@ -26,6 +26,7 @@ var examplesWindow = new OverlayWebWindow({ var toolHeight = 50; var toolWidth = 50; +var TOOLBAR_MARGIN_Y = 25; function showExamples(marketplaceID) { @@ -57,11 +58,14 @@ 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, + y: windowDimensions.y }; + }, { + x: -toolWidth / 2, + y: -TOOLBAR_MARGIN_Y - toolHeight }); browseExamplesButton = toolBar.addTool({ imageURL: toolIconUrl + "examples-01.svg", 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