fixed sounds. fixed constants

This commit is contained in:
DaveDubUK 2015-06-25 12:40:51 +07:00
parent ececf68f06
commit ce31e586b0
6 changed files with 121 additions and 134 deletions

View file

@ -2,16 +2,16 @@
<head> <head>
<link rel="stylesheet" type="text/css" href="walkStyle.css"> <link rel="stylesheet" type="text/css" href="walkStyle.css">
<script> <script>
function emitUpdate() { function emitUpdate() {
EventBridge.emitWebEvent(JSON.stringify({ EventBridge.emitWebEvent(JSON.stringify({
type: "update", type: "update",
armsFree: elArmsFree.checked, armsFree: elArmsFree.checked,
footstepSounds: elFootstepSounds.checked, makesFootStepSounds: elFootstepSounds.checked,
blenderPreRotations: elBlenderPreRotations.checked blenderPreRotations: elBlenderPreRotations.checked
})); }));
} }
function loaded() { function loaded() {
// assign form elements to vars // assign form elements to vars
var powerOn = true; var powerOn = true;
@ -23,17 +23,17 @@
if (window.EventBridge !== undefined) { if (window.EventBridge !== undefined) {
EventBridge.scriptEventReceived.connect(function(data) { EventBridge.scriptEventReceived.connect(function(data) {
data = JSON.parse(data); data = JSON.parse(data);
if (data.type == "update") { if (data.type == "update") {
if (data.armsFree !== undefined) { if (data.armsFree !== undefined) {
elArmsFree.checked = data.armsFree; elArmsFree.checked = data.armsFree;
} }
if (data.footstepSounds !== undefined) { if (data.makesFootStepSounds !== undefined) {
elFootstepSounds.checked = data.footstepSounds; elFootstepSounds.checked = data.makesFootStepSounds;
} }
if (data.blenderPreRotations !== undefined) { if (data.blenderPreRotations !== undefined) {
elBlenderPreRotations.checked = data.blenderPreRotations; elBlenderPreRotations.checked = data.blenderPreRotations;
} }
} }
}); });
} }
@ -50,8 +50,8 @@
} else { } else {
elPower.value = "Turn Animation On"; elPower.value = "Turn Animation On";
} }
}); });
// request initial values // request initial values
EventBridge.emitWebEvent(JSON.stringify({ type: 'init' })); EventBridge.emitWebEvent(JSON.stringify({ type: 'init' }));
} }
</script> </script>
@ -62,7 +62,7 @@
<div id="walk-settings-header"> <div id="walk-settings-header">
<input type="button" id="power" value="Turn Animation Off" style="margin-left:30px; margin-top:10px"></button> <input type="button" id="power" value="Turn Animation Off" style="margin-left:30px; margin-top:10px"></button>
</div> </div>
<div class="settings-section"> <div class="settings-section">
<label>Arms free</label> <label>Arms free</label>
<span> <span>

View file

@ -3,7 +3,7 @@
// version 1.3 // version 1.3
// //
// Created by David Wooldridge, June 2015 // Created by David Wooldridge, June 2015
// Copyright © 2014 - 2015 High Fidelity, Inc. // Copyright © 2014 - 2015 High Fidelity, Inc.
// //
// Exposes API for use by walk.js version 1.2+. // Exposes API for use by walk.js version 1.2+.
// //
@ -13,46 +13,11 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
// locomotion states // included here to ensure walkApi.js can be used as an API, separate from walk.js
const STATIC = 1; Script.include("./libraries/walkConstants.js");
const SURFACE_MOTION = 2;
const AIR_MOTION = 4;
// directions
const UP = 1;
const DOWN = 2;
const LEFT = 4;
const RIGHT = 8;
const FORWARDS = 16;
const BACKWARDS = 32;
const NONE = 64;
// waveshapes
const SAWTOOTH = 1;
const TRIANGLE = 2;
const SQUARE = 4;
// constants used by walk.js and walkApi.js
const MAX_WALK_SPEED = 2.9; // peak, by observation
const MAX_FT_WHEEL_INCREMENT = 25; // avoid fast walk when landing
const TOP_SPEED = 300;
const ON_SURFACE_THRESHOLD = 0.1; // height above surface to be considered as on the surface
const TRANSITION_COMPLETE = 1000;
const HIFI_PUBLIC_BUCKET = "https://hifi-public.s3.amazonaws.com/";
// constants used by walkApi.js
const MOVE_THRESHOLD = 0.075;
const ACCELERATION_THRESHOLD = 0.2; // detect stop to walking
const DECELERATION_THRESHOLD = -6; // detect walking to stop
const FAST_DECELERATION_THRESHOLD = -150; // detect flying to stop
const BOUNCE_ACCELERATION_THRESHOLD = 25; // used to ignore gravity influence fluctuations after landing
const GRAVITY_THRESHOLD = 3.0; // height above surface where gravity is in effect
const OVERCOME_GRAVITY_SPEED = 0.5; // reaction sensitivity to jumping under gravity
const LANDING_THRESHOLD = 0.35; // metres from a surface below which need to prepare for impact
const MAX_TRANSITION_RECURSION = 10; // how many nested transitions are permitted
Avatar = function() { Avatar = function() {
// if Hydras are connected, the only way to enable use is by never setting any rotations on the arm joints // if Hydras are connected, the only way to enable use is to never set any arm joint rotation
this.hydraCheck = function() { this.hydraCheck = function() {
// function courtesy of Thijs Wenker (frisbee.js) // function courtesy of Thijs Wenker (frisbee.js)
var numberOfButtons = Controller.getNumberOfButtons(); var numberOfButtons = Controller.getNumberOfButtons();
@ -75,8 +40,8 @@ Avatar = function() {
// settings // settings
this.headFree = true; this.headFree = true;
this.armsFree = this.hydraCheck(); // automatically sets true to enable Hydra support - temporary fix this.armsFree = this.hydraCheck(); // automatically sets true to enable Hydra support - temporary fix
this.makesFootStepSounds = false; this.makesFootStepSounds = true;
this.isBlenderExport = false; // temporary fix this.blenderPreRotations = false; // temporary fix
this.animationSet = undefined; // currently just one animation set this.animationSet = undefined; // currently just one animation set
this.setAnimationSet = function(animationSet) { this.setAnimationSet = function(animationSet) {
this.animationSet = animationSet; this.animationSet = animationSet;
@ -123,7 +88,7 @@ Avatar = function() {
this.calibration.hipsToFeet = MyAvatar.getJointPosition("Hips").y - MyAvatar.getJointPosition("RightToeBase").y; this.calibration.hipsToFeet = MyAvatar.getJointPosition("Hips").y - MyAvatar.getJointPosition("RightToeBase").y;
// maybe measuring before Blender pre-rotations have been applied? // maybe measuring before Blender pre-rotations have been applied?
if (this.calibration.hipsToFeet < 0 && this.isBlenderExport) { if (this.calibration.hipsToFeet < 0 && this.blenderPreRotations) {
this.calibration.hipsToFeet *= -1; this.calibration.hipsToFeet *= -1;
} }
@ -165,7 +130,6 @@ Avatar = function() {
// footsteps // footsteps
this.nextStep = RIGHT; // the first step is right, because the waveforms say so this.nextStep = RIGHT; // the first step is right, because the waveforms say so
this.leftAudioInjector = null; this.leftAudioInjector = null;
this.rightAudioInjector = null; this.rightAudioInjector = null;
this.makeFootStepSound = function() { this.makeFootStepSound = function() {
@ -173,16 +137,18 @@ Avatar = function() {
const SPEED_THRESHOLD = 0.4; const SPEED_THRESHOLD = 0.4;
const VOLUME_ATTENUATION = 0.8; const VOLUME_ATTENUATION = 0.8;
const MIN_VOLUME = 0.5; const MIN_VOLUME = 0.5;
var volume = Vec3.length(motion.velocity) > SPEED_THRESHOLD ?
VOLUME_ATTENUATION * Vec3.length(motion.velocity) / MAX_WALK_SPEED : MIN_VOLUME;
volume = volume > 1 ? 1 : volume; // occurs when landing at speed - can walk faster than max walking speed
var options = { var options = {
position: Vec3.sum(MyAvatar.position, {x:0, y: -this.calibration.hipsToFeet, z:0}), position: Vec3.sum(MyAvatar.position, {x:0, y: -this.calibration.hipsToFeet, z:0}),
volume: Vec3.length(motion.velocity) > SPEED_THRESHOLD ? volume: volume
VOLUME_ATTENUATION * Vec3.length(motion.velocity) / MAX_WALK_SPEED : MIN_VOLUME
}; };
if (this.nextStep === RIGHT) { if (this.nextStep === RIGHT) {
if (this.rightAudioInjector === null) { if (this.rightAudioInjector === null) {
this.rightAudioInjector = Audio.playSound(walkAssets.footsteps[0], options); this.rightAudioInjector = Audio.playSound(walkAssets.footsteps[0], options);
} else { } else {
//this.rightAudioInjector.setOptions(options); this.rightAudioInjector.setOptions(options);
this.rightAudioInjector.restart(); this.rightAudioInjector.restart();
} }
this.nextStep = LEFT; this.nextStep = LEFT;
@ -190,7 +156,7 @@ Avatar = function() {
if (this.leftAudioInjector === null) { if (this.leftAudioInjector === null) {
this.leftAudioInjector = Audio.playSound(walkAssets.footsteps[1], options); this.leftAudioInjector = Audio.playSound(walkAssets.footsteps[1], options);
} else { } else {
//this.leftAudioInjector.setOptions(options); this.leftAudioInjector.setOptions(options);
this.leftAudioInjector.restart(); this.leftAudioInjector.restart();
} }
this.nextStep = RIGHT; this.nextStep = RIGHT;
@ -200,6 +166,7 @@ Avatar = function() {
// constructor for the Motion object // constructor for the Motion object
Motion = function() { Motion = function() {
this.isLive = true;
// locomotion status // locomotion status
this.state = STATIC; this.state = STATIC;
this.nextState = STATIC; this.nextState = STATIC;
@ -212,14 +179,6 @@ Motion = function() {
this.isComingToHalt = false; this.isComingToHalt = false;
this.directedAcceleration = 0; this.directedAcceleration = 0;
// settings
this.isLive = true;
this.calibration = {
PITCH_MAX: 60,
ROLL_MAX: 80,
DELTA_YAW_MAX: 1.7
}
// used to make sure at least one step has been taken when transitioning from a walk cycle // used to make sure at least one step has been taken when transitioning from a walk cycle
this.elapsedFTDegrees = 0; this.elapsedFTDegrees = 0;
@ -360,6 +319,7 @@ Motion = function() {
(movingDirectlyUpOrDown && !isOnSurface)); (movingDirectlyUpOrDown && !isOnSurface));
var staticToSurfaceMotion = surfaceMotion && !motion.isComingToHalt && !movingDirectlyUpOrDown && var staticToSurfaceMotion = surfaceMotion && !motion.isComingToHalt && !movingDirectlyUpOrDown &&
!this.isDecelerating && lateralVelocity > MOVE_THRESHOLD; !this.isDecelerating && lateralVelocity > MOVE_THRESHOLD;
if (staticToAirMotion) { if (staticToAirMotion) {
this.nextState = AIR_MOTION; this.nextState = AIR_MOTION;
} else if (staticToSurfaceMotion) { } else if (staticToSurfaceMotion) {
@ -376,6 +336,7 @@ Motion = function() {
var surfaceMotionToAirMotion = (acceleratingAndAirborne || goingTooFastToWalk || movingDirectlyUpOrDown) && var surfaceMotionToAirMotion = (acceleratingAndAirborne || goingTooFastToWalk || movingDirectlyUpOrDown) &&
(!surfaceMotion && isTakingOff) || (!surfaceMotion && isTakingOff) ||
(!surfaceMotion && this.isMoving && !isComingInToLand); (!surfaceMotion && this.isMoving && !isComingInToLand);
if (surfaceMotionToStatic) { if (surfaceMotionToStatic) {
// working on the assumption that stopping is now inevitable // working on the assumption that stopping is now inevitable
if (!motion.isComingToHalt && isOnSurface) { if (!motion.isComingToHalt && isOnSurface) {
@ -392,6 +353,7 @@ Motion = function() {
case AIR_MOTION: case AIR_MOTION:
var airMotionToSurfaceMotion = (surfaceMotion || aboutToLand) && !movingDirectlyUpOrDown; var airMotionToSurfaceMotion = (surfaceMotion || aboutToLand) && !movingDirectlyUpOrDown;
var airMotionToStatic = !this.isMoving && this.direction === this.lastDirection; var airMotionToStatic = !this.isMoving && this.direction === this.lastDirection;
if (airMotionToSurfaceMotion){ if (airMotionToSurfaceMotion){
this.nextState = SURFACE_MOTION; this.nextState = SURFACE_MOTION;
} else if (airMotionToStatic) { } else if (airMotionToStatic) {
@ -492,7 +454,7 @@ animationOperations = (function() {
var joint = animation.joints[jointName]; var joint = animation.joints[jointName];
var jointRotations = {x:0, y:0, z:0}; var jointRotations = {x:0, y:0, z:0};
if (avatar.isBlenderExport) { if (avatar.blenderPreRotations) {
jointRotations = Vec3.sum(jointRotations, walkAssets.blenderPreRotations.joints[jointName]); jointRotations = Vec3.sum(jointRotations, walkAssets.blenderPreRotations.joints[jointName]);
} }
@ -670,7 +632,7 @@ TransitionParameters = function() {
this.duration = 0.5; this.duration = 0.5;
this.easingLower = {x:0.25, y:0.75}; this.easingLower = {x:0.25, y:0.75};
this.easingUpper = {x:0.75, y:0.25}; this.easingUpper = {x:0.75, y:0.25};
this.reachPoseNames = []; this.reachPoses = [];
} }
const QUARTER_CYCLE = 90; const QUARTER_CYCLE = 90;
@ -710,8 +672,8 @@ Transition = function(nextAnimation, lastAnimation, lastTransition, playTransiti
walkAssets.getTransitionParameters(lastAnimation, nextAnimation, this.parameters); walkAssets.getTransitionParameters(lastAnimation, nextAnimation, this.parameters);
// fire up any reach poses for this transition // fire up any reach poses for this transition
if (playTransitionReachPoses) { if (playTransitionReachPoses) {
for (poseName in this.parameters.reachPoseNames) { for (poseName in this.parameters.reachPoses) {
this.liveReachPoses.push(new ReachPose(this.parameters.reachPoseNames[poseName])); this.liveReachPoses.push(new ReachPose(this.parameters.reachPoses[poseName]));
} }
} }
} }

View file

@ -0,0 +1,54 @@
//
// walkConstants.js
// version 1.0
//
// Created by David Wooldridge, June 2015
// Copyright © 2015 High Fidelity, Inc.
//
// Provides constants necessary for the operation of the walk.js script and the walkApi.js script
//
// Editing tools for animation data files available here: https://github.com/DaveDubUK/walkTools
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
// locomotion states
STATIC = 1;
SURFACE_MOTION = 2;
AIR_MOTION = 4;
// directions
UP = 1;
DOWN = 2;
LEFT = 4;
RIGHT = 8;
FORWARDS = 16;
BACKWARDS = 32;
NONE = 64;
// waveshapes
SAWTOOTH = 1;
TRIANGLE = 2;
SQUARE = 4;
// used by walk.js and walkApi.js
MAX_WALK_SPEED = 2.9; // peak, by observation
MAX_FT_WHEEL_INCREMENT = 25; // avoid fast walk when landing
TOP_SPEED = 300;
ON_SURFACE_THRESHOLD = 0.1; // height above surface to be considered as on the surface
TRANSITION_COMPLETE = 1000;
PITCH_MAX = 60; // maximum speed induced pitch
ROLL_MAX = 80; // maximum speed induced leaning / banking
DELTA_YAW_MAX = 1.7; // maximum change in yaw in rad/s
// used by walkApi.js only
MOVE_THRESHOLD = 0.075; // movement dead zone
ACCELERATION_THRESHOLD = 0.2; // detect stop to walking
DECELERATION_THRESHOLD = -6; // detect walking to stop
FAST_DECELERATION_THRESHOLD = -150; // detect flying to stop
BOUNCE_ACCELERATION_THRESHOLD = 25; // used to ignore gravity influence fluctuations after landing
GRAVITY_THRESHOLD = 3.0; // height above surface where gravity is in effect
OVERCOME_GRAVITY_SPEED = 0.5; // reaction sensitivity to jumping under gravity
LANDING_THRESHOLD = 0.35; // metres from a surface below which need to prepare for impact
MAX_TRANSITION_RECURSION = 10; // how many nested transitions are permitted

View file

@ -2,8 +2,8 @@
// walkFilters.js // walkFilters.js
// version 1.1 // version 1.1
// //
// Created by David Wooldridge, Autumn 2014 // Created by David Wooldridge, June 2015
// Copyright © 2014 - 2015 High Fidelity, Inc. // Copyright © 2014 - 2015 High Fidelity, Inc.
// //
// Provides a variety of filters for use by the walk.js script v1.2+ // Provides a variety of filters for use by the walk.js script v1.2+
// //

View file

@ -3,7 +3,7 @@
// version 0.1 // version 0.1
// //
// Created by David Wooldridge, June 2015 // Created by David Wooldridge, June 2015
// Copyright © 2014 - 2015 High Fidelity, Inc. // Copyright © 2015 High Fidelity, Inc.
// //
// Presents settings for walk.js // Presents settings for walk.js
// //
@ -31,7 +31,7 @@ WalkSettings = function() {
function mousePressEvent(event) { function mousePressEvent(event) {
if (Overlays.getOverlayAtPoint(event) === minimisedTab) { if (Overlays.getOverlayAtPoint(event) === minimisedTab) {
_visible = !_visible; _visible = !_visible;
_webView.setVisible(_visible); _webWindow.setVisible(_visible);
} }
} }
Controller.mousePressEvent.connect(mousePressEvent); Controller.mousePressEvent.connect(mousePressEvent);
@ -55,7 +55,7 @@ WalkSettings = function() {
} }
if (_shift && (event.text === 'o' || event.text === 'O')) { if (_shift && (event.text === 'o' || event.text === 'O')) {
_visible = !_visible; _visible = !_visible;
_webView.setVisible(_visible); _webWindow.setVisible(_visible);
} }
} }
function keyReleaseEvent(event) { function keyReleaseEvent(event) {
@ -67,30 +67,29 @@ WalkSettings = function() {
Controller.keyReleaseEvent.connect(keyReleaseEvent); Controller.keyReleaseEvent.connect(keyReleaseEvent);
// web window // web window
var _url = Script.resolvePath('html/walkSettings.html');
const PANEL_WIDTH = 200; const PANEL_WIDTH = 200;
const PANEL_HEIGHT = 180; const PANEL_HEIGHT = 180;
var _webView = new WebWindow('Walk Settings', _url, PANEL_WIDTH, PANEL_HEIGHT, false); var _url = Script.resolvePath('html/walkSettings.html');
_webView.setVisible(false); var _webWindow = new WebWindow('Walk Settings', _url, PANEL_WIDTH, PANEL_HEIGHT, false);
_webWindow.setVisible(false);
_webView.eventBridge.webEventReceived.connect(function(data) { _webWindow.eventBridge.webEventReceived.connect(function(data) {
data = JSON.parse(data); data = JSON.parse(data);
if (data.type == "init") { if (data.type == "init") {
// send the current settings to the window // send the current settings to the window
_webView.eventBridge.emitScriptEvent(JSON.stringify({ _webWindow.eventBridge.emitScriptEvent(JSON.stringify({
type: "update", type: "update",
armsFree: avatar.armsFree, armsFree: avatar.armsFree,
footstepSounds: avatar.makesFootStepSounds, makesFootStepSounds: avatar.makesFootStepSounds,
blenderPreRotations: avatar.isBlenderExport blenderPreRotations: avatar.blenderPreRotations
})); }));
} else if (data.type == "powerToggle") { } else if (data.type == "powerToggle") {
motion.isLive = !motion.isLive; motion.isLive = !motion.isLive;
} else if (data.type == "update") { } else if (data.type == "update") {
// receive settings from the window // receive settings from the window
avatar.armsFree = data.armsFree; avatar.armsFree = data.armsFree;
avatar.makesFootStepSounds = data.footstepSounds; avatar.makesFootStepSounds = data.makesFootStepSounds;
avatar.isBlenderExport = data.blenderPreRotations; avatar.blenderPreRotations = data.blenderPreRotations;
} }
}); });
}; };

View file

@ -3,7 +3,7 @@
// version 1.25 // version 1.25
// //
// Created by David Wooldridge, June 2015 // Created by David Wooldridge, June 2015
// Copyright © 2014 - 2015 High Fidelity, Inc. // Copyright © 2014 - 2015 High Fidelity, Inc.
// //
// Animates an avatar using procedural animation techniques. // Animates an avatar using procedural animation techniques.
// //
@ -13,61 +13,25 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
// locomotion states // animations, reach poses, reach pose parameters, transitions, transition parameters, sounds, image/s and reference files
var STATIC = 1;
var SURFACE_MOTION = 2;
var AIR_MOTION = 4;
// directions
var UP = 1;
var DOWN = 2;
var LEFT = 4;
var RIGHT = 8;
var FORWARDS = 16;
var BACKWARDS = 32;
var NONE = 64;
// waveshapes
var SAWTOOTH = 1;
var TRIANGLE = 2;
var SQUARE = 4;
// constants
const MAX_WALK_SPEED = 2.9; // peak, by observation
const MAX_FT_WHEEL_INCREMENT = 25; // avoid fast walk when landing
const TOP_SPEED = 300;
const ON_SURFACE_THRESHOLD = 0.1; // height above surface to be considered as on the surface
const TRANSITION_COMPLETE = 1000;
const HIFI_PUBLIC_BUCKET = "https://hifi-public.s3.amazonaws.com/"; const HIFI_PUBLIC_BUCKET = "https://hifi-public.s3.amazonaws.com/";
// path to animations, reach-poses, reachPoses, transitions, overlay images and reference files
var pathToAssets = HIFI_PUBLIC_BUCKET + "procedural-animator/assets/"; var pathToAssets = HIFI_PUBLIC_BUCKET + "procedural-animator/assets/";
Script.include([ Script.include([
"./libraries/walkConstants.js",
"./libraries/walkFilters.js", "./libraries/walkFilters.js",
"./libraries/walkApi.js", "./libraries/walkApi.js",
pathToAssets + "walkAssets.js" pathToAssets + "walkAssets.js"
]); ]);
// construct Avatar and Motion // construct Avatar, Motion and (null) Transition
var avatar = new Avatar(); var avatar = new Avatar();
var motion = new Motion(); var motion = new Motion();
// create settings dialog
Script.include("./libraries/walkSettings.js");
// create and initialise Transition
var nullTransition = new Transition(); var nullTransition = new Transition();
motion.currentTransition = nullTransition; motion.currentTransition = nullTransition;
// motion smoothing / damping filters // create settings (gets initial values from avatar)
var FLY_BLEND_DAMPING = 50; Script.include("./libraries/walkSettings.js");
var leanPitchSmoothingFilter = filter.createButterworthFilter();
var leanRollSmoothingFilter = filter.createButterworthFilter();
var flyUpFilter = filter.createAveragingFilter(FLY_BLEND_DAMPING);
var flyDownFilter = filter.createAveragingFilter(FLY_BLEND_DAMPING);
var flyForwardFilter = filter.createAveragingFilter(FLY_BLEND_DAMPING);
var flyBackwardFilter = filter.createAveragingFilter(FLY_BLEND_DAMPING);
// Main loop // Main loop
Script.update.connect(function(deltaTime) { Script.update.connect(function(deltaTime) {
@ -80,8 +44,8 @@ Script.update.connect(function(deltaTime) {
// decide which animation should be playing // decide which animation should be playing
selectAnimation(); selectAnimation();
// turn the frequency time wheels and determine stride length // advance the animation cycle/s by the correct amount/s
determineStride(); advanceAnimations();
// update the progress of any live transitions // update the progress of any live transitions
updateTransitions(); updateTransitions();
@ -89,7 +53,7 @@ Script.update.connect(function(deltaTime) {
// apply translation and rotations // apply translation and rotations
renderMotion(); renderMotion();
// record this frame's parameters // save this frame's parameters
motion.saveHistory(); motion.saveHistory();
} }
}); });
@ -130,6 +94,13 @@ function setTransition(nextAnimation, playTransitionReachPoses) {
} }
} }
// fly animation blending: smoothing / damping filters
const FLY_BLEND_DAMPING = 50;
var flyUpFilter = filter.createAveragingFilter(FLY_BLEND_DAMPING);
var flyDownFilter = filter.createAveragingFilter(FLY_BLEND_DAMPING);
var flyForwardFilter = filter.createAveragingFilter(FLY_BLEND_DAMPING);
var flyBackwardFilter = filter.createAveragingFilter(FLY_BLEND_DAMPING);
// select / blend the appropriate animation for the current state of motion // select / blend the appropriate animation for the current state of motion
function selectAnimation() { function selectAnimation() {
var playTransitionReachPoses = true; var playTransitionReachPoses = true;
@ -259,7 +230,7 @@ function selectAnimation() {
} }
// determine the length of stride. advance the frequency time wheels. advance frequency time wheels for any live transitions // determine the length of stride. advance the frequency time wheels. advance frequency time wheels for any live transitions
function determineStride() { function advanceAnimations() {
var wheelAdvance = 0; var wheelAdvance = 0;
// turn the frequency time wheel // turn the frequency time wheel
@ -338,7 +309,6 @@ function updateTransitions() {
} }
} }
} }
// update the Transition progress
if (motion.currentTransition.updateProgress() === TRANSITION_COMPLETE) { if (motion.currentTransition.updateProgress() === TRANSITION_COMPLETE) {
motion.currentTransition = nullTransition; motion.currentTransition = nullTransition;
} }
@ -346,6 +316,7 @@ function updateTransitions() {
} }
// helper function for renderMotion(). calculate the amount to lean forwards (or backwards) based on the avi's velocity // helper function for renderMotion(). calculate the amount to lean forwards (or backwards) based on the avi's velocity
var leanPitchSmoothingFilter = filter.createButterworthFilter();
function getLeanPitch() { function getLeanPitch() {
var leanProgress = 0; var leanProgress = 0;
@ -356,10 +327,11 @@ function getLeanPitch() {
} }
// use filters to shape the walking acceleration response // use filters to shape the walking acceleration response
leanProgress = leanPitchSmoothingFilter.process(leanProgress); leanProgress = leanPitchSmoothingFilter.process(leanProgress);
return motion.calibration.PITCH_MAX * leanProgress; return PITCH_MAX * leanProgress;
} }
// helper function for renderMotion(). calculate the angle at which to bank into corners whilst turning // helper function for renderMotion(). calculate the angle at which to bank into corners whilst turning
var leanRollSmoothingFilter = filter.createButterworthFilter();
function getLeanRoll() { function getLeanRoll() {
var leanRollProgress = 0; var leanRollProgress = 0;
var linearContribution = 0; var linearContribution = 0;
@ -368,7 +340,7 @@ function getLeanRoll() {
if (Vec3.length(motion.velocity) > 0) { if (Vec3.length(motion.velocity) > 0) {
linearContribution = (Math.log(Vec3.length(motion.velocity) / TOP_SPEED) + LOG_SCALER) / LOG_SCALER; linearContribution = (Math.log(Vec3.length(motion.velocity) / TOP_SPEED) + LOG_SCALER) / LOG_SCALER;
} }
var angularContribution = Math.abs(motion.yawDelta) / motion.calibration.DELTA_YAW_MAX; var angularContribution = Math.abs(motion.yawDelta) / DELTA_YAW_MAX;
leanRollProgress = linearContribution; leanRollProgress = linearContribution;
leanRollProgress *= angularContribution; leanRollProgress *= angularContribution;
// shape the response curve // shape the response curve
@ -382,7 +354,7 @@ function getLeanRoll() {
} }
// filter progress // filter progress
leanRollProgress = leanRollSmoothingFilter.process(turnSign * leanRollProgress); leanRollProgress = leanRollSmoothingFilter.process(turnSign * leanRollProgress);
return motion.calibration.ROLL_MAX * leanRollProgress; return ROLL_MAX * leanRollProgress;
} }
// animate the avatar using sine waves, geometric waveforms and harmonic generators // animate the avatar using sine waves, geometric waveforms and harmonic generators