This commit is contained in:
Howard Stearns 2015-11-04 10:46:16 -08:00
commit 7b9245022c
2 changed files with 44 additions and 14 deletions

View file

@ -1,10 +1,20 @@
"use strict"; "use strict";
/*jslint vars: true, plusplus: true*/ /*jslint vars: true, plusplus: true*/
/*global HMD, AudioDevice, MyAvatar, Controller, Script, Overlays, print*/ /*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. // 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. // See MAIN CONTROL, below, for what "paused" actually does.
var IK_WINDOW_AFTER_GOING_ACTIVE = 3000; // milliseconds
var OVERLAY_DATA = { var OVERLAY_DATA = {
text: "Paused:\npress any key to continue", text: "Paused:\npress any key to continue",
font: {size: 75}, font: {size: 75},
@ -15,23 +25,41 @@ var OVERLAY_DATA = {
// ANIMATION // ANIMATION
// We currently don't have play/stopAnimation integrated with the animation graph, but we can get the same effect // 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. // 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 playAwayAnimation() {
function animateAway() { 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); awayAnimationHandlerId = MyAvatar.addAnimationStateHandler(animateAway, null);
} }
function stopAwayAnimation() { function stopAwayAnimation() {
MyAvatar.removeAnimationStateHandler(awayAnimationHandlerId); 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) { function animateActive(state) {
if (!state.isAway) { // Once the right state gets reflected back to us, we don't need the hander any more. if (state.ikOverlayAlpha) {
// But we are locked against handler changes during the execution of a handler, so remove asynchronously. // Once the right state gets reflected back to us, we don't need the hander any more.
Script.setTimeout(function () { MyAvatar.removeAnimationStateHandler(activeAnimationHandlerId); }, 0); // 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. }
// 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 // OVERLAY
@ -48,8 +76,8 @@ hideOverlay();
// MAIN CONTROL // MAIN CONTROL
var wasMuted, isAway; var wasMuted, isAway;
function goAway() { function goAway(event) {
if (isAway) { if (isAway || event.isAutoRepeat) { // isAutoRepeat is true when held down (or when Windows feels like it)
return; return;
} }
isAway = true; isAway = true;
@ -63,9 +91,9 @@ function goAway() {
showOverlay(); showOverlay();
} }
function goActive(event) { function goActive(event) {
if (!isAway) { if (!isAway || event.isAutoRepeat) {
if (event.text === '.') { if (event.text === '.') {
goAway(); goAway(event);
} }
return; return;
} }
@ -79,6 +107,7 @@ function goActive(event) {
hideOverlay(); hideOverlay();
} }
Controller.keyPressEvent.connect(goActive); Controller.keyPressEvent.connect(goActive);
Script.scriptEnding.connect(goActive);
if (HMD.active) { if (HMD.active) {
goAway(); goAway({}); // give a dummy event object
} }

View file

@ -5,6 +5,7 @@
"type": "overlay", "type": "overlay",
"data": { "data": {
"alpha": 1.0, "alpha": 1.0,
"alphaVar": "ikOverlayAlpha",
"boneSet": "fullBody" "boneSet": "fullBody"
}, },
"children": [ "children": [