From 94ae1ef638c5e48788853fe1a6ceb13315214999 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 2 Nov 2015 20:37:57 -0800 Subject: [PATCH 01/11] Fix accumulateTime --- libraries/animation/src/AnimClip.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/animation/src/AnimClip.cpp b/libraries/animation/src/AnimClip.cpp index 8f50874ed3..b2b6f728fd 100644 --- a/libraries/animation/src/AnimClip.cpp +++ b/libraries/animation/src/AnimClip.cpp @@ -81,7 +81,7 @@ void AnimClip::setCurrentFrameInternal(float frame) { // because dt is 0, we should not encounter any triggers const float dt = 0.0f; Triggers triggers; - _frame = ::accumulateTime(_startFrame, _endFrame, _timeScale, frame, dt, _loopFlag, _id, triggers); + _frame = ::accumulateTime(_startFrame, _endFrame, _timeScale, frame + _startFrame, dt, _loopFlag, _id, triggers); } void AnimClip::copyFromNetworkAnim() { From b74ed36883ad03602096c8280a230e5475df8b51 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 2 Nov 2015 20:39:31 -0800 Subject: [PATCH 02/11] Fix outro start times, and introduce away states (which are not used in C++ code, but are used in script). --- .../defaultAvatar_full/avatar-animation.json | 89 ++++++++++++++++--- 1 file changed, 78 insertions(+), 11 deletions(-) diff --git a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json index fd1099a85b..9398b94890 100644 --- a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json +++ b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json @@ -178,7 +178,7 @@ "type": "clip", "data": { "url": "http://hifi-public.s3.amazonaws.com/ozan/anim/hand_anims/point_right_hand.fbx", - "startFrame": 0.0, + "startFrame": 12.0, "endFrame": 65.0, "timeScale": 1.0, "loopFlag": false @@ -327,7 +327,7 @@ "type": "clip", "data": { "url": "http://hifi-public.s3.amazonaws.com/ozan/anim/hand_anims/point_left_hand.fbx", - "startFrame": 0.0, + "startFrame": 12.0, "endFrame": 65.0, "timeScale": 1.0, "loopFlag": false @@ -378,15 +378,16 @@ "states": [ { "id": "idle", - "interpTarget": 6, - "interpDuration": 6, + "interpTarget": 15, + "interpDuration": 15, "transitions": [ { "var": "isMovingForward", "state": "walkFwd" }, { "var": "isMovingBackward", "state": "walkBwd" }, { "var": "isMovingRight", "state": "strafeRight" }, { "var": "isMovingLeft", "state": "strafeLeft" }, { "var": "isTurningRight", "state": "turnRight" }, - { "var": "isTurningLeft", "state": "turnLeft" } + { "var": "isTurningLeft", "state": "turnLeft" }, + { "var": "isAway", "state": "awayIntro" } ] }, { @@ -399,7 +400,8 @@ { "var": "isMovingRight", "state": "strafeRight" }, { "var": "isMovingLeft", "state": "strafeLeft" }, { "var": "isTurningRight", "state": "turnRight" }, - { "var": "isTurningLeft", "state": "turnLeft" } + { "var": "isTurningLeft", "state": "turnLeft" }, + { "var": "isAway", "state": "awayIntro" } ] }, { @@ -412,7 +414,8 @@ { "var": "isMovingRight", "state": "strafeRight" }, { "var": "isMovingLeft", "state": "strafeLeft" }, { "var": "isTurningRight", "state": "turnRight" }, - { "var": "isTurningLeft", "state": "turnLeft" } + { "var": "isTurningLeft", "state": "turnLeft" }, + { "var": "isAway", "state": "awayIntro" } ] }, { @@ -425,7 +428,8 @@ { "var": "isMovingBackward", "state": "walkBwd" }, { "var": "isMovingLeft", "state": "strafeLeft" }, { "var": "isTurningRight", "state": "turnRight" }, - { "var": "isTurningLeft", "state": "turnLeft" } + { "var": "isTurningLeft", "state": "turnLeft" }, + { "var": "isAway", "state": "awayIntro" } ] }, { @@ -438,7 +442,8 @@ { "var": "isMovingBackward", "state": "walkBwd" }, { "var": "isMovingRight", "state": "strafeRight" }, { "var": "isTurningRight", "state": "turnRight" }, - { "var": "isTurningLeft", "state": "turnLeft" } + { "var": "isTurningLeft", "state": "turnLeft" }, + { "var": "isAway", "state": "awayIntro" } ] }, { @@ -451,7 +456,8 @@ { "var": "isMovingBackward", "state": "walkBwd" }, { "var": "isMovingRight", "state": "strafeRight" }, { "var": "isMovingLeft", "state": "strafeLeft" }, - { "var": "isTurningLeft", "state": "turnLeft" } + { "var": "isTurningLeft", "state": "turnLeft" }, + { "var": "isAway", "state": "awayIntro" } ] }, { @@ -464,7 +470,32 @@ { "var": "isMovingBackward", "state": "walkBwd" }, { "var": "isMovingRight", "state": "strafeRight" }, { "var": "isMovingLeft", "state": "strafeLeft" }, - { "var": "isTurningRight", "state": "turnRight" } + { "var": "isTurningRight", "state": "turnRight" }, + { "var": "isAway", "state": "awayIntro" } + ] + }, + { + "id": "awayIntro", + "interpTarget": 30, + "interpDuration": 30, + "transitions": [ + { "var": "awayIntroOnDone", "state": "away"} + ] + }, + { + "id": "away", + "interpTarget": 3, + "interpDuration": 3, + "transitions": [ + { "var": "isNotAway", "state": "awayOutro" } + ] + }, + { + "id": "awayOutro", + "interpTarget": 3, + "interpDuration": 3, + "transitions": [ + { "var": "awayOutroOnDone", "state": "idle" } ] } ] @@ -704,6 +735,42 @@ "children": [] } ] + }, + { + "id": "awayIntro", + "type": "clip", + "data": { + "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/kneel/kneel.fbx", + "startFrame": 0.0, + "endFrame": 83.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "away", + "type": "clip", + "data": { + "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/kneel/kneel.fbx", + "startFrame": 83.0, + "endFrame": 84.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "awayOutro", + "type": "clip", + "data": { + "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/kneel/kneel.fbx", + "startFrame": 84.0, + "endFrame": 167.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] } ] } From 1b7ed3d847fa71d6df316bf36755b43daedf4c20 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 2 Nov 2015 20:40:40 -0800 Subject: [PATCH 03/11] away script --- examples/away.js | 84 ++++++++++++++++++++++++++++++++++++++ examples/defaultScripts.js | 1 + 2 files changed, 85 insertions(+) create mode 100644 examples/away.js diff --git a/examples/away.js b/examples/away.js new file mode 100644 index 0000000000..9fd688dbb7 --- /dev/null +++ b/examples/away.js @@ -0,0 +1,84 @@ +"use strict"; +/*jslint vars: true, plusplus: true*/ +/*global HMD, AudioDevice, MyAvatar, Controller, Script, Overlays, print*/ + +// Goes into "paused" when the '.' key (and automatically when started in HMD), and normal when pressing any key. +// See MAIN CONTROL, below, for what "paused" actually does. + +var OVERLAY_DATA = { + text: "Paused:\npress any key to continue", + font: {size: 75}, + color: {red: 200, green: 255, blue: 255}, + alpha: 0.9 +}; + +// ANIMATION +// We currently don't have play/stopAnimation integrated with the animation graph, but we can get the same effect +// using an animation graph with a state that we turn on and off through the animation var defined with that state. +var awayAnimationHandlerId, activeAnimationHandlerId; +function playAwayAnimation() { + function animateAway() { + return {isAway: true, isNotAway: false, isNotMoving: false}; + } + awayAnimationHandlerId = MyAvatar.addAnimationStateHandler(animateAway, null); +} +function stopAwayAnimation() { + MyAvatar.removeAnimationStateHandler(awayAnimationHandlerId); + function animateActive(state) { + if (!state.isAway) { // Once the right state gets reflected back to us, we don't need the hander any more. + // But we are locked against handler changes during the execution of a handler, so remove asynchronously. + Script.setTimeout(function () { MyAvatar.removeAnimationStateHandler(activeAnimationHandlerId); }, 0); + } + return {isAway: false, isNotAway: true}; // IWBNI we had a way of deleting an anim var. + } + activeAnimationHandlerId = MyAvatar.addAnimationStateHandler(animateActive, ['isAway']); +} + +// OVERLAY +var overlay = Overlays.addOverlay("text", OVERLAY_DATA); +function showOverlay() { + var screen = Controller.getViewportDimensions(); + Overlays.editOverlay(overlay, {visible: true, x: screen.x / 4, y: screen.y / 4}); +} +function hideOverlay() { + Overlays.editOverlay(overlay, {visible: false}); +} +hideOverlay(); + + +// MAIN CONTROL +var wasMuted, isAway; +function goAway() { + if (isAway) { + return; + } + isAway = true; + print('going "away"'); + wasMuted = AudioDevice.getMuted(); + if (!wasMuted) { + AudioDevice.toggleMute(); + } + MyAvatar.setEnableMeshVisible(false); // just for our own display, without changing point of view + playAwayAnimation(); // animation is still seen by others + showOverlay(); +} +function goActive(event) { + if (!isAway) { + if (event.text === '.') { + goAway(); + } + return; + } + isAway = false; + print('going "active"'); + if (!wasMuted) { + AudioDevice.toggleMute(); + } + MyAvatar.setEnableMeshVisible(true); // IWBNI we respected Developer->Avatar->Draw Mesh setting. + stopAwayAnimation(); + hideOverlay(); +} +Controller.keyPressEvent.connect(goActive); +if (HMD.active) { + goAway(); +} diff --git a/examples/defaultScripts.js b/examples/defaultScripts.js index 53e7e43aa9..6efe6edef3 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("away.js"); Script.load("progress.js"); Script.load("edit.js"); Script.load("selectAudioDevice.js"); From a7162eefbebbc550548f9eba209331643a7c0deb Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Tue, 3 Nov 2015 13:10:25 -0800 Subject: [PATCH 04/11] Add alphaVar for ik. --- .../resources/meshes/defaultAvatar_full/avatar-animation.json | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json index 9398b94890..df8b9b16c8 100644 --- a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json +++ b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json @@ -5,6 +5,7 @@ "type": "overlay", "data": { "alpha": 1.0, + "alphaVar": "ikOverlayAlpha", "boneSet": "fullBody" }, "children": [ From fb4174b9a2753fbf280c6e59520264e360589bc5 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Tue, 3 Nov 2015 13:11:31 -0800 Subject: [PATCH 05/11] Control alphaVar, and deal with overlapping cycles. --- examples/away.js | 46 +++++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/examples/away.js b/examples/away.js index 9fd688dbb7..c183f236fd 100644 --- a/examples/away.js +++ b/examples/away.js @@ -5,6 +5,7 @@ // Goes into "paused" when the '.' key (and automatically when started in HMD), and normal when pressing any key. // See MAIN CONTROL, below, for what "paused" actually does. +var IK_WINDOW_AFTER_GOING_ACTIVE = 3000; // milliseconds var OVERLAY_DATA = { text: "Paused:\npress any key to continue", font: {size: 75}, @@ -15,23 +16,41 @@ var OVERLAY_DATA = { // ANIMATION // We currently don't have play/stopAnimation integrated with the animation graph, but we can get the same effect // using an animation graph with a state that we turn on and off through the animation var defined with that state. -var awayAnimationHandlerId, activeAnimationHandlerId; +var awayAnimationHandlerId, activeAnimationHandlerId, stopper; function playAwayAnimation() { function animateAway() { - return {isAway: true, isNotAway: false, isNotMoving: false}; + return {isAway: true, isNotAway: false, isNotMoving: false, ikOverlayAlpha: 0.0}; + } + if (stopper) { + Script.clearTimeout(stopper); + MyAvatar.removeAnimationStateHandler(activeAnimationHandlerId); // do it now, before making new assignment } awayAnimationHandlerId = MyAvatar.addAnimationStateHandler(animateAway, null); } function stopAwayAnimation() { MyAvatar.removeAnimationStateHandler(awayAnimationHandlerId); + if (stopper) { print('WARNING: unexpected double stop'); return; } + // How do we know when to turn ikOverlayAlpha back on? + // It cannot be as soon as we want to stop the away animation, because then things will look goofy as we come out of that animation. + // (Imagine an away animation that sits or kneels, and then stands back up when coming out of it. If head is at the HMD, then it won't + // want to track the standing up animation.) + // Our standard anim graph flips 'awayOutroOnDone' for one frame, but it's a trigger (not an animVar) and other folks might use different graphs. + // So... Just give us a fixed amount of time to be done with animation, before we turn ik back on. + var backToNormal = false; + stopper = Script.setTimeout(function () { + backToNormal = true; + stopper = false; + }, IK_WINDOW_AFTER_GOING_ACTIVE); function animateActive(state) { - if (!state.isAway) { // Once the right state gets reflected back to us, we don't need the hander any more. - // But we are locked against handler changes during the execution of a handler, so remove asynchronously. - Script.setTimeout(function () { MyAvatar.removeAnimationStateHandler(activeAnimationHandlerId); }, 0); - } - return {isAway: false, isNotAway: true}; // IWBNI we had a way of deleting an anim var. + if (state.ikOverlayAlpha) { + // Once the right state gets reflected back to us, we don't need the hander any more. + // But we are locked against handler changes during the execution of a handler, so remove asynchronously. + Script.setTimeout(function () { MyAvatar.removeAnimationStateHandler(activeAnimationHandlerId); }, 0); + } + // It might be cool to "come back to life" by fading the ik overlay back in over a short time. But let's see how this goes. + return {isAway: false, isNotAway: true, ikOverlayAlpha: backToNormal ? 1.0 : 0.0}; // IWBNI we had a way of deleting an anim var. } - activeAnimationHandlerId = MyAvatar.addAnimationStateHandler(animateActive, ['isAway']); + activeAnimationHandlerId = MyAvatar.addAnimationStateHandler(animateActive, ['isAway', 'isNotAway', 'isNotMoving', 'ikOverlayAlpha']); } // OVERLAY @@ -48,8 +67,8 @@ hideOverlay(); // MAIN CONTROL var wasMuted, isAway; -function goAway() { - if (isAway) { +function goAway(event) { + if (isAway || event.isAutoRepeat) { // isAutoRepeat is true when held down (or when Windows feels like it) return; } isAway = true; @@ -63,9 +82,9 @@ function goAway() { showOverlay(); } function goActive(event) { - if (!isAway) { + if (!isAway || event.isAutoRepeat) { if (event.text === '.') { - goAway(); + goAway(event); } return; } @@ -79,6 +98,7 @@ function goActive(event) { hideOverlay(); } Controller.keyPressEvent.connect(goActive); +Script.scriptEnding.connect(goActive); if (HMD.active) { - goAway(); + goAway({}); // give a dummy event object } From 4bf98613505631009bb9b799d11d81bc9f3d3fa9 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Tue, 3 Nov 2015 15:36:02 -0800 Subject: [PATCH 06/11] Forgot license header. --- examples/away.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/examples/away.js b/examples/away.js index c183f236fd..dba26e0697 100644 --- a/examples/away.js +++ b/examples/away.js @@ -1,7 +1,16 @@ "use strict"; /*jslint vars: true, plusplus: true*/ /*global HMD, AudioDevice, MyAvatar, Controller, Script, Overlays, print*/ - +// +// away.js +// examples +// +// Created by Howard Stearns 11/3/15 +// Copyright 2015 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 +// // Goes into "paused" when the '.' key (and automatically when started in HMD), and normal when pressing any key. // See MAIN CONTROL, below, for what "paused" actually does. From fe12891f61dfa2ecefe1a3e1281a7bfeb1be7f36 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Wed, 4 Nov 2015 10:48:02 -0800 Subject: [PATCH 07/11] whitespace only --- examples/away.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/away.js b/examples/away.js index dba26e0697..eb841a07f8 100644 --- a/examples/away.js +++ b/examples/away.js @@ -31,8 +31,8 @@ function playAwayAnimation() { return {isAway: true, isNotAway: false, isNotMoving: false, ikOverlayAlpha: 0.0}; } if (stopper) { - Script.clearTimeout(stopper); - MyAvatar.removeAnimationStateHandler(activeAnimationHandlerId); // do it now, before making new assignment + Script.clearTimeout(stopper); + MyAvatar.removeAnimationStateHandler(activeAnimationHandlerId); // do it now, before making new assignment } awayAnimationHandlerId = MyAvatar.addAnimationStateHandler(animateAway, null); } @@ -47,16 +47,16 @@ function stopAwayAnimation() { // So... Just give us a fixed amount of time to be done with animation, before we turn ik back on. var backToNormal = false; stopper = Script.setTimeout(function () { - backToNormal = true; - stopper = false; + backToNormal = true; + stopper = false; }, IK_WINDOW_AFTER_GOING_ACTIVE); function animateActive(state) { - if (state.ikOverlayAlpha) { - // Once the right state gets reflected back to us, we don't need the hander any more. - // But we are locked against handler changes during the execution of a handler, so remove asynchronously. - Script.setTimeout(function () { MyAvatar.removeAnimationStateHandler(activeAnimationHandlerId); }, 0); - } - // It might be cool to "come back to life" by fading the ik overlay back in over a short time. But let's see how this goes. + if (state.ikOverlayAlpha) { + // Once the right state gets reflected back to us, we don't need the hander any more. + // But we are locked against handler changes during the execution of a handler, so remove asynchronously. + Script.setTimeout(function () { MyAvatar.removeAnimationStateHandler(activeAnimationHandlerId); }, 0); + } + // It might be cool to "come back to life" by fading the ik overlay back in over a short time. But let's see how this goes. return {isAway: false, isNotAway: true, ikOverlayAlpha: backToNormal ? 1.0 : 0.0}; // IWBNI we had a way of deleting an anim var. } activeAnimationHandlerId = MyAvatar.addAnimationStateHandler(animateActive, ['isAway', 'isNotAway', 'isNotMoving', 'ikOverlayAlpha']); From 883f9c09bf9c4e917dd4f35fe0be339c6ca2eb73 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Wed, 4 Nov 2015 10:49:12 -0800 Subject: [PATCH 08/11] add gratuitous whitespace --- examples/away.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/away.js b/examples/away.js index eb841a07f8..5cefd0d609 100644 --- a/examples/away.js +++ b/examples/away.js @@ -38,7 +38,10 @@ function playAwayAnimation() { } function stopAwayAnimation() { MyAvatar.removeAnimationStateHandler(awayAnimationHandlerId); - if (stopper) { print('WARNING: unexpected double stop'); return; } + if (stopper) { + print('WARNING: unexpected double stop'); + return; + } // How do we know when to turn ikOverlayAlpha back on? // It cannot be as soon as we want to stop the away animation, because then things will look goofy as we come out of that animation. // (Imagine an away animation that sits or kneels, and then stands back up when coming out of it. If head is at the HMD, then it won't From 3fdd7ca470d9aae563c5752ea65796063684a44f Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Wed, 4 Nov 2015 10:57:03 -0800 Subject: [PATCH 09/11] obscure the code and increase the likelihood of future whitespace-only diffs --- examples/away.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/away.js b/examples/away.js index 5cefd0d609..fa7925a545 100644 --- a/examples/away.js +++ b/examples/away.js @@ -98,16 +98,16 @@ function goActive(event) { if (event.text === '.') { goAway(event); } - return; + } else { + isAway = false; + print('going "active"'); + if (!wasMuted) { + AudioDevice.toggleMute(); + } + MyAvatar.setEnableMeshVisible(true); // IWBNI we respected Developer->Avatar->Draw Mesh setting. + stopAwayAnimation(); + hideOverlay(); } - isAway = false; - print('going "active"'); - if (!wasMuted) { - AudioDevice.toggleMute(); - } - MyAvatar.setEnableMeshVisible(true); // IWBNI we respected Developer->Avatar->Draw Mesh setting. - stopAwayAnimation(); - hideOverlay(); } Controller.keyPressEvent.connect(goActive); Script.scriptEnding.connect(goActive); From 4fd2027fb4400af3eacaeeaa57987d74307ee0a5 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Wed, 4 Nov 2015 11:42:21 -0800 Subject: [PATCH 10/11] change name --- examples/away.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/away.js b/examples/away.js index fa7925a545..516365218c 100644 --- a/examples/away.js +++ b/examples/away.js @@ -93,7 +93,7 @@ function goAway(event) { playAwayAnimation(); // animation is still seen by others showOverlay(); } -function goActive(event) { +function switchActiveState(event) { if (!isAway || event.isAutoRepeat) { if (event.text === '.') { goAway(event); @@ -109,8 +109,8 @@ function goActive(event) { hideOverlay(); } } -Controller.keyPressEvent.connect(goActive); -Script.scriptEnding.connect(goActive); +Controller.keyPressEvent.connect(switchActiveState); +Script.scriptEnding.connect(switchActiveState); if (HMD.active) { goAway({}); // give a dummy event object } From 8f65ee87bcc77a6cbecb9b287a118086e9415695 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Thu, 5 Nov 2015 13:19:29 -0800 Subject: [PATCH 11/11] Clean up script, go away when putting HMD (not just on startup), and clear stopper properly. --- examples/away.js | 55 ++++++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/examples/away.js b/examples/away.js index 516365218c..8cc3790200 100644 --- a/examples/away.js +++ b/examples/away.js @@ -32,6 +32,7 @@ function playAwayAnimation() { } if (stopper) { Script.clearTimeout(stopper); + stopper = false; MyAvatar.removeAnimationStateHandler(activeAnimationHandlerId); // do it now, before making new assignment } awayAnimationHandlerId = MyAvatar.addAnimationStateHandler(animateAway, null); @@ -79,8 +80,8 @@ hideOverlay(); // MAIN CONTROL var wasMuted, isAway; -function goAway(event) { - if (isAway || event.isAutoRepeat) { // isAutoRepeat is true when held down (or when Windows feels like it) +function goAway() { + if (isAway) { return; } isAway = true; @@ -93,24 +94,36 @@ function goAway(event) { playAwayAnimation(); // animation is still seen by others showOverlay(); } -function switchActiveState(event) { - if (!isAway || event.isAutoRepeat) { - if (event.text === '.') { - goAway(event); - } - } else { - isAway = false; - print('going "active"'); - if (!wasMuted) { - AudioDevice.toggleMute(); - } - MyAvatar.setEnableMeshVisible(true); // IWBNI we respected Developer->Avatar->Draw Mesh setting. - stopAwayAnimation(); - hideOverlay(); +function goActive() { + if (!isAway) { + return; } + isAway = false; + print('going "active"'); + if (!wasMuted) { + AudioDevice.toggleMute(); + } + MyAvatar.setEnableMeshVisible(true); // IWBNI we respected Developer->Avatar->Draw Mesh setting. + stopAwayAnimation(); + hideOverlay(); } -Controller.keyPressEvent.connect(switchActiveState); -Script.scriptEnding.connect(switchActiveState); -if (HMD.active) { - goAway({}); // give a dummy event object -} +Script.scriptEnding.connect(goActive); +Controller.keyPressEvent.connect(function (event) { + if (event.isAutoRepeat) { // isAutoRepeat is true when held down (or when Windows feels like it) + return; + } + if (!isAway && (event.text === '.')) { + goAway(); + } else { + goActive(); + } +}); +var wasHmdActive = false; +Script.update.connect(function () { + if (HMD.active !== wasHmdActive) { + wasHmdActive = !wasHmdActive; + if (wasHmdActive) { + goAway(); + } + } +});