From 7a1f7bd41888a47411420e45428e89319a728296 Mon Sep 17 00:00:00 2001 From: DaveDubUK Date: Wed, 5 Nov 2014 20:11:11 +0000 Subject: [PATCH 01/20] Update to walk.js v 1.1 Revised code structure (see /libraries for new files), walk animation completely overhauled (now using geometric wave generators, Fourier synthesis and Butterworth LP filtering for selected motion curve construction), redesigned sidestepping animations, tweaked flying animations, decreased maximum walk speed in Interface to more natural human value, improved Hydra support, added support for Leap motion, animation file sizes optimised, cleared out code used to work around now fixed bugs, lots of minor tweaks and improvements. walk.js is now under 100,000 characters, but I had to use tabs instead of 4 spaces to get it below the threshold. --- examples/libraries/walkApi.js | 409 ++ examples/libraries/walkFilters.js | 230 + examples/libraries/walkInterface.js | 2713 ++++++++++++ examples/walk.js | 6105 +++++++++++---------------- interface/src/avatar/MyAvatar.cpp | 2 +- 5 files changed, 5761 insertions(+), 3698 deletions(-) create mode 100644 examples/libraries/walkApi.js create mode 100644 examples/libraries/walkFilters.js create mode 100644 examples/libraries/walkInterface.js diff --git a/examples/libraries/walkApi.js b/examples/libraries/walkApi.js new file mode 100644 index 0000000000..90b9dad623 --- /dev/null +++ b/examples/libraries/walkApi.js @@ -0,0 +1,409 @@ +// +// walkObjects.js +// +// version 1.000 +// +// Created by David Wooldridge, Autumn 2014 +// +// Motion, state and Transition objects for use by the walk.js script v1.1 +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +// constructor for the Motion object +Motion = function() { + + this.setGender = function(gender) { + + this.avatarGender = gender; + + switch(this.avatarGender) { + + case MALE: + + this.selWalk = walkAssets.maleStandardWalk; + this.selStand = walkAssets.maleStandOne; + this.selFlyUp = walkAssets.maleFlyingUp; + this.selFly = walkAssets.maleFlying; + this.selFlyDown = walkAssets.maleFlyingDown; + this.selSideStepLeft = walkAssets.maleSideStepLeft; + this.selSideStepRight = walkAssets.maleSideStepRight; + this.curAnim = this.selStand; + return; + + case FEMALE: + + this.selWalk = walkAssets.femaleStandardWalk; + this.selStand = walkAssets.femaleStandOne; + this.selFlyUp = walkAssets.femaleFlyingUp; + this.selFly = walkAssets.femaleFlying; + this.selFlyDown = walkAssets.femaleFlyingDown; + this.selSideStepLeft = walkAssets.femaleSideStepLeft; + this.selSideStepRight = walkAssets.femaleSideStepRight; + this.curAnim = this.selStand; + return; + } + } + + this.hydraCheck = function() { + + // function courtesy of Thijs Wenker, frisbee.js + var numberOfButtons = Controller.getNumberOfButtons(); + var numberOfTriggers = Controller.getNumberOfTriggers(); + var numberOfSpatialControls = Controller.getNumberOfSpatialControls(); + var controllersPerTrigger = numberOfSpatialControls / numberOfTriggers; + hydrasConnected = (numberOfButtons == 12 && numberOfTriggers == 2 && controllersPerTrigger == 2); + return hydrasConnected; + } + + // settings + this.armsFree = this.hydraCheck(); // automatically sets true for Hydra support - temporary fix + this.makesFootStepSounds = true; + this.avatarGender = MALE; + this.motionPitchMax = 60; + this.motionRollMax = 40; + + // timing + this.frameStartTime = 0; // used for measuring frame execution times + this.frameExecutionTimeMax = 0; // keep track of the longest frame execution time + this.cumulativeTime = 0.0; + this.lastWalkStartTime = 0; + + // selected animations + this.selWalk = walkAssets.maleStandardWalk; + this.selStand = walkAssets.maleStandOne; + this.selFlyUp = walkAssets.maleFlyingUp; + this.selFly = walkAssets.maleFlying; + this.selFlyDown = walkAssets.maleFlyingDown; + this.selSideStepLeft = walkAssets.maleSideStepLeft; + this.selSideStepRight = walkAssets.maleSideStepRight; + + // the currently selected animation, joint and transition + this.curAnim = this.selStand; + this.curJointIndex = 0; + this.curTransition = null; + + // zero out avi's joints, curl the fingers nicely then take some measurements + this.avatarJointNames = MyAvatar.getJointNames(); + if (!this.armsFree) { + + for (var i = 0; i < this.avatarJointNames.length; i++) { + + if (i > 17 || i < 34) + // left hand fingers + MyAvatar.setJointData(this.avatarJointNames[i], Quat.fromPitchYawRollDegrees(16, 0, 0)); + + else if (i > 33 || i < 38) + // left hand thumb + MyAvatar.setJointData(this.avatarJointNames[i], Quat.fromPitchYawRollDegrees(4, 0, 0)); + + else if (i > 41 || i < 58) + // right hand fingers + MyAvatar.setJointData(this.avatarJointNames[i], Quat.fromPitchYawRollDegrees(16, 0, 0)); + + else if (i > 57 || i < 62) + // right hand thumb + MyAvatar.setJointData(this.avatarJointNames[i], Quat.fromPitchYawRollDegrees(4, 0, 0)); + + else + // zero out the remaining joints + MyAvatar.clearJointData(this.avatarJointNames[i]); + } + } + + this.footRPos = MyAvatar.getJointPosition("RightFoot"); + this.hipsToFeet = MyAvatar.getJointPosition("Hips").y - this.footRPos.y; + + // walkwheel (foot / ground speed matching) + this.direction = FORWARDS; + this.nextStep = RIGHT; + this.nFrames = 0; + this.strideLength = this.selWalk.calibration.strideLengthForwards; + this.walkWheelPos = 0; + + this.advanceWalkWheel = function(angle){ + + this.walkWheelPos += angle; + if (motion.walkWheelPos >= 360) + this.walkWheelPos = this.walkWheelPos % 360; + } + + // last frame history + this.lastDirection = 0; + this.lastVelocity = 0; + +}; // end Motion constructor + +// finite state machine +state = (function () { + + return { + + // the finite list of states + STANDING: 1, + WALKING: 2, + SIDE_STEP: 3, + FLYING: 4, + EDIT_WALK_STYLES: 5, + EDIT_WALK_TWEAKS: 6, + EDIT_WALK_JOINTS: 7, + EDIT_STANDING: 8, + EDIT_FLYING: 9, + EDIT_FLYING_UP: 10, + EDIT_FLYING_DOWN: 11, + EDIT_SIDESTEP_LEFT: 12, + EDIT_SIDESTEP_RIGHT: 14, + currentState: this.STANDING, + + // status vars + powerOn: true, + minimised: true, + editing:false, + editingTranslation: false, + + setInternalState: function(newInternalState) { + + switch (newInternalState) { + + case this.WALKING: + + this.currentState = this.WALKING; + this.editing = false; + motion.lastWalkStartTime = new Date().getTime(); + walkInterface.updateMenu(); + return; + + case this.FLYING: + + this.currentState = this.FLYING; + this.editing = false; + motion.lastWalkStartTime = 0; + walkInterface.updateMenu(); + return; + + case this.SIDE_STEP: + + this.currentState = this.SIDE_STEP; + this.editing = false; + motion.lastWalkStartTime = new Date().getTime(); + walkInterface.updateMenu(); + return; + + case this.EDIT_WALK_STYLES: + + this.currentState = this.EDIT_WALK_STYLES; + this.editing = true; + motion.lastWalkStartTime = new Date().getTime(); + motion.curAnim = motion.selWalk; + walkInterface.updateMenu(); + return; + + case this.EDIT_WALK_TWEAKS: + + this.currentState = this.EDIT_WALK_TWEAKS; + this.editing = true; + motion.lastWalkStartTime = new Date().getTime(); + motion.curAnim = motion.selWalk; + walkInterface.updateMenu(); + return; + + case this.EDIT_WALK_JOINTS: + + this.currentState = this.EDIT_WALK_JOINTS; + this.editing = true; + motion.lastWalkStartTime = new Date().getTime(); + motion.curAnim = motion.selWalk; + walkInterface.updateMenu(); + return; + + case this.EDIT_STANDING: + + this.currentState = this.EDIT_STANDING; + this.editing = true; + motion.lastWalkStartTime = 0; + motion.curAnim = motion.selStand; + walkInterface.updateMenu(); + return; + + case this.EDIT_SIDESTEP_LEFT: + + this.currentState = this.EDIT_SIDESTEP_LEFT; + this.editing = true; + motion.lastWalkStartTime = new Date().getTime(); + motion.curAnim = motion.selSideStepLeft; + walkInterface.updateMenu(); + return; + + case this.EDIT_SIDESTEP_RIGHT: + + this.currentState = this.EDIT_SIDESTEP_RIGHT; + this.editing = true; + motion.lastWalkStartTime = new Date().getTime(); + motion.curAnim = motion.selSideStepRight; + walkInterface.updateMenu(); + return; + + case this.EDIT_FLYING: + + this.currentState = this.EDIT_FLYING; + this.editing = true; + motion.lastWalkStartTime = 0; + motion.curAnim = motion.selFly; + walkInterface.updateMenu(); + return; + + case this.EDIT_FLYING_UP: + + this.currentState = this.EDIT_FLYING_UP; + this.editing = true; + motion.lastWalkStartTime = 0; + motion.curAnim = motion.selFlyUp; + walkInterface.updateMenu(); + return; + + case this.EDIT_FLYING_DOWN: + + this.currentState = this.EDIT_FLYING_DOWN; + this.editing = true; + motion.lastWalkStartTime = 0; + motion.curAnim = motion.selFlyDown; + walkInterface.updateMenu(); + return; + + case this.STANDING: + default: + + this.currentState = this.STANDING; + this.editing = false; + motion.lastWalkStartTime = 0; + motion.curAnim = motion.selStand; + walkInterface.updateMenu(); + + // initialisation - runs at script startup only + if (motion.strideLength === 0) { + + motion.setGender(MALE); + if (motion.direction === BACKWARDS) + motion.strideLength = motion.selWalk.calibration.strideLengthBackwards; + else + motion.strideLength = motion.selWalk.calibration.strideLengthForwards; + } + return; + } + } + } +})(); // end state object literal + +// constructor for animation Transition +Transition = function(lastAnimation, nextAnimation, reachPoses, transitionDuration, easingLower, easingUpper) { + + this.lastAnim = lastAnimation; // name of last animation + if (lastAnimation === motion.selWalk || + nextAnimation === motion.selSideStepLeft || + nextAnimation === motion.selSideStepRight) + this.walkingAtStart = true; // boolean - is the last animation a walking animation? + else + this.walkingAtStart = false; // boolean - is the last animation a walking animation? + this.nextAnimation = nextAnimation; // name of next animation + if (nextAnimation === motion.selWalk || + nextAnimation === motion.selSideStepLeft || + nextAnimation === motion.selSideStepRight) + this.walkingAtEnd = true; // boolean - is the next animation a walking animation? + else + this.walkingAtEnd = false; // boolean - is the next animation a walking animation? + this.reachPoses = reachPoses; // placeholder / stub: array of reach poses for squash and stretch techniques + this.transitionDuration = transitionDuration; // length of transition (seconds) + this.easingLower = easingLower; // Bezier curve handle (normalised) + this.easingUpper = easingUpper; // Bezier curve handle (normalised) + this.startTime = new Date().getTime(); // Starting timestamp (seconds) + this.progress = 0; // how far are we through the transition? + this.walkWheelIncrement = 6; // how much to turn the walkwheel each frame when transitioning to / from walking + this.walkWheelAdvance = 0; // how many degrees the walk wheel has been advanced during the transition + this.walkStopAngle = 0; // what angle should we stop the walk cycle? + +}; // end Transition constructor + + +walkAssets = (function () { + + // path to the sounds used for the footsteps + var _pathToSounds = 'https://s3.amazonaws.com/hifi-public/sounds/Footsteps/'; + + // read in the sounds + var _footsteps = []; + _footsteps.push(new Sound(_pathToSounds+"FootstepW2Left-12db.wav")); + _footsteps.push(new Sound(_pathToSounds+"FootstepW2Right-12db.wav")); + _footsteps.push(new Sound(_pathToSounds+"FootstepW3Left-12db.wav")); + _footsteps.push(new Sound(_pathToSounds+"FootstepW3Right-12db.wav")); + _footsteps.push(new Sound(_pathToSounds+"FootstepW5Left-12db.wav")); + _footsteps.push(new Sound(_pathToSounds+"FootstepW5Right-12db.wav")); + + // load the animation datafiles + Script.include(pathToAssets+"animations/dd-female-standard-walk-animation.js"); + Script.include(pathToAssets+"animations/dd-female-flying-up-animation.js"); + Script.include(pathToAssets+"animations/dd-female-flying-animation.js"); + Script.include(pathToAssets+"animations/dd-female-flying-down-animation.js"); + Script.include(pathToAssets+"animations/dd-female-standing-one-animation.js"); + Script.include(pathToAssets+"animations/dd-female-sidestep-left-animation.js"); + Script.include(pathToAssets+"animations/dd-female-sidestep-right-animation.js"); + Script.include(pathToAssets+"animations/dd-male-standard-walk-animation.js"); + Script.include(pathToAssets+"animations/dd-male-flying-up-animation.js"); + Script.include(pathToAssets+"animations/dd-male-flying-animation.js"); + Script.include(pathToAssets+"animations/dd-male-flying-down-animation.js"); + Script.include(pathToAssets+"animations/dd-male-standing-one-animation.js"); + Script.include(pathToAssets+"animations/dd-male-sidestep-left-animation.js"); + Script.include(pathToAssets+"animations/dd-male-sidestep-right-animation.js"); + + // read in the animation files + var _FemaleStandardWalkFile = new FemaleStandardWalk(); + var _femaleStandardWalk = _FemaleStandardWalkFile.loadAnimation(); + var _FemaleFlyingUpFile = new FemaleFlyingUp(); + var _femaleFlyingUp = _FemaleFlyingUpFile.loadAnimation(); + var _FemaleFlyingFile = new FemaleFlying(); + var _femaleFlying = _FemaleFlyingFile.loadAnimation(); + var _FemaleFlyingDownFile = new FemaleFlyingDown(); + var _femaleFlyingDown = _FemaleFlyingDownFile.loadAnimation(); + var _FemaleStandOneFile = new FemaleStandingOne(); + var _femaleStandOne = _FemaleStandOneFile.loadAnimation(); + var _FemaleSideStepLeftFile = new FemaleSideStepLeft(); + var _femaleSideStepLeft = _FemaleSideStepLeftFile.loadAnimation(); + var _FemaleSideStepRightFile = new FemaleSideStepRight(); + var _femaleSideStepRight = _FemaleSideStepRightFile.loadAnimation(); + var _MaleStandardWalkFile = new MaleStandardWalk(filter); + var _maleStandardWalk = _MaleStandardWalkFile.loadAnimation(); + var _MaleFlyingUpFile = new MaleFlyingUp(); + var _maleFlyingUp = _MaleFlyingUpFile.loadAnimation(); + var _MaleFlyingFile = new MaleFlying(); + var _maleFlying = _MaleFlyingFile.loadAnimation(); + var _MaleFlyingDownFile = new MaleFlyingDown(); + var _maleFlyingDown = _MaleFlyingDownFile.loadAnimation(); + var _MaleStandOneFile = new MaleStandingOne(); + var _maleStandOne = _MaleStandOneFile.loadAnimation(); + var _MaleSideStepLeftFile = new MaleSideStepLeft(); + var _maleSideStepLeft = _MaleSideStepLeftFile.loadAnimation(); + var _MaleSideStepRightFile = new MaleSideStepRight(); + var _maleSideStepRight = _MaleSideStepRightFile.loadAnimation(); + + return { + + // expose the sound assets + footsteps: _footsteps, + + // expose the animation assets + femaleStandardWalk: _femaleStandardWalk, + femaleFlyingUp: _femaleFlyingUp, + femaleFlying: _femaleFlying, + femaleFlyingDown: _femaleFlyingDown, + femaleStandOne: _femaleStandOne, + femaleSideStepLeft: _femaleSideStepLeft, + femaleSideStepRight: _femaleSideStepRight, + maleStandardWalk: _maleStandardWalk, + maleFlyingUp: _maleFlyingUp, + maleFlying: _maleFlying, + maleFlyingDown: _maleFlyingDown, + maleStandOne: _maleStandOne, + maleSideStepLeft: _maleSideStepLeft, + maleSideStepRight: _maleSideStepRight, + } +})(); \ No newline at end of file diff --git a/examples/libraries/walkFilters.js b/examples/libraries/walkFilters.js new file mode 100644 index 0000000000..608618e580 --- /dev/null +++ b/examples/libraries/walkFilters.js @@ -0,0 +1,230 @@ +// +// walkFilters.js +// +// version 1.000 +// +// Created by David Wooldridge, Autumn 2014 +// +// Provides a variety of filters for use by the walk.js script v1.1 +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +AveragingFilter = function(length) { + + //this.name = name; + this.pastValues = []; + + for(var i = 0; i < length; i++) { + + this.pastValues.push(0); + } + + // single arg is the nextInputValue + this.process = function() { + + if (this.pastValues.length === 0 && arguments[0]) { + return arguments[0]; + } + else if (arguments[0]) { + + // apply quick and simple LP filtering + this.pastValues.push(arguments[0]); + this.pastValues.shift(); + var nextOutputValue = 0; + for (var ea in this.pastValues) nextOutputValue += this.pastValues[ea]; + return nextOutputValue / this.pastValues.length; + } + else return 0; + }; +}; + +// 2nd order Butterworth LP filter - calculate coeffs here: http://www-users.cs.york.ac.uk/~fisher/mkfilter/trad.html +// provides LP filtering with a more stable frequency / phase response +ButterworthFilter = function(cutOff) { + + switch(cutOff) { + + case 5: + + this.gain = 20.20612010; + this.coeffOne = -0.4775922501; + this.coeffTwo = 1.2796324250; + break; + } + + // initialise the arrays + this.xv = []; + this.yv = []; + for(var i = 0; i < 3; i++) { + this.xv.push(0); + this.yv.push(0); + } + + // process values + this.process = function(nextInputValue) { + + this.xv[0] = this.xv[1]; + this.xv[1] = this.xv[2]; + this.xv[2] = nextInputValue / this.gain; + + this.yv[0] = this.yv[1]; + this.yv[1] = this.yv[2]; + this.yv[2] = (this.xv[0] + this.xv[2]) + + 2 * this.xv[1] + + (this.coeffOne * this.yv[0]) + + (this.coeffTwo * this.yv[1]); + + return this.yv[2]; + }; +}; // end Butterworth filter contructor + +// Add harmonics to a given sine wave to form square, sawtooth or triangle waves +// Geometric wave synthesis fundamentals taken from: http://hyperphysics.phy-astr.gsu.edu/hbase/audio/geowv.html +WaveSynth = function(waveShape, numHarmonics, smoothing) { + + this.numHarmonics = numHarmonics; + this.waveShape = waveShape; + this.averagingFilter = new AveragingFilter(smoothing); + + // NB: frequency in radians + this.shapeWave = function(frequency) { + + // make some shapes + var harmonics = 0; + var multiplier = 0; + var iterations = this.numHarmonics * 2 + 2; + if (this.waveShape === TRIANGLE) iterations++; + + for(var n = 2; n < iterations; n++) { + + switch(this.waveShape) { + + case SAWTOOTH: + + multiplier = 1 / n; + harmonics += multiplier * Math.sin(n * frequency); + break; + + case TRIANGLE: + + if (n % 2 === 1) { + + var mulitplier = 1 / (n * n); + + // multiply every (4n-1)th harmonic by -1 + if (n === 3 || n === 7 || n === 11 || n === 15) + mulitplier *= -1; + harmonics += mulitplier * Math.sin(n * frequency); + } + break; + + case SQUARE: + + if (n % 2 === 1) { + + multiplier = 1 / n; + harmonics += multiplier * Math.sin(n * frequency); + } + break; + } + } + + // smooth the result and return + return this.averagingFilter.process(harmonics); + }; +}; + +// Create a wave shape by summing pre-calcualted sinusoidal harmonics +HarmonicsFilter = function(magnitudes, phaseAngles) { + + this.magnitudes = magnitudes; + this.phaseAngles = phaseAngles; + + this.calculate = function(twoPiFT) { + + var harmonics = 0; + var numHarmonics = magnitudes.length; + + for(var n = 0; n < numHarmonics; n++) + + harmonics += this.magnitudes[n] * Math.cos(n * twoPiFT - this.phaseAngles[n]); + + return harmonics; + }; +}; + +// the main filter object literal +filter = (function() { + + // Bezier private functions + function _B1(t) { return t * t * t }; + function _B2(t) { return 3 * t * t * (1 - t) }; + function _B3(t) { return 3 * t * (1 - t) * (1 - t) }; + function _B4(t) { return (1 - t) * (1 - t) * (1 - t) }; + + return { + + // helper methods + degToRad: function(degrees) { + + var convertedValue = degrees * Math.PI / 180; + return convertedValue; + }, + + radToDeg: function(radians) { + + var convertedValue = radians * 180 / Math.PI; + return convertedValue; + }, + + // these filters need instantiating, as they hold arrays of previous values + createAveragingFilter: function(length) { + + var newAveragingFilter = new AveragingFilter(length); + return newAveragingFilter; + }, + + createButterworthFilter: function(cutoff) { + + var newButterworthFilter = new ButterworthFilter(cutoff); + return newButterworthFilter; + }, + + createWaveSynth: function(waveShape, numHarmonics, smoothing) { + + var newWaveSynth = new WaveSynth(waveShape, numHarmonics, smoothing); + return newWaveSynth; + }, + + createHarmonicsFilter: function(magnitudes, phaseAngles) { + + var newHarmonicsFilter = new HarmonicsFilter(magnitudes, phaseAngles); + return newHarmonicsFilter; + }, + + + // the following filters do not need separate instances, as they hold no previous values + bezier: function(percent, C1, C2, C3, C4) { + + // Bezier functions for more natural transitions + // based on script by Dan Pupius (www.pupius.net) http://13thparallel.com/archive/bezier-curves/ + var pos = {x: 0, y: 0}; + pos.x = C1.x * _B1(percent) + C2.x * _B2(percent) + C3.x * _B3(percent) + C4.x * _B4(percent); + pos.y = C1.y * _B1(percent) + C2.y * _B2(percent) + C3.y * _B3(percent) + C4.y * _B4(percent); + return pos; + }, + + // simple clipping filter (faster way to make square waveforms) + clipTrough: function(inputValue, peak, strength) { + + var outputValue = inputValue * strength; + if (outputValue < -peak) + outputValue = -peak; + + return outputValue; + } + } + +})(); \ No newline at end of file diff --git a/examples/libraries/walkInterface.js b/examples/libraries/walkInterface.js new file mode 100644 index 0000000000..71e4462933 --- /dev/null +++ b/examples/libraries/walkInterface.js @@ -0,0 +1,2713 @@ +// +// walkInterface.js +// +// version 1.000 +// +// Created by David Wooldridge, Autumn 2014 +// +// Presents the UI for the walk.js script v1.1 +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +walkInterface = (function() { + + // controller element positions and dimensions + var _backgroundWidth = 350; + var _backgroundHeight = 700; + var _backgroundX = Window.innerWidth - _backgroundWidth - 58; + var _backgroundY = Window.innerHeight / 2 - _backgroundHeight / 2; + var _minSliderX = _backgroundX + 30; + var _sliderRangeX = 295 - 30; + var _jointsControlWidth = 200; + var _jointsControlHeight = 300; + var _jointsControlX = _backgroundX + _backgroundWidth / 2 - _jointsControlWidth / 2; + var _jointsControlY = _backgroundY + 242 - _jointsControlHeight / 2; + var _buttonsY = 20; // distance from top of panel to menu buttons + var _bigButtonsY = 408; // distance from top of panel to top of first big button + + // arrays of overlay names + var _sliderThumbOverlays = []; + var _backgroundOverlays = []; + var _buttonOverlays = []; + var _jointsControlOverlays = []; + var _bigbuttonOverlays = []; + + // reference to the internal state + var _state = { + editingTranslation: false + }; + + // reference to the Motion object + var _motion = null; + + var _walkAssets = null; + + // constants + var MAX_WALK_SPEED = 1257; + + // look and feel + var momentaryButtonTimer = null; + + // all slider controls have a range (with the exception of phase controls that are always +-180) + var _sliderRanges = { + "joints": [{ + "name": "hips", + "pitchRange": 12, + "yawRange": 18, + "rollRange": 12, + "pitchOffsetRange": 25, + "yawOffsetRange": 25, + "rollOffsetRange": 25, + "swayRange": 0.12, + "bobRange": 0.05, + "thrustRange": 0.05, + "swayOffsetRange": 0.25, + "bobOffsetRange": 0.25, + "thrustOffsetRange": 0.25 + }, { + "name": "upperLegs", + "pitchRange": 30, + "yawRange": 35, + "rollRange": 35, + "pitchOffsetRange": 20, + "yawOffsetRange": 20, + "rollOffsetRange": 20 + }, { + "name": "lowerLegs", + "pitchRange": 10, + "yawRange": 20, + "rollRange": 20, + "pitchOffsetRange": 180, + "yawOffsetRange": 20, + "rollOffsetRange": 20 + }, { + "name": "feet", + "pitchRange": 10, + "yawRange": 20, + "rollRange": 20, + "pitchOffsetRange": 180, + "yawOffsetRange": 50, + "rollOffsetRange": 50 + }, { + "name": "toes", + "pitchRange": 90, + "yawRange": 20, + "rollRange": 20, + "pitchOffsetRange": 90, + "yawOffsetRange": 20, + "rollOffsetRange": 20 + }, { + "name": "spine", + "pitchRange": 40, + "yawRange": 40, + "rollRange": 40, + "pitchOffsetRange": 90, + "yawOffsetRange": 50, + "rollOffsetRange": 50 + }, { + "name": "spine1", + "pitchRange": 20, + "yawRange": 40, + "rollRange": 20, + "pitchOffsetRange": 90, + "yawOffsetRange": 50, + "rollOffsetRange": 50 + }, { + "name": "spine2", + "pitchRange": 20, + "yawRange": 40, + "rollRange": 20, + "pitchOffsetRange": 90, + "yawOffsetRange": 50, + "rollOffsetRange": 50 + }, { + "name": "shoulders", + "pitchRange": 35, + "yawRange": 40, + "rollRange": 20, + "pitchOffsetRange": 180, + "yawOffsetRange": 180, + "rollOffsetRange": 180 + }, { + "name": "upperArms", + "pitchRange": 90, + "yawRange": 90, + "rollRange": 90, + "pitchOffsetRange": 180, + "yawOffsetRange": 180, + "rollOffsetRange": 180 + }, { + "name": "lowerArms", + "pitchRange": 90, + "yawRange": 90, + "rollRange": 120, + "pitchOffsetRange": 180, + "yawOffsetRange": 180, + "rollOffsetRange": 180 + }, { + "name": "hands", + "pitchRange": 90, + "yawRange": 180, + "rollRange": 90, + "pitchOffsetRange": 180, + "yawOffsetRange": 180, + "rollOffsetRange": 180 + }, { + "name": "head", + "pitchRange": 20, + "yawRange": 20, + "rollRange": 20, + "pitchOffsetRange": 90, + "yawOffsetRange": 90, + "rollOffsetRange": 90 + }] + }; + + // load overlay images + var _controlsMinimisedTab = Overlays.addOverlay("image", { + x: Window.innerWidth - 58, + y: Window.innerHeight - 145, + width: 50, + height: 50, + imageURL: pathToAssets + 'overlay-images/ddao-minimise-tab.png', + visible: true, + alpha: 0.9 + }); + + var _controlsBackground = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX, + y: _backgroundY, + width: _backgroundWidth, + height: _backgroundHeight + }, + imageURL: pathToAssets + "overlay-images/ddao-background.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _backgroundOverlays.push(_controlsBackground); + + var _controlsBackgroundWalkEditStyles = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX, + y: _backgroundY, + width: _backgroundWidth, + height: _backgroundHeight + }, + imageURL: pathToAssets + "overlay-images/ddao-background-edit-styles.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _backgroundOverlays.push(_controlsBackgroundWalkEditStyles); + + var _controlsBackgroundWalkEditTweaks = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX, + y: _backgroundY, + width: _backgroundWidth, + height: _backgroundHeight + }, + imageURL: pathToAssets + "overlay-images/ddao-background-edit-tweaks.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _backgroundOverlays.push(_controlsBackgroundWalkEditTweaks); + + var _controlsBackgroundWalkEditHipTrans = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX, + y: _backgroundY, + width: _backgroundWidth, + height: _backgroundHeight + }, + imageURL: pathToAssets + "overlay-images/ddao-background-edit-translation.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _backgroundOverlays.push(_controlsBackgroundWalkEditHipTrans); + + var _controlsBackgroundWalkEditJoints = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX, + y: _backgroundY, + width: _backgroundWidth, + height: _backgroundHeight + }, + imageURL: pathToAssets + "overlay-images/ddao-background-edit-joints.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _backgroundOverlays.push(_controlsBackgroundWalkEditJoints); + + // load character joint selection control images + var _hipsJointsTranslation = Overlays.addOverlay("image", { + bounds: { + x: _jointsControlX, + y: _jointsControlY, + width: 200, + height: 300 + }, + imageURL: pathToAssets + "overlay-images/ddao-background-edit-hips-translation.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _jointsControlOverlays.push(_hipsJointsTranslation); + + var _hipsJointControl = Overlays.addOverlay("image", { + bounds: { + x: _jointsControlX, + y: _jointsControlY, + width: 200, + height: 300 + }, + imageURL: pathToAssets + "overlay-images/ddao-background-edit-hips.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _jointsControlOverlays.push(_hipsJointControl); + + var _upperLegsJointControl = Overlays.addOverlay("image", { + bounds: { + x: _jointsControlX, + y: _jointsControlY, + width: 200, + height: 300 + }, + imageURL: pathToAssets + "overlay-images/ddao-background-edit-upper-legs.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _jointsControlOverlays.push(_upperLegsJointControl); + + var _lowerLegsJointControl = Overlays.addOverlay("image", { + bounds: { + x: _jointsControlX, + y: _jointsControlY, + width: 200, + height: 300 + }, + imageURL: pathToAssets + "overlay-images/ddao-background-edit-lower-legs.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _jointsControlOverlays.push(_lowerLegsJointControl); + + var _feetJointControl = Overlays.addOverlay("image", { + bounds: { + x: _jointsControlX, + y: _jointsControlY, + width: 200, + height: 300 + }, + imageURL: pathToAssets + "overlay-images/ddao-background-edit-feet.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _jointsControlOverlays.push(_feetJointControl); + + var _toesJointControl = Overlays.addOverlay("image", { + bounds: { + x: _jointsControlX, + y: _jointsControlY, + width: 200, + height: 300 + }, + imageURL: pathToAssets + "overlay-images/ddao-background-edit-toes.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _jointsControlOverlays.push(_toesJointControl); + + var _spineJointControl = Overlays.addOverlay("image", { + bounds: { + x: _jointsControlX, + y: _jointsControlY, + width: 200, + height: 300 + }, + imageURL: pathToAssets + "overlay-images/ddao-background-edit-spine.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _jointsControlOverlays.push(_spineJointControl); + + var _spine1JointControl = Overlays.addOverlay("image", { + bounds: { + x: _jointsControlX, + y: _jointsControlY, + width: 200, + height: 300 + }, + imageURL: pathToAssets + "overlay-images/ddao-background-edit-spine1.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _jointsControlOverlays.push(_spine1JointControl); + + var _spine2JointControl = Overlays.addOverlay("image", { + bounds: { + x: _jointsControlX, + y: _jointsControlY, + width: 200, + height: 300 + }, + imageURL: pathToAssets + "overlay-images/ddao-background-edit-spine2.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _jointsControlOverlays.push(_spine2JointControl); + + var _shouldersJointControl = Overlays.addOverlay("image", { + bounds: { + x: _jointsControlX, + y: _jointsControlY, + width: 200, + height: 300 + }, + imageURL: pathToAssets + "overlay-images/ddao-background-edit-shoulders.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _jointsControlOverlays.push(_shouldersJointControl); + + var _upperArmsJointControl = Overlays.addOverlay("image", { + bounds: { + x: _jointsControlX, + y: _jointsControlY, + width: 200, + height: 300 + }, + imageURL: pathToAssets + "overlay-images/ddao-background-edit-upper-arms.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _jointsControlOverlays.push(_upperArmsJointControl); + + var _forearmsJointControl = Overlays.addOverlay("image", { + bounds: { + x: _jointsControlX, + y: _jointsControlY, + width: 200, + height: 300 + }, + imageURL: pathToAssets + "overlay-images/ddao-background-edit-forearms.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _jointsControlOverlays.push(_forearmsJointControl); + + var _handsJointControl = Overlays.addOverlay("image", { + bounds: { + x: _jointsControlX, + y: _jointsControlY, + width: 200, + height: 300 + }, + imageURL: pathToAssets + "overlay-images/ddao-background-edit-hands.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _jointsControlOverlays.push(_handsJointControl); + + var _headJointControl = Overlays.addOverlay("image", { + bounds: { + x: _jointsControlX, + y: _jointsControlY, + width: 200, + height: 300 + }, + imageURL: pathToAssets + "overlay-images/ddao-background-edit-head.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _jointsControlOverlays.push(_headJointControl); + + + // slider thumb overlays + var _sliderOne = Overlays.addOverlay("image", { + bounds: { + x: 0, + y: 0, + width: 25, + height: 25 + }, + imageURL: pathToAssets + "overlay-images/ddao-slider-handle.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _sliderThumbOverlays.push(_sliderOne); + + var _sliderTwo = Overlays.addOverlay("image", { + bounds: { + x: 0, + y: 0, + width: 25, + height: 25 + }, + imageURL: pathToAssets + "overlay-images/ddao-slider-handle.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _sliderThumbOverlays.push(_sliderTwo); + + var _sliderThree = Overlays.addOverlay("image", { + bounds: { + x: 0, + y: 0, + width: 25, + height: 25 + }, + imageURL: pathToAssets + "overlay-images/ddao-slider-handle.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _sliderThumbOverlays.push(_sliderThree); + + var _sliderFour = Overlays.addOverlay("image", { + bounds: { + x: 0, + y: 0, + width: 25, + height: 25 + }, + imageURL: pathToAssets + "overlay-images/ddao-slider-handle.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _sliderThumbOverlays.push(_sliderFour); + + var _sliderFive = Overlays.addOverlay("image", { + bounds: { + x: 0, + y: 0, + width: 25, + height: 25 + }, + imageURL: pathToAssets + "overlay-images/ddao-slider-handle.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _sliderThumbOverlays.push(_sliderFive); + + var _sliderSix = Overlays.addOverlay("image", { + bounds: { + x: 0, + y: 0, + width: 25, + height: 25 + }, + imageURL: pathToAssets + "overlay-images/ddao-slider-handle.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _sliderThumbOverlays.push(_sliderSix); + + var _sliderSeven = Overlays.addOverlay("image", { + bounds: { + x: 0, + y: 0, + width: 25, + height: 25 + }, + imageURL: pathToAssets + "overlay-images/ddao-slider-handle.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _sliderThumbOverlays.push(_sliderSeven); + + var _sliderEight = Overlays.addOverlay("image", { + bounds: { + x: 0, + y: 0, + width: 25, + height: 25 + }, + imageURL: pathToAssets + "overlay-images/ddao-slider-handle.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _sliderThumbOverlays.push(_sliderEight); + + var _sliderNine = Overlays.addOverlay("image", { + bounds: { + x: 0, + y: 0, + width: 25, + height: 25 + }, + imageURL: pathToAssets + "overlay-images/ddao-slider-handle.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _sliderThumbOverlays.push(_sliderNine); + + + // button overlays + var _onButton = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 20, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-on-button.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_onButton); + + var _offButton = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 20, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-off-button.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_offButton); + + var _configWalkButton = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 83, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-edit-walk-button.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_configWalkButton); + + var _configWalkButtonSelected = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 83, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-edit-walk-button-selected.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_configWalkButtonSelected); + + var _configStandButton = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 146, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-edit-stand-button.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_configStandButton); + + var _configStandButtonSelected = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 146, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-edit-stand-button-selected.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_configStandButtonSelected); + + var _configFlyingButton = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 209, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-edit-fly-button.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_configFlyingButton); + + var _configFlyingButtonSelected = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 209, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-edit-fly-button-selected.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_configFlyingButtonSelected); + + var _configFlyingUpButton = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 83, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-edit-fly-up-button.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_configFlyingUpButton); + + var _configFlyingUpButtonSelected = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 83, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-edit-fly-up-button-selected.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_configFlyingUpButtonSelected); + + var _configFlyingDownButton = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 146, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-edit-fly-down-button.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_configFlyingDownButton); + + var _configFlyingDownButtonSelected = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 146, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-edit-fly-down-button-selected.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_configFlyingDownButtonSelected); + + var _hideButton = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 272, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-hide-button.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_hideButton); + + var _hideButtonSelected = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 272, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-hide-button-selected.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_hideButtonSelected); + + var _configWalkStylesButton = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 83, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-walk-styles-button.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_configWalkStylesButton); + + var _configWalkStylesButtonSelected = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 83, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-walk-styles-button-selected.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_configWalkStylesButtonSelected); + + var _configWalkTweaksButton = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 146, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-walk-tweaks-button.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_configWalkTweaksButton); + + var _configWalkTweaksButtonSelected = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 146, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-walk-tweaks-button-selected.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_configWalkTweaksButtonSelected); + + var _configSideStepLeftButton = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 83, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-edit-sidestep-left-button.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_configSideStepLeftButton); + + var _configSideStepLeftButtonSelected = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 83, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-edit-sidestep-left-button-selected.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_configSideStepLeftButtonSelected); + + var _configSideStepRightButton = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 209, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-edit-sidestep-right-button.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_configSideStepRightButton); + + var _configSideStepRightButtonSelected = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 209, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-edit-sidestep-right-button-selected.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_configSideStepRightButtonSelected); + + var _configWalkJointsButton = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 209, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-joints-button.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_configWalkJointsButton); + + var _configWalkJointsButtonSelected = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 209, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-joints-button-selected.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_configWalkJointsButtonSelected); + + var _backButton = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 272, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-back-button.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_backButton); + + var _backButtonSelected = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + 272, + y: _backgroundY + _buttonsY, + width: 60, + height: 47 + }, + imageURL: pathToAssets + "overlay-images/ddao-back-button-selected.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _buttonOverlays.push(_backButtonSelected); + + // big button overlays - front panel + var _femaleBigButton = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + _backgroundWidth / 2 - 115, + y: _backgroundY + _bigButtonsY, + width: 230, + height: 36 + }, + imageURL: pathToAssets + "overlay-images/ddao-female-big-button.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _bigbuttonOverlays.push(_femaleBigButton); + + var _femaleBigButtonSelected = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + _backgroundWidth / 2 - 115, + y: _backgroundY + _bigButtonsY, + width: 230, + height: 36 + }, + imageURL: pathToAssets + "overlay-images/ddao-female-big-button-selected.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _bigbuttonOverlays.push(_femaleBigButtonSelected); + + var _maleBigButton = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + _backgroundWidth / 2 - 115, + y: _backgroundY + _bigButtonsY + 60, + width: 230, + height: 36 + }, + imageURL: pathToAssets + "overlay-images/ddao-male-big-button.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _bigbuttonOverlays.push(_maleBigButton); + + var _maleBigButtonSelected = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + _backgroundWidth / 2 - 115, + y: _backgroundY + _bigButtonsY + 60, + width: 230, + height: 36 + }, + imageURL: pathToAssets + "overlay-images/ddao-male-big-button-selected.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _bigbuttonOverlays.push(_maleBigButtonSelected); + + var _armsFreeBigButton = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + _backgroundWidth / 2 - 115, + y: _backgroundY + _bigButtonsY + 120, + width: 230, + height: 36 + }, + imageURL: pathToAssets + "overlay-images/ddao-arms-free-button.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _bigbuttonOverlays.push(_armsFreeBigButton); + + var _armsFreeBigButtonSelected = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + _backgroundWidth / 2 - 115, + y: _backgroundY + _bigButtonsY + 120, + width: 230, + height: 36 + }, + imageURL: pathToAssets + "overlay-images/ddao-arms-free-button-selected.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _bigbuttonOverlays.push(_armsFreeBigButtonSelected); + + var _footstepsBigButton = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + _backgroundWidth / 2 - 115, + y: _backgroundY + _bigButtonsY + 180, + width: 230, + height: 36 + }, + imageURL: pathToAssets + "overlay-images/ddao-footsteps-big-button.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _bigbuttonOverlays.push(_footstepsBigButton); + + var _footstepsBigButtonSelected = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + _backgroundWidth / 2 - 115, + y: _backgroundY + _bigButtonsY + 180, + width: 230, + height: 36 + }, + imageURL: pathToAssets + "overlay-images/ddao-footsteps-big-button-selected.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _bigbuttonOverlays.push(_footstepsBigButtonSelected); + + + // walk styles + _bigButtonsY = 121; + var _standardWalkBigButton = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + _backgroundWidth / 2 - 115, + y: _backgroundY + _bigButtonsY, + width: 230, + height: 36 + }, + imageURL: pathToAssets + "overlay-images/ddao-walk-select-button-standard.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _bigbuttonOverlays.push(_standardWalkBigButton); + + var _standardWalkBigButtonSelected = Overlays.addOverlay("image", { + bounds: { + x: _backgroundX + _backgroundWidth / 2 - 115, + y: _backgroundY + _bigButtonsY, + width: 230, + height: 36 + }, + imageURL: pathToAssets + "overlay-images/ddao-walk-select-button-standard-selected.png", + color: { + red: 255, + green: 255, + blue: 255 + }, + alpha: 1, + visible: false + }); + _bigbuttonOverlays.push(_standardWalkBigButtonSelected); + + // various show / hide GUI element functions + function minimiseDialog(minimise) { + + if (momentaryButtonTimer) { + Script.clearInterval(momentaryButtonTimer); + momentaryButtonTimer = null; + } + + if (minimise) { + setBackground(); + hideMenuButtons(); + setSliderThumbsVisible(false); + hideJointSelectors(); + initialiseFrontPanel(false); + Overlays.editOverlay(_controlsMinimisedTab, { + visible: true + }); + } else { + Overlays.editOverlay(_controlsMinimisedTab, { + visible: false + }); + } + }; + + function setBackground(backgroundID) { + for (var i in _backgroundOverlays) { + if (_backgroundOverlays[i] === backgroundID) + Overlays.editOverlay(_backgroundOverlays[i], { + visible: true + }); + else Overlays.editOverlay(_backgroundOverlays[i], { + visible: false + }); + } + }; + + // top row menu type buttons (on | walk | stand | fly | hide) + function hideMenuButtons() { + for (var i in _buttonOverlays) { + Overlays.editOverlay(_buttonOverlays[i], { + visible: false + }); + } + }; + + function hideJointSelectors() { + for (var i in _jointsControlOverlays) { + Overlays.editOverlay(_jointsControlOverlays[i], { + visible: false + }); + } + }; + + function setSliderThumbsVisible(thumbsVisible) { + for (var i = 0; i < _sliderThumbOverlays.length; i++) { + Overlays.editOverlay(_sliderThumbOverlays[i], { + visible: thumbsVisible + }); + } + }; + + function setButtonOverlayVisible(buttonOverlayName) { + for (var i in _buttonOverlays) { + if (_buttonOverlays[i] === buttonOverlayName) { + Overlays.editOverlay(buttonOverlayName, { + visible: true + }); + } + } + }; + + function initialiseFrontPanel(showButtons) { + + if (_motion.avatarGender === FEMALE) { + Overlays.editOverlay(_femaleBigButtonSelected, { + visible: showButtons + }); + Overlays.editOverlay(_femaleBigButton, { + visible: false + }); + Overlays.editOverlay(_maleBigButtonSelected, { + visible: false + }); + Overlays.editOverlay(_maleBigButton, { + visible: showButtons + }); + + } else { + + Overlays.editOverlay(_femaleBigButtonSelected, { + visible: false + }); + Overlays.editOverlay(_femaleBigButton, { + visible: showButtons + }); + Overlays.editOverlay(_maleBigButtonSelected, { + visible: showButtons + }); + Overlays.editOverlay(_maleBigButton, { + visible: false + }); + } + if (_motion.armsFree) { + Overlays.editOverlay(_armsFreeBigButtonSelected, { + visible: showButtons + }); + Overlays.editOverlay(_armsFreeBigButton, { + visible: false + }); + + } else { + + Overlays.editOverlay(_armsFreeBigButtonSelected, { + visible: false + }); + Overlays.editOverlay(_armsFreeBigButton, { + visible: showButtons + }); + } + if (_motion.makesFootStepSounds) { + Overlays.editOverlay(_footstepsBigButtonSelected, { + visible: showButtons + }); + Overlays.editOverlay(_footstepsBigButton, { + visible: false + }); + + } else { + + Overlays.editOverlay(_footstepsBigButtonSelected, { + visible: false + }); + Overlays.editOverlay(_footstepsBigButton, { + visible: showButtons + }); + } + }; + + function initialiseWalkStylesPanel(showButtons) { + + // set all big buttons to hidden, but skip the first 8, as are used by the front panel + for (var i = 8; i < _bigbuttonOverlays.length; i++) { + Overlays.editOverlay(_bigbuttonOverlays[i], { + visible: false + }); + } + + if (!showButtons) return; + + // set all the non-selected ones to showing + for (var i = 8; i < _bigbuttonOverlays.length; i += 2) { + Overlays.editOverlay(_bigbuttonOverlays[i], { + visible: true + }); + } + + // set the currently selected one + if (_motion.selWalk === _walkAssets.femaleStandardWalk || + _motion.selWalk === _walkAssets.maleStandardWalk) { + + Overlays.editOverlay(_standardWalkBigButtonSelected, { + visible: true + }); + Overlays.editOverlay(_standardWalkBigButton, { + visible: false + }); + } + }; + + function initialiseWalkTweaksPanel() { + + // sliders for commonly required walk adjustments + var i = 0; + var yLocation = _backgroundY + 71; + + // walk speed + var sliderXPos = _motion.curAnim.calibration.frequency / MAX_WALK_SPEED * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[i], { + x: _minSliderX + sliderXPos, + y: yLocation += 60, + visible: true + }); + + // lean (hips pitch offset) + sliderXPos = (((_sliderRanges.joints[0].pitchOffsetRange + _motion.curAnim.joints[0].pitchOffset) / 2) / + _sliderRanges.joints[0].pitchOffsetRange) * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 60, + visible: true + }); + + // stride (upper legs pitch) + sliderXPos = _motion.curAnim.joints[1].pitch / _sliderRanges.joints[1].pitchRange * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 60, + visible: true + }); + + // Legs separation (upper legs roll offset) + sliderXPos = (((_sliderRanges.joints[1].rollOffsetRange + _motion.curAnim.joints[1].rollOffset) / 2) / + _sliderRanges.joints[1].rollOffsetRange) * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 60, + visible: true + }); + + // Legs forward (upper legs pitch offset) + sliderXPos = (((_sliderRanges.joints[1].pitchOffsetRange + _motion.curAnim.joints[1].pitchOffset) / 2) / + _sliderRanges.joints[1].pitchOffsetRange) * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 60, + visible: true + }); + + // Lower legs splay (lower legs roll offset) + sliderXPos = (((_sliderRanges.joints[2].rollOffsetRange + _motion.curAnim.joints[2].rollOffset) / 2) / + _sliderRanges.joints[2].rollOffsetRange) * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 60, + visible: true + }); + + // Arms forward (upper arms yaw offset) + sliderXPos = (((_sliderRanges.joints[9].yawOffsetRange + _motion.curAnim.joints[9].yawOffset) / 2) / + _sliderRanges.joints[9].yawOffsetRange) * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 60, + visible: true + }); + + // Arms out (upper arm pitch offset) + sliderXPos = (((_sliderRanges.joints[9].pitchOffsetRange - _motion.curAnim.joints[9].pitchOffset) / 2) / + _sliderRanges.joints[9].pitchOffsetRange) * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 60, + visible: true + }); + + // Lower arms splay (lower arm pitch offset) + sliderXPos = (((_sliderRanges.joints[10].pitchOffsetRange - _motion.curAnim.joints[10].pitchOffset) / 2) / + _sliderRanges.joints[10].pitchOffsetRange) * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 60, + visible: true + }); + }; + + function initialiseJointsEditingPanel() { + + var i = 0; + var yLocation = _backgroundY + 359; + hideJointSelectors(); + + if (_state.editingTranslation) { + + // display the joint control selector for hips translations + Overlays.editOverlay(_hipsJointsTranslation, {visible: true}); + + // Hips sway + var sliderXPos = _motion.curAnim.joints[0].sway / _sliderRanges.joints[0].swayRange * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[i], { + x: _minSliderX + sliderXPos, + y: yLocation += 30, + visible: true + }); + + // Hips bob + sliderXPos = _motion.curAnim.joints[0].bob / _sliderRanges.joints[0].bobRange * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 30, + visible: true + }); + + // Hips thrust + sliderXPos = _motion.curAnim.joints[0].thrust / _sliderRanges.joints[0].thrustRange * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 30, + visible: true + }); + + // Sway Phase + sliderXPos = (90 + _motion.curAnim.joints[0].swayPhase / 2) / 180 * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 30, + visible: true + }); + + // Bob Phase + sliderXPos = (90 + _motion.curAnim.joints[0].bobPhase / 2) / 180 * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 30, + visible: true + }); + + // Thrust Phase + sliderXPos = (90 + _motion.curAnim.joints[0].thrustPhase / 2) / 180 * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 30, + visible: true + }); + + // offset ranges are also -ve thr' zero to +ve, so we centre them + sliderXPos = (((_sliderRanges.joints[0].swayOffsetRange + _motion.curAnim.joints[0] + .swayOffset) / 2) / _sliderRanges.joints[0].swayOffsetRange) * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 30, + visible: true + }); + + sliderXPos = (((_sliderRanges.joints[0].bobOffsetRange + _motion.curAnim.joints[0] + .bobOffset) / 2) / _sliderRanges.joints[0].bobOffsetRange) * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 30, + visible: true + }); + + sliderXPos = (((_sliderRanges.joints[0].thrustOffsetRange + _motion.curAnim.joints[0] + .thrustOffset) / 2) / _sliderRanges.joints[0].thrustOffsetRange) * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 30, + visible: true + }); + + } else { + + switch (_motion.curJointIndex) { + + case 0: + Overlays.editOverlay(_hipsJointControl, { + visible: true + }); + break; + case 1: + Overlays.editOverlay(_upperLegsJointControl, { + visible: true + }); + break; + case 2: + Overlays.editOverlay(_lowerLegsJointControl, { + visible: true + }); + break; + case 3: + Overlays.editOverlay(_feetJointControl, { + visible: true + }); + break; + case 4: + Overlays.editOverlay(_toesJointControl, { + visible: true + }); + break; + case 5: + Overlays.editOverlay(_spineJointControl, { + visible: true + }); + break; + case 6: + Overlays.editOverlay(_spine1JointControl, { + visible: true + }); + break; + case 7: + Overlays.editOverlay(_spine2JointControl, { + visible: true + }); + break; + case 8: + Overlays.editOverlay(_shouldersJointControl, { + visible: true + }); + break; + case 9: + Overlays.editOverlay(_upperArmsJointControl, { + visible: true + }); + break; + case 10: + Overlays.editOverlay(_forearmsJointControl, { + visible: true + }); + break; + case 11: + Overlays.editOverlay(_handsJointControl, { + visible: true + }); + break; + case 12: + Overlays.editOverlay(_headJointControl, { + visible: true + }); + break; + } + + var sliderXPos = _motion.curAnim.joints[_motion.curJointIndex].pitch / + _sliderRanges.joints[_motion.curJointIndex].pitchRange * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[i], { + x: _minSliderX + sliderXPos, + y: yLocation += 30, + visible: true + }); + + sliderXPos = _motion.curAnim.joints[_motion.curJointIndex].yaw / + _sliderRanges.joints[_motion.curJointIndex].yawRange * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 30, + visible: true + }); + + sliderXPos = _motion.curAnim.joints[_motion.curJointIndex].roll / + _sliderRanges.joints[_motion.curJointIndex].rollRange * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 30, + visible: true + }); + + // set phases (full range, -180 to 180) + sliderXPos = (90 + _motion.curAnim.joints[_motion.curJointIndex].pitchPhase / 2) / 180 * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 30, + visible: true + }); + + sliderXPos = (90 + _motion.curAnim.joints[_motion.curJointIndex].yawPhase / 2) / 180 * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 30, + visible: true + }); + + sliderXPos = (90 + _motion.curAnim.joints[_motion.curJointIndex].rollPhase / 2) / 180 * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 30, + visible: true + }); + + // offset ranges are also -ve thr' zero to +ve, so we offset + sliderXPos = (((_sliderRanges.joints[_motion.curJointIndex].pitchOffsetRange + + _motion.curAnim.joints[_motion.curJointIndex].pitchOffset) / 2) / + _sliderRanges.joints[_motion.curJointIndex].pitchOffsetRange) * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 30, + visible: true + }); + + sliderXPos = (((_sliderRanges.joints[_motion.curJointIndex].yawOffsetRange + + _motion.curAnim.joints[_motion.curJointIndex].yawOffset) / 2) / + _sliderRanges.joints[_motion.curJointIndex].yawOffsetRange) * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 30, + visible: true + }); + + sliderXPos = (((_sliderRanges.joints[_motion.curJointIndex].rollOffsetRange + + _motion.curAnim.joints[_motion.curJointIndex].rollOffset) / 2) / + _sliderRanges.joints[_motion.curJointIndex].rollOffsetRange) * _sliderRangeX; + Overlays.editOverlay(_sliderThumbOverlays[++i], { + x: _minSliderX + sliderXPos, + y: yLocation += 30, + visible: true + }); + } + }; + + // mouse event handlers + var _movingSliderOne = false; + var _movingSliderTwo = false; + var _movingSliderThree = false; + var _movingSliderFour = false; + var _movingSliderFive = false; + var _movingSliderSix = false; + var _movingSliderSeven = false; + var _movingSliderEight = false; + var _movingSliderNine = false; + + function mousePressEvent(event) { + + var clickedOverlay = Overlays.getOverlayAtPoint({ + x: event.x, + y: event.y + }); + + if (_state.currentState === _state.EDIT_WALK_JOINTS || + _state.currentState === _state.EDIT_STANDING || + _state.currentState === _state.EDIT_FLYING || + _state.currentState === _state.EDIT_FLYING_UP || + _state.currentState === _state.EDIT_FLYING_DOWN || + _state.currentState === _state.EDIT_SIDESTEP_LEFT || + _state.currentState === _state.EDIT_SIDESTEP_RIGHT) { + + // check for new joint selection and update display accordingly + var clickX = event.x - _backgroundX - 75; + var clickY = event.y - _backgroundY - 92; + + if (clickX > 60 && clickX < 120 && clickY > 123 && clickY < 155) { + _motion.curJointIndex = 0; + initialiseJointsEditingPanel(); + return; + + } else if (clickX > 63 && clickX < 132 && clickY > 156 && clickY < 202) { + _motion.curJointIndex = 1; + initialiseJointsEditingPanel(); + return; + + } else if (clickX > 58 && clickX < 137 && clickY > 203 && clickY < 250) { + _motion.curJointIndex = 2; + initialiseJointsEditingPanel(); + return; + + } else if (clickX > 58 && clickX < 137 && clickY > 250 && clickY < 265) { + _motion.curJointIndex = 3; + initialiseJointsEditingPanel(); + return; + + } else if (clickX > 58 && clickX < 137 && clickY > 265 && clickY < 280) { + _motion.curJointIndex = 4; + initialiseJointsEditingPanel(); + return; + } else if (clickX > 78 && clickX < 121 && clickY > 111 && clickY < 128) { + _motion.curJointIndex = 5; + initialiseJointsEditingPanel(); + return; + + } else if (clickX > 78 && clickX < 128 && clickY > 89 && clickY < 111) { + _motion.curJointIndex = 6; + initialiseJointsEditingPanel(); + return; + + } else if (clickX > 85 && clickX < 118 && clickY > 77 && clickY < 94) { + _motion.curJointIndex = 7; + initialiseJointsEditingPanel(); + return; + + } else if (clickX > 64 && clickX < 125 && clickY > 55 && clickY < 77) { + _motion.curJointIndex = 8; + initialiseJointsEditingPanel(); + return; + + } else if ((clickX > 44 && clickX < 73 && clickY > 71 && clickY < 94) || + (clickX > 125 && clickX < 144 && clickY > 71 && clickY < 94)) { + _motion.curJointIndex = 9; + initialiseJointsEditingPanel(); + return; + + } else if ((clickX > 28 && clickX < 57 && clickY > 94 && clickY < 119) || + (clickX > 137 && clickX < 170 && clickY > 97 && clickY < 114)) { + _motion.curJointIndex = 10; + initialiseJointsEditingPanel(); + return; + + } else if ((clickX > 18 && clickX < 37 && clickY > 115 && clickY < 136) || + (clickX > 157 && clickX < 182 && clickY > 115 && clickY < 136)) { + _motion.curJointIndex = 11; + initialiseJointsEditingPanel(); + return; + + } else if (clickX > 81 && clickX < 116 && clickY > 12 && clickY < 53) { + _motion.curJointIndex = 12; + initialiseJointsEditingPanel(); + return; + + } else if (clickX > 188 && clickX < 233 && clickY > 6 && clickY < 34) { + + // translation editing radio selection + if (_state.editingTranslation) { + + hideJointSelectors(); + setBackground(_controlsBackgroundWalkEditJoints); + _state.editingTranslation = false; + + } else { + + hideJointSelectors(); + setBackground(_controlsBackgroundWalkEditHipTrans); + _state.editingTranslation = true; + } + initialiseJointsEditingPanel(); + return; + } + } + + switch (clickedOverlay) { + + case _offButton: + + _state.powerOn = true; + Overlays.editOverlay(_offButton, { + visible: false + }); + Overlays.editOverlay(_onButton, { + visible: true + }); + _state.setInternalState(state.STANDING); + return; + + case _controlsMinimisedTab: + + _state.minimised = false; + minimiseDialog(_state.minimised); + _state.setInternalState(_state.STANDING); + return; + + case _hideButton: + _hideButtonSelected: + + Overlays.editOverlay(_hideButton, { + visible: false + }); + Overlays.editOverlay(_hideButtonSelected, { + visible: true + }); + _state.minimised = true; + momentaryButtonTimer = Script.setInterval(function() { + minimiseDialog(_state.minimised); + }, 80); + return; + + case _backButton: + + Overlays.editOverlay(_backButton, { + visible: false + }); + Overlays.editOverlay(_backButtonSelected, { + visible: true + }); + momentaryButtonTimer = Script.setInterval(function() { + + _state.setInternalState(_state.STANDING); + Overlays.editOverlay(_backButton, { + visible: false + }); + Overlays.editOverlay(_backButtonSelected, { + visible: false + }); + Script.clearInterval(momentaryButtonTimer); + momentaryButtonTimer = null; + }, 80); + return; + + case _footstepsBigButton: + + _motion.makesFootStepSounds = true; + Overlays.editOverlay(_footstepsBigButtonSelected, { + visible: true + }); + Overlays.editOverlay(_footstepsBigButton, { + visible: false + }); + return; + + case _footstepsBigButtonSelected: + + _motion.makesFootStepSounds = false; + Overlays.editOverlay(_footstepsBigButton, { + visible: true + }); + Overlays.editOverlay(_footstepsBigButtonSelected, { + visible: false + }); + return; + + case _femaleBigButton: + case _maleBigButtonSelected: + + _motion.setGender(FEMALE); + + Overlays.editOverlay(_femaleBigButtonSelected, { + visible: true + }); + Overlays.editOverlay(_femaleBigButton, { + visible: false + }); + Overlays.editOverlay(_maleBigButton, { + visible: true + }); + Overlays.editOverlay(_maleBigButtonSelected, { + visible: false + }); + return; + + case _maleBigButton: + case _femaleBigButtonSelected: + + _motion.setGender(MALE); + + Overlays.editOverlay(_femaleBigButton, { + visible: true + }); + Overlays.editOverlay(_femaleBigButtonSelected, { + visible: false + }); + Overlays.editOverlay(_maleBigButtonSelected, { + visible: true + }); + Overlays.editOverlay(_maleBigButton, { + visible: false + }); + return; + + case _armsFreeBigButton: + + _motion.armsFree = true; + + Overlays.editOverlay(_armsFreeBigButtonSelected, { + visible: true + }); + Overlays.editOverlay(_armsFreeBigButton, { + visible: false + }); + return; + + case _armsFreeBigButtonSelected: + + _motion.armsFree = false; + + Overlays.editOverlay(_armsFreeBigButtonSelected, { + visible: false + }); + Overlays.editOverlay(_armsFreeBigButton, { + visible: true + }); + return; + + case _standardWalkBigButton: + + if (_motion.avatarGender === FEMALE) _motion.selWalk = _motion.femaleStandardWalk; + else _motion.selWalk = _motion.maleStandardWalk; + _motion.curAnim = _motion.selWalk; + initialiseWalkStylesPanel(true); + return; + + case _standardWalkBigButtonSelected: + + // toggle forwards / backwards walk display + if (_motion.direction === FORWARDS) { + _motion.direction = BACKWARDS; + } else _motion.direction = FORWARDS; + return; + + case _sliderOne: + + _movingSliderOne = true; + return; + + case _sliderTwo: + + _movingSliderTwo = true; + return; + + case _sliderThree: + + _movingSliderThree = true; + return; + + case _sliderFour: + + _movingSliderFour = true; + return; + + case _sliderFive: + + _movingSliderFive = true; + return; + + case _sliderSix: + + _movingSliderSix = true; + return; + + case _sliderSeven: + + _movingSliderSeven = true; + return; + + case _sliderEight: + + _movingSliderEight = true; + return; + + case _sliderNine: + + _movingSliderNine = true; + return; + + case _configWalkButtonSelected: + case _configStandButtonSelected: + case _configSideStepLeftButtonSelected: + case _configSideStepRightButtonSelected: + case _configFlyingButtonSelected: + case _configFlyingUpButtonSelected: + case _configFlyingDownButtonSelected: + case _configWalkStylesButtonSelected: + case _configWalkTweaksButtonSelected: + case _configWalkJointsButtonSelected: + + // exit edit modes + _motion.curAnim = _motion.selStand; + _state.setInternalState(_state.STANDING); + break; + + case _onButton: + + _state.powerOn = false; + _state.setInternalState(state.STANDING); + Overlays.editOverlay(_offButton, { + visible: true + }); + Overlays.editOverlay(_onButton, { + visible: false + }); + //resetJoints(); + break; + + case _backButton: + case _backButtonSelected: + + Overlays.editOverlay(_backButton, { + visible: false + }); + Overlays.editOverlay(_backButtonSelected, { + visible: false + }); + _state.setInternalState(_state.STANDING); + break; + + case _configWalkStylesButton: + + _state.setInternalState(_state.EDIT_WALK_STYLES); + break; + + case _configWalkTweaksButton: + + _state.setInternalState(_state.EDIT_WALK_TWEAKS); + break; + + case _configWalkJointsButton: + + _state.setInternalState(_state.EDIT_WALK_JOINTS); + break; + + case _configWalkButton: + + _state.setInternalState(_state.EDIT_WALK_STYLES); + break; + + case _configStandButton: + + _state.setInternalState(_state.EDIT_STANDING); + break; + + case _configSideStepLeftButton: + _state.setInternalState(_state.EDIT_SIDESTEP_LEFT); + + break; + + case _configSideStepRightButton: + + _state.setInternalState(_state.EDIT_SIDESTEP_RIGHT); + break; + + case _configFlyingButton: + + _state.setInternalState(_state.EDIT_FLYING); + break; + + case _configFlyingUpButton: + + _state.setInternalState(_state.EDIT_FLYING_UP); + break; + + case _configFlyingDownButton: + + _state.setInternalState(_state.EDIT_FLYING_DOWN); + break; + } + }; + + function mouseMoveEvent(event) { + + // workaround for bug (https://worklist.net/20160) + if ((event.x > 310 && event.x < 318 && event.y > 1350 && event.y < 1355) || + (event.x > 423 && event.x < 428 && event.y > 1505 && event.y < 1508 )) return; + + if (_state.currentState === _state.EDIT_WALK_JOINTS || + _state.currentState === _state.EDIT_STANDING || + _state.currentState === _state.EDIT_FLYING || + _state.currentState === _state.EDIT_FLYING_UP || + _state.currentState === _state.EDIT_FLYING_DOWN || + _state.currentState === _state.EDIT_SIDESTEP_LEFT || + _state.currentState === _state.EDIT_SIDESTEP_RIGHT) { + + var thumbClickOffsetX = event.x - _minSliderX; + var thumbPositionNormalised = thumbClickOffsetX / _sliderRangeX; + if (thumbPositionNormalised < 0) thumbPositionNormalised = 0; + if (thumbPositionNormalised > 1) thumbPositionNormalised = 1; + var sliderX = thumbPositionNormalised * _sliderRangeX; // sets range + + if (_movingSliderOne) { + + // currently selected joint pitch or sway + Overlays.editOverlay(_sliderOne, { + x: sliderX + _minSliderX + }); + if (_state.editingTranslation) { + + _motion.curAnim.joints[0].sway = + thumbPositionNormalised * _sliderRanges.joints[0].swayRange; + + } else { + + _motion.curAnim.joints[_motion.curJointIndex].pitch = + thumbPositionNormalised * _sliderRanges.joints[_motion.curJointIndex].pitchRange; + } + + } else if (_movingSliderTwo) { + + // currently selected joint yaw or bob + Overlays.editOverlay(_sliderTwo, { + x: sliderX + _minSliderX + }); + if (_state.editingTranslation) { + + _motion.curAnim.joints[0].bob = + thumbPositionNormalised * _sliderRanges.joints[0].bobRange; + + } else { + + _motion.curAnim.joints[_motion.curJointIndex].yaw = + thumbPositionNormalised * _sliderRanges.joints[_motion.curJointIndex].yawRange; + } + + } else if (_movingSliderThree) { + + // currently selected joint roll or thrust + Overlays.editOverlay(_sliderThree, { + x: sliderX + _minSliderX + }); + if (_state.editingTranslation) { + + _motion.curAnim.joints[0].thrust = + thumbPositionNormalised * _sliderRanges.joints[0].thrustRange; + + } else { + + _motion.curAnim.joints[_motion.curJointIndex].roll = + thumbPositionNormalised * _sliderRanges.joints[_motion.curJointIndex].rollRange; + } + + } else if (_movingSliderFour) { + + // currently selected joint pitch phase + Overlays.editOverlay(_sliderFour, { + x: sliderX + _minSliderX + }); + + var newPhase = 360 * thumbPositionNormalised - 180; + + if (_state.editingTranslation) { + + _motion.curAnim.joints[0].swayPhase = newPhase; + + } else { + + _motion.curAnim.joints[_motion.curJointIndex].pitchPhase = newPhase; + } + + } else if (_movingSliderFive) { + + // currently selected joint yaw phase; + Overlays.editOverlay(_sliderFive, { + x: sliderX + _minSliderX + }); + + var newPhase = 360 * thumbPositionNormalised - 180; + + if (_state.editingTranslation) { + + _motion.curAnim.joints[0].bobPhase = newPhase; + + } else { + + _motion.curAnim.joints[_motion.curJointIndex].yawPhase = newPhase; + } + + } else if (_movingSliderSix) { + + // currently selected joint roll phase + Overlays.editOverlay(_sliderSix, { + x: sliderX + _minSliderX + }); + + var newPhase = 360 * thumbPositionNormalised - 180; + + if (_state.editingTranslation) { + + _motion.curAnim.joints[0].thrustPhase = newPhase; + + } else { + + _motion.curAnim.joints[_motion.curJointIndex].rollPhase = newPhase; + } + + } else if (_movingSliderSeven) { + + // currently selected joint pitch offset + Overlays.editOverlay(_sliderSeven, { + x: sliderX + _minSliderX + }); + if (_state.editingTranslation) { + + var newOffset = (thumbPositionNormalised - 0.5) * + 2 * _sliderRanges.joints[0].swayOffsetRange; + _motion.curAnim.joints[0].swayOffset = newOffset; + + } else { + + var newOffset = (thumbPositionNormalised - 0.5) * + 2 * _sliderRanges.joints[_motion.curJointIndex].pitchOffsetRange; + _motion.curAnim.joints[_motion.curJointIndex].pitchOffset = newOffset; + } + + } else if (_movingSliderEight) { + + // currently selected joint yaw offset + Overlays.editOverlay(_sliderEight, { + x: sliderX + _minSliderX + }); + if (_state.editingTranslation) { + + var newOffset = (thumbPositionNormalised - 0.5) * + 2 *_sliderRanges.joints[0].bobOffsetRange; + _motion.curAnim.joints[0].bobOffset = newOffset; + + } else { + + var newOffset = (thumbPositionNormalised - 0.5) * + 2 * _sliderRanges.joints[_motion.curJointIndex].yawOffsetRange; + _motion.curAnim.joints[_motion.curJointIndex].yawOffset = newOffset; + } + + } else if (_movingSliderNine) { + + // currently selected joint roll offset + Overlays.editOverlay(_sliderNine, { + x: sliderX + _minSliderX + }); + if (_state.editingTranslation) { + + var newOffset = (thumbPositionNormalised - 0.5) * + 2 * _sliderRanges.joints[0].thrustOffsetRange; + _motion.curAnim.joints[0].thrustOffset = newOffset; + + } else { + + var newOffset = (thumbPositionNormalised - 0.5) * + 2 * _sliderRanges.joints[_motion.curJointIndex].rollOffsetRange; + _motion.curAnim.joints[_motion.curJointIndex].rollOffset = newOffset; + } + } + + } // end if editing joints + else if (_state.currentState === _state.EDIT_WALK_TWEAKS) { + + // sliders for commonly required walk adjustments + var thumbClickOffsetX = event.x - _minSliderX; + var thumbPositionNormalised = thumbClickOffsetX / _sliderRangeX; + if (thumbPositionNormalised < 0) thumbPositionNormalised = 0; + if (thumbPositionNormalised > 1) thumbPositionNormalised = 1; + var sliderX = thumbPositionNormalised * _sliderRangeX; // sets range + + if (_movingSliderOne) { + + // walk speed + Overlays.editOverlay(_sliderOne, { + x: sliderX + _minSliderX + }); + _motion.curAnim.calibration.frequency = thumbPositionNormalised * MAX_WALK_SPEED; + + } else if (_movingSliderTwo) { + + // lean (hips pitch offset) + Overlays.editOverlay(_sliderTwo, { + x: sliderX + _minSliderX + }); + var newOffset = (thumbPositionNormalised - 0.5) * 2 * _sliderRanges.joints[0].pitchOffsetRange; + _motion.curAnim.joints[0].pitchOffset = newOffset; + + } else if (_movingSliderThree) { + + // stride (upper legs pitch) + Overlays.editOverlay(_sliderThree, { + x: sliderX + _minSliderX + }); + _motion.curAnim.joints[1].pitch = thumbPositionNormalised * _sliderRanges.joints[1].pitchRange; + + } else if (_movingSliderFour) { + + // legs separation (upper legs roll) + Overlays.editOverlay(_sliderFour, { + x: sliderX + _minSliderX + }); + _motion.curAnim.joints[1].rollOffset = (thumbPositionNormalised - 0.5) * + 2 * _sliderRanges.joints[1].rollOffsetRange; + + } else if (_movingSliderFive) { + + // legs forward (lower legs pitch offset) + Overlays.editOverlay(_sliderFive, { + x: sliderX + _minSliderX + }); + _motion.curAnim.joints[1].pitchOffset = (thumbPositionNormalised - 0.5) * + 2 * _sliderRanges.joints[1].pitchOffsetRange; + + } else if (_movingSliderSix) { + + // lower legs splay (lower legs roll offset) + Overlays.editOverlay(_sliderSix, { + x: sliderX + _minSliderX + }); + _motion.curAnim.joints[2].rollOffset = (thumbPositionNormalised - 0.5) * + 2 * _sliderRanges.joints[2].rollOffsetRange; + + } else if (_movingSliderSeven) { + + // arms forward (upper arms yaw offset) + Overlays.editOverlay(_sliderSeven, { + x: sliderX + _minSliderX + }); + _motion.curAnim.joints[9].yawOffset = (thumbPositionNormalised - 0.5) * + 2 * _sliderRanges.joints[9].yawOffsetRange; + + } else if (_movingSliderEight) { + + // arms out (upper arm pitch offset) + Overlays.editOverlay(_sliderEight, { + x: sliderX + _minSliderX + }); + _motion.curAnim.joints[9].pitchOffset = (thumbPositionNormalised - 0.5) * + -2 * _sliderRanges.joints[9].pitchOffsetRange; + + } else if (_movingSliderNine) { + + // lower arms splay (lower arm pitch offset) + Overlays.editOverlay(_sliderNine, { + x: sliderX + _minSliderX + }); + _motion.curAnim.joints[10].pitchOffset = (thumbPositionNormalised - 0.5) * + -2 * _sliderRanges.joints[10].pitchOffsetRange; + } + + } // if tweaking + }; + + function mouseReleaseEvent(event) { + + if (_movingSliderOne) _movingSliderOne = false; + else if (_movingSliderTwo) _movingSliderTwo = false; + else if (_movingSliderThree) _movingSliderThree = false; + else if (_movingSliderFour) _movingSliderFour = false; + else if (_movingSliderFive) _movingSliderFive = false; + else if (_movingSliderSix) _movingSliderSix = false; + else if (_movingSliderSeven) _movingSliderSeven = false; + else if (_movingSliderEight) _movingSliderEight = false; + else if (_movingSliderNine) _movingSliderNine = false; + }; + + Controller.mousePressEvent.connect(mousePressEvent); + Controller.mouseMoveEvent.connect(mouseMoveEvent); + Controller.mouseReleaseEvent.connect(mouseReleaseEvent); + + // Script ending + Script.scriptEnding.connect(function() { + + // delete the background overlays + for (var i in _backgroundOverlays) { + Overlays.deleteOverlay(_backgroundOverlays[i]); + } + // delete the button overlays + for (var i in _buttonOverlays) { + Overlays.deleteOverlay(_buttonOverlays[i]); + } + // delete the slider thumb overlays + for (var i in _sliderThumbOverlays) { + Overlays.deleteOverlay(_sliderThumbOverlays[i]); + } + // delete the character joint control overlays + for (var i in _jointsControlOverlays) { + Overlays.deleteOverlay(_jointsControlOverlays[i]); + } + // delete the big button overlays + for (var i in _bigbuttonOverlays) { + Overlays.deleteOverlay(_bigbuttonOverlays[i]); + } + // delete the mimimised tab + Overlays.deleteOverlay(_controlsMinimisedTab); + }); + + // public methods + return { + + // gather references to objects from the walk.js script + initialise: function(state, motion, walkAssets) { + + _state = state; + _motion = motion; + _walkAssets = walkAssets; + }, + + updateMenu: function() { + + if (!_state.minimised) { + + switch (_state.currentState) { + + case _state.EDIT_WALK_STYLES: + case _state.EDIT_WALK_TWEAKS: + case _state.EDIT_WALK_JOINTS: + + hideMenuButtons(); + initialiseFrontPanel(false); + hideJointSelectors(); + + if (_state.currentState === _state.EDIT_WALK_STYLES) { + + setBackground(_controlsBackgroundWalkEditStyles); + initialiseWalkStylesPanel(true); + setSliderThumbsVisible(false); + hideJointSelectors(); + setButtonOverlayVisible(_configWalkStylesButtonSelected); + setButtonOverlayVisible(_configWalkTweaksButton); + setButtonOverlayVisible(_configWalkJointsButton); + + } else if (_state.currentState === _state.EDIT_WALK_TWEAKS) { + + setBackground(_controlsBackgroundWalkEditTweaks); + initialiseWalkStylesPanel(false); + setSliderThumbsVisible(true); + hideJointSelectors(); + initialiseWalkTweaksPanel(); + setButtonOverlayVisible(_configWalkStylesButton); + setButtonOverlayVisible(_configWalkTweaksButtonSelected); + setButtonOverlayVisible(_configWalkJointsButton); + + } else if (_state.currentState === _state.EDIT_WALK_JOINTS) { + + if (_state.editingTranslation) + setBackground(_controlsBackgroundWalkEditHipTrans); + else + setBackground(_controlsBackgroundWalkEditJoints); + + initialiseWalkStylesPanel(false); + setSliderThumbsVisible(true); + setButtonOverlayVisible(_configWalkStylesButton); + setButtonOverlayVisible(_configWalkTweaksButton); + setButtonOverlayVisible(_configWalkJointsButtonSelected); + initialiseJointsEditingPanel(); + } + setButtonOverlayVisible(_onButton); + setButtonOverlayVisible(_backButton); + return; + + case _state.EDIT_STANDING: + case _state.EDIT_SIDESTEP_LEFT: + case _state.EDIT_SIDESTEP_RIGHT: + + if (_state.editingTranslation) + setBackground(_controlsBackgroundWalkEditHipTrans); + else + setBackground(_controlsBackgroundWalkEditJoints); + hideMenuButtons(); + initialiseWalkStylesPanel(false); + initialiseFrontPanel(false); + + if (_state.currentState === _state.EDIT_SIDESTEP_LEFT) { + + setButtonOverlayVisible(_configSideStepRightButton); + setButtonOverlayVisible(_configSideStepLeftButtonSelected); + setButtonOverlayVisible(_configStandButton); + + } else if (_state.currentState === _state.EDIT_SIDESTEP_RIGHT) { + + setButtonOverlayVisible(_configSideStepRightButtonSelected); + setButtonOverlayVisible(_configSideStepLeftButton); + setButtonOverlayVisible(_configStandButton); + + } else if (_state.currentState === _state.EDIT_STANDING) { + + setButtonOverlayVisible(_configSideStepRightButton); + setButtonOverlayVisible(_configSideStepLeftButton); + setButtonOverlayVisible(_configStandButtonSelected); + } + initialiseJointsEditingPanel(); + setButtonOverlayVisible(_onButton); + setButtonOverlayVisible(_backButton); + return; + + case _state.EDIT_FLYING: + case _state.EDIT_FLYING_UP: + case _state.EDIT_FLYING_DOWN: + + setBackground(_controlsBackgroundWalkEditJoints); + hideMenuButtons(); + initialiseWalkStylesPanel(false); + initialiseFrontPanel(false); + if (_state.currentState === _state.EDIT_FLYING) { + + setButtonOverlayVisible(_configFlyingUpButton); + setButtonOverlayVisible(_configFlyingDownButton); + setButtonOverlayVisible(_configFlyingButtonSelected); + + } else if (_state.currentState === _state.EDIT_FLYING_UP) { + + setButtonOverlayVisible(_configFlyingUpButtonSelected); + setButtonOverlayVisible(_configFlyingDownButton); + setButtonOverlayVisible(_configFlyingButton); + + } else if (_state.currentState === _state.EDIT_FLYING_DOWN) { + + setButtonOverlayVisible(_configFlyingUpButton); + setButtonOverlayVisible(_configFlyingDownButtonSelected); + setButtonOverlayVisible(_configFlyingButton); + } + initialiseJointsEditingPanel(); + setButtonOverlayVisible(_onButton); + setButtonOverlayVisible(_backButton); + return; + + case _state.STANDING: + case _state.WALKING: + case _state.FLYING: + case _state.SIDE_STEP: + default: + + hideMenuButtons(); + hideJointSelectors(); + setBackground(_controlsBackground); + if (_state.powerOn) setButtonOverlayVisible(_onButton); + else setButtonOverlayVisible(_offButton); + setButtonOverlayVisible(_configWalkButton); + setButtonOverlayVisible(_configStandButton); + setButtonOverlayVisible(_configFlyingButton); + setButtonOverlayVisible(_hideButton); + setSliderThumbsVisible(false); + initialiseFrontPanel(true); + initialiseWalkStylesPanel(false); + return; + } + } + } + }; // end public methods (return) + +})(); \ No newline at end of file diff --git a/examples/walk.js b/examples/walk.js index a9e8f401d6..1e1cd7748b 100644 --- a/examples/walk.js +++ b/examples/walk.js @@ -1,3851 +1,2562 @@ // // walk.js // -// version 1.007b +// version 1.1 // -// Created by Davedub, August / September 2014 +// Created by David Wooldridge, Autumn 2014 +// +// Animates an avatar using procedural animation techniques // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -// path to the animation files -var pathToAnimFiles = 'http://s3-us-west-1.amazonaws.com/highfidelity-public/procedural-animator/animation-files/'; // working (but only without https) - -// path to the images used for the overlays -var pathToOverlays = 'http://s3-us-west-1.amazonaws.com/highfidelity-public/procedural-animator/overlays/'; // working (but only without https) - -// path to the sounds used for the footsteps -var pathToSounds = 'http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Footsteps/'; - -// load the animation datafiles -Script.include(pathToAnimFiles+"dd-female-strut-walk-animation.js"); -Script.include(pathToAnimFiles+"dd-female-flying-up-animation.js"); -Script.include(pathToAnimFiles+"dd-female-flying-animation.js"); -Script.include(pathToAnimFiles+"dd-female-flying-down-animation.js"); -Script.include(pathToAnimFiles+"dd-female-standing-one-animation.js"); -Script.include(pathToAnimFiles+"dd-female-sidestep-left-animation.js"); -Script.include(pathToAnimFiles+"dd-female-sidestep-right-animation.js"); -Script.include(pathToAnimFiles+"dd-male-strut-walk-animation.js"); -Script.include(pathToAnimFiles+"dd-male-flying-up-animation.js"); -Script.include(pathToAnimFiles+"dd-male-flying-animation.js"); -Script.include(pathToAnimFiles+"dd-male-flying-down-animation.js"); -Script.include(pathToAnimFiles+"dd-male-standing-one-animation.js"); -Script.include(pathToAnimFiles+"dd-male-sidestep-left-animation.js"); -Script.include(pathToAnimFiles+"dd-male-sidestep-right-animation.js"); - -// read in the data from the animation files -var FemaleStrutWalkFile = new FemaleStrutWalk(); -var femaleStrutWalk = FemaleStrutWalkFile.loadAnimation(); -var FemaleFlyingUpFile = new FemaleFlyingUp(); -var femaleFlyingUp = FemaleFlyingUpFile.loadAnimation(); -var FemaleFlyingFile = new FemaleFlying(); -var femaleFlying = FemaleFlyingFile.loadAnimation(); -var FemaleFlyingDownFile = new FemaleFlyingDown(); -var femaleFlyingDown = FemaleFlyingDownFile.loadAnimation(); -var FemaleStandOneFile = new FemaleStandingOne(); -var femaleStandOne = FemaleStandOneFile.loadAnimation(); -var FemaleSideStepLeftFile = new FemaleSideStepLeft(); -var femaleSideStepLeft = FemaleSideStepLeftFile.loadAnimation(); -var FemaleSideStepRightFile = new FemaleSideStepRight(); -var femaleSideStepRight = FemaleSideStepRightFile.loadAnimation(); -var MaleStrutWalkFile = new MaleStrutWalk(); -var maleStrutWalk = MaleStrutWalkFile.loadAnimation(); -var MaleFlyingUpFile = new MaleFlyingUp(); -var maleFlyingUp = MaleFlyingUpFile.loadAnimation(); -var MaleFlyingFile = new MaleFlying(); -var maleFlying = MaleFlyingFile.loadAnimation(); -var MaleFlyingDownFile = new MaleFlyingDown(); -var maleFlyingDown = MaleFlyingDownFile.loadAnimation(); -var MaleStandOneFile = new MaleStandingOne(); -var maleStandOne = MaleStandOneFile.loadAnimation(); -var MaleSideStepLeftFile = new MaleSideStepLeft(); -var maleSideStepLeft = MaleSideStepLeftFile.loadAnimation(); -var MaleSideStepRightFile = new MaleSideStepRight(); -var maleSideStepRight = MaleSideStepRightFile.loadAnimation(); - -// read in the sounds -var footsteps = []; -footsteps.push(new Sound(pathToSounds+"FootstepW2Left-12db.wav")); -footsteps.push(new Sound(pathToSounds+"FootstepW2Right-12db.wav")); -footsteps.push(new Sound(pathToSounds+"FootstepW3Left-12db.wav")); -footsteps.push(new Sound(pathToSounds+"FootstepW3Right-12db.wav")); -footsteps.push(new Sound(pathToSounds+"FootstepW5Left-12db.wav")); -footsteps.push(new Sound(pathToSounds+"FootstepW5Right-12db.wav")); - -// all slider controls have a range (with the exception of phase controls that are always +-180) so we store them all here -var sliderRanges = {"joints":[{"name":"hips","pitchRange":25,"yawRange":25,"rollRange":25,"pitchOffsetRange":25,"yawOffsetRange":25,"rollOffsetRange":25,"thrustRange":0.01,"bobRange":0.02,"swayRange":0.01},{"name":"upperLegs","pitchRange":90,"yawRange":35,"rollRange":35,"pitchOffsetRange":60,"yawOffsetRange":20,"rollOffsetRange":20},{"name":"lowerLegs","pitchRange":90,"yawRange":20,"rollRange":20,"pitchOffsetRange":90,"yawOffsetRange":20,"rollOffsetRange":20},{"name":"feet","pitchRange":60,"yawRange":20,"rollRange":20,"pitchOffsetRange":60,"yawOffsetRange":50,"rollOffsetRange":50},{"name":"toes","pitchRange":90,"yawRange":20,"rollRange":20,"pitchOffsetRange":90,"yawOffsetRange":20,"rollOffsetRange":20},{"name":"spine","pitchRange":40,"yawRange":40,"rollRange":40,"pitchOffsetRange":90,"yawOffsetRange":50,"rollOffsetRange":50},{"name":"spine1","pitchRange":20,"yawRange":40,"rollRange":20,"pitchOffsetRange":90,"yawOffsetRange":50,"rollOffsetRange":50},{"name":"spine2","pitchRange":20,"yawRange":40,"rollRange":20,"pitchOffsetRange":90,"yawOffsetRange":50,"rollOffsetRange":50},{"name":"shoulders","pitchRange":35,"yawRange":40,"rollRange":20,"pitchOffsetRange":180,"yawOffsetRange":180,"rollOffsetRange":180},{"name":"upperArms","pitchRange":90,"yawRange":90,"rollRange":90,"pitchOffsetRange":180,"yawOffsetRange":180,"rollOffsetRange":180},{"name":"lowerArms","pitchRange":90,"yawRange":90,"rollRange":120,"pitchOffsetRange":180,"yawOffsetRange":180,"rollOffsetRange":180},{"name":"hands","pitchRange":90,"yawRange":180,"rollRange":90,"pitchOffsetRange":180,"yawOffsetRange":180,"rollOffsetRange":180},{"name":"head","pitchRange":20,"yawRange":20,"rollRange":20,"pitchOffsetRange":90,"yawOffsetRange":90,"rollOffsetRange":90}]}; - -// internal state (FSM based) constants -var STANDING = 1; -var WALKING = 2; -var SIDE_STEPPING = 3; -var FLYING = 4; -var CONFIG_WALK_STYLES = 5; -var CONFIG_WALK_TWEAKS = 6; -var CONFIG_WALK_JOINTS = 7; -var CONFIG_STANDING = 8; -var CONFIG_FLYING = 9; -var CONFIG_FLYING_UP = 10; -var CONFIG_FLYING_DOWN = 11; -var CONFIG_SIDESTEP_LEFT = 12; -var CONFIG_SIDESTEP_RIGHT = 14; -var INTERNAL_STATE = STANDING; - -// status -var powerOn = true; -var paused = false; // pause animation playback whilst adjusting certain parameters -var minimised = true; -var armsFree = true; // set true for hydra support - temporary fix for Hydras -var statsOn = false; -var playFootStepSounds = true; - // constants -var MAX_WALK_SPEED = 1257; // max oscillation speed -var FLYING_SPEED = 6.4;// 12.4; // m/s - real humans can't run any faster than 12.4 m/s -var TERMINAL_VELOCITY = 300; // max speed imposed by Interface -var DIRECTION_UP = 1; -var DIRECTION_DOWN = 2; -var DIRECTION_LEFT = 4; -var DIRECTION_RIGHT = 8; -var DIRECTION_FORWARDS = 16; -var DIRECTION_BACKWARDS = 32; -var DIRECTION_NONE = 64; var MALE = 1; var FEMALE = 2; +var MAX_WALK_SPEED = 2.5; +var TAKE_FLIGHT_SPEED = 4.55; +var TOP_SPEED = 300; +var UP = 1; +var DOWN = 2; +var LEFT = 4; +var RIGHT = 8; +var FORWARDS = 16; +var BACKWARDS = 32; -// start of animation control section -var cumulativeTime = 0.0; -var lastOrientation; +// ovelay images location +var pathToAssets = 'http://s3.amazonaws.com/hifi-public/WalkScript/'; -// avi gender and default animations -var avatarGender = MALE; -var selectedWalk = maleStrutWalk; // the currently selected animation walk file (to edit any animation, paste it's name here and select walk editing mode) -var selectedStand = maleStandOne; -var selectedFlyUp = maleFlyingUp; -var selectedFly = maleFlying; -var selectedFlyDown = maleFlyingDown; -var selectedSideStepLeft = maleSideStepLeft; -var selectedSideStepRight = maleSideStepRight; -if(avatarGender===FEMALE) { +// load the UI +Script.include("./libraries/walkInterface.js"); - // to make toggling the default quick - selectedWalk = femaleStrutWalk; - selectedStand = femaleStandOne; - selectedFlyUp = femaleFlyingUp; - selectedFly = femaleFlying; - selectedFlyDown = femaleFlyingDown; - selectedSideStepLeft = femaleSideStepLeft; - selectedSideStepRight = femaleSideStepRight; -} -var currentAnimation = selectedStand; // the current animation -var selectedJointIndex = 0; // the index of the joint currently selected for editing -var currentTransition = null; // used as a pointer to a Transition +// load filters (Bezier, Butterworth, add harmonics, averaging) +Script.include("./libraries/walkFilters.js"); -// walkwheel (foot / ground speed matching) -var sideStepCycleStartLeft = 270; -var sideStepCycleStartRight = 90; -var walkWheelPosition = 0; -var nextStep = DIRECTION_RIGHT; // first step is always right, because the sine waves say so. Unless you're mirrored. -var nFrames = 0; // counts number of frames -var strideLength = 0; // stride calibration -var aviFootSize = {x:0.1, y:0.1, z:0.25}; // experimental values for addition to stride length - TODO: analyse and confirm is increasing smaller stride lengths accuracy once we have better ground detection +// load objects, constructors and assets (state, Motion, Transition, walkAssets) +Script.include("./libraries/walkApi.js"); -// stats -var frameStartTime = 0; // when the frame first starts we take a note of the time -var frameExecutionTimeMax = 0; // keep track of the longest frame execution time +// initialise the motion state / history object +var motion = new Motion(); -// constructor for recent RecentMotion (i.e. frame data) class -function RecentMotion(velocity, acceleration, principleDirection, state) { - this.velocity = velocity; - this.acceleration = acceleration; - this.principleDirection = principleDirection; - this.state = state; -} +// initialise Transitions +var nullTransition = new Transition(); +motion.curTransition = nullTransition; -// constructor for the FramesHistory object -function FramesHistory() { - this.recentMotions = []; - for(var i = 0 ; i < 10 ; i++) { - var blank = new RecentMotion({ x:0, y:0, z:0 }, { x:0, y:0, z:0 }, DIRECTION_FORWARDS, STANDING ); - this.recentMotions.push(blank); - } +// initialise the UI +walkInterface.initialise(state, motion, walkAssets); - // recentDirection 'method' args: (direction enum, number of steps back to compare) - this.recentDirection = function () { +// wave shapes +var SAWTOOTH = 1; +var TRIANGLE = 2; +var SQUARE = 4; - if( arguments[0] && arguments[1] ) { +// filters for synthesising more complex, natural waveforms +var leanPitchFilter = filter.createAveragingFilter(15); +var leanRollFilter = filter.createAveragingFilter(15); +var hipsYawShaper = filter.createWaveSynth(TRIANGLE, 3, 2); +var hipsBobLPFilter = filter.createButterworthFilter(5); - var directionCount = 0; - if( arguments[1] > this.recentMotions.length ) - arguments[1] = this.recentMotions.length; - - for(var i = 0 ; i < arguments[1] ; i++ ) { - if( this.recentMotions[i].principleDirection === arguments[0] ) - directionCount++; - } - return directionCount / arguments[1] === 1 ? true : false; - } - return false; - } - - // recentState 'method' args: (state enum, number of steps back to compare) - this.recentState = function () { - - if( arguments[0] && arguments[1] ) { - - var stateCount = 0; - if( arguments[1] > this.recentMotions.length ) - arguments[1] = this.recentMotions.length; - - for(var i = 0 ; i < arguments[1] ; i++ ) { - if( this.recentMotions[i].state === arguments[0] ) - stateCount++; - } - return stateCount / arguments[1] === 1 ? true : false; - } - return false; - } - this.lastWalkStartTime = 0; // short walks and long walks need different handling -} -var framesHistory = new FramesHistory(); - -// constructor for animation Transition class -function Transition(lastAnimation, nextAnimation, reachPoses, transitionDuration, easingLower, easingUpper) { - this.lastAnimation = lastAnimation; // name of last animation - if(lastAnimation === selectedWalk || - nextAnimation === selectedSideStepLeft || - nextAnimation === selectedSideStepRight) - this.walkingAtStart = true; // boolean - is the last animation a walking animation? - else - this.walkingAtStart = false; // boolean - is the last animation a walking animation? - this.nextAnimation = nextAnimation; // name of next animation - if(nextAnimation === selectedWalk || - nextAnimation === selectedSideStepLeft || - nextAnimation === selectedSideStepRight) - this.walkingAtEnd = true; // boolean - is the next animation a walking animation? - else - this.walkingAtEnd = false; // boolean - is the next animation a walking animation? - this.reachPoses = reachPoses; // array of reach poses - am very much looking forward to putting these in! - this.transitionDuration = transitionDuration; // length of transition (seconds) - this.easingLower = easingLower; // Bezier curve handle (normalised) - this.easingUpper = easingUpper; // Bezier curve handle (normalised) - this.startTime = new Date().getTime(); // Starting timestamp (seconds) - this.progress = 0; // how far are we through the transition? - this.walkWheelIncrement = 3; // how much to turn the walkwheel each frame when coming to a halt. Get's set to 0 once the feet are under the avi - this.walkWheelAdvance = 0; // how many degrees the walk wheel has been advanced during the transition - this.walkStopAngle = 0; // what angle should we stop the walk cycle? (calculated on the fly) -} - -// convert a local (to the avi) translation to a global one -function localToGlobal(localTranslation) { - - var aviOrientation = MyAvatar.orientation; - var front = Quat.getFront(aviOrientation); - var right = Quat.getRight(aviOrientation); - var up = Quat.getUp (aviOrientation); - var aviFront = Vec3.multiply(front,localTranslation.z); - var aviRight = Vec3.multiply(right,localTranslation.x); - var aviUp = Vec3.multiply(up ,localTranslation.y); - var globalTranslation = {x:0,y:0,z:0}; // final value - globalTranslation = Vec3.sum(globalTranslation, aviFront); - globalTranslation = Vec3.sum(globalTranslation, aviRight); - globalTranslation = Vec3.sum(globalTranslation, aviUp); - return globalTranslation; -} - -// similar ot above - convert hips translations to global and apply -function translateHips(localHipsTranslation) { - - var aviOrientation = MyAvatar.orientation; - var front = Quat.getFront(aviOrientation); - var right = Quat.getRight(aviOrientation); - var up = Quat.getUp (aviOrientation); - var aviFront = Vec3.multiply(front,localHipsTranslation.y); - var aviRight = Vec3.multiply(right,localHipsTranslation.x); - var aviUp = Vec3.multiply(up ,localHipsTranslation.z); - var AviTranslationOffset = {x:0,y:0,z:0}; // final value - AviTranslationOffset = Vec3.sum(AviTranslationOffset, aviFront); - AviTranslationOffset = Vec3.sum(AviTranslationOffset, aviRight); - AviTranslationOffset = Vec3.sum(AviTranslationOffset, aviUp); - MyAvatar.position = {x: MyAvatar.position.x + AviTranslationOffset.x, - y: MyAvatar.position.y + AviTranslationOffset.y, - z: MyAvatar.position.z + AviTranslationOffset.z }; -} - -// clear all joint data -function resetJoints() { - - var avatarJointNames = MyAvatar.getJointNames(); - for (var i = 0; i < avatarJointNames.length; i++) { - MyAvatar.clearJointData(avatarJointNames[i]); - } -} - -// play footstep sound -function playFootstep(side) { - - var options = new AudioInjectionOptions(); - options.position = Camera.getPosition(); - options.volume = 0.5; - var walkNumber = 2; // 0 to 2 - if(side===DIRECTION_RIGHT && playFootStepSounds) { - Audio.playSound(footsteps[walkNumber+1], options); - } - else if(side===DIRECTION_LEFT && playFootStepSounds) { - Audio.playSound(footsteps[walkNumber], options); - } -} - -// put the fingers into a relaxed pose -function curlFingers() { - - // left hand fingers - for(var i = 18 ; i < 34 ; i++) { - MyAvatar.setJointData(jointList[i], Quat.fromPitchYawRollDegrees(8,0,0)); - } - // left hand thumb - for(var i = 34 ; i < 38 ; i++) { - MyAvatar.setJointData(jointList[i], Quat.fromPitchYawRollDegrees(0,0,0)); - } - // right hand fingers - for(var i = 42 ; i < 58 ; i++) { - MyAvatar.setJointData(jointList[i], Quat.fromPitchYawRollDegrees(8,0,0)); - } - // right hand thumb - for(var i = 58 ; i < 62 ; i++) { - MyAvatar.setJointData(jointList[i], Quat.fromPitchYawRollDegrees(0,0,0)); - } -} - -// additional maths functions -function degToRad( degreesValue ) { return degreesValue * Math.PI / 180; } -function radToDeg( radiansValue ) { return radiansValue * 180 / Math.PI; } - -// animateAvatar - sine wave generators working like clockwork -function animateAvatar( deltaTime, velocity, principleDirection ) { - - // adjusting the walk speed in edit mode causes a nasty flicker. pausing the animation stops this - if(paused) return; - - var cycle = cumulativeTime; - var transitionProgress = 1; - var adjustedFrequency = currentAnimation.settings.baseFrequency; - - // upper legs phase reversal for walking backwards - var forwardModifier = 1; - if(principleDirection===DIRECTION_BACKWARDS) - forwardModifier = -1; - - // don't want to lean forwards if going directly upwards - var leanPitchModifier = 1; - if(principleDirection===DIRECTION_UP) - leanPitchModifier = 0; - - // is there a Transition to include? - if(currentTransition!==null) { - - // if is a new transiton - if(currentTransition.progress===0) { - - if( currentTransition.walkingAtStart ) { - - if( INTERNAL_STATE !== SIDE_STEPPING ) { - - // work out where we want the walk cycle to stop - var leftStop = selectedWalk.settings.stopAngleForwards + 180; - var rightStop = selectedWalk.settings.stopAngleForwards; - if( principleDirection === DIRECTION_BACKWARDS ) { - leftStop = selectedWalk.settings.stopAngleBackwards + 180; - rightStop = selectedWalk.settings.stopAngleBackwards; - } - - // find the closest stop point from the walk wheel's angle - var angleToLeftStop = 180 - Math.abs( Math.abs( walkWheelPosition - leftStop ) - 180); - var angleToRightStop = 180 - Math.abs( Math.abs( walkWheelPosition - rightStop ) - 180); - if( walkWheelPosition > angleToLeftStop ) angleToLeftStop = 360 - angleToLeftStop; - if( walkWheelPosition > angleToRightStop ) angleToRightStop = 360 - angleToRightStop; - - currentTransition.walkWheelIncrement = 6; - - // keep the walkwheel turning by setting the walkWheelIncrement until our feet are tucked nicely underneath us. - if( angleToLeftStop < angleToRightStop ) { - - currentTransition.walkStopAngle = leftStop; - - } else { - - currentTransition.walkStopAngle = rightStop; - } - - } else { - - // freeze wheel for sidestepping transitions - currentTransition.walkWheelIncrement = 0; - } - } - } // end if( currentTransition.walkingAtStart ) - - // calculate the Transition progress - var elapasedTime = (new Date().getTime() - currentTransition.startTime) / 1000; - currentTransition.progress = elapasedTime / currentTransition.transitionDuration; - transitionProgress = getBezier((1-currentTransition.progress), {x:0,y:0}, currentTransition.easingLower, currentTransition.easingUpper, {x:1,y:1}).y; - - if(currentTransition.progress>=1) { - - // time to kill off the transition - delete currentTransition; - currentTransition = null; - - } else { - - if( currentTransition.walkingAtStart ) { - - if( INTERNAL_STATE !== SIDE_STEPPING ) { - - // if at a stop angle, hold the walk wheel position for remainder of transition - var tolerance = 7; // must be greater than the walkWheel increment - if(( walkWheelPosition > (currentTransition.walkStopAngle - tolerance )) && - ( walkWheelPosition < (currentTransition.walkStopAngle + tolerance ))) { - - currentTransition.walkWheelIncrement = 0; - } - // keep turning walk wheel until both feet are below the avi - walkWheelPosition += currentTransition.walkWheelIncrement; - currentTransition.walkWheelAdvance += currentTransition.walkWheelIncrement; - } - } - } - } - - // will we need to use the walk wheel this frame? - if(currentAnimation === selectedWalk || - currentAnimation === selectedSideStepLeft || - currentAnimation === selectedSideStepRight || - currentTransition !== null) { - - // set the stride length - if( INTERNAL_STATE!==SIDE_STEPPING && - INTERNAL_STATE!==CONFIG_SIDESTEP_LEFT && - INTERNAL_STATE!==CONFIG_SIDESTEP_RIGHT && - currentTransition===null ) { - - // if the timing's right, take a snapshot of the stride max and recalibrate - var tolerance = 1.0; // higher the number, the higher the chance of a calibration taking place, but is traded off with lower accuracy - var strideOne = 40; - var strideTwo = 220; - - if( principleDirection === DIRECTION_BACKWARDS ) { - strideOne = 130; - strideTwo = 300; - } - - if(( walkWheelPosition < (strideOne+tolerance) && walkWheelPosition > (strideOne-tolerance) ) || - ( walkWheelPosition < (strideTwo+tolerance) && walkWheelPosition > (strideTwo-tolerance) )) { - - // calculate the feet's offset from each other (in local Z only) - var footRPos = localToGlobal(MyAvatar.getJointPosition("RightFoot")); - var footLPos = localToGlobal(MyAvatar.getJointPosition("LeftFoot")); - var footOffsetZ = Math.abs(footRPos.z - footLPos.z); - if(footOffsetZ>1) strideLength = 2 * footOffsetZ + aviFootSize.z; // sometimes getting very low value here - just ignore for now - if(statsOn) print('Stride length calibrated to '+strideLength.toFixed(4)+' metres at '+walkWheelPosition.toFixed(1)+' degrees'); - if(principleDirection===DIRECTION_FORWARDS) { - currentAnimation.calibration.strideLengthForwards = strideLength; - } else if (principleDirection===DIRECTION_BACKWARDS) { - currentAnimation.calibration.strideLengthBackwards = strideLength; - } - - } else { - - if(principleDirection===DIRECTION_FORWARDS) - strideLength = currentAnimation.calibration.strideLengthForwards; - else if (principleDirection===DIRECTION_BACKWARDS) - strideLength = currentAnimation.calibration.strideLengthBackwards; - } - } - else if(( INTERNAL_STATE===SIDE_STEPPING || - INTERNAL_STATE===CONFIG_SIDESTEP_LEFT || - INTERNAL_STATE===CONFIG_SIDESTEP_RIGHT ) ) { - - // calculate lateral stride - same same, but different - // if the timing's right, take a snapshot of the stride max and recalibrate the stride length - var tolerance = 1.0; // higher the number, the higher the chance of a calibration taking place, but is traded off with lower accuracy - if(principleDirection===DIRECTION_LEFT) { - - if( walkWheelPosition < (3+tolerance) && walkWheelPosition > (3-tolerance) ) { - - // calculate the feet's offset from the hips (in local X only) - var footRPos = localToGlobal(MyAvatar.getJointPosition("RightFoot")); - var footLPos = localToGlobal(MyAvatar.getJointPosition("LeftFoot")); - var footOffsetX = Math.abs(footRPos.x - footLPos.x); - strideLength = footOffsetX; - if(statsOn) print('Stride width calibrated to '+strideLength.toFixed(4)+ ' metres at '+walkWheelPosition.toFixed(1)+' degrees'); - currentAnimation.calibration.strideLengthLeft = strideLength; - - } else { - - strideLength = currentAnimation.calibration.strideLengthLeft; - } - } - else if (principleDirection===DIRECTION_RIGHT) { - - if( walkWheelPosition < (170+tolerance) && walkWheelPosition > (170-tolerance) ) { - - // calculate the feet's offset from the hips (in local X only) - var footRPos = localToGlobal(MyAvatar.getJointPosition("RightFoot")); - var footLPos = localToGlobal(MyAvatar.getJointPosition("LeftFoot")); - var footOffsetX = Math.abs(footRPos.x - footLPos.x); - strideLength = footOffsetX; - if(statsOn) print('Stride width calibrated to '+strideLength.toFixed(4)+ ' metres at '+walkWheelPosition.toFixed(1)+' degrees'); - currentAnimation.calibration.strideLengthRight = strideLength; - - } else { - - strideLength = currentAnimation.calibration.strideLengthRight; - } - } - } // end stride length calculations - - // wrap the stride length around a 'surveyor's wheel' twice and calculate the angular velocity at the given (linear) velocity - // omega = v / r , where r = circumference / 2 PI , where circumference = 2 * stride length - var wheelRadius = strideLength / Math.PI; - var angularVelocity = velocity / wheelRadius; - - // calculate the degrees turned (at this angular velocity) since last frame - var radiansTurnedSinceLastFrame = deltaTime * angularVelocity; - var degreesTurnedSinceLastFrame = radToDeg(radiansTurnedSinceLastFrame); - - // if we are in an edit mode, we will need fake time to turn the wheel - if( INTERNAL_STATE!==WALKING && - INTERNAL_STATE!==SIDE_STEPPING ) - degreesTurnedSinceLastFrame = currentAnimation.settings.baseFrequency / 70; - - if( walkWheelPosition >= 360 ) - walkWheelPosition = walkWheelPosition % 360; - - // advance the walk wheel the appropriate amount - if( currentTransition===null || currentTransition.walkingAtEnd ) - walkWheelPosition += degreesTurnedSinceLastFrame; - - // set the new values for the exact correct walk cycle speed at this velocity - adjustedFrequency = 1; - cycle = walkWheelPosition; - - // show stats and walk wheel? - if(statsOn) { - - var distanceTravelled = velocity * deltaTime; - var deltaTimeMS = deltaTime * 1000; - - if( INTERNAL_STATE===SIDE_STEPPING || - INTERNAL_STATE===CONFIG_SIDESTEP_LEFT || - INTERNAL_STATE===CONFIG_SIDESTEP_RIGHT ) { - - // draw the walk wheel turning around the z axis for sidestepping - var directionSign = 1; - if(principleDirection===DIRECTION_RIGHT) directionSign = -1; - var yOffset = hipsToFeetDistance - (wheelRadius/1.2); // /1.2 is a visual kludge, probably necessary because of either the 'avi feet penetrate floor' issue - TODO - once ground plane following is in Interface, lock this down - var sinWalkWheelPosition = wheelRadius * Math.sin(degToRad( directionSign * walkWheelPosition )); - var cosWalkWheelPosition = wheelRadius * Math.cos(degToRad( directionSign * -walkWheelPosition )); - var wheelXPos = {x: cosWalkWheelPosition, y:-sinWalkWheelPosition - yOffset, z: 0}; - var wheelXEnd = {x: -cosWalkWheelPosition, y:sinWalkWheelPosition - yOffset, z: 0}; - sinWalkWheelPosition = wheelRadius * Math.sin(degToRad( -directionSign * walkWheelPosition+90 )); - cosWalkWheelPosition = wheelRadius * Math.cos(degToRad( -directionSign * walkWheelPosition+90 )); - var wheelYPos = {x:cosWalkWheelPosition, y:sinWalkWheelPosition - yOffset, z: 0}; - var wheelYEnd = {x:-cosWalkWheelPosition, y:-sinWalkWheelPosition - yOffset, z: 0}; - Overlays.editOverlay(walkWheelYLine, {visible: true, position:wheelYPos, end:wheelYEnd}); - Overlays.editOverlay(walkWheelZLine, {visible: true, position:wheelXPos, end:wheelXEnd}); - - } else { - - // draw the walk wheel turning around the x axis for walking forwards or backwards - var yOffset = hipsToFeetDistance - (wheelRadius/1.2); // /1.2 is a visual kludge, probably necessary because of either the 'avi feet penetrate floor' issue - TODO - once ground plane following is in Interface, lock this down - var sinWalkWheelPosition = wheelRadius * Math.sin(degToRad((forwardModifier*-1) * walkWheelPosition)); - var cosWalkWheelPosition = wheelRadius * Math.cos(degToRad((forwardModifier*-1) * -walkWheelPosition)); - var wheelZPos = {x:0, y:-sinWalkWheelPosition - yOffset, z: cosWalkWheelPosition}; - var wheelZEnd = {x:0, y:sinWalkWheelPosition - yOffset, z: -cosWalkWheelPosition}; - sinWalkWheelPosition = wheelRadius * Math.sin(degToRad(forwardModifier * walkWheelPosition+90)); - cosWalkWheelPosition = wheelRadius * Math.cos(degToRad(forwardModifier * walkWheelPosition+90)); - var wheelYPos = {x:0, y:sinWalkWheelPosition - yOffset, z: cosWalkWheelPosition}; - var wheelYEnd = {x:0, y:-sinWalkWheelPosition - yOffset, z: -cosWalkWheelPosition}; - Overlays.editOverlay(walkWheelYLine, { visible: true, position:wheelYPos, end:wheelYEnd }); - Overlays.editOverlay(walkWheelZLine, { visible: true, position:wheelZPos, end:wheelZEnd }); - } - - // populate stats overlay - var walkWheelInfo = - ' Walk Wheel Stats\n--------------------------------------\n \n \n' - + '\nFrame time: '+deltaTimeMS.toFixed(2) - + ' mS\nVelocity: '+velocity.toFixed(2) - + ' m/s\nDistance: '+distanceTravelled.toFixed(3) - + ' m\nOmega: '+angularVelocity.toFixed(3) - + ' rad / s\nDeg to turn: '+degreesTurnedSinceLastFrame.toFixed(2) - + ' deg\nWheel position: '+cycle.toFixed(1) - + ' deg\nWheel radius: '+wheelRadius.toFixed(3) - + ' m\nHips To Feet: '+hipsToFeetDistance.toFixed(3) - + ' m\nStride: '+strideLength.toFixed(3) - + ' m\n'; - Overlays.editOverlay(walkWheelStats, {text: walkWheelInfo}); - } - } // end of walk wheel and stride length calculation - - - // Start applying motion - var pitchOscillation = 0; - var yawOscillation = 0; - var rollOscillation = 0; - var pitchOscillationLast = 0; - var yawOscillationLast = 0; - var rollOscillationLast = 0; - var pitchOffset = 0; - var yawOffset = 0; - var rollOffset = 0; - var pitchOffsetLast = 0; - var yawOffsetLast = 0; - var rollOffsetLast = 0; - - // calcualte any hips translation - // Note: can only apply hips translations whilst in a config (edit) mode at present, not whilst under locomotion - if( INTERNAL_STATE===CONFIG_WALK_STYLES || - INTERNAL_STATE===CONFIG_WALK_TWEAKS || - INTERNAL_STATE===CONFIG_WALK_JOINTS || - INTERNAL_STATE===CONFIG_SIDESTEP_LEFT || - INTERNAL_STATE===CONFIG_SIDESTEP_RIGHT || - INTERNAL_STATE===CONFIG_FLYING || - INTERNAL_STATE===CONFIG_FLYING_UP || - INTERNAL_STATE===CONFIG_FLYING_DOWN ) { - - // calculate hips translation - var motorOscillation = Math.sin(degToRad((cycle * adjustedFrequency * 2) + currentAnimation.joints[0].thrustPhase)) + currentAnimation.joints[0].thrustOffset; - var swayOscillation = Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[0].swayPhase)) + currentAnimation.joints[0].swayOffset; - var bobOscillation = Math.sin(degToRad((cycle * adjustedFrequency * 2) + currentAnimation.joints[0].bobPhase)) + currentAnimation.joints[0].bobOffset; - - // apply hips translation - translateHips({x:swayOscillation*currentAnimation.joints[0].sway, y:motorOscillation*currentAnimation.joints[0].thrust, z:bobOscillation*currentAnimation.joints[0].bob}); - } - - // hips rotation - // apply the current Transition? - if(currentTransition!==null) { - - if( currentTransition.walkingAtStart ) { - - pitchOscillation = currentAnimation.joints[0].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency * 2) - + currentAnimation.joints[0].pitchPhase)) + currentAnimation.joints[0].pitchOffset; - - yawOscillation = currentAnimation.joints[0].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) - + currentAnimation.joints[0].yawPhase)) + currentAnimation.joints[0].yawOffset; - - rollOscillation = (currentAnimation.joints[0].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) - + currentAnimation.joints[0].rollPhase)) + currentAnimation.joints[0].rollOffset); - - pitchOscillationLast = currentTransition.lastAnimation.joints[0].pitch * Math.sin(degToRad(( walkWheelPosition * 2) - + currentTransition.lastAnimation.joints[0].pitchPhase)) + currentTransition.lastAnimation.joints[0].pitchOffset; - - yawOscillationLast = currentTransition.lastAnimation.joints[0].yaw * Math.sin(degToRad(( walkWheelPosition ) - + currentTransition.lastAnimation.joints[0].yawPhase)) + currentTransition.lastAnimation.joints[0].yawOffset; - - rollOscillationLast = (currentTransition.lastAnimation.joints[0].roll * Math.sin(degToRad(( walkWheelPosition ) - + currentTransition.lastAnimation.joints[0].rollPhase)) + currentTransition.lastAnimation.joints[0].rollOffset); - - } else { - - pitchOscillation = currentAnimation.joints[0].pitch * Math.sin(degToRad((cycle * adjustedFrequency * 2) - + currentAnimation.joints[0].pitchPhase)) + currentAnimation.joints[0].pitchOffset; - - yawOscillation = currentAnimation.joints[0].yaw * Math.sin(degToRad((cycle * adjustedFrequency ) - + currentAnimation.joints[0].yawPhase)) + currentAnimation.joints[0].yawOffset; - - rollOscillation = (currentAnimation.joints[0].roll * Math.sin(degToRad((cycle * adjustedFrequency ) - + currentAnimation.joints[0].rollPhase)) + currentAnimation.joints[0].rollOffset); - - pitchOscillationLast = currentTransition.lastAnimation.joints[0].pitch * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency * 2) - + currentTransition.lastAnimation.joints[0].pitchPhase)) + currentTransition.lastAnimation.joints[0].pitchOffset; - - yawOscillationLast = currentTransition.lastAnimation.joints[0].yaw * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) - + currentTransition.lastAnimation.joints[0].yawPhase)) + currentTransition.lastAnimation.joints[0].yawOffset; - - rollOscillationLast = (currentTransition.lastAnimation.joints[0].roll * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) - + currentTransition.lastAnimation.joints[0].rollPhase)) + currentTransition.lastAnimation.joints[0].rollOffset); - - } - - pitchOscillation = (transitionProgress * pitchOscillation) + ((1-transitionProgress) * pitchOscillationLast); - yawOscillation = (transitionProgress * yawOscillation) + ((1-transitionProgress) * yawOscillationLast); - rollOscillation = (transitionProgress * rollOscillation) + ((1-transitionProgress) * rollOscillationLast); - - } else { - - pitchOscillation = currentAnimation.joints[0].pitch * Math.sin(degToRad((cycle * adjustedFrequency * 2) - + currentAnimation.joints[0].pitchPhase)) + currentAnimation.joints[0].pitchOffset; - - yawOscillation = currentAnimation.joints[0].yaw * Math.sin(degToRad((cycle * adjustedFrequency ) - + currentAnimation.joints[0].yawPhase)) + currentAnimation.joints[0].yawOffset; - - rollOscillation = (currentAnimation.joints[0].roll * Math.sin(degToRad((cycle * adjustedFrequency ) - + currentAnimation.joints[0].rollPhase)) + currentAnimation.joints[0].rollOffset); - } - - // apply hips rotation - MyAvatar.setJointData("Hips", Quat.fromPitchYawRollDegrees(-pitchOscillation + (leanPitchModifier * getLeanPitch(velocity)), // getLeanPitch - lean forwards as velocity increases - yawOscillation, // Yup, that's correct ;-) - rollOscillation + getLeanRoll(deltaTime, velocity))); // getLeanRoll - banking on cornering - - // upper legs - if( INTERNAL_STATE!==SIDE_STEPPING && - INTERNAL_STATE!==CONFIG_SIDESTEP_LEFT && - INTERNAL_STATE!==CONFIG_SIDESTEP_RIGHT ) { - - // apply the current Transition to the upper legs? - if(currentTransition!==null) { - - if(currentTransition.walkingAtStart) { - - pitchOscillation = currentAnimation.joints[1].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + (forwardModifier * currentAnimation.joints[1].pitchPhase))); - yawOscillation = currentAnimation.joints[1].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[1].yawPhase)); - rollOscillation = currentAnimation.joints[1].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[1].rollPhase)); - - pitchOffset = currentAnimation.joints[1].pitchOffset; - yawOffset = currentAnimation.joints[1].yawOffset; - rollOffset = currentAnimation.joints[1].rollOffset; - - pitchOscillationLast = currentTransition.lastAnimation.joints[1].pitch - * Math.sin(degToRad( walkWheelPosition + (forwardModifier * currentTransition.lastAnimation.joints[1].pitchPhase ))); - - yawOscillationLast = currentTransition.lastAnimation.joints[1].yaw - * Math.sin(degToRad( walkWheelPosition + currentTransition.lastAnimation.joints[1].yawPhase )); - - rollOscillationLast = currentTransition.lastAnimation.joints[1].roll - * Math.sin(degToRad( walkWheelPosition + currentTransition.lastAnimation.joints[1].rollPhase )); - - pitchOffsetLast = currentTransition.lastAnimation.joints[1].pitchOffset; - yawOffsetLast = currentTransition.lastAnimation.joints[1].yawOffset; - rollOffsetLast = currentTransition.lastAnimation.joints[1].rollOffset; - - } else { - - pitchOscillation = currentAnimation.joints[1].pitch * Math.sin(degToRad((cycle * adjustedFrequency ) + (forwardModifier * currentAnimation.joints[1].pitchPhase))); - yawOscillation = currentAnimation.joints[1].yaw * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[1].yawPhase)); - rollOscillation = currentAnimation.joints[1].roll * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[1].rollPhase)); - - pitchOffset = currentAnimation.joints[1].pitchOffset; - yawOffset = currentAnimation.joints[1].yawOffset; - rollOffset = currentAnimation.joints[1].rollOffset; - - pitchOscillationLast = currentTransition.lastAnimation.joints[1].pitch - * Math.sin(degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency - + (forwardModifier * currentTransition.lastAnimation.joints[1].pitchPhase ))); - - yawOscillationLast = currentTransition.lastAnimation.joints[1].yaw - * Math.sin(degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency - + currentTransition.lastAnimation.joints[1].yawPhase )); - - rollOscillationLast = currentTransition.lastAnimation.joints[1].roll - * Math.sin(degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency - + currentTransition.lastAnimation.joints[1].rollPhase )); - - pitchOffsetLast = currentTransition.lastAnimation.joints[1].pitchOffset; - yawOffsetLast = currentTransition.lastAnimation.joints[1].yawOffset; - rollOffsetLast = currentTransition.lastAnimation.joints[1].rollOffset; - } - - pitchOscillation = (transitionProgress * pitchOscillation ) + ((1-transitionProgress) * pitchOscillationLast); - yawOscillation = (transitionProgress * yawOscillation ) + ((1-transitionProgress) * yawOscillationLast); - rollOscillation = (transitionProgress * rollOscillation ) + ((1-transitionProgress) * rollOscillationLast); - - pitchOffset = (transitionProgress * pitchOffset) + ((1-transitionProgress) * pitchOffsetLast); - yawOffset = (transitionProgress * yawOffset) + ((1-transitionProgress) * yawOffsetLast); - rollOffset = (transitionProgress * rollOffset) + ((1-transitionProgress) * rollOffsetLast); - - } else { - - pitchOscillation = currentAnimation.joints[1].pitch * Math.sin(degToRad((cycle * adjustedFrequency ) + (forwardModifier * currentAnimation.joints[1].pitchPhase))); - yawOscillation = currentAnimation.joints[1].yaw * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[1].yawPhase)); - rollOscillation = currentAnimation.joints[1].roll * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[1].rollPhase)); - - pitchOffset = currentAnimation.joints[1].pitchOffset; - yawOffset = currentAnimation.joints[1].yawOffset; - rollOffset = currentAnimation.joints[1].rollOffset; - } - - // apply the upper leg rotations - MyAvatar.setJointData("RightUpLeg", Quat.fromPitchYawRollDegrees( pitchOscillation + pitchOffset, yawOscillation + yawOffset, -rollOscillation - rollOffset )); - MyAvatar.setJointData("LeftUpLeg", Quat.fromPitchYawRollDegrees( -pitchOscillation + pitchOffset, yawOscillation - yawOffset, -rollOscillation + rollOffset )); - - - // lower leg - if(currentTransition!==null) { - - if(currentTransition.walkingAtStart) { - - pitchOscillation = currentAnimation.joints[2].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[2].pitchPhase)); - yawOscillation = currentAnimation.joints[2].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[2].yawPhase)); - rollOscillation = currentAnimation.joints[2].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[2].rollPhase)); - - pitchOffset = currentAnimation.joints[2].pitchOffset; - yawOffset = currentAnimation.joints[2].yawOffset; - rollOffset = currentAnimation.joints[2].rollOffset; - - pitchOscillationLast = currentTransition.lastAnimation.joints[2].pitch * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[2].pitchPhase)); - yawOscillationLast = currentTransition.lastAnimation.joints[2].yaw * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[2].yawPhase)); - rollOscillationLast = currentTransition.lastAnimation.joints[2].roll * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[2].rollPhase)); - - pitchOffsetLast = currentTransition.lastAnimation.joints[2].pitchOffset; - yawOffsetLast = currentTransition.lastAnimation.joints[2].yawOffset; - rollOffsetLast = currentTransition.lastAnimation.joints[2].rollOffset; - - } else { - - pitchOscillation = currentAnimation.joints[2].pitch * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[2].pitchPhase)); - yawOscillation = currentAnimation.joints[2].yaw * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[2].yawPhase)); - rollOscillation = currentAnimation.joints[2].roll * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[2].rollPhase)); - - pitchOffset = currentAnimation.joints[2].pitchOffset; - yawOffset = currentAnimation.joints[2].yawOffset; - rollOffset = currentAnimation.joints[2].rollOffset; - - pitchOscillationLast = currentTransition.lastAnimation.joints[2].pitch - * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) - + currentTransition.lastAnimation.joints[2].pitchPhase)); - yawOscillationLast = currentTransition.lastAnimation.joints[2].yaw - * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) - + currentTransition.lastAnimation.joints[2].yawPhase)); - rollOscillationLast = currentTransition.lastAnimation.joints[2].roll - * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) - + currentTransition.lastAnimation.joints[2].rollPhase)); - - pitchOffsetLast = currentTransition.lastAnimation.joints[2].pitchOffset; - yawOffsetLast = currentTransition.lastAnimation.joints[2].yawOffset; - rollOffsetLast = currentTransition.lastAnimation.joints[2].rollOffset; - } - - pitchOscillation = ( transitionProgress * pitchOscillation ) + ( (1-transitionProgress) * pitchOscillationLast ); - yawOscillation = ( transitionProgress * yawOscillation ) + ( (1-transitionProgress) * yawOscillationLast ); - rollOscillation = ( transitionProgress * rollOscillation ) + ( (1-transitionProgress) * rollOscillationLast ); - - pitchOffset = ( transitionProgress * pitchOffset ) + ( (1-transitionProgress) * pitchOffsetLast ); - yawOffset = ( transitionProgress * yawOffset ) + ( (1-transitionProgress) * yawOffsetLast ); - rollOffset = ( transitionProgress * rollOffset ) + ( (1-transitionProgress) * rollOffsetLast ); - - } else { - - pitchOscillation = currentAnimation.joints[2].pitch * Math.sin( degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[2].pitchPhase )); - yawOscillation = currentAnimation.joints[2].yaw * Math.sin( degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[2].yawPhase )); - rollOscillation = currentAnimation.joints[2].roll * Math.sin( degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[2].rollPhase )); - - pitchOffset = currentAnimation.joints[2].pitchOffset; - yawOffset = currentAnimation.joints[2].yawOffset; - rollOffset = currentAnimation.joints[2].rollOffset; - } - - // apply lower leg joint rotations - MyAvatar.setJointData("RightLeg", Quat.fromPitchYawRollDegrees( -pitchOscillation + pitchOffset, yawOscillation - yawOffset, rollOscillation - rollOffset )); - MyAvatar.setJointData("LeftLeg", Quat.fromPitchYawRollDegrees( pitchOscillation + pitchOffset, yawOscillation + yawOffset, rollOscillation + rollOffset )); - - } // end if !SIDE_STEPPING - - else if( INTERNAL_STATE===SIDE_STEPPING || - INTERNAL_STATE===CONFIG_SIDESTEP_LEFT || - INTERNAL_STATE===CONFIG_SIDESTEP_RIGHT ) { - - // sidestepping uses the sinewave generators slightly differently for the legs - pitchOscillation = currentAnimation.joints[1].pitch * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[1].pitchPhase)); - yawOscillation = currentAnimation.joints[1].yaw * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[1].yawPhase)); - rollOscillation = currentAnimation.joints[1].roll * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[1].rollPhase)); - - // apply upper leg rotations for sidestepping - MyAvatar.setJointData("RightUpLeg", Quat.fromPitchYawRollDegrees( - -pitchOscillation + currentAnimation.joints[1].pitchOffset, - yawOscillation + currentAnimation.joints[1].yawOffset, - rollOscillation + currentAnimation.joints[1].rollOffset )); - MyAvatar.setJointData("LeftUpLeg", Quat.fromPitchYawRollDegrees( - pitchOscillation + currentAnimation.joints[1].pitchOffset, - yawOscillation - currentAnimation.joints[1].yawOffset, - -rollOscillation - currentAnimation.joints[1].rollOffset )); - - // calculate lower leg joint rotations for sidestepping - pitchOscillation = currentAnimation.joints[2].pitch * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[2].pitchPhase)); - yawOscillation = currentAnimation.joints[2].yaw * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[2].yawPhase)); - rollOscillation = currentAnimation.joints[2].roll * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[2].rollPhase)); - - // apply lower leg joint rotations - MyAvatar.setJointData("RightLeg", Quat.fromPitchYawRollDegrees( - -pitchOscillation + currentAnimation.joints[2].pitchOffset, - yawOscillation - currentAnimation.joints[2].yawOffset, - rollOscillation - currentAnimation.joints[2].rollOffset)); // TODO: needs a kick just before fwd peak - MyAvatar.setJointData("LeftLeg", Quat.fromPitchYawRollDegrees( - pitchOscillation + currentAnimation.joints[2].pitchOffset, - yawOscillation + currentAnimation.joints[2].yawOffset, - rollOscillation + currentAnimation.joints[2].rollOffset)); - } - - // feet - if(currentTransition!==null) { - - if(currentTransition.walkingAtStart) { - - pitchOscillation = currentAnimation.joints[3].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[3].pitchPhase)); - yawOscillation = currentAnimation.joints[3].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[3].yawPhase)); - rollOscillation = currentAnimation.joints[3].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[3].rollPhase)); - - pitchOffset = currentAnimation.joints[3].pitchOffset; - yawOffset = currentAnimation.joints[3].yawOffset; - rollOffset = currentAnimation.joints[3].rollOffset; - - pitchOscillationLast = currentTransition.lastAnimation.joints[3].pitch * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[3].pitchPhase)); - yawOscillationLast = currentTransition.lastAnimation.joints[3].yaw * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[3].yawPhase)); - rollOscillationLast = currentTransition.lastAnimation.joints[3].roll * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[3].rollPhase)); - - pitchOffsetLast = currentTransition.lastAnimation.joints[3].pitchOffset; - yawOffsetLast = currentTransition.lastAnimation.joints[3].yawOffset; - rollOffsetLast = currentTransition.lastAnimation.joints[3].rollOffset; - - } else { - - pitchOscillation = currentAnimation.joints[3].pitch * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[3].pitchPhase)); - yawOscillation = currentAnimation.joints[3].yaw * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[3].yawPhase)); - rollOscillation = currentAnimation.joints[3].roll * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[3].rollPhase)); - - pitchOffset = currentAnimation.joints[3].pitchOffset; - yawOffset = currentAnimation.joints[3].yawOffset; - rollOffset = currentAnimation.joints[3].rollOffset; - - pitchOscillationLast = currentTransition.lastAnimation.joints[3].pitch - * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) - + currentTransition.lastAnimation.joints[3].pitchPhase)); - - yawOscillationLast = currentTransition.lastAnimation.joints[3].yaw - * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) - + currentTransition.lastAnimation.joints[3].yawPhase)); - - rollOscillationLast = currentTransition.lastAnimation.joints[3].roll - * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) - + currentTransition.lastAnimation.joints[3].rollPhase)); - - pitchOffsetLast = currentTransition.lastAnimation.joints[3].pitchOffset; - yawOffsetLast = currentTransition.lastAnimation.joints[3].yawOffset; - rollOffsetLast = currentTransition.lastAnimation.joints[3].rollOffset; - } - - pitchOscillation = (transitionProgress * pitchOscillation ) + ((1-transitionProgress) * pitchOscillationLast); - yawOscillation = (transitionProgress * yawOscillation ) + ((1-transitionProgress) * yawOscillationLast); - rollOscillation = (transitionProgress * rollOscillation ) + ((1-transitionProgress) * rollOscillationLast); - - pitchOffset = (transitionProgress * pitchOffset) + ((1-transitionProgress) * pitchOffsetLast); - yawOffset = (transitionProgress * yawOffset) + ((1-transitionProgress) * yawOffsetLast); - rollOffset = (transitionProgress * rollOffset) + ((1-transitionProgress) * rollOffsetLast); - - } else { - - pitchOscillation = currentAnimation.joints[3].pitch * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[3].pitchPhase)); - yawOscillation = currentAnimation.joints[3].yaw * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[3].yawPhase)); - rollOscillation = currentAnimation.joints[3].roll * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[3].rollPhase)); - - pitchOffset = currentAnimation.joints[3].pitchOffset; - yawOffset = currentAnimation.joints[3].yawOffset; - rollOffset = currentAnimation.joints[3].rollOffset; - } - - // apply foot rotations - MyAvatar.setJointData("RightFoot", Quat.fromPitchYawRollDegrees( pitchOscillation + pitchOffset, yawOscillation + yawOffset, rollOscillation + rollOffset )); - MyAvatar.setJointData("LeftFoot", Quat.fromPitchYawRollDegrees( -pitchOscillation + pitchOffset, yawOscillation - yawOffset, rollOscillation - rollOffset )); - - // play footfall sound yet? To determine this, we take the differential of the foot's pitch curve to decide when the foot hits the ground. - if( INTERNAL_STATE===WALKING || - INTERNAL_STATE===SIDE_STEPPING || - INTERNAL_STATE===CONFIG_WALK_STYLES || - INTERNAL_STATE===CONFIG_WALK_TWEAKS || - INTERNAL_STATE===CONFIG_WALK_JOINTS || - INTERNAL_STATE===CONFIG_SIDESTEP_LEFT || - INTERNAL_STATE===CONFIG_SIDESTEP_RIGHT ) { - - // finding dy/dx is as simple as determining the cosine wave for the foot's pitch function. - var feetPitchDifferential = Math.cos(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[3].pitchPhase)); - var threshHold = 0.9; // sets the audio trigger point. with accuracy. - if(feetPitchDifferential<-threshHold && - nextStep===DIRECTION_LEFT && - principleDirection!==DIRECTION_UP && - principleDirection!==DIRECTION_DOWN) { - - playFootstep(DIRECTION_LEFT); - nextStep = DIRECTION_RIGHT; - } - else if(feetPitchDifferential>threshHold && - nextStep===DIRECTION_RIGHT && - principleDirection!==DIRECTION_UP && - principleDirection!==DIRECTION_DOWN) { - - playFootstep(DIRECTION_RIGHT); - nextStep = DIRECTION_LEFT; - } - } - - // toes - if(currentTransition!==null) { - - if(currentTransition.walkingAtStart) { - - pitchOscillation = currentAnimation.joints[4].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[4].pitchPhase)); - yawOscillation = currentAnimation.joints[4].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[4].yawPhase)) + currentAnimation.joints[4].yawOffset; - rollOscillation = currentAnimation.joints[4].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[4].rollPhase)) + currentAnimation.joints[4].rollOffset; - - pitchOffset = currentAnimation.joints[4].pitchOffset; - - pitchOscillationLast = currentTransition.lastAnimation.joints[4].pitch * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[4].pitchPhase)); - yawOscillationLast = currentTransition.lastAnimation.joints[4].yaw * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[4].yawPhase)) + currentTransition.lastAnimation.joints[4].yawOffset;; - rollOscillationLast = currentTransition.lastAnimation.joints[4].roll * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[4].rollPhase))+ currentTransition.lastAnimation.joints[4].rollOffset; - - pitchOffsetLast = currentTransition.lastAnimation.joints[4].pitchOffset; - - } else { - - pitchOscillation = currentAnimation.joints[4].pitch * Math.sin(degToRad((cycle * adjustedFrequency) + currentAnimation.joints[4].pitchPhase)); - yawOscillation = currentAnimation.joints[4].yaw * Math.sin(degToRad((cycle * adjustedFrequency) + currentAnimation.joints[4].yawPhase)) + currentAnimation.joints[4].yawOffset; - rollOscillation = currentAnimation.joints[4].roll * Math.sin(degToRad((cycle * adjustedFrequency) + currentAnimation.joints[4].rollPhase)) + currentAnimation.joints[4].rollOffset; - - pitchOffset = currentAnimation.joints[4].pitchOffset; - - pitchOscillationLast = currentTransition.lastAnimation.joints[4].pitch - * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) - + currentTransition.lastAnimation.joints[4].pitchPhase)); - - yawOscillationLast = currentTransition.lastAnimation.joints[4].yaw - * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) - + currentTransition.lastAnimation.joints[4].yawPhase)) + currentTransition.lastAnimation.joints[4].yawOffset;; - - rollOscillationLast = currentTransition.lastAnimation.joints[4].roll - * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) - + currentTransition.lastAnimation.joints[4].rollPhase))+ currentTransition.lastAnimation.joints[4].rollOffset; - - pitchOffsetLast = currentTransition.lastAnimation.joints[4].pitchOffset; - } - - pitchOscillation = (transitionProgress * pitchOscillation) + ((1-transitionProgress) * pitchOscillationLast); - yawOscillation = (transitionProgress * yawOscillation) + ((1-transitionProgress) * yawOscillationLast); - rollOscillation = (transitionProgress * rollOscillation) + ((1-transitionProgress) * rollOscillationLast); - - pitchOffset = (transitionProgress * pitchOffset) + ((1-transitionProgress) * pitchOffsetLast); - - } else { - - pitchOscillation = currentAnimation.joints[4].pitch * Math.sin(degToRad((cycle * adjustedFrequency) + currentAnimation.joints[4].pitchPhase)); - yawOscillation = currentAnimation.joints[4].yaw * Math.sin(degToRad((cycle * adjustedFrequency) + currentAnimation.joints[4].yawPhase)) + currentAnimation.joints[4].yawOffset; - rollOscillation = currentAnimation.joints[4].roll * Math.sin(degToRad((cycle * adjustedFrequency) + currentAnimation.joints[4].rollPhase)) + currentAnimation.joints[4].rollOffset; - - pitchOffset = currentAnimation.joints[4].pitchOffset; - } - - // apply toe rotations - MyAvatar.setJointData("RightToeBase", Quat.fromPitchYawRollDegrees(-pitchOscillation + pitchOffset, yawOscillation, rollOscillation)); - MyAvatar.setJointData("LeftToeBase", Quat.fromPitchYawRollDegrees( pitchOscillation + pitchOffset, yawOscillation, rollOscillation)); - - // spine - if( currentTransition !== null ) { - - if( currentTransition.walkingAtStart ) { - - pitchOscillation = currentAnimation.joints[5].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency * 2 ) + currentAnimation.joints[5].pitchPhase)) + currentAnimation.joints[5].pitchOffset; - yawOscillation = currentAnimation.joints[5].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[5].yawPhase)) + currentAnimation.joints[5].yawOffset; - rollOscillation = currentAnimation.joints[5].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[5].rollPhase)) + currentAnimation.joints[5].rollOffset; - - // calculate where we would have been if we'd continued in the last state - pitchOscillationLast = currentTransition.lastAnimation.joints[5].pitch - * Math.sin(degToRad(( walkWheelPosition * 2 ) + currentTransition.lastAnimation.joints[5].pitchPhase)) - + currentTransition.lastAnimation.joints[5].pitchOffset; - yawOscillationLast = currentTransition.lastAnimation.joints[5].yaw - * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[5].yawPhase)) - + currentTransition.lastAnimation.joints[5].yawOffset; - rollOscillationLast = currentTransition.lastAnimation.joints[5].roll - * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[5].rollPhase)) - + currentTransition.lastAnimation.joints[5].rollOffset; - } else { - - pitchOscillation = currentAnimation.joints[5].pitch * Math.sin( degToRad(( cycle * adjustedFrequency * 2) - + currentAnimation.joints[5].pitchPhase)) + currentAnimation.joints[5].pitchOffset; - - yawOscillation = currentAnimation.joints[5].yaw * Math.sin( degToRad(( cycle * adjustedFrequency ) - + currentAnimation.joints[5].yawPhase)) + currentAnimation.joints[5].yawOffset; - - rollOscillation = currentAnimation.joints[5].roll * Math.sin( degToRad(( cycle * adjustedFrequency ) - + currentAnimation.joints[5].rollPhase)) + currentAnimation.joints[5].rollOffset; - - pitchOscillationLast = currentTransition.lastAnimation.joints[5].pitch - * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency * 2 ) - + currentTransition.lastAnimation.joints[5].pitchPhase)) - + currentTransition.lastAnimation.joints[5].pitchOffset; - - yawOscillationLast = currentTransition.lastAnimation.joints[5].yaw - * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) - + currentTransition.lastAnimation.joints[5].yawPhase)) - + currentTransition.lastAnimation.joints[5].yawOffset; - - rollOscillationLast = currentTransition.lastAnimation.joints[5].roll - * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) - + currentTransition.lastAnimation.joints[5].rollPhase)) - + currentTransition.lastAnimation.joints[5].rollOffset; - } - - pitchOscillation = (transitionProgress * pitchOscillation ) + ((1-transitionProgress) * pitchOscillationLast); - yawOscillation = (transitionProgress * yawOscillation ) + ((1-transitionProgress) * yawOscillationLast); - rollOscillation = (transitionProgress * rollOscillation ) + ((1-transitionProgress) * rollOscillationLast); - - } else { - - pitchOscillation = currentAnimation.joints[5].pitch * Math.sin(degToRad(( cycle * adjustedFrequency * 2) + currentAnimation.joints[5].pitchPhase)) + currentAnimation.joints[5].pitchOffset; - yawOscillation = currentAnimation.joints[5].yaw * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[5].yawPhase)) + currentAnimation.joints[5].yawOffset; - rollOscillation = currentAnimation.joints[5].roll * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[5].rollPhase)) + currentAnimation.joints[5].rollOffset; - } - - // apply spine joint rotations - MyAvatar.setJointData("Spine", Quat.fromPitchYawRollDegrees( pitchOscillation, yawOscillation, rollOscillation )); - - // spine 1 - if(currentTransition!==null) { - - if(currentTransition.walkingAtStart) { - - pitchOscillation = currentAnimation.joints[6].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency * 2) + currentAnimation.joints[6].pitchPhase)) + currentAnimation.joints[6].pitchOffset; - yawOscillation = currentAnimation.joints[6].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[6].yawPhase)) + currentAnimation.joints[6].yawOffset; - rollOscillation = currentAnimation.joints[6].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[6].rollPhase)) + currentAnimation.joints[6].rollOffset; - - pitchOscillationLast = currentTransition.lastAnimation.joints[6].pitch - * Math.sin(degToRad(( walkWheelPosition * 2 ) + currentTransition.lastAnimation.joints[6].pitchPhase)) - + currentTransition.lastAnimation.joints[6].pitchOffset; - yawOscillationLast = currentTransition.lastAnimation.joints[6].yaw - * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[6].yawPhase)) - + currentTransition.lastAnimation.joints[6].yawOffset; - rollOscillationLast = currentTransition.lastAnimation.joints[6].roll - * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[6].rollPhase)) - + currentTransition.lastAnimation.joints[6].rollOffset; - - } else { - - pitchOscillation = currentAnimation.joints[6].pitch * Math.sin( degToRad(( cycle * adjustedFrequency * 2) - + currentAnimation.joints[6].pitchPhase)) + currentAnimation.joints[6].pitchOffset; - - yawOscillation = currentAnimation.joints[6].yaw * Math.sin( degToRad(( cycle * adjustedFrequency ) - + currentAnimation.joints[6].yawPhase)) + currentAnimation.joints[6].yawOffset; - - rollOscillation = currentAnimation.joints[6].roll * Math.sin( degToRad(( cycle * adjustedFrequency ) - + currentAnimation.joints[6].rollPhase)) + currentAnimation.joints[6].rollOffset; - - pitchOscillationLast = currentTransition.lastAnimation.joints[6].pitch - * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency * 2 ) - + currentTransition.lastAnimation.joints[6].pitchPhase)) - + currentTransition.lastAnimation.joints[6].pitchOffset; - - yawOscillationLast = currentTransition.lastAnimation.joints[6].yaw - * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) - + currentTransition.lastAnimation.joints[6].yawPhase)) - + currentTransition.lastAnimation.joints[6].yawOffset; - - rollOscillationLast = currentTransition.lastAnimation.joints[6].roll - * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) - + currentTransition.lastAnimation.joints[6].rollPhase)) - + currentTransition.lastAnimation.joints[6].rollOffset; - } - - pitchOscillation = (transitionProgress * pitchOscillation) + ((1-transitionProgress) * pitchOscillationLast); - yawOscillation = (transitionProgress * yawOscillation) + ((1-transitionProgress) * yawOscillationLast); - rollOscillation = (transitionProgress * rollOscillation) + ((1-transitionProgress) * rollOscillationLast); - - } else { - - pitchOscillation = currentAnimation.joints[6].pitch * Math.sin(degToRad(( cycle * adjustedFrequency * 2) + currentAnimation.joints[6].pitchPhase)) + currentAnimation.joints[6].pitchOffset; - yawOscillation = currentAnimation.joints[6].yaw * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[6].yawPhase)) + currentAnimation.joints[6].yawOffset; - rollOscillation = currentAnimation.joints[6].roll * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[6].rollPhase)) + currentAnimation.joints[6].rollOffset; - } - // apply spine1 joint rotations - MyAvatar.setJointData("Spine1", Quat.fromPitchYawRollDegrees( pitchOscillation, yawOscillation, rollOscillation )); - - // spine 2 - if(currentTransition!==null) { - - if(currentTransition.walkingAtStart) { - pitchOscillation = currentAnimation.joints[7].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency * 2) + currentAnimation.joints[7].pitchPhase)) + currentAnimation.joints[7].pitchOffset; - yawOscillation = currentAnimation.joints[7].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[7].yawPhase)) + currentAnimation.joints[7].yawOffset; - rollOscillation = currentAnimation.joints[7].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[7].rollPhase)) + currentAnimation.joints[7].rollOffset; - - pitchOscillationLast = currentTransition.lastAnimation.joints[7].pitch - * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[7].pitchPhase)) - + currentTransition.lastAnimation.joints[7].pitchOffset; - - yawOscillationLast = currentTransition.lastAnimation.joints[7].yaw - * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[7].yawPhase)) - + currentTransition.lastAnimation.joints[7].yawOffset; - - rollOscillationLast = currentTransition.lastAnimation.joints[7].roll - * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[7].rollPhase)) - + currentTransition.lastAnimation.joints[7].rollOffset; - - } else { - - pitchOscillation = currentAnimation.joints[7].pitch - * Math.sin( degToRad(( cycle * adjustedFrequency * 2) - + currentAnimation.joints[7].pitchPhase)) - + currentAnimation.joints[7].pitchOffset; - - yawOscillation = currentAnimation.joints[7].yaw - * Math.sin( degToRad(( cycle * adjustedFrequency ) - + currentAnimation.joints[7].yawPhase)) - + currentAnimation.joints[7].yawOffset; - - rollOscillation = currentAnimation.joints[7].roll - * Math.sin( degToRad(( cycle * adjustedFrequency ) - + currentAnimation.joints[7].rollPhase)) - + currentAnimation.joints[7].rollOffset; - - pitchOscillationLast = currentTransition.lastAnimation.joints[7].pitch - * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) - + currentTransition.lastAnimation.joints[7].pitchPhase)) - + currentTransition.lastAnimation.joints[7].pitchOffset; - - yawOscillationLast = currentTransition.lastAnimation.joints[7].yaw - * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) - + currentTransition.lastAnimation.joints[7].yawPhase)) - + currentTransition.lastAnimation.joints[7].yawOffset; - - rollOscillationLast = currentTransition.lastAnimation.joints[7].roll - * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) - + currentTransition.lastAnimation.joints[7].rollPhase)) - + currentTransition.lastAnimation.joints[7].rollOffset; - } - - pitchOscillation = (transitionProgress * pitchOscillation ) + ((1-transitionProgress) * pitchOscillationLast); - yawOscillation = (transitionProgress * yawOscillation ) + ((1-transitionProgress) * yawOscillationLast); - rollOscillation = (transitionProgress * rollOscillation ) + ((1-transitionProgress) * rollOscillationLast); - - } else { - - pitchOscillation = currentAnimation.joints[7].pitch * Math.sin(degToRad(( cycle * adjustedFrequency * 2) + currentAnimation.joints[7].pitchPhase)) - + currentAnimation.joints[7].pitchOffset; - - yawOscillation = currentAnimation.joints[7].yaw * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[7].yawPhase)) - + currentAnimation.joints[7].yawOffset; - - rollOscillation = currentAnimation.joints[7].roll * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[7].rollPhase)) - + currentAnimation.joints[7].rollOffset; - } - // apply spine2 joint rotations - MyAvatar.setJointData("Spine2", Quat.fromPitchYawRollDegrees( pitchOscillation, yawOscillation, rollOscillation )); - - if(!armsFree) { - - // shoulders - if(currentTransition!==null) { - - if(currentTransition.walkingAtStart) { - pitchOscillation = currentAnimation.joints[8].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) - + currentAnimation.joints[8].pitchPhase)) + currentAnimation.joints[8].pitchOffset; - - yawOscillation = currentAnimation.joints[8].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) - + currentAnimation.joints[8].yawPhase)); - - rollOscillation = currentAnimation.joints[8].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency * 2) - + currentAnimation.joints[8].rollPhase)) + currentAnimation.joints[8].rollOffset; - - yawOffset = currentAnimation.joints[8].yawOffset; - - - pitchOscillationLast = currentTransition.lastAnimation.joints[8].pitch - * Math.sin(degToRad( walkWheelPosition + currentTransition.lastAnimation.joints[8].pitchPhase)) - + currentTransition.lastAnimation.joints[8].pitchOffset; - - yawOscillationLast = currentTransition.lastAnimation.joints[8].yaw - * Math.sin(degToRad( walkWheelPosition + currentTransition.lastAnimation.joints[8].yawPhase)) - - rollOscillationLast = currentTransition.lastAnimation.joints[8].roll - * Math.sin(degToRad( walkWheelPosition + currentTransition.lastAnimation.joints[8].rollPhase)) - + currentTransition.lastAnimation.joints[8].rollOffset; - - yawOffsetLast = currentTransition.lastAnimation.joints[8].yawOffset; - - } else { - - pitchOscillation = currentAnimation.joints[8].pitch * Math.sin( degToRad(( cycle * adjustedFrequency ) - + currentAnimation.joints[8].pitchPhase)) + currentAnimation.joints[8].pitchOffset; - - yawOscillation = currentAnimation.joints[8].yaw * Math.sin( degToRad(( cycle * adjustedFrequency ) - + currentAnimation.joints[8].yawPhase)); - - rollOscillation = currentAnimation.joints[8].roll * Math.sin( degToRad(( cycle * adjustedFrequency * 2) - + currentAnimation.joints[8].rollPhase)) + currentAnimation.joints[8].rollOffset; - - yawOffset = currentAnimation.joints[8].yawOffset; - - pitchOscillationLast = currentTransition.lastAnimation.joints[8].pitch - * Math.sin( degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency - + currentTransition.lastAnimation.joints[8].pitchPhase)) - + currentTransition.lastAnimation.joints[8].pitchOffset; - - yawOscillationLast = currentTransition.lastAnimation.joints[8].yaw - * Math.sin( degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency - + currentTransition.lastAnimation.joints[8].yawPhase)) - - rollOscillationLast = currentTransition.lastAnimation.joints[8].roll - * Math.sin( degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency - + currentTransition.lastAnimation.joints[8].rollPhase)) - + currentTransition.lastAnimation.joints[8].rollOffset; - - yawOffsetLast = currentTransition.lastAnimation.joints[8].yawOffset; - } - - pitchOscillation = (transitionProgress * pitchOscillation) + ((1-transitionProgress) * pitchOscillationLast); - yawOscillation = (transitionProgress * yawOscillation) + ((1-transitionProgress) * yawOscillationLast); - rollOscillation = (transitionProgress * rollOscillation) + ((1-transitionProgress) * rollOscillationLast); - - yawOffset = (transitionProgress * yawOffset) + ((1-transitionProgress) * yawOffsetLast); - - } else { - - pitchOscillation = currentAnimation.joints[8].pitch * Math.sin(degToRad(( cycle * adjustedFrequency ) - + currentAnimation.joints[8].pitchPhase)) + currentAnimation.joints[8].pitchOffset; - - yawOscillation = currentAnimation.joints[8].yaw * Math.sin(degToRad(( cycle * adjustedFrequency ) - + currentAnimation.joints[8].yawPhase)); - - rollOscillation = currentAnimation.joints[8].roll * Math.sin(degToRad(( cycle * adjustedFrequency * 2) - + currentAnimation.joints[8].rollPhase)) + currentAnimation.joints[8].rollOffset; - - yawOffset = currentAnimation.joints[8].yawOffset; - } - - MyAvatar.setJointData("RightShoulder", Quat.fromPitchYawRollDegrees(pitchOscillation, yawOscillation + yawOffset, rollOscillation )); - MyAvatar.setJointData("LeftShoulder", Quat.fromPitchYawRollDegrees(pitchOscillation, yawOscillation - yawOffset, -rollOscillation )); - - // upper arms - if(currentTransition!==null) { - - if(currentTransition.walkingAtStart) { - - pitchOscillation = currentAnimation.joints[9].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[9].pitchPhase)); - yawOscillation = currentAnimation.joints[9].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[9].yawPhase)); - rollOscillation = currentAnimation.joints[9].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency * 2) + currentAnimation.joints[9].rollPhase)) + currentAnimation.joints[9].rollOffset; - - pitchOffset = currentAnimation.joints[9].pitchOffset; - yawOffset = currentAnimation.joints[9].yawOffset; - - pitchOscillationLast = currentTransition.lastAnimation.joints[9].pitch - * Math.sin(degToRad( walkWheelPosition + currentTransition.lastAnimation.joints[9].pitchPhase)) - - yawOscillationLast = currentTransition.lastAnimation.joints[9].yaw - * Math.sin(degToRad( walkWheelPosition + currentTransition.lastAnimation.joints[9].yawPhase)) - - rollOscillationLast = currentTransition.lastAnimation.joints[9].roll - * Math.sin(degToRad( walkWheelPosition + currentTransition.lastAnimation.joints[9].rollPhase)) - + currentTransition.lastAnimation.joints[9].rollOffset; - - pitchOffsetLast = currentTransition.lastAnimation.joints[9].pitchOffset; - yawOffsetLast = currentTransition.lastAnimation.joints[9].yawOffset; - - } else { - - pitchOscillation = currentAnimation.joints[9].pitch - * Math.sin( degToRad(( cycle * adjustedFrequency ) - + currentAnimation.joints[9].pitchPhase)); - - yawOscillation = currentAnimation.joints[9].yaw - * Math.sin( degToRad(( cycle * adjustedFrequency ) - + currentAnimation.joints[9].yawPhase)); - - rollOscillation = currentAnimation.joints[9].roll - * Math.sin(degToRad(( cycle * adjustedFrequency * 2) - + currentAnimation.joints[9].rollPhase)) - + currentAnimation.joints[9].rollOffset; - - pitchOffset = currentAnimation.joints[9].pitchOffset; - yawOffset = currentAnimation.joints[9].yawOffset; - - pitchOscillationLast = currentTransition.lastAnimation.joints[9].pitch - * Math.sin( degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency - + currentTransition.lastAnimation.joints[9].pitchPhase)) - - yawOscillationLast = currentTransition.lastAnimation.joints[9].yaw - * Math.sin( degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency - + currentTransition.lastAnimation.joints[9].yawPhase)) - - rollOscillationLast = currentTransition.lastAnimation.joints[9].roll - * Math.sin( degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency - + currentTransition.lastAnimation.joints[9].rollPhase)) - + currentTransition.lastAnimation.joints[9].rollOffset; - - pitchOffsetLast = currentTransition.lastAnimation.joints[9].pitchOffset; - yawOffsetLast = currentTransition.lastAnimation.joints[9].yawOffset; - } - - pitchOscillation = (transitionProgress * pitchOscillation) + ((1-transitionProgress) * pitchOscillationLast); - yawOscillation = (transitionProgress * yawOscillation) + ((1-transitionProgress) * yawOscillationLast); - rollOscillation = (transitionProgress * rollOscillation) + ((1-transitionProgress) * rollOscillationLast); - - pitchOffset = (transitionProgress * pitchOffset) + ((1-transitionProgress) * pitchOffsetLast); - yawOffset = (transitionProgress * yawOffset) + ((1-transitionProgress) * yawOffsetLast); - - } else { - - pitchOscillation = currentAnimation.joints[9].pitch - * Math.sin( degToRad(( cycle * adjustedFrequency ) - + currentAnimation.joints[9].pitchPhase)); - - yawOscillation = currentAnimation.joints[9].yaw - * Math.sin( degToRad(( cycle * adjustedFrequency ) - + currentAnimation.joints[9].yawPhase)); - - rollOscillation = currentAnimation.joints[9].roll - * Math.sin( degToRad(( cycle * adjustedFrequency * 2) - + currentAnimation.joints[9].rollPhase)) - + currentAnimation.joints[9].rollOffset; - - pitchOffset = currentAnimation.joints[9].pitchOffset; - yawOffset = currentAnimation.joints[9].yawOffset; - - } - MyAvatar.setJointData("RightArm", Quat.fromPitchYawRollDegrees( -pitchOscillation + pitchOffset, yawOscillation - yawOffset, rollOscillation )); - MyAvatar.setJointData("LeftArm", Quat.fromPitchYawRollDegrees( pitchOscillation + pitchOffset, yawOscillation + yawOffset, -rollOscillation )); - - // forearms - if(currentTransition!==null) { - - if(currentTransition.walkingAtStart) { - - pitchOscillation = currentAnimation.joints[10].pitch - * Math.sin( degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) - + currentAnimation.joints[10].pitchPhase )) - + currentAnimation.joints[10].pitchOffset; - - yawOscillation = currentAnimation.joints[10].yaw - * Math.sin( degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) - + currentAnimation.joints[10].yawPhase )); - - rollOscillation = currentAnimation.joints[10].roll - * Math.sin( degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) - + currentAnimation.joints[10].rollPhase )); - - yawOffset = currentAnimation.joints[10].yawOffset; - rollOffset = currentAnimation.joints[10].rollOffset; - - pitchOscillationLast = currentTransition.lastAnimation.joints[10].pitch - * Math.sin( degToRad(( walkWheelPosition ) - + currentTransition.lastAnimation.joints[10].pitchPhase)) - + currentTransition.lastAnimation.joints[10].pitchOffset; - - yawOscillationLast = currentTransition.lastAnimation.joints[10].yaw - * Math.sin( degToRad(( walkWheelPosition ) - + currentTransition.lastAnimation.joints[10].yawPhase)); - - rollOscillationLast = currentTransition.lastAnimation.joints[10].roll - * Math.sin( degToRad(( walkWheelPosition ) - + currentTransition.lastAnimation.joints[10].rollPhase)); - - yawOffsetLast = currentTransition.lastAnimation.joints[10].yawOffset; - rollOffsetLast = currentTransition.lastAnimation.joints[10].rollOffset; - - } else { - - pitchOscillation = currentAnimation.joints[10].pitch - * Math.sin( degToRad(( cycle * adjustedFrequency ) - + currentAnimation.joints[10].pitchPhase )) - + currentAnimation.joints[10].pitchOffset; - - yawOscillation = currentAnimation.joints[10].yaw - * Math.sin( degToRad(( cycle * adjustedFrequency ) - + currentAnimation.joints[10].yawPhase )); - - rollOscillation = currentAnimation.joints[10].roll - * Math.sin( degToRad(( cycle * adjustedFrequency ) - + currentAnimation.joints[10].rollPhase )); - - yawOffset = currentAnimation.joints[10].yawOffset; - rollOffset = currentAnimation.joints[10].rollOffset; - - pitchOscillationLast = currentTransition.lastAnimation.joints[10].pitch - * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) - + currentTransition.lastAnimation.joints[10].pitchPhase)) - + currentTransition.lastAnimation.joints[10].pitchOffset; - - yawOscillationLast = currentTransition.lastAnimation.joints[10].yaw - * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) - + currentTransition.lastAnimation.joints[10].yawPhase)); - - rollOscillationLast = currentTransition.lastAnimation.joints[10].roll - * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) - + currentTransition.lastAnimation.joints[10].rollPhase)); - - yawOffsetLast = currentTransition.lastAnimation.joints[10].yawOffset; - rollOffsetLast = currentTransition.lastAnimation.joints[10].rollOffset; - } - - // blend the previous and next - pitchOscillation = (transitionProgress * pitchOscillation) + ((1-transitionProgress) * pitchOscillationLast); - yawOscillation = -(transitionProgress * yawOscillation) + ((1-transitionProgress) * yawOscillationLast); - rollOscillation = (transitionProgress * rollOscillation) + ((1-transitionProgress) * rollOscillationLast); - - yawOffset = (transitionProgress * yawOffset) + ((1-transitionProgress) * yawOffsetLast); - rollOffset = (transitionProgress * rollOffset) + ((1-transitionProgress) * rollOffsetLast); - - } else { - - pitchOscillation = currentAnimation.joints[10].pitch - * Math.sin( degToRad(( cycle * adjustedFrequency ) - + currentAnimation.joints[10].pitchPhase )) - + currentAnimation.joints[10].pitchOffset; - - yawOscillation = currentAnimation.joints[10].yaw - * Math.sin( degToRad(( cycle * adjustedFrequency ) - + currentAnimation.joints[10].yawPhase )); - - rollOscillation = currentAnimation.joints[10].roll - * Math.sin( degToRad(( cycle * adjustedFrequency ) - + currentAnimation.joints[10].rollPhase )); - - yawOffset = currentAnimation.joints[10].yawOffset; - rollOffset = currentAnimation.joints[10].rollOffset; - } - - // apply forearms rotations - MyAvatar.setJointData("RightForeArm", Quat.fromPitchYawRollDegrees( pitchOscillation, yawOscillation + yawOffset, rollOscillation + rollOffset )); - MyAvatar.setJointData("LeftForeArm", Quat.fromPitchYawRollDegrees( pitchOscillation, yawOscillation - yawOffset, rollOscillation - rollOffset )); - - // hands - var sideStepSign = 1; - if(INTERNAL_STATE===SIDE_STEPPING) { - sideStepSign = 1; - } - if(currentTransition!==null) { - - if(currentTransition.walkingAtStart) { - - pitchOscillation = currentAnimation.joints[11].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[11].pitchPhase)) + currentAnimation.joints[11].pitchOffset; - yawOscillation = currentAnimation.joints[11].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[11].yawPhase)) + currentAnimation.joints[11].yawOffset; - rollOscillation = currentAnimation.joints[11].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[11].rollPhase)) ; - - pitchOscillationLast = currentTransition.lastAnimation.joints[11].pitch - * Math.sin(degToRad( walkWheelPosition + currentTransition.lastAnimation.joints[11].pitchPhase)) - + currentTransition.lastAnimation.joints[11].pitchOffset; - - yawOscillationLast = currentTransition.lastAnimation.joints[11].yaw - * Math.sin(degToRad( walkWheelPosition + currentTransition.lastAnimation.joints[11].yawPhase)) - + currentTransition.lastAnimation.joints[11].yawOffset; - - rollOscillationLast = currentTransition.lastAnimation.joints[11].roll - * Math.sin(degToRad( walkWheelPosition + currentTransition.lastAnimation.joints[11].rollPhase)) - - rollOffset = currentAnimation.joints[11].rollOffset; - rollOffsetLast = currentTransition.lastAnimation.joints[11].rollOffset; - - } else { - - pitchOscillation = currentAnimation.joints[11].pitch - * Math.sin( degToRad(( cycle * adjustedFrequency ) - + currentAnimation.joints[11].pitchPhase)) - + currentAnimation.joints[11].pitchOffset; - - yawOscillation = currentAnimation.joints[11].yaw - * Math.sin( degToRad(( cycle * adjustedFrequency ) - + currentAnimation.joints[11].yawPhase)) - + currentAnimation.joints[11].yawOffset; - - rollOscillation = currentAnimation.joints[11].roll - * Math.sin( degToRad(( cycle * adjustedFrequency ) - + currentAnimation.joints[11].rollPhase)); - - rollOffset = currentAnimation.joints[11].rollOffset; - - pitchOscillationLast = currentTransition.lastAnimation.joints[11].pitch - * Math.sin(degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency - + currentTransition.lastAnimation.joints[11].pitchPhase)) - + currentTransition.lastAnimation.joints[11].pitchOffset; - - yawOscillationLast = currentTransition.lastAnimation.joints[11].yaw - * Math.sin(degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency - + currentTransition.lastAnimation.joints[11].yawPhase)) - + currentTransition.lastAnimation.joints[11].yawOffset; - - rollOscillationLast = currentTransition.lastAnimation.joints[11].roll - * Math.sin(degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency - + currentTransition.lastAnimation.joints[11].rollPhase)) - - rollOffset = currentAnimation.joints[11].rollOffset; - rollOffsetLast = currentTransition.lastAnimation.joints[11].rollOffset; - } - - pitchOscillation = (transitionProgress * pitchOscillation) + ((1-transitionProgress) * pitchOscillationLast); - yawOscillation = (transitionProgress * yawOscillation) + ((1-transitionProgress) * yawOscillationLast); - rollOscillation = (transitionProgress * rollOscillation) + ((1-transitionProgress) * rollOscillationLast); - - rollOffset = (transitionProgress * rollOffset) + ((1-transitionProgress) * rollOffsetLast); - - } else { - - pitchOscillation = currentAnimation.joints[11].pitch * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[11].pitchPhase)) + currentAnimation.joints[11].pitchOffset; - yawOscillation = currentAnimation.joints[11].yaw * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[11].yawPhase)) + currentAnimation.joints[11].yawOffset; - rollOscillation = currentAnimation.joints[11].roll * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[11].rollPhase)); - - rollOffset = currentAnimation.joints[11].rollOffset; - } - - // set the hand rotations - MyAvatar.setJointData("RightHand", Quat.fromPitchYawRollDegrees( sideStepSign * pitchOscillation, yawOscillation, rollOscillation + rollOffset)); - MyAvatar.setJointData("LeftHand", Quat.fromPitchYawRollDegrees( pitchOscillation, -yawOscillation, rollOscillation - rollOffset)); - - } // end if(!armsFree) - - // head (includes neck joint) - currently zeroed out in STANDING animation files by request - if( currentTransition !== null ) { - - if(currentTransition.walkingAtStart) { - - pitchOscillation = 0.5 * currentAnimation.joints[12].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency * 2) - + currentAnimation.joints[12].pitchPhase)) + currentAnimation.joints[12].pitchOffset; - - yawOscillation = 0.5 * currentAnimation.joints[12].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) - + currentAnimation.joints[12].yawPhase)) + currentAnimation.joints[12].yawOffset; - - rollOscillation = 0.5 * currentAnimation.joints[12].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) - + currentAnimation.joints[12].rollPhase)) + currentAnimation.joints[12].rollOffset; - - pitchOscillationLast = 0.5 * currentTransition.lastAnimation.joints[12].pitch - * Math.sin(degToRad(( walkWheelPosition * 2) + currentTransition.lastAnimation.joints[12].pitchPhase)) - + currentTransition.lastAnimation.joints[12].pitchOffset; - - yawOscillationLast = 0.5 * currentTransition.lastAnimation.joints[12].yaw - * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[12].yawPhase)) - + currentTransition.lastAnimation.joints[12].yawOffset; - - rollOscillationLast = 0.5 * currentTransition.lastAnimation.joints[12].roll - * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[12].rollPhase)) - + currentTransition.lastAnimation.joints[12].rollOffset; - - } else { - - pitchOscillation = 0.5 * currentAnimation.joints[12].pitch * Math.sin(degToRad(( cycle * adjustedFrequency * 2) + currentAnimation.joints[12].pitchPhase)) + currentAnimation.joints[12].pitchOffset; - yawOscillation = 0.5 * currentAnimation.joints[12].yaw * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[12].yawPhase)) + currentAnimation.joints[12].yawOffset; - rollOscillation = 0.5 * currentAnimation.joints[12].roll * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[12].rollPhase)) + currentAnimation.joints[12].rollOffset; - - pitchOscillationLast = 0.5 * currentTransition.lastAnimation.joints[12].pitch - * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency * 2) - + currentTransition.lastAnimation.joints[12].pitchPhase)) - + currentTransition.lastAnimation.joints[12].pitchOffset; - - yawOscillationLast = 0.5 * currentTransition.lastAnimation.joints[12].yaw - * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) - + currentTransition.lastAnimation.joints[12].yawPhase)) - + currentTransition.lastAnimation.joints[12].yawOffset; - - rollOscillationLast = 0.5 * currentTransition.lastAnimation.joints[12].roll - * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) - + currentTransition.lastAnimation.joints[12].rollPhase)) - + currentTransition.lastAnimation.joints[12].rollOffset; - } - - pitchOscillation = (transitionProgress * pitchOscillation) + ((1-transitionProgress) * pitchOscillationLast); - yawOscillation = (transitionProgress * yawOscillation) + ((1-transitionProgress) * yawOscillationLast); - rollOscillation = (transitionProgress * rollOscillation) + ((1-transitionProgress) * rollOscillationLast); - - } else { - - pitchOscillation = 0.5 * currentAnimation.joints[12].pitch * Math.sin(degToRad(( cycle * adjustedFrequency * 2) + currentAnimation.joints[12].pitchPhase)) + currentAnimation.joints[12].pitchOffset; - yawOscillation = 0.5 * currentAnimation.joints[12].yaw * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[12].yawPhase)) + currentAnimation.joints[12].yawOffset; - rollOscillation = 0.5 * currentAnimation.joints[12].roll * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[12].rollPhase)) + currentAnimation.joints[12].rollOffset; - } - - MyAvatar.setJointData( "Head", Quat.fromPitchYawRollDegrees( pitchOscillation, yawOscillation, rollOscillation )); - MyAvatar.setJointData( "Neck", Quat.fromPitchYawRollDegrees( pitchOscillation, yawOscillation, rollOscillation )); -} - - - -// Bezier function for applying to transitions - src: Dan Pupius (www.pupius.net) http://13thparallel.com/archive/bezier-curves/ -Coord = function (x,y) { - if(!x) var x=0; - if(!y) var y=0; - return {x: x, y: y}; -} - -function B1(t) { return t*t*t } -function B2(t) { return 3*t*t*(1-t) } -function B3(t) { return 3*t*(1-t)*(1-t) } -function B4(t) { return (1-t)*(1-t)*(1-t) } - -function getBezier(percent,C1,C2,C3,C4) { - var pos = new Coord(); - pos.x = C1.x*B1(percent) + C2.x*B2(percent) + C3.x*B3(percent) + C4.x*B4(percent); - pos.y = C1.y*B1(percent) + C2.y*B2(percent) + C3.y*B3(percent) + C4.y*B4(percent); - return pos; -} - -// Butterworth LP filter - coeffs calculated using: http://www-users.cs.york.ac.uk/~fisher/mkfilter/trad.html -var NZEROS = 8; -var NPOLES = 8; -var GAIN = 17.40692157; -var xv = [0,0,0,0,0,0,0,0,0]; //xv.length = NZEROS+1; -var yv = [0,0,0,0,0,0,0,0,0]; //yv.length = NPOLES+1; - -function filterButterworth(nextInputValue) -{ - xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4]; xv[4] = xv[5]; xv[5] = xv[6]; xv[6] = xv[7]; xv[7] = xv[8]; - xv[8] = nextInputValue / GAIN; - yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4]; yv[4] = yv[5]; yv[5] = yv[6]; yv[6] = yv[7]; yv[7] = yv[8]; - yv[8] = (xv[0] + xv[8]) + 8 * (xv[1] + xv[7]) + 28 * (xv[2] + xv[6]) - + 56 * (xv[3] + xv[5]) + 70 * xv[4] - + ( -0.0033008230 * yv[0]) + ( -0.0440409341 * yv[1]) - + ( -0.2663485333 * yv[2]) + ( -0.9570250765 * yv[3]) - + ( -2.2596729000 * yv[4]) + ( -3.6088345059 * yv[5]) - + ( -3.9148571397 * yv[6]) + ( -2.6527135283 * yv[7]); - return yv[8]; -} - -// the faster we go, the further we lean forward. the angle is calcualted here -var leanAngles = []; // smooth out and add damping with simple averaging filter. -leanAngles.length = 15; - -function getLeanPitch(velocity) { - - if(velocity>TERMINAL_VELOCITY) velocity=TERMINAL_VELOCITY; - var leanProgress = velocity / TERMINAL_VELOCITY; - var responseSharpness = 1.8; - if(principleDirection==DIRECTION_BACKWARDS) responseSharpness = 3.6; // lean back a bit extra when walking backwards - var leanProgressBezier = getBezier((1-leanProgress),{x:0,y:0},{x:0,y:responseSharpness},{x:0,y:1},{x:1,y:1}).y; - - // simple averaging filter seems to give best results - leanAngles.push(leanProgressBezier); - leanAngles.shift(); // FIFO - var totalLeanAngles = 0; - for(ea in leanAngles) totalLeanAngles += leanAngles[ea]; - var leanProgressAverageFiltered = totalLeanAngles / leanAngles.length; - - // calculate final return value - var leanPitchFinal = 0; - if(principleDirection===DIRECTION_BACKWARDS) { - leanPitchFinal = -currentAnimation.settings.flyingHipsPitch * leanProgressAverageFiltered;// + finalAccelerationResponse; - } else { - leanPitchFinal = currentAnimation.settings.flyingHipsPitch * leanProgressAverageFiltered;// + finalAccelerationResponse; - } - return leanPitchFinal; -} - -// calculate the angle at which to bank into corners when turning -var leanRollAngles = []; // smooth out and add damping with simple averaging filter -leanRollAngles.length = 25; - -var angularVelocities = []; // keep a record of the last few so can filter out spurious values -angularVelocities.length = 5; - -function getLeanRoll(deltaTime, velocity) { - - // what's our current anglular velocity? - var angularVelocityMax = 70; // from observation - var currentOrientationVec3 = Quat.safeEulerAngles(MyAvatar.orientation); - var lastOrientationVec3 = Quat.safeEulerAngles(lastOrientation); - var deltaYaw = lastOrientationVec3.y-currentOrientationVec3.y; - lastOrientation = MyAvatar.orientation; - - var angularVelocity = deltaYaw / deltaTime; - if(angularVelocity>angularVelocityMax) angularVelocity = angularVelocityMax; - if(angularVelocity<-angularVelocityMax) angularVelocity = -angularVelocityMax; - - // filter the angular velocity for a nicer response and a bit of wobble (intentional overshoot / ringing) - angularVelocity = filterButterworth(angularVelocity); - - var turnSign = 1; - if(angularVelocity<0) turnSign = -1; - if(principleDirection===DIRECTION_BACKWARDS) - turnSign *= -1; - - // calculate the amount of roll based on both angular and linear velocities - if(velocity>TERMINAL_VELOCITY) velocity = TERMINAL_VELOCITY; - var leanRollProgress = (velocity / TERMINAL_VELOCITY) * (Math.abs(angularVelocity) / angularVelocityMax); - - // apply our response curve - var leanRollProgressBezier = getBezier((1-leanRollProgress),{x:0,y:0},{x:0,y:2.5},{x:0,y:1},{x:1,y:1}).y; - - // simple averaging filter - leanRollAngles.push(turnSign * leanRollProgressBezier); - leanRollAngles.shift(); // FIFO - var totalLeanRollAngles = 0; - for(var ea in leanRollAngles) totalLeanRollAngles += leanRollAngles[ea]; - var leanRollProgressAverageFiltered = totalLeanRollAngles / leanRollAngles.length; - - return currentAnimation.settings.maxBankingAngle * leanRollProgressAverageFiltered; -} - -// set up the interface components, update the internal state and kick off any transitions -function setInternalState(newInternalState) { - - switch(newInternalState) { - - case WALKING: - - if(!minimised) doStandardMenu(); - INTERNAL_STATE = WALKING; - return; - - case FLYING: - - if(!minimised) doStandardMenu(); - INTERNAL_STATE = FLYING; - return; - - case SIDE_STEPPING: - - if(!minimised) doStandardMenu(); - INTERNAL_STATE = SIDE_STEPPING; - return; - - case CONFIG_WALK_STYLES: - - INTERNAL_STATE = CONFIG_WALK_STYLES; - currentAnimation = selectedWalk; - if(!minimised) { - hidebuttonOverlays(); - hideJointControls(); - showFrontPanelButtons(false); - showWalkStyleButtons(true); - setBackground(controlsBackgroundWalkEditStyles); - setButtonOverlayVisible(onButton); - setButtonOverlayVisible(configWalkStylesButtonSelected); - setButtonOverlayVisible(configWalkTweaksButton); - setButtonOverlayVisible(configWalkJointsButton); - setButtonOverlayVisible(backButton); - setSliderThumbsVisible(false); - } - return; - - case CONFIG_WALK_TWEAKS: - - INTERNAL_STATE = CONFIG_WALK_TWEAKS; - currentAnimation = selectedWalk; - if(!minimised) { - hidebuttonOverlays(); - hideJointControls(); - showFrontPanelButtons(false); - showWalkStyleButtons(false); - setBackground(controlsBackgroundWalkEditTweaks); - setButtonOverlayVisible(onButton); - setButtonOverlayVisible(configWalkStylesButton); - setButtonOverlayVisible(configWalkTweaksButtonSelected); - setButtonOverlayVisible(configWalkJointsButton); - setButtonOverlayVisible(backButton); - initialiseWalkTweaks(); - } - return; - - case CONFIG_WALK_JOINTS: - - INTERNAL_STATE = CONFIG_WALK_JOINTS; - currentAnimation = selectedWalk; - if(!minimised) { - hidebuttonOverlays(); - showFrontPanelButtons(false); - showWalkStyleButtons(false); - setBackground(controlsBackgroundWalkEditJoints); - setButtonOverlayVisible(onButton); - setButtonOverlayVisible(configWalkStylesButton); - setButtonOverlayVisible(configWalkTweaksButton); - setButtonOverlayVisible(configWalkJointsButtonSelected); - setButtonOverlayVisible(backButton); - initialiseJointsEditingPanel(selectedJointIndex); - } - return; - - case CONFIG_STANDING: - - INTERNAL_STATE = CONFIG_STANDING; - currentAnimation = selectedStand; - if(!minimised) { - hidebuttonOverlays(); - showFrontPanelButtons(false); - showWalkStyleButtons(false); - setBackground(controlsBackgroundWalkEditJoints); - setButtonOverlayVisible(onButton); - setButtonOverlayVisible(configSideStepRightButton); - setButtonOverlayVisible(configSideStepLeftButton); - setButtonOverlayVisible(configStandButtonSelected); - setButtonOverlayVisible(backButton); - initialiseJointsEditingPanel(selectedJointIndex); - } - return; - - case CONFIG_SIDESTEP_LEFT: - - INTERNAL_STATE = CONFIG_SIDESTEP_LEFT; - currentAnimation = selectedSideStepLeft; - if(!minimised) { - hidebuttonOverlays(); - showFrontPanelButtons(false); - showWalkStyleButtons(false); - setBackground(controlsBackgroundWalkEditJoints); - setButtonOverlayVisible(onButton); - setButtonOverlayVisible(configSideStepRightButton); - setButtonOverlayVisible(configSideStepLeftButtonSelected); - setButtonOverlayVisible(configStandButton); - setButtonOverlayVisible(backButton); - initialiseJointsEditingPanel(selectedJointIndex); - } - return; - - case CONFIG_SIDESTEP_RIGHT: - - INTERNAL_STATE = CONFIG_SIDESTEP_RIGHT; - currentAnimation = selectedSideStepRight; - if(!minimised) { - hidebuttonOverlays(); - showFrontPanelButtons(false); - showWalkStyleButtons(false); - setBackground(controlsBackgroundWalkEditJoints); - setButtonOverlayVisible(onButton); - setButtonOverlayVisible(configSideStepRightButtonSelected); - setButtonOverlayVisible(configSideStepLeftButton); - setButtonOverlayVisible(configStandButton); - setButtonOverlayVisible(backButton); - initialiseJointsEditingPanel(selectedJointIndex); - } - return; - - case CONFIG_FLYING: - - INTERNAL_STATE = CONFIG_FLYING; - currentAnimation = selectedFly; - if(!minimised) { - hidebuttonOverlays(); - showFrontPanelButtons(false); - showWalkStyleButtons(false); - setBackground(controlsBackgroundWalkEditJoints); - setButtonOverlayVisible(onButton); - setButtonOverlayVisible(configFlyingUpButton); - setButtonOverlayVisible(configFlyingDownButton); - setButtonOverlayVisible(configFlyingButtonSelected); - setButtonOverlayVisible(backButton); - initialiseJointsEditingPanel(selectedJointIndex); - } - return; - - case CONFIG_FLYING_UP: - - INTERNAL_STATE = CONFIG_FLYING_UP; - currentAnimation = selectedFlyUp; - if(!minimised) { - hidebuttonOverlays(); - showFrontPanelButtons(false); - showWalkStyleButtons(false); - setBackground(controlsBackgroundWalkEditJoints); - setButtonOverlayVisible(onButton); - setButtonOverlayVisible(configFlyingUpButtonSelected); - setButtonOverlayVisible(configFlyingDownButton); - setButtonOverlayVisible(configFlyingButton); - setButtonOverlayVisible(backButton); - initialiseJointsEditingPanel(selectedJointIndex); - } - return; - - case CONFIG_FLYING_DOWN: - - INTERNAL_STATE = CONFIG_FLYING_DOWN; - currentAnimation = selectedFlyDown; - if(!minimised) { - hidebuttonOverlays(); - showFrontPanelButtons(false); - showWalkStyleButtons(false); - setBackground(controlsBackgroundWalkEditJoints); - setButtonOverlayVisible(onButton); - setButtonOverlayVisible(configFlyingUpButton); - setButtonOverlayVisible(configFlyingDownButtonSelected); - setButtonOverlayVisible(configFlyingButton); - setButtonOverlayVisible(backButton); - initialiseJointsEditingPanel(selectedJointIndex); - } - return; - - case STANDING: - default: - - INTERNAL_STATE = STANDING; - if(!minimised) doStandardMenu(); - - // initialisation - runs at script startup only - if(strideLength===0) { - - if(principleDirection===DIRECTION_BACKWARDS) - strideLength = selectedWalk.calibration.strideLengthBackwards; - else - strideLength = selectedWalk.calibration.strideLengthForwards; - - curlFingers(); - } - return; - } -} // Main loop - -// stabilising vars - most state changes are preceded by a couple of hints that they are about to happen rather than -// momentarilly switching between states (causes flicker), we count the number of hints in a row before actually changing state -var standHints = 0; -var walkHints = 0; -var flyHints = 0; -var requiredHints = 2; // tweakable - debounce state changes - how many times do we get a state change request in a row before we actually change state? (used to be 4 or 5) -var principleDirection = 0; - -// helper function for stats output -function directionAsString(directionEnum) { - - switch(directionEnum) { - case DIRECTION_UP: return 'Up'; - case DIRECTION_DOWN: return 'Down'; - case DIRECTION_LEFT: return 'Left'; - case DIRECTION_RIGHT: return 'Right'; - case DIRECTION_FORWARDS: return 'Forwards'; - case DIRECTION_BACKWARDS: return 'Backwards'; - default: return 'Unknown'; - } -} -// helper function for stats output -function internalStateAsString(internalState) { - - switch(internalState) { - case STANDING: return 'Standing'; - case WALKING: return 'Walking'; - case SIDE_STEPPING: return 'Side Stepping'; - case FLYING: return 'Flying'; - default: return 'Editing'; - } -} - Script.update.connect(function(deltaTime) { - if(powerOn) { + if (state.powerOn) { - frameStartTime = new Date().getTime(); - cumulativeTime += deltaTime; - nFrames++; - var speed = 0; + motion.frameStartTime = new Date().getTime(); + motion.cumulativeTime += deltaTime; + motion.nFrames++; + var speed = 0; - // firstly check for editing modes, as these require no positioning calculations - var editing = false; - switch(INTERNAL_STATE) { + // check for editing modes first, as these require no positioning calculations + switch (state.currentState) { - case CONFIG_WALK_STYLES: - currentAnimation = selectedWalk; - animateAvatar(deltaTime, speed, principleDirection); - editing = true; - break; - case CONFIG_WALK_TWEAKS: - currentAnimation = selectedWalk; - animateAvatar(deltaTime, speed, DIRECTION_FORWARDS); - editing = true; - break; - case CONFIG_WALK_JOINTS: - currentAnimation = selectedWalk; - animateAvatar(deltaTime, speed, DIRECTION_FORWARDS); - editing = true; - break; - case CONFIG_STANDING: - currentAnimation = selectedStand; - animateAvatar(deltaTime, speed, DIRECTION_FORWARDS); - editing = true; - break; - case CONFIG_SIDESTEP_LEFT: - currentAnimation = selectedSideStepLeft; - animateAvatar(deltaTime, speed, DIRECTION_LEFT); - editing = true; - break; - case CONFIG_SIDESTEP_RIGHT: - currentAnimation = selectedSideStepRight; - animateAvatar(deltaTime, speed, DIRECTION_RIGHT); - editing = true; - break; - case CONFIG_FLYING: - currentAnimation = selectedFly; - animateAvatar(deltaTime, speed, DIRECTION_FORWARDS); - editing = true; - break; - case CONFIG_FLYING_UP: - currentAnimation = selectedFlyUp; - animateAvatar(deltaTime, speed, DIRECTION_UP); - editing = true; - break; - case CONFIG_FLYING_DOWN: - currentAnimation = selectedFlyDown; - animateAvatar(deltaTime, speed, DIRECTION_DOWN); - editing = true; - break; - default: - break; - } + case state.EDIT_WALK_STYLES: + motion.curAnim = motion.selWalk; + animateAvatar(deltaTime, speed); + break; - // we have to declare these vars here ( outside 'if(!editing)' ), so they are still in scope - // when we record the frame's data and when we do the stats update at the end - var deltaX = 0; - var deltaY = 0; - var deltaZ = 0; - var acceleration = { x:0, y:0, z:0 }; - var accelerationJS = MyAvatar.getAcceleration(); + case state.EDIT_WALK_TWEAKS: + motion.curAnim = motion.selWalk; + animateAvatar(deltaTime, speed); + break; - // calculate overriding (local) direction of translation for use later when decide which animation should be played - var inverseRotation = Quat.inverse(MyAvatar.orientation); - var localVelocity = Vec3.multiplyQbyV(inverseRotation, MyAvatar.getVelocity()); + case state.EDIT_WALK_JOINTS: + motion.curAnim = motion.selWalk; + animateAvatar(deltaTime, speed); + break; - if(!editing) { + case state.EDIT_STANDING: + motion.curAnim = motion.selStand; + motion.direction = FORWARDS; + animateAvatar(deltaTime, speed); + break; - // the first thing to do is find out how fast we're going, - // what our acceleration is and which direction we're principly moving in + case state.EDIT_SIDESTEP_LEFT: + motion.curAnim = motion.selSideStepLeft; + motion.direction = LEFT; + animateAvatar(deltaTime, speed); + break; - // calcualte (local) change in velocity - var velocity = MyAvatar.getVelocity(); - speed = Vec3.length(velocity); + case state.EDIT_SIDESTEP_RIGHT: + motion.curAnim = motion.selSideStepRight; + motion.direction = RIGHT; + animateAvatar(deltaTime, speed); + break; - // determine the candidate animation to play - var actionToTake = 0; - if( speed < 0.5) { - actionToTake = STANDING; - standHints++; - } - else if( speed < FLYING_SPEED ) { - actionToTake = WALKING; - walkHints++; - } - else if( speed >= FLYING_SPEED ) { - actionToTake = FLYING; - flyHints++; - } + case state.EDIT_FLYING: + motion.curAnim = motion.selFly; + motion.direction = FORWARDS; + animateAvatar(deltaTime, speed); + break; - deltaX = localVelocity.x; - deltaY = localVelocity.y; - deltaZ = -localVelocity.z; + case state.EDIT_FLYING_UP: + motion.curAnim = motion.selFlyUp; + motion.direction = UP; + animateAvatar(deltaTime, speed); + break; + + case state.EDIT_FLYING_DOWN: + motion.curAnim = motion.selFlyDown; + motion.direction = DOWN; + animateAvatar(deltaTime, speed); + break; + + default: + break; + } + + // calcualte velocity and speed + var velocity = MyAvatar.getVelocity(); + speed = Vec3.length(velocity); + + if (motion.curTransition !== nullTransition) { + + // finish any live transition before changing state + animateAvatar(deltaTime, speed); + return; + } + var localVelocity = {x: 0, y: 0, z: 0}; + if (speed > 0) + localVelocity = Vec3.multiplyQbyV(Quat.inverse(MyAvatar.orientation), velocity); + + if (!state.editing) { + + // determine the candidate animation state + var actionToTake = undefined; + if (speed < 0.05) actionToTake = state.STANDING; // as per MIN_AVATAR_SPEED, MyAvatar.cpp + else if (speed < TAKE_FLIGHT_SPEED) actionToTake = state.WALKING; + else if (speed >= TAKE_FLIGHT_SPEED) actionToTake = state.FLYING; // determine the principle direction - if(Math.abs(deltaX)>Math.abs(deltaY) - &&Math.abs(deltaX)>Math.abs(deltaZ)) { - if(deltaX<0) { - principleDirection = DIRECTION_RIGHT; - } else { - principleDirection = DIRECTION_LEFT; - } - } - else if(Math.abs(deltaY)>Math.abs(deltaX) - &&Math.abs(deltaY)>Math.abs(deltaZ)) { - if(deltaY>0) { - principleDirection = DIRECTION_UP; - } - else { - principleDirection = DIRECTION_DOWN; - } - } - else if(Math.abs(deltaZ)>Math.abs(deltaX) - &&Math.abs(deltaZ)>Math.abs(deltaY)) { - if(deltaZ>0) { - principleDirection = DIRECTION_FORWARDS; - } else { - principleDirection = DIRECTION_BACKWARDS; - } - } + if (Math.abs(localVelocity.x) > Math.abs(localVelocity.y) && + Math.abs(localVelocity.x) > Math.abs(localVelocity.z)) { - // NB: this section will change significantly once we are ground plane aware - // it will change even more once we have uneven surfaces to deal with + if (localVelocity.x < 0) motion.direction = LEFT; + else motion.direction = RIGHT; + + } else if (Math.abs(localVelocity.y) > Math.abs(localVelocity.x) && + Math.abs(localVelocity.y) > Math.abs(localVelocity.z)) { + + if (localVelocity.y > 0) motion.direction = UP; + else motion.direction = DOWN; + + } else if (Math.abs(localVelocity.z) > Math.abs(localVelocity.x) && + Math.abs(localVelocity.z) > Math.abs(localVelocity.y)) { + + if (localVelocity.z < 0) motion.direction = FORWARDS; + else motion.direction = BACKWARDS; + } // maybe at walking speed, but sideways? - if( actionToTake === WALKING && - ( principleDirection === DIRECTION_LEFT || - principleDirection === DIRECTION_RIGHT )) { - - actionToTake = SIDE_STEPPING; - } - - // maybe at walking speed, but flying up? - if( actionToTake === WALKING && - ( principleDirection === DIRECTION_UP )) { - - actionToTake = FLYING; - standHints--; - flyHints++; - } - - // maybe at walking speed, but flying down? - if( actionToTake === WALKING && - ( principleDirection === DIRECTION_DOWN )) { - - actionToTake = FLYING; - standHints--; - flyHints++; - } - - // log this frame's motion for later reference - var accelerationX = ( framesHistory.recentMotions[0].velocity.x - localVelocity.x ) / deltaTime; - var accelerationY = ( localVelocity.y - framesHistory.recentMotions[0].velocity.y ) / deltaTime; - var accelerationZ = ( framesHistory.recentMotions[0].velocity.z - localVelocity.z ) / deltaTime; - acceleration = {x:accelerationX, y:accelerationY, z:accelerationZ}; + if (actionToTake === state.WALKING && + (motion.direction === LEFT || + motion.direction === RIGHT)) + actionToTake = state.SIDE_STEP; + // maybe at walking speed, but flying up or down? + if (actionToTake === state.WALKING && + (motion.direction === UP))// || + //motion.direction === DOWN)) + actionToTake = state.FLYING; // select appropriate animation and initiate Transition if required - switch(actionToTake) { + switch (actionToTake) { - case STANDING: + case state.STANDING: - if( standHints > requiredHints || INTERNAL_STATE===STANDING) { // wait for a few consecutive hints (17mS each) + // do we need to change state? + if (state.currentState !== state.STANDING) { - standHints = 0; - walkHints = 0; - flyHints = 0; + switch (motion.curAnim) { - // do we need to change state? - if( INTERNAL_STATE!==STANDING ) { + case motion.selWalk: - // initiate the transition - if(currentTransition) { - delete currentTransition; - currentTransition = null; - } + // Walking to standing + motion.curTransition = new Transition( + motion.curAnim, + motion.selWalk, + [], 0.25, + {x: 0.1, y: 0.5}, + {x: -0.25, y: 1.22}); + break; - switch(currentAnimation) { + case motion.selSideStepLeft: + case motion.selSideStepRight: - case selectedWalk: + break; - // Walking to Standing - var timeWalking = new Date().getTime() - framesHistory.lastWalkStartTime; + default: - var bezierCoeffsOne = {x:0.0, y:1.0}; - var bezierCoeffsTwo = {x:0.0, y:1.0}; - var transitionTime = 0.4; + // flying to standing + motion.curTransition = new Transition( + motion.curAnim, + motion.selStand, + [], 0.25, + {x: 0.5, y: 0.08}, + {x: 0.28, y: 1}); + break; + } + state.setInternalState(state.STANDING); + motion.curAnim = motion.selStand; + } + animateAvatar(deltaTime, speed); + break; - // very different curves for incremental steps - if( timeWalking < 550 ) { - bezierCoeffsOne = {x:0.63, y:0.17}; - bezierCoeffsTwo = {x:0.77, y:0.3}; - transitionTime = 0.75; - } - currentTransition = new Transition( currentAnimation, selectedStand, [], transitionTime, bezierCoeffsOne, bezierCoeffsTwo ); - break; + case state.WALKING: + if (state.currentState !== state.WALKING) { - case selectedSideStepLeft: - case selectedSideStepRight: + if (motion.direction === BACKWARDS) + motion.walkWheelPos = motion.selWalk.calibration.startAngleBackwards; + + else motion.walkWheelPos = motion.selWalk.calibration.startAngleForwards; + + switch (motion.curAnim) { + + case motion.selStand: + + // Standing to Walking + motion.curTransition = new Transition( + motion.curAnim, + motion.selWalk, + [], 0.1, + {x: 0.5, y: 0.1}, + {x: 0.5, y: 0.9}); + break; + + case motion.selSideStepLeft: + case motion.selSideStepRight: + + break; + + default: + + // Flying to Walking + motion.curTransition = new Transition( + motion.curAnim, + motion.selWalk, + [], 0.1, + {x: 0.24, y: 0.03}, + {x: 0.42, y: 1.0}); + break; + } + state.setInternalState(state.WALKING); + } + motion.curAnim = motion.selWalk; + animateAvatar(deltaTime, speed); + break; + + case state.SIDE_STEP: + + var selSideStep = 0; + if (motion.direction === LEFT) { + + if (motion.lastDirection !== LEFT) + motion.walkWheelPos = motion.selSideStepLeft.calibration.cycleStart; + selSideStep = motion.selSideStepLeft; + + } else { + + if (motion.lastDirection !== RIGHT) + motion.walkWheelPos = motion.selSideStepRight.calibration.cycleStart; + selSideStep = motion.selSideStepRight; + } + + if (state.currentState !== state.SIDE_STEP) { + + if (motion.direction === LEFT) { + + motion.walkWheelPos = motion.selSideStepLeft.calibration.cycleStart; + switch (motion.curAnim) { + + case motion.selStand: break; default: - currentTransition = new Transition(currentAnimation, selectedStand, [], 0.3, {x:0.5,y:0.08}, {x:0.28,y:1}); break; } - setInternalState(STANDING); - currentAnimation = selectedStand; - - } - animateAvatar(1,0,principleDirection); - } - break; - - case WALKING: - case SIDE_STEPPING: - if( walkHints > requiredHints || - INTERNAL_STATE===WALKING || - INTERNAL_STATE===SIDE_STEPPING ) { // wait for few consecutive hints (17mS each) - - standHints = 0; - walkHints = 0; - flyHints = 0; - - if( actionToTake === WALKING && INTERNAL_STATE !== WALKING) { - - // initiate the transition - if(currentTransition) { - delete currentTransition; - currentTransition = null; - } - - // set the appropriate start position for the walk wheel - if( principleDirection === DIRECTION_BACKWARDS ) { - - walkWheelPosition = selectedWalk.settings.startAngleBackwards; - - } else { - - walkWheelPosition = selectedWalk.settings.startAngleForwards; - } - - switch(currentAnimation) { - - case selectedStand: - - // Standing to Walking - currentTransition = new Transition(currentAnimation, selectedWalk, [], 0.25, {x:0.5,y:0.08}, {x:0.05,y:0.75}); - break; - - case selectedSideStepLeft: - case selectedSideStepRight: - - break; - - default: - - currentTransition = new Transition(currentAnimation, selectedWalk, [], 0.3, {x:0.5,y:0.08}, {x:0.05,y:0.75}); - break; - } - framesHistory.lastWalkStartTime = new Date().getTime(); - setInternalState(WALKING); - currentAnimation = selectedWalk; - } - else if(actionToTake===SIDE_STEPPING) { - - var selectedSideStep = selectedSideStepRight; - if( principleDirection === DIRECTION_LEFT ) { - - selectedSideStep = selectedSideStepLeft; - - } else { - - selectedSideStep = selectedSideStepRight; - } - - if( INTERNAL_STATE !== SIDE_STEPPING ) { - - if( principleDirection === DIRECTION_LEFT ) { - - walkWheelPosition = sideStepCycleStartLeft; - - } else { - - walkWheelPosition = sideStepCycleStartRight; - } - switch(currentAnimation) { - - case selectedStand: - - break; - - default: - - break; - } - setInternalState(SIDE_STEPPING); - } - - currentAnimation = selectedSideStep; - } - animateAvatar( deltaTime, speed, principleDirection ); - } - break; - - case FLYING: - - if( flyHints > requiredHints - 1 || INTERNAL_STATE===FLYING ) { // wait for a few consecutive hints (17mS each) - - standHints = 0; - walkHints = 0; - flyHints = 0; - - if(INTERNAL_STATE!==FLYING) setInternalState(FLYING); - - // change animation for flying directly up or down. TODO - check RecentMotions, if is a change then put a transition on it - if(principleDirection===DIRECTION_UP) { - - if(currentAnimation !== selectedFlyUp) { - - // initiate a Transition - if(currentTransition && currentTransition.nextAnimation!==selectedFlyUp) { - delete currentTransition; - currentTransition = null; - } - switch(currentAnimation) { - - case selectedStand: - - currentTransition = new Transition(currentAnimation, selectedFlyUp, [], 0.35, {x:0.5,y:0.08}, {x:0.28,y:1}); - break; - - case selectedSideStepLeft: - case selectedSideStepRight: - - break; - - default: - - currentTransition = new Transition(currentAnimation, selectedFlyUp, [], 0.35, {x:0.5,y:0.08}, {x:0.28,y:1}); - break; - } - currentAnimation = selectedFlyUp; - } - - } else if(principleDirection==DIRECTION_DOWN) { - - if(currentAnimation !== selectedFlyDown) { // TODO: as the locomotion gets cleaner (i.e. less false reports from Interface) this value can be reduced - - // initiate a Transition - if(currentTransition && currentTransition.nextAnimation!==selectedFlyDown) { - delete currentTransition; - currentTransition = null; - } - switch(currentAnimation) { - - case selectedStand: - - currentTransition = new Transition(currentAnimation, selectedFlyDown, [], 0.35, {x:0.5,y:0.08}, {x:0.28,y:1}); - break; - - case selectedSideStepLeft: - case selectedSideStepRight: - - break; - - default: - - currentTransition = new Transition(currentAnimation, selectedFlyDown, [], 0.35, {x:0.5,y:0.08}, {x:0.28,y:1}); - break; - } - currentAnimation = selectedFlyDown; - } - } else { - if(currentAnimation !== selectedFly) { // TODO: as the locomotion gets cleaner (i.e. less false reports from Interface) this value can be reduced + motion.walkWheelPos = motion.selSideStepRight.calibration.cycleStart; + switch (motion.curAnim) { - // initiate a Transition - if(currentTransition && currentTransition.nextAnimation!==selectedFly) { - delete currentTransition; - currentTransition = null; - } - switch(currentAnimation) { + case motion.selStand: - case selectedStand: + break; - currentTransition = new Transition(currentAnimation, selectedFly, [], 0.35, {x:0.5,y:0.08}, {x:0.28,y:1}); - break; + default: - case selectedSideStepLeft: - case selectedSideStepRight: - - break; - - default: - - currentTransition = new Transition(currentAnimation, selectedFly, [], 0.35, {x:0.5,y:0.08}, {x:0.28,y:1}); - break; - } - currentAnimation = selectedFly; + break; } } - animateAvatar(deltaTime, speed, principleDirection); + state.setInternalState(state.SIDE_STEP); } + motion.curAnim = selSideStep; + animateAvatar(deltaTime, speed); + break; + + case state.FLYING: + + if (state.currentState !== state.FLYING) + state.setInternalState(state.FLYING); + + // change animation for flying directly up or down + if (motion.direction === UP) { + + if (motion.curAnim !== motion.selFlyUp) { + + switch (motion.curAnim) { + + case motion.selStand: + case motion.selWalk: + + // standing | walking to flying up + motion.curTransition = new Transition( + motion.curAnim, + motion.selFlyUp, + [], 0.25, + {x: 0.5, y: 0.08}, + {x: 0.28, y: 1}); + break; + + case motion.selSideStepLeft: + case motion.selSideStepRight: + + break; + + default: + + motion.curTransition = new Transition( + motion.curAnim, + motion.selFlyUp, + [], 0.35, + {x: 0.5, y: 0.08}, + {x: 0.28, y: 1}); + break; + } + motion.curAnim = motion.selFlyUp; + } + + } else if (motion.direction == DOWN) { + + if (motion.curAnim !== motion.selFlyDown) { + + switch (motion.curAnim) { + + case motion.selStand: + case motion.selWalk: + + motion.curTransition = new Transition( + motion.curAnim, + motion.selFlyDown, + [], 0.35, + {x: 0.5, y: 0.08}, + {x: 0.28, y: 1}); + break; + + case motion.selSideStepLeft: + case motion.selSideStepRight: + + break; + + default: + + motion.curTransition = new Transition( + motion.curAnim, + motion.selFlyDown, + [], 0.5, + {x: 0.5, y: 0.08}, + {x: 0.28, y: 1}); + break; + } + motion.curAnim = motion.selFlyDown; + } + + } else { + + if (motion.curAnim !== motion.selFly) { + + switch (motion.curAnim) { + + case motion.selStand: + case motion.selWalk: + + motion.curTransition = new Transition( + motion.curAnim, + motion.selFly, + [], 0.35, + {x: 1.44, y:0.24}, + {x: 0.61, y:0.92}); + break; + + case motion.selSideStepLeft: + case motion.selSideStepRight: + + break; + + default: + + motion.curTransition = new Transition( + motion.curAnim, + motion.selFly, + [], 0.75, + {x: 0.5, y: 0.08}, + {x: 0.28, y: 1}); + break; + } + motion.curAnim = motion.selFly; + } + } + animateAvatar(deltaTime, speed); break; } // end switch(actionToTake) - } // end if(!editing) + } // end if (!state.editing) + + // record the frame's direction and local avatar's local velocity for future reference + motion.lastDirection = motion.direction; + motion.lastVelocity = localVelocity; + } +}); + +// the faster we go, the further we lean forward. the angle is calcualted here +function getLeanPitch(speed) { + + if (speed > TOP_SPEED) speed = TOP_SPEED; + var leanProgress = speed / TOP_SPEED; + + if (motion.direction === LEFT || + motion.direction === RIGHT) + leanProgress = 0; + + else { + + var responseSharpness = 1.5; + if (motion.direction == BACKWARDS) responseSharpness = 3.0; + + leanProgress = filter.bezier((1 - leanProgress), + {x: 0, y: 0.0}, + {x: 0, y: responseSharpness}, + {x: 0, y: 1.5}, + {x: 1, y: 1}).y; + + // determine final pitch and adjust for direction of momentum + if (motion.direction === BACKWARDS) + leanProgress = -motion.motionPitchMax * leanProgress; + else + leanProgress = motion.motionPitchMax * leanProgress; + } + + // return the smoothed response + return leanPitchFilter.process(leanProgress); +} + +// calculate the angle at which to bank into corners when turning +function getLeanRoll(deltaTime, speed) { + + var leanRollProgress = 0; + if (speed > TOP_SPEED) speed = TOP_SPEED; + + // what's our our anglular velocity? + var angularVelocityMax = 70; // from observation + var angularVelocity = filter.radToDeg(MyAvatar.getAngularVelocity().y); + if (angularVelocity > angularVelocityMax) angularVelocity = angularVelocityMax; + if (angularVelocity < -angularVelocityMax) angularVelocity = -angularVelocityMax; + + leanRollProgress = speed / TOP_SPEED; + + if (motion.direction !== LEFT && + motion.direction !== RIGHT) + leanRollProgress *= (Math.abs(angularVelocity) / angularVelocityMax); + + // apply our response curve + leanRollProgress = filter.bezier((1 - leanRollProgress), + {x: 0, y: 0}, + {x: 0, y: 1}, + {x: 0, y: 1}, + {x: 1, y: 1}).y; + // which way to lean? + var turnSign = -1; + if (angularVelocity < 0.001) turnSign = 1; + if (motion.direction === BACKWARDS || + motion.direction === LEFT) + turnSign *= -1; + + if (motion.direction === LEFT || + motion.direction === RIGHT) + leanRollProgress *= 2; + + // add damping with simple averaging filter + leanRollProgress = leanRollFilter.process(turnSign * leanRollProgress); + return motion.motionRollMax * leanRollProgress; +} + +function playFootstep(side) { + + var options = new AudioInjectionOptions(); + options.position = Camera.getPosition(); + options.volume = 0.2; + var soundNumber = 2; // 0 to 2 + if (side === RIGHT && motion.makesFootStepSounds) + Audio.playSound(walkAssets.footsteps[soundNumber + 1], options); + else if (side === LEFT && motion.makesFootStepSounds) + Audio.playSound(walkAssets.footsteps[soundNumber], options); +} + +// animate the avatar using sine wave generators. inspired by Victorian clockwork dolls +function animateAvatar(deltaTime, speed) { + + var cycle = motion.cumulativeTime; + var transProgress = 1; + var adjFreq = motion.curAnim.calibration.frequency; + + // legs phase and cycle reversal for walking backwards + var reverseModifier = 0; + var reverseSignModifier = 1; + if (motion.direction === BACKWARDS) { + reverseModifier = -180; + reverseSignModifier = -1; + } + + // don't lean into the direction of travel if going up + var leanMod = 1; + if (motion.direction === UP) + leanMod = 0; + + // adjust leaning direction for flying + var flyingModifier = 1; + if (state.currentState.FLYING) + flyingModifier = -1; + + if (motion.curTransition !== nullTransition) { + + // new transiton? + if (motion.curTransition.progress === 0 && + motion.curTransition.walkingAtStart) { + + if (state.currentState !== state.SIDE_STEP) { + + // work out where we want the walk cycle to stop + var leftStop = motion.selWalk.calibration.stopAngleForwards + 180; + var rightStop = motion.selWalk.calibration.stopAngleForwards; + + if (motion.direction === BACKWARDS) { + leftStop = motion.selWalk.calibration.stopAngleBackwards + 180; + rightStop = motion.selWalk.calibration.stopAngleBackwards; + } + + // find the closest stop point from the walk wheel's angle + var angleToLeftStop = 180 - Math.abs(Math.abs(motion.walkWheelPos - leftStop) - 180); + var angleToRightStop = 180 - Math.abs(Math.abs(motion.walkWheelPos - rightStop) - 180); + if (motion.walkWheelPos > angleToLeftStop) angleToLeftStop = 360 - angleToLeftStop; + if (motion.walkWheelPos > angleToRightStop) angleToRightStop = 360 - angleToRightStop; - // record the frame's stats for later reference - var thisMotion = new RecentMotion(localVelocity, acceleration, principleDirection, INTERNAL_STATE); - framesHistory.recentMotions.push(thisMotion); - framesHistory.recentMotions.shift(); + motion.curTransition.walkWheelIncrement = 3; + // keep the walkwheel turning by setting the walkWheelIncrement + // until our feet are tucked nicely underneath us. + if (angleToLeftStop < angleToRightStop) - // before we go, populate the stats overlay - if( statsOn ) { + motion.curTransition.walkStopAngle = leftStop; - var cumulativeTimeMS = Math.floor(cumulativeTime*1000); - var deltaTimeMS = deltaTime * 1000; - var frameExecutionTime = new Date().getTime() - frameStartTime; - if(frameExecutionTime>frameExecutionTimeMax) frameExecutionTimeMax = frameExecutionTime; + else + motion.curTransition.walkStopAngle = rightStop; - var angluarVelocity = Vec3.length(MyAvatar.getAngularVelocity()); + } else { - var debugInfo = '\n \n \n \n Stats\n--------------------------------------\n \n \n' - + '\nFrame number: '+nFrames - + '\nFrame time: '+deltaTimeMS.toFixed(2) - + ' mS\nRender time: '+frameExecutionTime.toFixed(0) - + ' mS\nLocalised speed: '+speed.toFixed(3) - + ' m/s\nCumulative Time '+cumulativeTimeMS.toFixed(0) - + ' mS\nState: '+internalStateAsString(INTERNAL_STATE) - + ' \nDirection: '+directionAsString(principleDirection) - + ' \nAngular Velocity: ' + angluarVelocity.toFixed(3) - + ' rad/s'; - Overlays.editOverlay(debugStats, {text: debugInfo}); - - // update these every 250 mS (assuming 60 fps) - if( nFrames % 15 === 0 ) { - var debugInfo = ' Periodic Stats\n--------------------------------------\n \n \n' - + ' \n \nRender time peak hold: '+frameExecutionTimeMax.toFixed(0) - + ' mS\n \n \n(L) MyAvatar.getVelocity()' - + ' \n \nlocalVelocityX: '+deltaX.toFixed(1) - + ' m/s\nlocalVelocityY: '+deltaY.toFixed(1) - + ' m/s\nlocalVelocityZ: '+deltaZ.toFixed(1) - + ' m/s\n \n(G) MyAvatar.getAcceleration()' - + ' \n\nAcceleration X: '+accelerationJS.x.toFixed(1) - + ' m/s/s\nAcceleration Y: '+accelerationJS.y.toFixed(1) - + ' m/s/s\nAcceleration Z: '+accelerationJS.z.toFixed(1) - + ' m/s/s\n \n(L) Acceleration using\nMyAvatar.getVelocity()' - + ' \n \nAcceleration X: '+acceleration.x.toFixed(1) - + ' m/s/s\nAcceleration Y: '+acceleration.y.toFixed(1) - + ' m/s/s\nAcceleration Z: '+acceleration.z.toFixed(1) - + ' m/s/s'; - Overlays.editOverlay(debugStatsPeriodic, {text: debugInfo}); - frameExecutionTimeMax = 0; + // freeze wheel for sidestepping transitions (for now) + motion.curTransition.walkWheelIncrement = 0; } + } // end if (new transition and curTransition.walkingAtStart) + + // update the Transition progress + var elapasedTime = (new Date().getTime() - motion.curTransition.startTime) / 1000; + motion.curTransition.progress = elapasedTime / motion.curTransition.transitionDuration; + transProgress = filter.bezier((1 - motion.curTransition.progress), {x: 0, y: 0}, + motion.curTransition.easingLower, + motion.curTransition.easingUpper, {x: 1, y: 1}).y; + + if (motion.curTransition.progress >= 1) { + + // time to kill off the transition + delete motion.curTransition; + motion.curTransition = nullTransition; + + } else { + + if (motion.curTransition.walkingAtStart) { + + if (state.currentState !== state.SIDE_STEP) { + + // if at a stop angle, hold the walk wheel position for remainder of transition + var tolerance = 7; // must be greater than the walkWheel increment + if ((motion.walkWheelPos > (motion.curTransition.walkStopAngle - tolerance)) && + (motion.walkWheelPos < (motion.curTransition.walkStopAngle + tolerance))) { + + motion.curTransition.walkWheelIncrement = 0; + } + // keep turning walk wheel until both feet are below the avi + + motion.advanceWalkWheel(motion.curTransition.walkWheelIncrement); + //motion.curTransition.walkWheelAdvance += motion.curTransition.walkWheelIncrement; + } + else motion.curTransition.walkWheelIncrement = 0; // sidestep + } + } } // end motion.curTransition !== nullTransition + + + // walking? then get the stride length + if (motion.curAnim === motion.selWalk) { + + // if the timing's right, take a snapshot of the stride max and recalibrate + var strideMaxAt = motion.curAnim.calibration.forwardStrideMaxAt; + if (motion.direction === BACKWARDS) + strideMaxAt = motion.curAnim.calibration.backwardsStrideMaxAt; + + var tolerance = 1.0; + if (motion.walkWheelPos < (strideMaxAt + tolerance) && + motion.walkWheelPos > (strideMaxAt - tolerance)) { + + // measure and save stride length + var footRPos = MyAvatar.getJointPosition("RightFoot"); + var footLPos = MyAvatar.getJointPosition("LeftFoot"); + motion.strideLength = Vec3.distance(footRPos, footLPos); + + if (motion.direction === FORWARDS) + motion.curAnim.calibration.strideLengthForwards = motion.strideLength; + else if (motion.direction === BACKWARDS) + motion.curAnim.calibration.strideLengthBackwards = motion.strideLength; + + } else { + + // use the saved value for stride length + if (motion.direction === FORWARDS) + motion.strideLength = motion.curAnim.calibration.strideLengthForwards; + else if (motion.direction === BACKWARDS) + motion.strideLength = motion.curAnim.calibration.strideLengthBackwards; } - } -}); + } // end get walk stride length + // sidestepping? get the stride length + if (motion.curAnim === motion.selSideStepLeft || + motion.curAnim === motion.selSideStepRight) { -// overlays start + // if the timing's right, take a snapshot of the stride max and recalibrate the stride length + var tolerance = 1.0; + if (motion.direction === LEFT) { -// controller dimensions -var backgroundWidth = 350; -var backgroundHeight = 700; -var backgroundX = Window.innerWidth-backgroundWidth-58; -var backgroundY = Window.innerHeight/2 - backgroundHeight/2; -var minSliderX = backgroundX + 30; -var maxSliderX = backgroundX + 295; -var sliderRangeX = 295 - 30; -var jointsControlWidth = 200; -var jointsControlHeight = 300; -var jointsControlX = backgroundX + backgroundWidth/2 - jointsControlWidth/2; -var jointsControlY = backgroundY + 242 - jointsControlHeight/2; -var buttonsY = 20; // distance from top of panel to buttons + if (motion.walkWheelPos < motion.curAnim.calibration.strideMaxAt + tolerance && + motion.walkWheelPos > motion.curAnim.calibration.strideMaxAt - tolerance) { -// arrays of overlay names -var sliderThumbOverlays = []; // thumb sliders -var backgroundOverlays = []; -var buttonOverlays = []; -var jointsControlOverlays = []; -var bigButtonOverlays = []; + var footRPos = MyAvatar.getJointPosition("RightFoot"); + var footLPos = MyAvatar.getJointPosition("LeftFoot"); + motion.strideLength = Vec3.distance(footRPos, footLPos); + motion.curAnim.calibration.strideLength = motion.strideLength; + } else motion.strideLength = motion.selSideStepLeft.calibration.strideLength; -// load UI backgrounds -var controlsBackground = Overlays.addOverlay("image", { - bounds: { x: backgroundX, y: backgroundY, width: backgroundWidth, height: backgroundHeight }, - imageURL: pathToOverlays+"ddao-background.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -backgroundOverlays.push(controlsBackground); + } else if (motion.direction === RIGHT) { -var controlsBackgroundWalkEditStyles = Overlays.addOverlay("image", { - bounds: { x: backgroundX, y: backgroundY, width: backgroundWidth, height: backgroundHeight }, - imageURL: pathToOverlays+"ddao-background-edit-styles.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -backgroundOverlays.push(controlsBackgroundWalkEditStyles); + if (motion.walkWheelPos < motion.curAnim.calibration.strideMaxAt + tolerance && + motion.walkWheelPos > motion.curAnim.calibration.strideMaxAt - tolerance) { -var controlsBackgroundWalkEditTweaks = Overlays.addOverlay("image", { - bounds: { x: backgroundX, y: backgroundY, width: backgroundWidth, height: backgroundHeight }, - imageURL: pathToOverlays+"ddao-background-edit-tweaks.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -backgroundOverlays.push(controlsBackgroundWalkEditTweaks); + var footRPos = MyAvatar.getJointPosition("RightFoot"); + var footLPos = MyAvatar.getJointPosition("LeftFoot"); + motion.strideLength = Vec3.distance(footRPos, footLPos); + motion.curAnim.calibration.strideLength = motion.strideLength; -var controlsBackgroundWalkEditJoints = Overlays.addOverlay("image", { - bounds: { x: backgroundX, y: backgroundY, width: backgroundWidth, height: backgroundHeight }, - imageURL: pathToOverlays+"ddao-background-edit-joints.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -backgroundOverlays.push(controlsBackgroundWalkEditJoints); + } else motion.strideLength = motion.selSideStepRight.calibration.strideLength; + } + } // end get sidestep stride length -var controlsBackgroundFlyingEdit = Overlays.addOverlay("image", { - bounds: { x: backgroundX, y: backgroundY, width: backgroundWidth, height: backgroundHeight }, - imageURL: pathToOverlays+"ddao-background-flying-edit.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -backgroundOverlays.push(controlsBackgroundFlyingEdit); + // turn the walk wheel + if (motion.curAnim === motion.selWalk || + motion.curAnim === motion.selSideStepLeft || + motion.curAnim === motion.selSideStepRight || + motion.curTransition.walkingAtStart) { -// minimised tab - not put in array, as is a one off -var controlsMinimisedTab = Overlays.addOverlay("image", { - x: Window.innerWidth-58, y: Window.innerHeight -145, width: 50, height: 50, - //subImage: { x: 0, y: 50, width: 50, height: 50 }, - imageURL: pathToOverlays + 'ddao-minimise-tab.png', - visible: minimised, - alpha: 0.9 - }); + // wrap the stride length around a 'surveyor's wheel' twice and calculate + // the angular speed at the given (linear) speed: + // omega = v / r , where r = circumference / 2 PI , where circumference = 2 * stride length + var strideLength = motion.strideLength; + var wheelRadius = strideLength / Math.PI; + var angularVelocity = speed / wheelRadius; -// load character joint selection control images -var hipsJointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, - imageURL: pathToOverlays+"ddao-background-edit-hips.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -jointsControlOverlays.push(hipsJointControl); + // calculate the degrees turned (at this angular speed) since last frame + var radiansTurnedSinceLastFrame = deltaTime * angularVelocity; + var degreesTurnedSinceLastFrame = filter.radToDeg(radiansTurnedSinceLastFrame); -var upperLegsJointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, - imageURL: pathToOverlays+"ddao-background-edit-upper-legs.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -jointsControlOverlays.push(upperLegsJointControl); + // if we are in an edit mode, we will need fake time to turn the wheel + if (state.currentState !== state.WALKING && + state.currentState !== state.SIDE_STEP) + degreesTurnedSinceLastFrame = motion.curAnim.calibration.frequency / 70; -var lowerLegsJointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, - imageURL: pathToOverlays+"ddao-background-edit-lower-legs.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -jointsControlOverlays.push(lowerLegsJointControl); + // advance the walk wheel the appropriate amount + motion.advanceWalkWheel(degreesTurnedSinceLastFrame); -var feetJointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, - imageURL: pathToOverlays+"ddao-background-edit-feet.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -jointsControlOverlays.push(feetJointControl); + // set the new values for the exact correct walk cycle speed + adjFreq = 1; + cycle = motion.walkWheelPos; -var toesJointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, - imageURL: pathToOverlays+"ddao-background-edit-toes.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -jointsControlOverlays.push(toesJointControl); + } // end of walk wheel and stride length calculation -var spineJointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, - imageURL: pathToOverlays+"ddao-background-edit-spine.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -jointsControlOverlays.push(spineJointControl); + // motion vars + var pitchOsc = 0; + var pitchOscLeft = 0; + var pitchOscRight = 0; + var yawOsc = 0; + var yawOscLeft = 0; + var yawOscRight = 0; + var rollOsc = 0; + var pitchOffset = 0; + var yawOffset = 0; + var rollOffset = 0; + var swayOsc = 0; + var bobOsc = 0; + var thrustOsc = 0; + var swayOscLast = 0; + var bobOscLast = 0; + var thrustOscLast = 0; -var spine1JointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, - imageURL: pathToOverlays+"ddao-background-edit-spine1.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -jointsControlOverlays.push(spine1JointControl); + // historical (for transitions) + var pitchOscLast = 0; + var pitchOscLeftLast = 0; + var pitchOscRightLast = 0; + var yawOscLast = 0; + var rollOscLast = 0; + var pitchOffsetLast = 0; + var yawOffsetLast = 0; + var rollOffsetLast = 0; -var spine2JointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, - imageURL: pathToOverlays+"ddao-background-edit-spine2.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -jointsControlOverlays.push(spine2JointControl); + // feet + var sideStepFootPitchModifier = 1; + var sideStepHandPitchSign = 1; -var shouldersJointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, - imageURL: pathToOverlays+"ddao-background-edit-shoulders.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -jointsControlOverlays.push(shouldersJointControl); + // The below code should probably be optimised into some sort of loop, where + // the joints are iterated through. However, this has not been done yet, as there + // are still some quite fundamental changes to be made (e.g. turning on the spot + // animation and sidestepping transitions) so it's been left as is for ease of + // understanding and editing. -var upperArmsJointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, - imageURL: pathToOverlays+"ddao-background-edit-upper-arms.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -jointsControlOverlays.push(upperArmsJointControl); + // calculate hips translation + if (motion.curTransition !== nullTransition) { -var forearmsJointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, - imageURL: pathToOverlays+"ddao-background-edit-forearms.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -jointsControlOverlays.push(forearmsJointControl); + if (motion.curTransition.walkingAtStart) { -var handsJointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, - imageURL: pathToOverlays+"ddao-background-edit-hands.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -jointsControlOverlays.push(handsJointControl); + swayOsc = motion.curAnim.joints[0].sway * + Math.sin(filter.degToRad(motion.cumulativeTime * motion.curAnim.calibration.frequency + + motion.curAnim.joints[0].swayPhase)) + motion.curAnim.joints[0].swayOffset; -var headJointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, - imageURL: pathToOverlays+"ddao-background-edit-head.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -jointsControlOverlays.push(headJointControl); + var bobPhase = motion.curAnim.joints[0].bobPhase; + if (motion.direction === motion.BACKWARDS) bobPhase += 90; + bobOsc = motion.curAnim.joints[0].bob * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curAnim.calibration.frequency + bobPhase)) + + motion.curAnim.joints[0].bobOffset; + thrustOsc = motion.curAnim.joints[0].thrust * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curAnim.calibration.frequency * 2 + + motion.curAnim.joints[0].thrustPhase)) + + motion.curAnim.joints[0].thrustOffset; -// sider thumb overlays -var sliderOne = Overlays.addOverlay("image", { - bounds: { x: 0, y: 0, width: 25, height: 25 }, - imageURL: pathToOverlays+"ddao-slider-handle.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -sliderThumbOverlays.push(sliderOne); -var sliderTwo = Overlays.addOverlay("image", { - bounds: { x: 0, y: 0, width: 25, height: 25 }, - imageURL: pathToOverlays+"ddao-slider-handle.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -sliderThumbOverlays.push(sliderTwo); -var sliderThree = Overlays.addOverlay("image", { - bounds: { x: 0, y: 0, width: 25, height: 25 }, - imageURL: pathToOverlays+"ddao-slider-handle.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -sliderThumbOverlays.push(sliderThree); -var sliderFour = Overlays.addOverlay("image", { - bounds: { x: 0, y: 0, width: 25, height: 25 }, - imageURL: pathToOverlays+"ddao-slider-handle.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -sliderThumbOverlays.push(sliderFour); -var sliderFive = Overlays.addOverlay("image", { - bounds: { x: 0, y: 0, width: 25, height: 25 }, - imageURL: pathToOverlays+"ddao-slider-handle.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -sliderThumbOverlays.push(sliderFive); -var sliderSix = Overlays.addOverlay("image", { - bounds: { x: 0, y: 0, width: 25, height: 25 }, - imageURL: pathToOverlays+"ddao-slider-handle.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -sliderThumbOverlays.push(sliderSix); -var sliderSeven = Overlays.addOverlay("image", { - bounds: { x: 0, y: 0, width: 25, height: 25 }, - imageURL: pathToOverlays+"ddao-slider-handle.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -sliderThumbOverlays.push(sliderSeven); -var sliderEight = Overlays.addOverlay("image", { - bounds: { x: 0, y: 0, width: 25, height: 25 }, - imageURL: pathToOverlays+"ddao-slider-handle.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -sliderThumbOverlays.push(sliderEight); -var sliderNine = Overlays.addOverlay("image", { - bounds: { x: 0, y: 0, width: 25, height: 25 }, - imageURL: pathToOverlays+"ddao-slider-handle.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -sliderThumbOverlays.push(sliderNine); + swayOscLast = motion.curTransition.lastAnim.joints[0].sway * + Math.sin(filter.degToRad(motion.walkWheelPos + + motion.curTransition.lastAnim.joints[0].swayPhase)) + + motion.curTransition.lastAnim.joints[0].swayOffset; + var bobPhaseLast = motion.curTransition.lastAnim.joints[0].bobPhase; + if (motion.direction === motion.BACKWARDS) bobPhaseLast +=90; + bobOscLast = motion.curTransition.lastAnim.joints[0].bob * + Math.sin(filter.degToRad(motion.walkWheelPos + bobPhaseLast)); + bobOscLast = filter.clipTrough(bobOscLast, motion.curTransition.lastAnim.joints[0].bob , 2); + bobOscLast = hipsBobLPFilter.process(bobOscLast); + bobOscLast += motion.curTransition.lastAnim.joints[0].bobOffset; -// button overlays -var onButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+20, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-on-button.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(onButton); -var offButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+20, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-off-button.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(offButton); -var configWalkButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-edit-walk-button.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(configWalkButton); -var configWalkButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-edit-walk-button-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(configWalkButtonSelected); -var configStandButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+146, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-edit-stand-button.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(configStandButton); -var configStandButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX+146, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-edit-stand-button-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(configStandButtonSelected); + thrustOscLast = motion.curTransition.lastAnim.joints[0].thrust * + Math.sin(filter.degToRad(motion.walkWheelPos * 2 + + motion.curTransition.lastAnim.joints[0].thrustPhase)) + + motion.curTransition.lastAnim.joints[0].thrustOffset; -var configFlyingButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+209, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-edit-fly-button.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(configFlyingButton); -var configFlyingButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX+209, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-edit-fly-button-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(configFlyingButtonSelected); + } // end if walking at start of transition + else { -var configFlyingUpButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-edit-fly-up-button.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(configFlyingUpButton); -var configFlyingUpButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-edit-fly-up-button-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(configFlyingUpButtonSelected); + swayOsc = motion.curAnim.joints[0].sway * + Math.sin(filter.degToRad(cycle * adjFreq + motion.curAnim.joints[0].swayPhase)) + + motion.curAnim.joints[0].swayOffset; -var configFlyingDownButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+146, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-edit-fly-down-button.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(configFlyingDownButton); -var configFlyingDownButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX+146, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-edit-fly-down-button-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(configFlyingDownButtonSelected); + var bobPhase = motion.curAnim.joints[0].bobPhase; + if (motion.direction === motion.BACKWARDS) bobPhase += 90; + bobOsc = motion.curAnim.joints[0].bob * + Math.sin(filter.degToRad(cycle * adjFreq * 2 + bobPhase)); + if (state.currentState === state.WALKING || + state.currentState === state.EDIT_WALK_STYLES || + state.currentState === state.EDIT_WALK_TWEAKS || + state.currentState === state.EDIT_WALK_JOINTS) { -var hideButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+272, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-hide-button.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(hideButton); -var hideButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX+272, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-hide-button-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(hideButtonSelected); -var configWalkStylesButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-walk-styles-button.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(configWalkStylesButton); -var configWalkStylesButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-walk-styles-button-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(configWalkStylesButtonSelected); -var configWalkTweaksButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+146, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-walk-tweaks-button.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(configWalkTweaksButton); -var configWalkTweaksButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX+146, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-walk-tweaks-button-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(configWalkTweaksButtonSelected); + // apply clipping filter to flatten the curve's peaks (inputValue, peak, strength) + bobOsc = filter.clipTrough(bobOsc, motion.curAnim.joints[0].bob , 2); + bobOsc = hipsBobLPFilter.process(bobOsc); + } + bobOsc += motion.curAnim.joints[0].bobOffset; -var configSideStepLeftButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-edit-sidestep-left-button.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(configSideStepLeftButton); -var configSideStepLeftButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-edit-sidestep-left-button-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(configSideStepLeftButtonSelected); + thrustOsc = motion.curAnim.joints[0].thrust * + Math.sin(filter.degToRad(cycle * adjFreq * 2 + + motion.curAnim.joints[0].thrustPhase)) + + motion.curAnim.joints[0].thrustOffset; -var configSideStepRightButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+209, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-edit-sidestep-right-button.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(configSideStepRightButton); -var configSideStepRightButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX+209, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-edit-sidestep-right-button-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(configSideStepRightButtonSelected); + swayOscLast = motion.curTransition.lastAnim.joints[0].sway * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency + + motion.curTransition.lastAnim.joints[0].swayPhase)) + + motion.curTransition.lastAnim.joints[0].swayOffset; -var configWalkJointsButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+209, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-bones-button.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(configWalkJointsButton); -var configWalkJointsButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX+209, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-bones-button-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(configWalkJointsButtonSelected); + bobOscLast = motion.curTransition.lastAnim.joints[0].bob * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency * 2 + + motion.curTransition.lastAnim.joints[0].bobPhase)) + + motion.curTransition.lastAnim.joints[0].bobOffset; -var backButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+272, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-back-button.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(backButton); -var backButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX+272, y: backgroundY+buttonsY, width: 60, height: 47 }, - imageURL: pathToOverlays+"ddao-back-button-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -buttonOverlays.push(backButtonSelected); + thrustOscLast = motion.curTransition.lastAnim.joints[0].thrust * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency * 2 + + motion.curTransition.lastAnim.joints[0].thrustPhase)) + + motion.curTransition.lastAnim.joints[0].thrustOffset; + } -// big button overlays - front panel -var bigButtonYOffset = 408; // distance from top of panel to top of first button + swayOsc = (transProgress * swayOsc) + ((1 - transProgress) * swayOscLast); + bobOsc = (transProgress * bobOsc) + ((1 - transProgress) * bobOscLast); + thrustOsc = (transProgress * thrustOsc) + ((1 - transProgress) * thrustOscLast); -var femaleBigButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36}, - imageURL: pathToOverlays+"ddao-female-big-button.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(femaleBigButton); + }// if current transition active + else { -var femaleBigButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36}, - imageURL: pathToOverlays+"ddao-female-big-button-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(femaleBigButtonSelected); + swayOsc = motion.curAnim.joints[0].sway * + Math.sin(filter.degToRad(cycle * adjFreq + motion.curAnim.joints[0].swayPhase)) + + motion.curAnim.joints[0].swayOffset; -var maleBigButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset + 60, width: 230, height: 36}, - imageURL: pathToOverlays+"ddao-male-big-button.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(maleBigButton); + bobPhase = motion.curAnim.joints[0].bobPhase; + if (motion.direction === motion.BACKWARDS) bobPhase += 90; + bobOsc = motion.curAnim.joints[0].bob * Math.sin(filter.degToRad(cycle * adjFreq * 2 + bobPhase)); + if (state.currentState === state.WALKING || + state.currentState === state.EDIT_WALK_STYLES || + state.currentState === state.EDIT_WALK_TWEAKS || + state.currentState === state.EDIT_WALK_JOINTS) { -var maleBigButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset + 60, width: 230, height: 36}, - imageURL: pathToOverlays+"ddao-male-big-button-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(maleBigButtonSelected); + // apply clipping filter to flatten the curve's peaks (inputValue, peak, strength) + bobOsc = filter.clipTrough(bobOsc, motion.curAnim.joints[0].bob , 2); + bobOsc = hipsBobLPFilter.process(bobOsc); + } + bobOsc += motion.curAnim.joints[0].bobOffset; -var armsFreeBigButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset + 120, width: 230, height: 36}, - imageURL: pathToOverlays+"ddao-arms-free-button.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(armsFreeBigButton); + thrustOsc = motion.curAnim.joints[0].thrust * + Math.sin(filter.degToRad(cycle * adjFreq * 2 + + motion.curAnim.joints[0].thrustPhase)) + + motion.curAnim.joints[0].thrustOffset; + } -var armsFreeBigButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset + 120, width: 230, height: 36}, - imageURL: pathToOverlays+"ddao-arms-free-button-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(armsFreeBigButtonSelected); + // convert local hips translations to global and apply + var aviOrientation = MyAvatar.orientation; + var front = Quat.getFront(aviOrientation); + var right = Quat.getRight(aviOrientation); + var up = Quat.getUp(aviOrientation); + var aviFront = Vec3.multiply(front, thrustOsc); + var aviRight = Vec3.multiply(right, swayOsc); + var aviUp = Vec3.multiply(up, bobOsc); + var aviTranslationOffset = {x: 0, y: 0, z: 0}; -var footstepsBigButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset + 180, width: 230, height: 36}, - imageURL: pathToOverlays+"ddao-footsteps-big-button.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(footstepsBigButton); + aviTranslationOffset = Vec3.sum(aviTranslationOffset, aviFront); + aviTranslationOffset = Vec3.sum(aviTranslationOffset, aviRight); + aviTranslationOffset = Vec3.sum(aviTranslationOffset, aviUp); -var footstepsBigButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset + 180, width: 230, height: 36}, - imageURL: pathToOverlays+"ddao-footsteps-big-button-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(footstepsBigButtonSelected); + MyAvatar.setSkeletonOffset({ + x: aviTranslationOffset.x, + y: aviTranslationOffset.y, + z: aviTranslationOffset.z + }); + // hips rotation + if (motion.curTransition !== nullTransition) { -// walk styles -bigButtonYOffset = 121; -var strutWalkBigButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, - imageURL: pathToOverlays+"ddao-walk-select-button-strut.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(strutWalkBigButton); + if (motion.curTransition.walkingAtStart) { -var strutWalkBigButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, - imageURL: pathToOverlays+"ddao-walk-select-button-strut-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(strutWalkBigButtonSelected); + pitchOsc = motion.curAnim.joints[0].pitch * + Math.sin(filter.degToRad(motion.cumulativeTime * motion.curAnim.calibration.frequency * 2 + + motion.curAnim.joints[0].pitchPhase)) + motion.curAnim.joints[0].pitchOffset; -// overlays to show the walk wheel stats -var walkWheelZLine = Overlays.addOverlay("line3d", { - position: { x: 0, y: 0, z:hipsToFeetDistance }, - end: { x: 0, y: 0, z: -hipsToFeetDistance }, - color: { red: 0, green: 255, blue: 255}, - alpha: 1, - lineWidth: 5, - visible: statsOn, - anchor: "MyAvatar" - }); -var walkWheelYLine = Overlays.addOverlay("line3d", { - position: { x: 0, y: hipsToFeetDistance, z:0 }, - end: { x: 0, y: -hipsToFeetDistance, z:0 }, - color: { red: 255, green: 0, blue: 255}, - alpha: 1, - lineWidth: 5, - visible: statsOn, - anchor: "MyAvatar" - }); -var debugStats = Overlays.addOverlay("text", { - x: backgroundX-199, y: backgroundY, - width: 200, - height: 180, - color: { red: 204, green: 204, blue: 204}, - topMargin: 10, - leftMargin: 15, - visible: statsOn, - backgroundColor: { red: 34, green: 34, blue: 34}, - alpha: 1.0, - text: "Debug Stats\n\n\nNothing to report yet." - }); -var debugStatsPeriodic = Overlays.addOverlay("text", { - x: backgroundX-199, y: backgroundY+179, - width: 200, - height: 392, - color: { red: 204, green: 204, blue: 204}, - topMargin: 5, - leftMargin: 15, - visible: statsOn, - backgroundColor: { red: 34, green: 34, blue: 34}, - alpha: 1.0, - text: "Debug Stats\n\n\nNothing to report yet." - }); -var walkWheelStats = Overlays.addOverlay("text", { - x: backgroundX-199, y: backgroundY+510, - width: 200, - height: 190, - color: { red: 204, green: 204, blue: 204}, - topMargin: 5, - leftMargin: 15, - visible: statsOn, - backgroundColor: { red: 34, green: 34, blue: 34}, - alpha: 1.0, - text: "WalkWheel Stats\n\n\nNothing to report yet.\n\n\nPlease start walking\nto see the walkwheel." - }); + yawOsc = motion.curAnim.joints[0].yaw * + Math.sin(filter.degToRad(motion.cumulativeTime * motion.curAnim.calibration.frequency + + motion.curAnim.joints[0].yawPhase - reverseModifier)) + motion.curAnim.joints[0].yawOffset; -// various show / hide GUI element functions -function doStandardMenu() { - hidebuttonOverlays(); - hideJointControls(); - setBackground(controlsBackground); - if(powerOn) setButtonOverlayVisible(onButton); - else setButtonOverlayVisible(offButton); - setButtonOverlayVisible(configWalkButton); - setButtonOverlayVisible(configStandButton); - setButtonOverlayVisible(configFlyingButton); - setButtonOverlayVisible(hideButton); - setSliderThumbsVisible(false); - showFrontPanelButtons(true); - showWalkStyleButtons(false); -} -function showFrontPanelButtons(showButtons) { + rollOsc = motion.curAnim.joints[0].roll * + Math.sin(filter.degToRad(motion.cumulativeTime * motion.curAnim.calibration.frequency + + motion.curAnim.joints[0].rollPhase)) + motion.curAnim.joints[0].rollOffset; + + pitchOscLast = motion.curTransition.lastAnim.joints[0].pitch * + Math.sin(filter.degToRad(motion.walkWheelPos * 2 + + motion.curTransition.lastAnim.joints[0].pitchPhase)) + + motion.curTransition.lastAnim.joints[0].pitchOffset; + + yawOscLast = motion.curTransition.lastAnim.joints[0].yaw * + Math.sin(filter.degToRad(motion.walkWheelPos + + motion.curTransition.lastAnim.joints[0].yawPhase)); + + yawOscLast += motion.curTransition.lastAnim.joints[0].yaw * + hipsYawShaper.shapeWave(filter.degToRad(motion.walkWheelPos + + motion.curTransition.lastAnim.joints[0].yawPhase - reverseModifier)) + + motion.curTransition.lastAnim.joints[0].yawOffset; + + rollOscLast = (motion.curTransition.lastAnim.joints[0].roll * + Math.sin(filter.degToRad(motion.walkWheelPos + + motion.curTransition.lastAnim.joints[0].rollPhase)) + + motion.curTransition.lastAnim.joints[0].rollOffset); + + } else { + + pitchOsc = motion.curAnim.joints[0].pitch * + Math.sin(filter.degToRad(cycle * adjFreq * 2 + + motion.curAnim.joints[0].pitchPhase)) + + motion.curAnim.joints[0].pitchOffset; + + yawOsc = motion.curAnim.joints[0].yaw * + Math.sin(filter.degToRad(cycle * adjFreq + + motion.curAnim.joints[0].yawPhase - reverseModifier)) + + motion.curAnim.joints[0].yawOffset; + + rollOsc = motion.curAnim.joints[0].roll * + Math.sin(filter.degToRad(cycle * adjFreq + + motion.curAnim.joints[0].rollPhase)) + + motion.curAnim.joints[0].rollOffset; + + pitchOscLast = motion.curTransition.lastAnim.joints[0].pitch * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency * 2 + + motion.curTransition.lastAnim.joints[0].pitchPhase)) + + motion.curTransition.lastAnim.joints[0].pitchOffset; + + yawOscLast = motion.curTransition.lastAnim.joints[0].yaw * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency + + motion.curTransition.lastAnim.joints[0].yawPhase - reverseModifier)) + + motion.curTransition.lastAnim.joints[0].yawOffset; + + rollOscLast = motion.curTransition.lastAnim.joints[0].roll * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency + + motion.curTransition.lastAnim.joints[0].rollPhase)) + + motion.curTransition.lastAnim.joints[0].rollOffset; + } + + pitchOsc = (transProgress * pitchOsc) + ((1 - transProgress) * pitchOscLast); + yawOsc = (transProgress * yawOsc) + ((1 - transProgress) * yawOscLast); + rollOsc = (transProgress * rollOsc) + ((1 - transProgress) * rollOscLast); - if(avatarGender===FEMALE) { - Overlays.editOverlay(femaleBigButtonSelected, { visible: showButtons } ); - Overlays.editOverlay(femaleBigButton, { visible: false } ); - Overlays.editOverlay(maleBigButtonSelected, { visible: false } ); - Overlays.editOverlay(maleBigButton, { visible: showButtons } ); } else { - Overlays.editOverlay(femaleBigButtonSelected, { visible: false } ); - Overlays.editOverlay(femaleBigButton, { visible: showButtons } ); - Overlays.editOverlay(maleBigButtonSelected, { visible: showButtons } ); - Overlays.editOverlay(maleBigButton, { visible: false } ); + + pitchOsc = motion.curAnim.joints[0].pitch * + Math.sin(filter.degToRad((cycle * adjFreq * 2) + + motion.curAnim.joints[0].pitchPhase)) + + motion.curAnim.joints[0].pitchOffset; + + yawOsc = motion.curAnim.joints[0].yaw * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[0].yawPhase)); + + yawOsc += motion.curAnim.joints[0].yaw * + hipsYawShaper.shapeWave(filter.degToRad(cycle * adjFreq) + + motion.curAnim.joints[0].yawPhase - reverseModifier)+ + motion.curAnim.joints[0].yawOffset; + + rollOsc = (motion.curAnim.joints[0].roll * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[0].rollPhase)) + + motion.curAnim.joints[0].rollOffset); } - if(armsFree) { - Overlays.editOverlay(armsFreeBigButtonSelected, { visible: showButtons } ); - Overlays.editOverlay(armsFreeBigButton, { visible: false } ); + + // apply hips rotation + MyAvatar.setJointData("Hips", Quat.fromPitchYawRollDegrees( + pitchOsc + (leanMod * getLeanPitch(speed)), + yawOsc, + rollOsc + getLeanRoll(deltaTime, speed))); + + // upper legs + if (state.currentState !== state.SIDE_STEP && + state.currentState !== state.EDIT_SIDESTEP_LEFT && + state.currentState !== state.EDIT_SIDESTEP_RIGHT) { + + if (motion.curTransition !== nullTransition) { + + if (motion.curTransition.walkingAtStart) { + + pitchOscLeft = motion.curAnim.joints[1].pitch * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curAnim.calibration.frequency + + reverseModifier * motion.curAnim.joints[1].pitchPhase)); + + pitchOscRight = motion.curAnim.joints[1].pitch * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curAnim.calibration.frequency + + reverseModifier * motion.curAnim.joints[1].pitchPhase)); + + yawOsc = motion.curAnim.joints[1].yaw * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curAnim.calibration.frequency + + motion.curAnim.joints[1].yawPhase)); + + rollOsc = motion.curAnim.joints[1].roll * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curAnim.calibration.frequency + + motion.curAnim.joints[1].rollPhase)); + + pitchOffset = motion.curAnim.joints[1].pitchOffset; + yawOffset = motion.curAnim.joints[1].yawOffset; + rollOffset = motion.curAnim.joints[1].rollOffset; + + pitchOscLeftLast = motion.curTransition.lastAnim.joints[1].pitch * + motion.curTransition.lastAnim.harmonics.leftUpperLeg.calculate( + filter.degToRad(motion.walkWheelPos + + motion.curTransition.lastAnim.joints[1].pitchPhase + 180 + reverseModifier)); + + pitchOscRightLast = motion.curTransition.lastAnim.joints[1].pitch * + motion.curTransition.lastAnim.harmonics.rightUpperLeg.calculate( + filter.degToRad(motion.walkWheelPos + + motion.curTransition.lastAnim.joints[1].pitchPhase + reverseModifier)); + + yawOscLast = motion.curTransition.lastAnim.joints[1].yaw * + Math.sin(filter.degToRad(motion.walkWheelPos + + motion.curTransition.lastAnim.joints[1].yawPhase)); + + rollOscLast = motion.curTransition.lastAnim.joints[1].roll * + Math.sin(filter.degToRad(motion.walkWheelPos + + motion.curTransition.lastAnim.joints[1].rollPhase)); + + pitchOffsetLast = motion.curTransition.lastAnim.joints[1].pitchOffset; + yawOffsetLast = motion.curTransition.lastAnim.joints[1].yawOffset; + rollOffsetLast = motion.curTransition.lastAnim.joints[1].rollOffset; + + } else { + + if (state.currentState === state.WALKING || + state.currentState === state.EDIT_WALK_STYLES || + state.currentState === state.EDIT_WALK_TWEAKS || + state.currentState === state.EDIT_WALK_JOINTS) { + + pitchOscLeft = motion.curAnim.joints[1].pitch * + motion.curAnim.harmonics.leftUpperLeg.calculate(filter.degToRad(cycle * adjFreq + + motion.curAnim.joints[1].pitchPhase + 180 + reverseModifier)); + pitchOscRight = motion.curAnim.joints[1].pitch * + motion.curAnim.harmonics.rightUpperLeg.calculate(filter.degToRad(cycle * adjFreq + + motion.curAnim.joints[1].pitchPhase + reverseModifier)); + } else { + + pitchOscLeft = motion.curAnim.joints[1].pitch * Math.sin(filter.degToRad(cycle * adjFreq + + motion.curAnim.joints[1].pitchPhase)); + pitchOscRight = motion.curAnim.joints[1].pitch * Math.sin(filter.degToRad(cycle * adjFreq + + motion.curAnim.joints[1].pitchPhase)); + } + + yawOsc = motion.curAnim.joints[1].yaw * + Math.sin(filter.degToRad(cycle * adjFreq + + motion.curAnim.joints[1].yawPhase)); + + rollOsc = motion.curAnim.joints[1].roll * + Math.sin(filter.degToRad(cycle * adjFreq + + motion.curAnim.joints[1].rollPhase)); + + pitchOffset = motion.curAnim.joints[1].pitchOffset; + yawOffset = motion.curAnim.joints[1].yawOffset; + rollOffset = motion.curAnim.joints[1].rollOffset; + + pitchOscLeftLast = motion.curTransition.lastAnim.joints[1].pitch * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency + + reverseModifier * motion.curTransition.lastAnim.joints[1].pitchPhase)); + + pitchOscRightLast = motion.curTransition.lastAnim.joints[1].pitch * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency + + reverseModifier * motion.curTransition.lastAnim.joints[1].pitchPhase)); + + yawOscLast = motion.curTransition.lastAnim.joints[1].yaw * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency + + motion.curTransition.lastAnim.joints[1].yawPhase)); + + rollOscLast = motion.curTransition.lastAnim.joints[1].roll * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency + + motion.curTransition.lastAnim.joints[1].rollPhase)); + + pitchOffsetLast = motion.curTransition.lastAnim.joints[1].pitchOffset; + yawOffsetLast = motion.curTransition.lastAnim.joints[1].yawOffset; + rollOffsetLast = motion.curTransition.lastAnim.joints[1].rollOffset; + } + pitchOscLeft = (transProgress * pitchOscLeft) + ((1 - transProgress) * pitchOscLeftLast); + pitchOscRight = (transProgress * pitchOscRight) + ((1 - transProgress) * pitchOscRightLast); + yawOsc = (transProgress * yawOsc) + ((1 - transProgress) * yawOscLast); + rollOsc = (transProgress * rollOsc) + ((1 - transProgress) * rollOscLast); + + pitchOffset = (transProgress * pitchOffset) + ((1 - transProgress) * pitchOffsetLast); + yawOffset = (transProgress * yawOffset) + ((1 - transProgress) * yawOffsetLast); + rollOffset = (transProgress * rollOffset) + ((1 - transProgress) * rollOffsetLast); + + } else { + + if (state.currentState === state.WALKING || + state.currentState === state.EDIT_WALK_STYLES || + state.currentState === state.EDIT_WALK_TWEAKS || + state.currentState === state.EDIT_WALK_JOINTS) { + + pitchOscLeft = motion.curAnim.joints[1].pitch * + motion.curAnim.harmonics.leftUpperLeg.calculate(filter.degToRad(cycle * adjFreq + + motion.curAnim.joints[1].pitchPhase + 180 + reverseModifier)); + pitchOscRight = motion.curAnim.joints[1].pitch * + motion.curAnim.harmonics.rightUpperLeg.calculate(filter.degToRad(cycle * adjFreq + + motion.curAnim.joints[1].pitchPhase + reverseModifier)); + } else { + + pitchOscLeft = motion.curAnim.joints[1].pitch * Math.sin(filter.degToRad(cycle * adjFreq + + motion.curAnim.joints[1].pitchPhase)); + pitchOscRight = motion.curAnim.joints[1].pitch * Math.sin(filter.degToRad(cycle * adjFreq + + motion.curAnim.joints[1].pitchPhase)); + } + + yawOsc = motion.curAnim.joints[1].yaw * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[1].yawPhase)); + + rollOsc = motion.curAnim.joints[1].roll * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[1].rollPhase)); + + pitchOffset = motion.curAnim.joints[1].pitchOffset; + yawOffset = motion.curAnim.joints[1].yawOffset; + rollOffset = motion.curAnim.joints[1].rollOffset; + } + + // apply the upper leg rotations + MyAvatar.setJointData("LeftUpLeg", Quat.fromPitchYawRollDegrees( + pitchOscLeft + pitchOffset, + yawOsc - yawOffset, + -rollOsc + rollOffset)); + + MyAvatar.setJointData("RightUpLeg", Quat.fromPitchYawRollDegrees( + pitchOscRight + pitchOffset, + yawOsc + yawOffset, + -rollOsc - rollOffset)); + + // lower leg + if (motion.curTransition !== nullTransition) { + + if (motion.curTransition.walkingAtStart) { + + pitchOscLeft = motion.curAnim.joints[2].pitch * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curAnim.calibration.frequency + + motion.curAnim.joints[2].pitchPhase + 180)); + + pitchOscRight = motion.curAnim.joints[2].pitch * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curAnim.calibration.frequency + + motion.curAnim.joints[2].pitchPhase)); + + yawOsc = motion.curAnim.joints[2].yaw * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curAnim.calibration.frequency + + motion.curAnim.joints[2].yawPhase)); + + rollOsc = motion.curAnim.joints[2].roll * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curAnim.calibration.frequency + + motion.curAnim.joints[2].rollPhase)); + + pitchOffset = motion.curAnim.joints[2].pitchOffset; + yawOffset = motion.curAnim.joints[2].yawOffset; + rollOffset = motion.curAnim.joints[2].rollOffset; + + pitchOscLeftLast = motion.curTransition.lastAnim.joints[2].pitch * + motion.curTransition.lastAnim.harmonics.leftLowerLeg.calculate(filter.degToRad(motion.walkWheelPos + + motion.curTransition.lastAnim.joints[2].pitchPhase + 180)); + + pitchOscRightLast = motion.curTransition.lastAnim.joints[2].pitch * + motion.curTransition.lastAnim.harmonics.leftLowerLeg.calculate(filter.degToRad(motion.walkWheelPos + + motion.curTransition.lastAnim.joints[2].pitchPhase)); + + yawOscLast = motion.curTransition.lastAnim.joints[2].yaw * + Math.sin(filter.degToRad(motion.walkWheelPos + + motion.curTransition.lastAnim.joints[2].yawPhase)); + + rollOscLast = motion.curTransition.lastAnim.joints[2].roll * + Math.sin(filter.degToRad(motion.walkWheelPos + + motion.curTransition.lastAnim.joints[2].rollPhase)); + + pitchOffsetLast = motion.curTransition.lastAnim.joints[2].pitchOffset; + yawOffsetLast = motion.curTransition.lastAnim.joints[2].yawOffset; + rollOffsetLast = motion.curTransition.lastAnim.joints[2].rollOffset; + + } else { + + if (state.currentState === state.WALKING || + state.currentState === state.EDIT_WALK_STYLES || + state.currentState === state.EDIT_WALK_TWEAKS || + state.currentState === state.EDIT_WALK_JOINTS) { + + pitchOscLeft = motion.curAnim.harmonics.leftLowerLeg.calculate(filter.degToRad(reverseSignModifier * cycle * adjFreq + + motion.curAnim.joints[2].pitchPhase + 180)); + pitchOscRight = motion.curAnim.harmonics.rightLowerLeg.calculate(filter.degToRad(reverseSignModifier * cycle * adjFreq + + motion.curAnim.joints[2].pitchPhase)); + + } else { + + pitchOscLeft = Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[2].pitchPhase + 180)); + + pitchOscRight = Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[2].pitchPhase)); + } + pitchOscLeft *= motion.curAnim.joints[2].pitch; + pitchOscRight *= motion.curAnim.joints[2].pitch; + + yawOsc = motion.curAnim.joints[2].yaw * + Math.sin(filter.degToRad(cycle * adjFreq + + motion.curAnim.joints[2].yawPhase)); + + rollOsc = motion.curAnim.joints[2].roll * + Math.sin(filter.degToRad(cycle * adjFreq + + motion.curAnim.joints[2].rollPhase)); + + pitchOffset = motion.curAnim.joints[2].pitchOffset; + yawOffset = motion.curAnim.joints[2].yawOffset; + rollOffset = motion.curAnim.joints[2].rollOffset; + + pitchOscLeftLast = motion.curTransition.lastAnim.joints[2].pitch * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency + + motion.curTransition.lastAnim.joints[2].pitchPhase + 180)); + + pitchOscRightLast = motion.curTransition.lastAnim.joints[2].pitch * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency + + motion.curTransition.lastAnim.joints[2].pitchPhase)); + + yawOscLast = motion.curTransition.lastAnim.joints[2].yaw * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency + + motion.curTransition.lastAnim.joints[2].yawPhase)); + + rollOscLast = motion.curTransition.lastAnim.joints[2].roll * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency + + motion.curTransition.lastAnim.joints[2].rollPhase)); + + pitchOffsetLast = motion.curTransition.lastAnim.joints[2].pitchOffset; + yawOffsetLast = motion.curTransition.lastAnim.joints[2].yawOffset; + rollOffsetLast = motion.curTransition.lastAnim.joints[2].rollOffset; + } + + pitchOscLeft = (transProgress * pitchOscLeft) + ((1 - transProgress) * pitchOscLeftLast); + pitchOscRight = (transProgress * pitchOscRight) + ((1 - transProgress) * pitchOscRightLast); + yawOsc = (transProgress * yawOsc) + ((1 - transProgress) * yawOscLast); + rollOsc = (transProgress * rollOsc) + ((1 - transProgress) * rollOscLast); + + pitchOffset = (transProgress * pitchOffset) + ((1 - transProgress) * pitchOffsetLast); + yawOffset = (transProgress * yawOffset) + ((1 - transProgress) * yawOffsetLast); + rollOffset = (transProgress * rollOffset) + ((1 - transProgress) * rollOffsetLast); + + rollOscLeft = rollOsc; + rollOscRight = rollOsc; + + } else { // end if transitioning + + if (state.currentState === state.WALKING || + state.currentState === state.EDIT_WALK_STYLES || + state.currentState === state.EDIT_WALK_TWEAKS || + state.currentState === state.EDIT_WALK_JOINTS) { + + pitchOscLeft = motion.curAnim.harmonics.leftLowerLeg.calculate(filter.degToRad(reverseSignModifier * cycle * adjFreq + + motion.curAnim.joints[2].pitchPhase + 180)); + pitchOscRight = motion.curAnim.harmonics.rightLowerLeg.calculate(filter.degToRad(reverseSignModifier * cycle * adjFreq + + motion.curAnim.joints[2].pitchPhase)); + + } else { + + pitchOscLeft = Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[2].pitchPhase + 180)); + + pitchOscRight = Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[2].pitchPhase)); + } + + pitchOscLeft *= motion.curAnim.joints[2].pitch; + pitchOscRight *= motion.curAnim.joints[2].pitch; + + yawOsc = motion.curAnim.joints[2].yaw * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[2].yawPhase)); + + rollOsc = Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[2].rollPhase)); + + rollOsc = motion.curAnim.joints[2].roll; + + pitchOffset = motion.curAnim.joints[2].pitchOffset; + yawOffset = motion.curAnim.joints[2].yawOffset; + rollOffset = motion.curAnim.joints[2].rollOffset; + } + + pitchOscLeft += pitchOffset; + pitchOscRight += pitchOffset; + + // apply lower leg joint rotations + MyAvatar.setJointData("LeftLeg", Quat.fromPitchYawRollDegrees( + pitchOscLeft, + yawOsc + yawOffset, + rollOsc + rollOffset)); + MyAvatar.setJointData("RightLeg", Quat.fromPitchYawRollDegrees( + pitchOscRight, + yawOsc - yawOffset, + rollOsc - rollOffset)); + + } // end if !state.SIDE_STEP + + else if (state.currentState === state.SIDE_STEP || + state.currentState === state.EDIT_SIDESTEP_LEFT || + state.currentState === state.EDIT_SIDESTEP_RIGHT) { + + // sidestepping uses the sinewave generators slightly differently for the legs + pitchOsc = motion.curAnim.joints[1].pitch * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[1].pitchPhase)); + + yawOsc = motion.curAnim.joints[1].yaw * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[1].yawPhase)); + + rollOsc = motion.curAnim.joints[1].roll * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[1].rollPhase)); + + // apply upper leg rotations for sidestepping + MyAvatar.setJointData("RightUpLeg", Quat.fromPitchYawRollDegrees( + -pitchOsc + motion.curAnim.joints[1].pitchOffset, + yawOsc + motion.curAnim.joints[1].yawOffset, + rollOsc + motion.curAnim.joints[1].rollOffset)); + + MyAvatar.setJointData("LeftUpLeg", Quat.fromPitchYawRollDegrees( + pitchOsc + motion.curAnim.joints[1].pitchOffset, + yawOsc - motion.curAnim.joints[1].yawOffset, + -rollOsc - motion.curAnim.joints[1].rollOffset)); + + // calculate lower leg joint rotations for sidestepping + pitchOsc = motion.curAnim.joints[2].pitch * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[2].pitchPhase)); + + yawOsc = motion.curAnim.joints[2].yaw * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[2].yawPhase)); + + rollOsc = motion.curAnim.joints[2].roll * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[2].rollPhase)); + + // apply lower leg joint rotations + MyAvatar.setJointData("RightLeg", Quat.fromPitchYawRollDegrees( + -pitchOsc + motion.curAnim.joints[2].pitchOffset, + yawOsc - motion.curAnim.joints[2].yawOffset, + rollOsc - motion.curAnim.joints[2].rollOffset)); + + MyAvatar.setJointData("LeftLeg", Quat.fromPitchYawRollDegrees( + pitchOsc + motion.curAnim.joints[2].pitchOffset, + yawOsc + motion.curAnim.joints[2].yawOffset, + rollOsc + motion.curAnim.joints[2].rollOffset)); + } + + // feet + if (motion.curAnim === motion.selSideStepLeft || + motion.curAnim === motion.selSideStepRight ) { + + sideStepHandPitchSign = -1; + sideStepFootPitchModifier = 0.5; + } + if (motion.curTransition !== nullTransition) { + + if (motion.curTransition.walkingAtStart) { + + pitchOscLeft = motion.curAnim.joints[3].pitch * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency) + + motion.curAnim.joints[3].pitchPhase) + 180); + + pitchOscRight = motion.curAnim.joints[3].pitch * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency) + + motion.curAnim.joints[3].pitchPhase)); + + yawOsc = motion.curAnim.joints[3].yaw * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency) + + motion.curAnim.joints[3].yawPhase)); + + rollOsc = motion.curAnim.joints[3].roll * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency) + + motion.curAnim.joints[3].rollPhase)); + + pitchOffset = motion.curAnim.joints[3].pitchOffset; + yawOffset = motion.curAnim.joints[3].yawOffset; + rollOffset = motion.curAnim.joints[3].rollOffset; + + pitchOscLeftLast = motion.curTransition.lastAnim.joints[3].pitch * + motion.curTransition.lastAnim.harmonics.leftFoot.calculate(filter.degToRad(reverseSignModifier * motion.walkWheelPos + + motion.curTransition.lastAnim.joints[3].pitchPhase + reverseModifier)); + + pitchOscRightLast = motion.curTransition.lastAnim.joints[3].pitch * + motion.curTransition.lastAnim.harmonics.rightFoot.calculate(filter.degToRad(reverseSignModifier * motion.walkWheelPos + + motion.curTransition.lastAnim.joints[3].pitchPhase + 180 + reverseModifier)); + + yawOscLast = motion.curTransition.lastAnim.joints[3].yaw * + Math.sin(filter.degToRad((motion.walkWheelPos) + + motion.curTransition.lastAnim.joints[3].yawPhase)); + + rollOscLast = motion.curTransition.lastAnim.joints[3].roll * + Math.sin(filter.degToRad((motion.walkWheelPos) + + motion.curTransition.lastAnim.joints[3].rollPhase)); + + pitchOffsetLast = motion.curTransition.lastAnim.joints[3].pitchOffset; + yawOffsetLast = motion.curTransition.lastAnim.joints[3].yawOffset; + rollOffsetLast = motion.curTransition.lastAnim.joints[3].rollOffset; + + } else { + + if (state.currentState === state.WALKING || + state.currentState === state.EDIT_WALK_STYLES || + state.currentState === state.EDIT_WALK_TWEAKS || + state.currentState === state.EDIT_WALK_JOINTS) { + + pitchOscLeft = motion.curAnim.harmonics.leftFoot.calculate(filter.degToRad(reverseSignModifier * cycle * adjFreq + + motion.curAnim.joints[3].pitchPhase + reverseModifier)); + + pitchOscRight = motion.curAnim.harmonics.rightFoot.calculate(filter.degToRad(reverseSignModifier * cycle * adjFreq + + motion.curAnim.joints[3].pitchPhase + 180 + reverseModifier)); + + } else { + + pitchOscLeft = Math.sin(filter.degToRad(cycle * adjFreq * sideStepFootPitchModifier + + motion.curAnim.joints[3].pitchPhase)); + + pitchOscRight = Math.sin(filter.degToRad(cycle * adjFreq * sideStepFootPitchModifier + + motion.curAnim.joints[3].pitchPhase + 180)); + } + + yawOsc = motion.curAnim.joints[3].yaw * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[3].yawPhase)); + + rollOsc = motion.curAnim.joints[3].roll * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[3].rollPhase)); + + pitchOffset = motion.curAnim.joints[3].pitchOffset; + yawOffset = motion.curAnim.joints[3].yawOffset; + rollOffset = motion.curAnim.joints[3].rollOffset; + + pitchOscLeftLast = motion.curTransition.lastAnim.joints[3].pitch * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency) + + motion.curTransition.lastAnim.joints[3].pitchPhase + 180)); + + pitchOscRightLast = motion.curTransition.lastAnim.joints[3].pitch * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency) + + motion.curTransition.lastAnim.joints[3].pitchPhase)); + + yawOscLast = motion.curTransition.lastAnim.joints[3].yaw * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency) + + motion.curTransition.lastAnim.joints[3].yawPhase)); + + rollOscLast = motion.curTransition.lastAnim.joints[3].roll * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency) + + motion.curTransition.lastAnim.joints[3].rollPhase)); + + pitchOffsetLast = motion.curTransition.lastAnim.joints[3].pitchOffset; + yawOffsetLast = motion.curTransition.lastAnim.joints[3].yawOffset; + rollOffsetLast = motion.curTransition.lastAnim.joints[3].rollOffset; + } + + pitchOscLeft = (transProgress * pitchOscLeft) + ((1 - transProgress) * pitchOscLeftLast); + pitchOscRight = (transProgress * pitchOscRight) + ((1 - transProgress) * pitchOscRightLast); + yawOsc = (transProgress * yawOsc) + ((1 - transProgress) * yawOscLast); + rollOsc = (transProgress * rollOsc) + ((1 - transProgress) * rollOscLast); + + pitchOffset = (transProgress * pitchOffset) + ((1 - transProgress) * pitchOffsetLast); + yawOffset = (transProgress * yawOffset) + ((1 - transProgress) * yawOffsetLast); + rollOffset = (transProgress * rollOffset) + ((1 - transProgress) * rollOffsetLast); + } else { - Overlays.editOverlay(armsFreeBigButtonSelected, { visible: false } ); - Overlays.editOverlay(armsFreeBigButton, { visible: showButtons } ); + + if (state.currentState === state.WALKING || + state.currentState === state.EDIT_WALK_STYLES || + state.currentState === state.EDIT_WALK_TWEAKS || + state.currentState === state.EDIT_WALK_JOINTS) { + + pitchOscLeft = motion.curAnim.harmonics.leftFoot.calculate(filter.degToRad(reverseSignModifier * cycle * adjFreq + + motion.curAnim.joints[3].pitchPhase + reverseModifier)); + + pitchOscRight = motion.curAnim.harmonics.rightFoot.calculate(filter.degToRad(reverseSignModifier * cycle * adjFreq + + motion.curAnim.joints[3].pitchPhase + 180 + reverseModifier)); + + } else { + + pitchOscLeft = Math.sin(filter.degToRad(cycle * adjFreq * sideStepFootPitchModifier + + motion.curAnim.joints[3].pitchPhase)); + + pitchOscRight = Math.sin(filter.degToRad(cycle * adjFreq * sideStepFootPitchModifier + + motion.curAnim.joints[3].pitchPhase + 180)); + } + + yawOsc = Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[3].yawPhase)); + + pitchOscLeft *= motion.curAnim.joints[3].pitch; + pitchOscRight *= motion.curAnim.joints[3].pitch; + + yawOsc *= motion.curAnim.joints[3].yaw; + + rollOsc = motion.curAnim.joints[3].roll * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[3].rollPhase)); + + pitchOffset = motion.curAnim.joints[3].pitchOffset; + yawOffset = motion.curAnim.joints[3].yawOffset; + rollOffset = motion.curAnim.joints[3].rollOffset; } - if(playFootStepSounds) { - Overlays.editOverlay(footstepsBigButtonSelected, { visible: showButtons } ); - Overlays.editOverlay(footstepsBigButton, { visible: false } ); + + // apply foot rotations + MyAvatar.setJointData("LeftFoot", Quat.fromPitchYawRollDegrees( + pitchOscLeft + pitchOffset, + yawOsc - yawOffset, + rollOsc - rollOffset)); + + MyAvatar.setJointData("RightFoot", Quat.fromPitchYawRollDegrees( + pitchOscRight + pitchOffset, + yawOsc + yawOffset, + rollOsc + rollOffset)); + + // play footfall sound yet? To determine this, we take the differential of the + // foot's pitch curve to decide when the foot hits the ground. + if (state.currentState === state.WALKING || + state.currentState === state.SIDE_STEP || + state.currentState === state.EDIT_WALK_STYLES || + state.currentState === state.EDIT_WALK_TWEAKS || + state.currentState === state.EDIT_WALK_JOINTS || + state.currentState === state.EDIT_SIDESTEP_LEFT || + state.currentState === state.EDIT_SIDESTEP_RIGHT) { + + // find dy/dx by determining the cosine wave for the foot's pitch function. + var feetPitchDifferential = Math.cos(filter.degToRad((cycle * adjFreq) + motion.curAnim.joints[3].pitchPhase)); + var threshHold = 0.9; // sets the audio trigger point. with accuracy. + if (feetPitchDifferential < -threshHold && + motion.nextStep === LEFT && + motion.direction !== UP && + motion.direction !== DOWN) { + + playFootstep(LEFT); + motion.nextStep = RIGHT; + } else if (feetPitchDifferential > threshHold && + motion.nextStep === RIGHT && + motion.direction !== UP && + motion.direction !== DOWN) { + + playFootstep(RIGHT); + motion.nextStep = LEFT; + } + } + + // toes + if (motion.curTransition !== nullTransition) { + + if (motion.curTransition.walkingAtStart) { + + pitchOsc = motion.curAnim.joints[4].pitch * + Math.sin(filter.degToRad((2 * motion.cumulativeTime * + motion.curAnim.calibration.frequency) + + motion.curAnim.joints[4].pitchPhase)); + + yawOsc = motion.curAnim.joints[4].yaw * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency) + + motion.curAnim.joints[4].yawPhase)); + + rollOsc = motion.curAnim.joints[4].roll * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency) + + motion.curAnim.joints[4].rollPhase)); + + pitchOffset = motion.curAnim.joints[4].pitchOffset; + yawOffset = motion.curAnim.joints[4].yawOffset; + rollOffset = motion.curAnim.joints[4].rollOffset; + + pitchOscLast = motion.curTransition.lastAnim.joints[4].pitch * + Math.sin(filter.degToRad((2 * motion.walkWheelPos) + + motion.curTransition.lastAnim.joints[4].pitchPhase)); + + yawOscLast = motion.curTransition.lastAnim.joints[4].yaw * + Math.sin(filter.degToRad((motion.walkWheelPos) + + motion.curTransition.lastAnim.joints[4].yawPhase)); + + rollOscLast = motion.curTransition.lastAnim.joints[4].roll * + Math.sin(filter.degToRad((motion.walkWheelPos) + + motion.curTransition.lastAnim.joints[4].rollPhase)); + + pitchOffsetLast = motion.curTransition.lastAnim.joints[4].pitchOffset; + yawOffsetLast = motion.curTransition.lastAnim.joints[4].yawOffset; + rollOffsetLast = motion.curTransition.lastAnim.joints[4].rollOffset; + + } else { + + pitchOsc = motion.curAnim.joints[4].pitch * + Math.sin(filter.degToRad((2 * cycle * adjFreq) + + motion.curAnim.joints[4].pitchPhase)); + + yawOsc = motion.curAnim.joints[4].yaw * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[4].yawPhase)); + + rollOsc = motion.curAnim.joints[4].roll * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[4].rollPhase)); + + pitchOffset = motion.curAnim.joints[4].pitchOffset; + yawOffset = motion.curAnim.joints[4].yawOffset; + rollOffset = motion.curAnim.joints[4].rollOffset; + + pitchOscLast = motion.curTransition.lastAnim.joints[4].pitch * + Math.sin(filter.degToRad((2 * motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency) + + motion.curTransition.lastAnim.joints[4].pitchPhase)); + + yawOscLast = motion.curTransition.lastAnim.joints[4].yaw * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency) + + motion.curTransition.lastAnim.joints[4].yawPhase)); + + rollOscLast = motion.curTransition.lastAnim.joints[4].roll * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency) + + motion.curTransition.lastAnim.joints[4].rollPhase)); + + pitchOffsetLast = motion.curTransition.lastAnim.joints[4].pitchOffset; + yawOffsetLast = motion.curTransition.lastAnim.joints[4].yawOffset; + rollOffsetLast = motion.curTransition.lastAnim.joints[4].rollOffset; + } + + pitchOsc = (transProgress * pitchOsc) + ((1 - transProgress) * pitchOscLast); + yawOsc = (transProgress * yawOsc) + ((1 - transProgress) * yawOscLast); + rollOsc = (transProgress * rollOsc) + ((1 - transProgress) * rollOscLast); + + pitchOffset = (transProgress * pitchOffset) + ((1 - transProgress) * pitchOffsetLast); + yawOffset = (transProgress * yawOffset) + ((1 - transProgress) * yawOffsetLast); + rollOffset = (transProgress * rollOffset) + ((1 - transProgress) * rollOffsetLast); + } else { - Overlays.editOverlay(footstepsBigButtonSelected, { visible: false } ); - Overlays.editOverlay(footstepsBigButton, { visible: showButtons } ); - } -} -function minimiseDialog() { - if(minimised) { - setBackground(); - hidebuttonOverlays(); - setSliderThumbsVisible(false); - hideJointControls(); - showFrontPanelButtons(false); - Overlays.editOverlay(controlsMinimisedTab, { visible: true } ); - } else { - setInternalState(STANDING); // show all the controls again - Overlays.editOverlay(controlsMinimisedTab, { visible: false } ); - } -} -function setBackground(backgroundName) { - for(var i in backgroundOverlays) { - if(backgroundOverlays[i] === backgroundName) - Overlays.editOverlay(backgroundName, { visible: true } ); - else Overlays.editOverlay(backgroundOverlays[i], { visible: false } ); - } -} -function setButtonOverlayVisible(buttonOverlayName) { - for(var i in buttonOverlays) { - if(buttonOverlays[i] === buttonOverlayName) { - Overlays.editOverlay(buttonOverlayName, { visible: true } ); - } - } -} -// top row menu type buttons (smaller) -function hidebuttonOverlays() { - for(var i in buttonOverlays) { - Overlays.editOverlay(buttonOverlays[i], { visible: false } ); - } -} -function hideJointControls() { - for(var i in jointsControlOverlays) { - Overlays.editOverlay(jointsControlOverlays[i], { visible: false } ); - } -} -function setSliderThumbsVisible(thumbsVisible) { - for(var i = 0 ; i < sliderThumbOverlays.length ; i++) { - Overlays.editOverlay(sliderThumbOverlays[i], { visible: thumbsVisible } ); - } -} -function initialiseJointsEditingPanel(propertyIndex) { + pitchOsc = motion.curAnim.joints[4].pitch * + Math.sin(filter.degToRad((2 * cycle * adjFreq) + + motion.curAnim.joints[4].pitchPhase)); - selectedJointIndex = propertyIndex; + yawOsc = motion.curAnim.joints[4].yaw * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[4].yawPhase)); - // set the image for the selected joint on the character control - hideJointControls(); - switch (selectedJointIndex) { - case 0: - Overlays.editOverlay(hipsJointControl, { visible: true }); - break; - case 1: - Overlays.editOverlay(upperLegsJointControl, { visible: true }); - break; - case 2: - Overlays.editOverlay(lowerLegsJointControl, { visible: true }); - break; - case 3: - Overlays.editOverlay(feetJointControl, { visible: true }); - break; - case 4: - Overlays.editOverlay(toesJointControl, { visible: true }); - break; - case 5: - Overlays.editOverlay(spineJointControl, { visible: true }); - break; - case 6: - Overlays.editOverlay(spine1JointControl, { visible: true }); - break; - case 7: - Overlays.editOverlay(spine2JointControl, { visible: true }); - break; - case 8: - Overlays.editOverlay(shouldersJointControl, { visible: true }); - break; - case 9: - Overlays.editOverlay(upperArmsJointControl, { visible: true }); - break; - case 10: - Overlays.editOverlay(forearmsJointControl, { visible: true }); - break; - case 11: - Overlays.editOverlay(handsJointControl, { visible: true }); - break; - case 12: - Overlays.editOverlay(headJointControl, { visible: true }); - break; - } + rollOsc = motion.curAnim.joints[4].roll * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[4].rollPhase)); - // set sliders to adjust individual joint properties - var i = 0; - var yLocation = backgroundY+359; - - // pitch your role - var sliderXPos = currentAnimation.joints[selectedJointIndex].pitch - / sliderRanges.joints[selectedJointIndex].pitchRange * sliderRangeX; - Overlays.editOverlay(sliderThumbOverlays[i], { x: minSliderX + sliderXPos, y: yLocation+=30, visible: true }); - sliderXPos = currentAnimation.joints[selectedJointIndex].yaw - / sliderRanges.joints[selectedJointIndex].yawRange * sliderRangeX; - Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=30, visible: true }); - sliderXPos = currentAnimation.joints[selectedJointIndex].roll - / sliderRanges.joints[selectedJointIndex].rollRange * sliderRangeX; - Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=30, visible: true }); - - // set phases (full range, -180 to 180) - sliderXPos = (90 + currentAnimation.joints[selectedJointIndex].pitchPhase/2)/180 * sliderRangeX; - Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=30, visible: true }); - sliderXPos = (90 + currentAnimation.joints[selectedJointIndex].yawPhase/2)/180 * sliderRangeX; - Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=30, visible: true }); - sliderXPos = (90 + currentAnimation.joints[selectedJointIndex].rollPhase/2)/180 * sliderRangeX; - Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=30, visible: true }); - - // offset ranges are also -ve thr' zero to +ve, so have to offset - sliderXPos = (((sliderRanges.joints[selectedJointIndex].pitchOffsetRange+currentAnimation.joints[selectedJointIndex].pitchOffset)/2) - /sliderRanges.joints[selectedJointIndex].pitchOffsetRange) * sliderRangeX; - Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=30, visible: true }); - sliderXPos = (((sliderRanges.joints[selectedJointIndex].yawOffsetRange+currentAnimation.joints[selectedJointIndex].yawOffset)/2) - /sliderRanges.joints[selectedJointIndex].yawOffsetRange) * sliderRangeX; - Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=30, visible: true }); - sliderXPos = (((sliderRanges.joints[selectedJointIndex].rollOffsetRange+currentAnimation.joints[selectedJointIndex].rollOffset)/2) - /sliderRanges.joints[selectedJointIndex].rollOffsetRange) * sliderRangeX; - Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=30, visible: true }); -} - -function initialiseWalkTweaks() { - - // set sliders to adjust walk properties - var i = 0; - var yLocation = backgroundY+71; - - var sliderXPos = currentAnimation.settings.baseFrequency / MAX_WALK_SPEED * sliderRangeX; // walk speed - Overlays.editOverlay(sliderThumbOverlays[i], { x: minSliderX + sliderXPos, y: yLocation+=60, visible: true }); - sliderXPos = 0 * sliderRangeX; // start flying speed - depricated - Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=60, visible: true }); - sliderXPos = currentAnimation.joints[0].sway / sliderRanges.joints[0].swayRange * sliderRangeX; // Hips sway - Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=60, visible: true }); - sliderXPos = currentAnimation.joints[0].bob / sliderRanges.joints[0].bobRange * sliderRangeX; // Hips bob - Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=60, visible: true }); - sliderXPos = currentAnimation.joints[0].thrust / sliderRanges.joints[0].thrustRange * sliderRangeX; // Hips thrust - Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=60, visible: true }); - sliderXPos = (((sliderRanges.joints[1].rollOffsetRange+currentAnimation.joints[1].rollOffset)/2) // legs separation - is upper legs roll offset - / sliderRanges.joints[1].rollOffsetRange) * sliderRangeX; - Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=60, visible: true }); - sliderXPos = currentAnimation.joints[1].pitch / sliderRanges.joints[1].pitchRange * sliderRangeX; // stride - is upper legs pitch - Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=60, visible: true }); - sliderXPos = currentAnimation.joints[9].yaw / sliderRanges.joints[9].yawRange * sliderRangeX; // arms swing - is upper arms yaw - Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=60, visible: true }); - sliderXPos = (((sliderRanges.joints[9].pitchOffsetRange-currentAnimation.joints[9].pitchOffset)/2) - / sliderRanges.joints[9].pitchOffsetRange) * sliderRangeX; // arms out - is upper arms pitch offset - Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=60, visible: true }); -} - -function showWalkStyleButtons(showButtons) { - - // set all big buttons to hidden, but skip the first 8, as are for the front panel - for(var i = 8 ; i < bigButtonOverlays.length ; i++) { - Overlays.editOverlay(bigButtonOverlays[i], { visible: false }); + pitchOffset = motion.curAnim.joints[4].pitchOffset; + yawOffset = motion.curAnim.joints[4].yawOffset; + rollOffset = motion.curAnim.joints[4].rollOffset; } - if(!showButtons) return; + // apply toe rotations + MyAvatar.setJointData("RightToeBase", Quat.fromPitchYawRollDegrees( + pitchOsc + pitchOffset, + yawOsc + yawOffset, + rollOsc + rollOffset)); - // set all the non-selected ones to showing - for(var i = 8 ; i < bigButtonOverlays.length ; i+=2) { - Overlays.editOverlay(bigButtonOverlays[i], { visible: showButtons }); + MyAvatar.setJointData("LeftToeBase", Quat.fromPitchYawRollDegrees( + pitchOsc + pitchOffset, + yawOsc - yawOffset, + rollOsc - rollOffset)); + + // spine + if (motion.curTransition !== nullTransition) { + + if (motion.curTransition.walkingAtStart) { + + pitchOsc = motion.curAnim.joints[5].pitch * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency * 2) + + motion.curAnim.joints[5].pitchPhase)) + + motion.curAnim.joints[5].pitchOffset; + + yawOsc = motion.curAnim.joints[5].yaw * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency) + + motion.curAnim.joints[5].yawPhase)) + + motion.curAnim + .joints[5].yawOffset; + + rollOsc = motion.curAnim.joints[5].roll * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency) + + motion.curAnim.joints[5].rollPhase)) + + motion.curAnim.joints[5].rollOffset; + + pitchOscLast = motion.curTransition.lastAnim.joints[5].pitch * + Math.sin(filter.degToRad((motion.walkWheelPos * 2) + + motion.curTransition.lastAnim.joints[5].pitchPhase)) + + motion.curTransition.lastAnim.joints[5].pitchOffset; + + yawOscLast = motion.curTransition.lastAnim.joints[5].yaw * + Math.sin(filter.degToRad((motion.walkWheelPos) + + motion.curTransition.lastAnim.joints[5].yawPhase)) + + motion.curTransition.lastAnim.joints[5].yawOffset; + + rollOscLast = motion.curTransition.lastAnim.joints[5].roll * + Math.sin(filter.degToRad((motion.walkWheelPos) + + motion.curTransition.lastAnim.joints[5].rollPhase)) + + motion.curTransition.lastAnim.joints[5].rollOffset; + } else { + + pitchOsc = motion.curAnim.joints[5].pitch * + Math.sin(filter.degToRad((cycle * adjFreq * 2) + + motion.curAnim.joints[5].pitchPhase)) + + motion.curAnim.joints[5].pitchOffset; + + yawOsc = motion.curAnim.joints[5].yaw * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[5].yawPhase)) + + motion.curAnim.joints[5].yawOffset; + + rollOsc = motion.curAnim.joints[5].roll * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[5].rollPhase)) + + motion.curAnim.joints[5].rollOffset; + + pitchOscLast = motion.curTransition.lastAnim.joints[5].pitch * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency * 2) + + motion.curTransition.lastAnim.joints[5].pitchPhase)) + + motion.curTransition.lastAnim.joints[5].pitchOffset; + + yawOscLast = motion.curTransition.lastAnim.joints[5].yaw * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency) + + motion.curTransition.lastAnim.joints[5].yawPhase)) + + motion.curTransition.lastAnim.joints[5].yawOffset; + + rollOscLast = motion.curTransition.lastAnim.joints[5].roll * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency) + + motion.curTransition.lastAnim.joints[5].rollPhase)) + + motion.curTransition.lastAnim.joints[5].rollOffset; + } + + pitchOsc = (transProgress * pitchOsc) + ((1 - transProgress) * pitchOscLast); + yawOsc = (transProgress * yawOsc) + ((1 - transProgress) * yawOscLast); + rollOsc = (transProgress * rollOsc) + ((1 - transProgress) * rollOscLast); + + } else { + + pitchOsc = motion.curAnim.joints[5].pitch * + Math.sin(filter.degToRad((cycle * adjFreq * 2) + + motion.curAnim.joints[5].pitchPhase)) + + motion.curAnim.joints[5].pitchOffset; + + yawOsc = motion.curAnim.joints[5].yaw * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[5].yawPhase)) + + motion.curAnim.joints[5].yawOffset; + + rollOsc = motion.curAnim.joints[5].roll * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[5].rollPhase)) + + motion.curAnim.joints[5].rollOffset; } - // set the currently selected one - if(selectedWalk === femaleStrutWalk || selectedWalk === maleStrutWalk) { - Overlays.editOverlay(strutWalkBigButtonSelected, { visible: showButtons }); - Overlays.editOverlay(strutWalkBigButton, {visible: false}); + // apply spine joint rotations + MyAvatar.setJointData("Spine", Quat.fromPitchYawRollDegrees(pitchOsc, yawOsc, rollOsc)); + + // spine 1 + if (motion.curTransition !== nullTransition) { + + if (motion.curTransition.walkingAtStart) { + + pitchOsc = motion.curAnim.joints[6].pitch * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency * 2) + + motion.curAnim.joints[6].pitchPhase)) + + motion.curAnim.joints[6].pitchOffset; + + yawOsc = motion.curAnim.joints[6].yaw * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency) + + motion.curAnim.joints[6].yawPhase)) + + motion.curAnim.joints[6].yawOffset; + + rollOsc = motion.curAnim.joints[6].roll * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency) + + motion.curAnim.joints[6].rollPhase)) + + motion.curAnim.joints[6].rollOffset; + + pitchOscLast = motion.curTransition.lastAnim.joints[6].pitch * + Math.sin(filter.degToRad((motion.walkWheelPos * 2) + + motion.curTransition.lastAnim.joints[6].pitchPhase)) + + motion.curTransition.lastAnim.joints[6].pitchOffset; + + yawOscLast = motion.curTransition.lastAnim.joints[6].yaw * + Math.sin(filter.degToRad((motion.walkWheelPos) + + motion.curTransition.lastAnim.joints[6].yawPhase)) + + motion.curTransition.lastAnim.joints[6].yawOffset; + + rollOscLast = motion.curTransition.lastAnim.joints[6].roll * + Math.sin(filter.degToRad((motion.walkWheelPos) + + motion.curTransition.lastAnim.joints[6].rollPhase)) + + motion.curTransition.lastAnim.joints[6].rollOffset; + + } else { + + pitchOsc = motion.curAnim.joints[6].pitch * + Math.sin(filter.degToRad((cycle * adjFreq * 2) + + motion.curAnim.joints[6].pitchPhase)) + + motion.curAnim.joints[6].pitchOffset; + + yawOsc = motion.curAnim.joints[6].yaw * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[6].yawPhase)) + + motion.curAnim.joints[6].yawOffset; + + rollOsc = motion.curAnim.joints[6].roll * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[6].rollPhase)) + + motion.curAnim.joints[6].rollOffset; + + pitchOscLast = motion.curTransition.lastAnim.joints[6].pitch * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency * 2) + + motion.curTransition.lastAnim.joints[6].pitchPhase)) + + motion.curTransition.lastAnim.joints[6].pitchOffset; + + yawOscLast = motion.curTransition.lastAnim.joints[6].yaw * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency) + + motion.curTransition.lastAnim.joints[6].yawPhase)) + + motion.curTransition.lastAnim.joints[6].yawOffset; + + rollOscLast = motion.curTransition.lastAnim.joints[6].roll * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency) + + motion.curTransition.lastAnim.joints[6].rollPhase)) + + motion.curTransition.lastAnim.joints[6].rollOffset; + } + + pitchOsc = (transProgress * pitchOsc) + ((1 - transProgress) * pitchOscLast); + yawOsc = (transProgress * yawOsc) + ((1 - transProgress) * yawOscLast); + rollOsc = (transProgress * rollOsc) + ((1 - transProgress) * rollOscLast); + + } else { + + pitchOsc = motion.curAnim.joints[6].pitch * + Math.sin(filter.degToRad((cycle * adjFreq * 2) + + motion.curAnim.joints[6].pitchPhase)) + + motion.curAnim.joints[6].pitchOffset; + + yawOsc = motion.curAnim.joints[6].yaw * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[6].yawPhase)) + + motion.curAnim.joints[6].yawOffset; + + rollOsc = motion.curAnim.joints[6].roll * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[6].rollPhase)) + + motion.curAnim.joints[6].rollOffset; } + + // apply spine1 joint rotations + MyAvatar.setJointData("Spine1", Quat.fromPitchYawRollDegrees(pitchOsc, yawOsc, rollOsc)); + + // spine 2 + if (motion.curTransition !== nullTransition) { + + if (motion.curTransition.walkingAtStart) { + + pitchOsc = motion.curAnim.joints[7].pitch * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curAnim.calibration.frequency * 2 + + motion.curAnim.joints[7].pitchPhase)) + + motion.curAnim.joints[7].pitchOffset; + + yawOsc = motion.curAnim.joints[7].yaw * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curAnim.calibration.frequency + + motion.curAnim.joints[7].yawPhase)) + + motion.curAnim.joints[7].yawOffset; + + rollOsc = motion.curAnim.joints[7].roll * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curAnim.calibration.frequency + + motion.curAnim.joints[7].rollPhase)) + + motion.curAnim.joints[7].rollOffset; + + pitchOscLast = motion.curTransition.lastAnim.joints[7].pitch * + Math.sin(filter.degToRad(motion.walkWheelPos * 2 + + motion.curTransition.lastAnim.joints[7].pitchPhase)) + + motion.curTransition.lastAnim.joints[7].pitchOffset; + + yawOscLast = motion.curTransition.lastAnim.joints[7].yaw * + Math.sin(filter.degToRad(motion.walkWheelPos + + motion.curTransition.lastAnim.joints[7].yawPhase)) + + motion.curTransition.lastAnim.joints[7].yawOffset; + + rollOscLast = motion.curTransition.lastAnim.joints[7].roll * + Math.sin(filter.degToRad(motion.walkWheelPos + + motion.curTransition.lastAnim.joints[7].rollPhase)) + + motion.curTransition.lastAnim.joints[7].rollOffset; + } else { + + pitchOsc = motion.curAnim.joints[7].pitch * + Math.sin(filter.degToRad(cycle * adjFreq * 2 + + motion.curAnim.joints[7].pitchPhase)) + + motion.curAnim.joints[7].pitchOffset; + + yawOsc = motion.curAnim.joints[7].yaw * + Math.sin(filter.degToRad(cycle * adjFreq + + motion.curAnim.joints[7].yawPhase)) + + motion.curAnim.joints[7].yawOffset; + + rollOsc = motion.curAnim.joints[7].roll * + Math.sin(filter.degToRad(cycle * adjFreq + + motion.curAnim.joints[7].rollPhase)) + + motion.curAnim.joints[7].rollOffset; + + pitchOscLast = motion.curTransition.lastAnim.joints[7].pitch * + Math.sin(filter.degToRad(motion.cumulativeTime * 2 * + motion.curTransition.lastAnim.calibration.frequency + + motion.curTransition.lastAnim.joints[7].pitchPhase)) + + motion.curTransition.lastAnim.joints[7].pitchOffset; + + yawOscLast = motion.curTransition.lastAnim.joints[7].yaw * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency + + motion.curTransition.lastAnim.joints[7].yawPhase)) + + motion.curTransition.lastAnim.joints[7].yawOffset; + + rollOscLast = motion.curTransition.lastAnim.joints[7].roll * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency + + motion.curTransition.lastAnim.joints[7].rollPhase)) + + motion.curTransition.lastAnim.joints[7].rollOffset; + } + + pitchOsc = (transProgress * pitchOsc) + ((1 - transProgress) * pitchOscLast); + yawOsc = (transProgress * yawOsc) + ((1 - transProgress) * yawOscLast); + rollOsc = (transProgress * rollOsc) + ((1 - transProgress) * rollOscLast); + + } else { + + pitchOsc = motion.curAnim.joints[7].pitch * + Math.sin(filter.degToRad(cycle * adjFreq * 2 + + motion.curAnim.joints[7].pitchPhase)) + + motion.curAnim.joints[7].pitchOffset; + + yawOsc = motion.curAnim.joints[7].yaw * + Math.sin(filter.degToRad(cycle * adjFreq + + motion.curAnim.joints[7].yawPhase)) + + motion.curAnim.joints[7].yawOffset; + + rollOsc = motion.curAnim.joints[7].roll * + Math.sin(filter.degToRad(cycle * adjFreq + + motion.curAnim.joints[7].rollPhase)) + + motion.curAnim.joints[7].rollOffset; + } + + // apply spine2 joint rotations + MyAvatar.setJointData("Spine2", Quat.fromPitchYawRollDegrees(pitchOsc, yawOsc, rollOsc)); + + if (!motion.armsFree) { + + // shoulders + if (motion.curTransition !== nullTransition) { + + if (motion.curTransition.walkingAtStart) { + + pitchOsc = motion.curAnim.joints[8].pitch * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curAnim.calibration.frequency + + motion.curAnim.joints[8].pitchPhase)) + + motion.curAnim.joints[8].pitchOffset; + + yawOsc = motion.curAnim.joints[8].yaw * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curAnim.calibration.frequency + + motion.curAnim.joints[8].yawPhase)); + + rollOsc = motion.curAnim.joints[8].roll * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curAnim.calibration.frequency + + motion.curAnim.joints[8].rollPhase)) + + motion.curAnim.joints[8].rollOffset; + + yawOffset = motion.curAnim.joints[8].yawOffset; + + pitchOscLast = motion.curTransition.lastAnim.joints[8].pitch * + Math.sin(filter.degToRad(motion.walkWheelPos + + motion.curTransition.lastAnim.joints[8].pitchPhase)) + + motion.curTransition.lastAnim.joints[8].pitchOffset; + + yawOscLast = motion.curTransition.lastAnim.joints[8].yaw * + Math.sin(filter.degToRad(motion.walkWheelPos + + motion.curTransition.lastAnim.joints[8].yawPhase)) + + rollOscLast = motion.curTransition.lastAnim.joints[8].roll * + Math.sin(filter.degToRad(motion.walkWheelPos + + motion.curTransition.lastAnim.joints[8].rollPhase)) + + motion.curTransition.lastAnim.joints[8].rollOffset; + + yawOffsetLast = motion.curTransition.lastAnim.joints[8].yawOffset; + + } else { + + pitchOsc = motion.curAnim.joints[8].pitch * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[8].pitchPhase)) + + motion.curAnim.joints[8].pitchOffset; + + yawOsc = motion.curAnim.joints[8].yaw * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[8].yawPhase)); + + rollOsc = motion.curAnim.joints[8].roll * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[8].rollPhase)) + + motion.curAnim.joints[8].rollOffset; + + yawOffset = motion.curAnim.joints[8].yawOffset; + + pitchOscLast = motion.curTransition.lastAnim.joints[8].pitch * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency + + motion.curTransition.lastAnim.joints[8].pitchPhase)) + + motion.curTransition.lastAnim.joints[8].pitchOffset; + + yawOscLast = motion.curTransition.lastAnim.joints[8].yaw * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency + + motion.curTransition.lastAnim.joints[8].yawPhase)) + + rollOscLast = motion.curTransition.lastAnim.joints[8].roll * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency + + motion.curTransition.lastAnim.joints[8].rollPhase)) + + motion.curTransition.lastAnim.joints[8].rollOffset; + + yawOffsetLast = motion.curTransition.lastAnim.joints[8].yawOffset; + } + + pitchOsc = (transProgress * pitchOsc) + ((1 - transProgress) * pitchOscLast); + yawOsc = (transProgress * yawOsc) + ((1 - transProgress) * yawOscLast); + rollOsc = (transProgress * rollOsc) + ((1 - transProgress) * rollOscLast); + + yawOffset = (transProgress * yawOffset) + ((1 - transProgress) * yawOffsetLast); + + } else { + + pitchOsc = motion.curAnim.joints[8].pitch * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[8].pitchPhase)) + + motion.curAnim.joints[8].pitchOffset; + + yawOsc = motion.curAnim.joints[8].yaw * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[8].yawPhase)); + + rollOsc = motion.curAnim.joints[8].roll * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[8].rollPhase)) + + motion.curAnim.joints[8].rollOffset; + + yawOffset = motion.curAnim.joints[8].yawOffset; + } + + MyAvatar.setJointData("RightShoulder", Quat.fromPitchYawRollDegrees(pitchOsc, yawOsc + yawOffset, rollOsc)); + MyAvatar.setJointData("LeftShoulder", Quat.fromPitchYawRollDegrees(pitchOsc, yawOsc - yawOffset, -rollOsc)); + + // upper arms + if (motion.curTransition !== nullTransition) { + + if (motion.curTransition.walkingAtStart) { + + pitchOsc = motion.curAnim.joints[9].pitch * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency) + + motion.curAnim.joints[9].pitchPhase)); + + yawOsc = motion.curAnim.joints[9].yaw * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency) + + motion.curAnim.joints[9].yawPhase)); + + rollOsc = motion.curAnim.joints[9].roll * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency * 2) + + motion.curAnim.joints[9].rollPhase)) + + motion.curAnim.joints[9].rollOffset; + + pitchOffset = motion.curAnim.joints[9].pitchOffset; + yawOffset = motion.curAnim.joints[9].yawOffset; + + pitchOscLast = motion.curTransition.lastAnim.joints[9].pitch * + Math.sin(filter.degToRad(motion.walkWheelPos + + motion.curTransition.lastAnim.joints[9].pitchPhase)); + + yawOscLast = motion.curTransition.lastAnim.joints[9].yaw * + Math.sin(filter.degToRad(motion.walkWheelPos + + motion.curTransition.lastAnim.joints[9].yawPhase)); + + rollOscLast = motion.curTransition.lastAnim.joints[9].roll * + Math.sin(filter.degToRad(motion.walkWheelPos + + motion.curTransition.lastAnim.joints[9].rollPhase)) + + motion.curTransition.lastAnim.joints[9].rollOffset; + + pitchOffsetLast = motion.curTransition.lastAnim.joints[9].pitchOffset; + yawOffsetLast = motion.curTransition.lastAnim.joints[9].yawOffset; + + } else { + + pitchOsc = motion.curAnim.joints[9].pitch * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[9].pitchPhase)); + + yawOsc = motion.curAnim.joints[9].yaw * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[9].yawPhase)); + + rollOsc = motion.curAnim.joints[9].roll * + Math.sin(filter.degToRad((cycle * adjFreq * 2) + + motion.curAnim.joints[9].rollPhase)) + + motion.curAnim.joints[9].rollOffset; + + pitchOffset = motion.curAnim.joints[9].pitchOffset; + yawOffset = motion.curAnim.joints[9].yawOffset; + + pitchOscLast = motion.curTransition.lastAnim.joints[9].pitch * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency + + motion.curTransition.lastAnim.joints[9].pitchPhase)) + + yawOscLast = motion.curTransition.lastAnim.joints[9].yaw * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency + + motion.curTransition.lastAnim.joints[9].yawPhase)) + + rollOscLast = motion.curTransition.lastAnim.joints[9].roll * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency + + motion.curTransition.lastAnim.joints[9].rollPhase)) + + motion.curTransition.lastAnim.joints[9].rollOffset; + + pitchOffsetLast = motion.curTransition.lastAnim.joints[9].pitchOffset; + yawOffsetLast = motion.curTransition.lastAnim.joints[9].yawOffset; + } + + pitchOsc = (transProgress * pitchOsc) + ((1 - transProgress) * pitchOscLast); + yawOsc = (transProgress * yawOsc) + ((1 - transProgress) * yawOscLast); + rollOsc = (transProgress * rollOsc) + ((1 - transProgress) * rollOscLast); + + pitchOffset = (transProgress * pitchOffset) + ((1 - transProgress) * pitchOffsetLast); + yawOffset = (transProgress * yawOffset) + ((1 - transProgress) * yawOffsetLast); + + } else { + + pitchOsc = motion.curAnim.joints[9].pitch * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[9].pitchPhase)); + + yawOsc = motion.curAnim.joints[9].yaw * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[9].yawPhase)); + + rollOsc = motion.curAnim.joints[9].roll * + Math.sin(filter.degToRad((cycle * adjFreq * 2) + + motion.curAnim.joints[9].rollPhase)) + + motion.curAnim.joints[9].rollOffset; + + pitchOffset = motion.curAnim.joints[9].pitchOffset; + yawOffset = motion.curAnim.joints[9].yawOffset; + + } + + MyAvatar.setJointData("RightArm", Quat.fromPitchYawRollDegrees( + (-1 * flyingModifier) * pitchOsc + pitchOffset, + yawOsc - yawOffset, + rollOsc)); + + MyAvatar.setJointData("LeftArm", Quat.fromPitchYawRollDegrees( + pitchOsc + pitchOffset, + yawOsc + yawOffset, + -rollOsc)); + + // forearms + if (motion.curTransition !== nullTransition) { + + if (motion.curTransition.walkingAtStart) { + + pitchOsc = motion.curAnim.joints[10].pitch * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency) + + motion.curAnim.joints[10].pitchPhase)) + + motion.curAnim.joints[10].pitchOffset; + + yawOsc = motion.curAnim.joints[10].yaw * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency) + + motion.curAnim.joints[10].yawPhase)); + + rollOsc = motion.curAnim.joints[10].roll * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency) + + motion.curAnim.joints[10].rollPhase)); + + yawOffset = motion.curAnim.joints[10].yawOffset; + rollOffset = motion.curAnim.joints[10].rollOffset; + + pitchOscLast = motion.curTransition.lastAnim.joints[10].pitch * + Math.sin(filter.degToRad((motion.walkWheelPos) + + motion.curTransition.lastAnim.joints[10].pitchPhase)) + + motion.curTransition.lastAnim.joints[10].pitchOffset; + + yawOscLast = motion.curTransition.lastAnim.joints[10].yaw * + Math.sin(filter.degToRad((motion.walkWheelPos) + + motion.curTransition.lastAnim.joints[10].yawPhase)); + + rollOscLast = motion.curTransition.lastAnim.joints[10].roll * + Math.sin(filter.degToRad((motion.walkWheelPos) + + motion.curTransition.lastAnim.joints[10].rollPhase)); + + yawOffsetLast = motion.curTransition.lastAnim.joints[10].yawOffset; + rollOffsetLast = motion.curTransition.lastAnim.joints[10].rollOffset; + + } else { + + pitchOsc = motion.curAnim.joints[10].pitch * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[10].pitchPhase)) + + motion.curAnim.joints[10].pitchOffset; + + yawOsc = motion.curAnim.joints[10].yaw * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[10].yawPhase)); + + rollOsc = motion.curAnim.joints[10].roll * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[10].rollPhase)); + + yawOffset = motion.curAnim.joints[10].yawOffset; + rollOffset = motion.curAnim.joints[10].rollOffset; + + pitchOscLast = motion.curTransition.lastAnim.joints[10].pitch * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency) + + motion.curTransition.lastAnim.joints[10].pitchPhase)) + + motion.curTransition.lastAnim.joints[10].pitchOffset; + + yawOscLast = motion.curTransition.lastAnim.joints[10].yaw * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency) + + motion.curTransition.lastAnim.joints[10].yawPhase)); + + rollOscLast = motion.curTransition.lastAnim.joints[10].roll * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency) + + motion.curTransition.lastAnim.joints[10].rollPhase)); + + yawOffsetLast = motion.curTransition.lastAnim.joints[10].yawOffset; + rollOffsetLast = motion.curTransition.lastAnim.joints[10].rollOffset; + } + + // blend the animations + pitchOsc = (transProgress * pitchOsc) + ((1 - transProgress) * pitchOscLast); + yawOsc = -(transProgress * yawOsc) + ((1 - transProgress) * yawOscLast); + rollOsc = (transProgress * rollOsc) + ((1 - transProgress) * rollOscLast); + + yawOffset = (transProgress * yawOffset) + ((1 - transProgress) * yawOffsetLast); + rollOffset = (transProgress * rollOffset) + ((1 - transProgress) * rollOffsetLast); + + } else { + + pitchOsc = motion.curAnim.joints[10].pitch * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[10].pitchPhase)) + + motion.curAnim.joints[10].pitchOffset; + + yawOsc = motion.curAnim.joints[10].yaw * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[10].yawPhase)); + + rollOsc = motion.curAnim.joints[10].roll * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[10].rollPhase)); + + yawOffset = motion.curAnim.joints[10].yawOffset; + rollOffset = motion.curAnim.joints[10].rollOffset; + } + + // apply forearms rotations + MyAvatar.setJointData("RightForeArm", + Quat.fromPitchYawRollDegrees(pitchOsc, yawOsc + yawOffset, rollOsc + rollOffset)); + MyAvatar.setJointData("LeftForeArm", + Quat.fromPitchYawRollDegrees(pitchOsc, yawOsc - yawOffset, rollOsc - rollOffset)); + + // hands + if (motion.curTransition !== nullTransition) { + + if (motion.curTransition.walkingAtStart) { + + pitchOsc = motion.curAnim.joints[11].pitch * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency) + + motion.curAnim.joints[11].pitchPhase)) + + motion.curAnim.joints[11].pitchOffset; + + yawOsc = motion.curAnim.joints[11].yaw * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency) + + motion.curAnim.joints[11].yawPhase)) + + motion.curAnim.joints[11].yawOffset; + + rollOsc = motion.curAnim.joints[11].roll * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency) + + motion.curAnim.joints[11].rollPhase)); + + pitchOscLast = motion.curTransition.lastAnim.joints[11].pitch * + Math.sin(filter.degToRad(motion.walkWheelPos + + motion.curTransition.lastAnim.joints[11].pitchPhase)) + + motion.curTransition.lastAnim.joints[11].pitchOffset; + + yawOscLast = motion.curTransition.lastAnim.joints[11].yaw * + Math.sin(filter.degToRad(motion.walkWheelPos + + motion.curTransition.lastAnim.joints[11].yawPhase)) + + motion.curTransition.lastAnim.joints[11].yawOffset; + + rollOscLast = motion.curTransition.lastAnim.joints[11].roll * + Math.sin(filter.degToRad(motion.walkWheelPos + + motion.curTransition.lastAnim.joints[11].rollPhase)) + + rollOffset = motion.curAnim.joints[11].rollOffset; + rollOffsetLast = motion.curTransition.lastAnim.joints[11].rollOffset; + + } else { + + pitchOsc = motion.curAnim.joints[11].pitch * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[11].pitchPhase)) + + motion.curAnim.joints[11].pitchOffset; + + yawOsc = motion.curAnim.joints[11].yaw * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[11].yawPhase)) + + motion.curAnim.joints[11].yawOffset; + + rollOsc = motion.curAnim.joints[11].roll * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[11].rollPhase)); + + rollOffset = motion.curAnim.joints[11].rollOffset; + + pitchOscLast = motion.curTransition.lastAnim.joints[11].pitch * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency + + motion.curTransition.lastAnim.joints[11].pitchPhase)) + + motion.curTransition.lastAnim.joints[11].pitchOffset; + + yawOscLast = motion.curTransition.lastAnim.joints[11].yaw * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency + + motion.curTransition.lastAnim.joints[11].yawPhase)) + + motion.curTransition.lastAnim.joints[11].yawOffset; + + rollOscLast = motion.curTransition.lastAnim.joints[11].roll * + Math.sin(filter.degToRad(motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency + + motion.curTransition.lastAnim.joints[11].rollPhase)) + + rollOffset = motion.curAnim.joints[11].rollOffset; + rollOffsetLast = motion.curTransition.lastAnim.joints[11].rollOffset; + } + + pitchOsc = (transProgress * pitchOsc) + ((1 - transProgress) * pitchOscLast); + yawOsc = (transProgress * yawOsc) + ((1 - transProgress) * yawOscLast); + rollOsc = (transProgress * rollOsc) + ((1 - transProgress) * rollOscLast); + + rollOffset = (transProgress * rollOffset) + ((1 - transProgress) * rollOffsetLast); + + } else { + + pitchOsc = motion.curAnim.joints[11].pitch * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[11].pitchPhase)) + + motion.curAnim.joints[11].pitchOffset; + + yawOsc = motion.curAnim.joints[11].yaw * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[11].yawPhase)) + + motion.curAnim.joints[11].yawOffset; + + rollOsc = motion.curAnim.joints[11].roll * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[11].rollPhase)); + + rollOffset = motion.curAnim.joints[11].rollOffset; + } + + // set the hand rotations + MyAvatar.setJointData("RightHand", + Quat.fromPitchYawRollDegrees(sideStepHandPitchSign * pitchOsc, yawOsc, rollOsc + rollOffset)); + MyAvatar.setJointData("LeftHand", + Quat.fromPitchYawRollDegrees(pitchOsc, -yawOsc, rollOsc - rollOffset)); + + } // end if (!motion.armsFree) + + // head and neck + if (motion.curTransition !== nullTransition) { + + if (motion.curTransition.walkingAtStart) { + + pitchOsc = 0.5 * motion.curAnim.joints[12].pitch * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency * 2) + + motion.curAnim.joints[12].pitchPhase)) + + motion.curAnim.joints[12].pitchOffset; + + yawOsc = 0.5 * motion.curAnim.joints[12].yaw * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency) + + motion.curAnim.joints[12].yawPhase)) + + motion.curAnim.joints[12].yawOffset; + + rollOsc = 0.5 * motion.curAnim.joints[12].roll * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curAnim.calibration.frequency) + + motion.curAnim.joints[12].rollPhase)) + + motion.curAnim.joints[12].rollOffset; + + pitchOscLast = 0.5 * motion.curTransition.lastAnim.joints[12].pitch * + Math.sin(filter.degToRad((motion.walkWheelPos * 2) + + motion.curTransition.lastAnim.joints[12].pitchPhase)) + + motion.curTransition.lastAnim.joints[12].pitchOffset; + + yawOscLast = 0.5 * motion.curTransition.lastAnim.joints[12].yaw * + Math.sin(filter.degToRad((motion.walkWheelPos) + + motion.curTransition.lastAnim.joints[12].yawPhase)) + + motion.curTransition.lastAnim.joints[12].yawOffset; + + rollOscLast = 0.5 * motion.curTransition.lastAnim.joints[12].roll * + Math.sin(filter.degToRad((motion.walkWheelPos) + + motion.curTransition.lastAnim.joints[12].rollPhase)) + + motion.curTransition.lastAnim.joints[12].rollOffset; + + } else { + + pitchOsc = 0.5 * motion.curAnim.joints[12].pitch * + Math.sin(filter.degToRad((cycle * adjFreq * 2) + + motion.curAnim.joints[12].pitchPhase)) + + motion.curAnim.joints[12].pitchOffset; + + yawOsc = 0.5 * motion.curAnim.joints[12].yaw * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[12].yawPhase)) + + motion.curAnim.joints[12].yawOffset; + + rollOsc = 0.5 * motion.curAnim.joints[12].roll * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[12].rollPhase)) + + motion.curAnim.joints[12].rollOffset; + + pitchOscLast = 0.5 * motion.curTransition.lastAnim.joints[12].pitch * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency * 2) + + motion.curTransition.lastAnim.joints[12].pitchPhase)) + + motion.curTransition.lastAnim.joints[12].pitchOffset; + + yawOscLast = 0.5 * motion.curTransition.lastAnim.joints[12].yaw * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency) + + motion.curTransition.lastAnim.joints[12].yawPhase)) + + motion.curTransition.lastAnim.joints[12].yawOffset; + + rollOscLast = 0.5 * motion.curTransition.lastAnim.joints[12].roll * + Math.sin(filter.degToRad((motion.cumulativeTime * + motion.curTransition.lastAnim.calibration.frequency) + + motion.curTransition.lastAnim.joints[12].rollPhase)) + + motion.curTransition.lastAnim.joints[12].rollOffset; + } + + pitchOsc = (transProgress * pitchOsc) + ((1 - transProgress) * pitchOscLast); + yawOsc = (transProgress * yawOsc) + ((1 - transProgress) * yawOscLast); + rollOsc = (transProgress * rollOsc) + ((1 - transProgress) * rollOscLast); + + } else { + + pitchOsc = 0.5 * motion.curAnim.joints[12].pitch * + Math.sin(filter.degToRad((cycle * adjFreq * 2) + + motion.curAnim.joints[12].pitchPhase)) + + motion.curAnim.joints[12].pitchOffset; + + yawOsc = 0.5 * motion.curAnim.joints[12].yaw * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[12].yawPhase)) + + motion.curAnim.joints[12].yawOffset; + + rollOsc = 0.5 * motion.curAnim.joints[12].roll * + Math.sin(filter.degToRad((cycle * adjFreq) + + motion.curAnim.joints[12].rollPhase)) + + motion.curAnim.joints[12].rollOffset; + } + + MyAvatar.setJointData("Head", Quat.fromPitchYawRollDegrees(pitchOsc, yawOsc, rollOsc)); + MyAvatar.setJointData("Neck", Quat.fromPitchYawRollDegrees(pitchOsc, yawOsc, rollOsc)); } -// mouse event handlers -var movingSliderOne = false; -var movingSliderTwo = false; -var movingSliderThree = false; -var movingSliderFour = false; -var movingSliderFive = false; -var movingSliderSix = false; -var movingSliderSeven = false; -var movingSliderEight = false; -var movingSliderNine = false; - -function mousePressEvent(event) { - - var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); - - // check for a character joint control click - switch (clickedOverlay) { - - case hideButton: - Overlays.editOverlay(hideButton, { visible: false } ); - Overlays.editOverlay(hideButtonSelected, { visible: true } ); - return; - - case backButton: - Overlays.editOverlay(backButton, { visible: false } ); - Overlays.editOverlay(backButtonSelected, { visible: true } ); - return; - - case controlsMinimisedTab: - // TODO: add visual user feedback for tab click - return; - - case footstepsBigButton: - playFootStepSounds = true; - Overlays.editOverlay(footstepsBigButtonSelected, { visible: true } ); - Overlays.editOverlay(footstepsBigButton, { visible: false } ); - return; - - case footstepsBigButtonSelected: - playFootStepSounds = false; - Overlays.editOverlay(footstepsBigButton, { visible: true } ); - Overlays.editOverlay(footstepsBigButtonSelected, { visible: false } ); - return; - - case femaleBigButton: - case maleBigButtonSelected: - avatarGender = FEMALE; - selectedWalk = femaleStrutWalk; - selectedStand = femaleStandOne; - selectedFlyUp = femaleFlyingUp; - selectedFly = femaleFlying; - selectedFlyDown = femaleFlyingDown; - selectedSideStepLeft = femaleSideStepLeft; - selectedSideStepRight = femaleSideStepRight; - Overlays.editOverlay(femaleBigButtonSelected, { visible: true } ); - Overlays.editOverlay(femaleBigButton, { visible: false } ); - Overlays.editOverlay(maleBigButton, { visible: true } ); - Overlays.editOverlay(maleBigButtonSelected, { visible: false } ); - return; - - case armsFreeBigButton: - armsFree = true; - Overlays.editOverlay(armsFreeBigButtonSelected, { visible: true } ); - Overlays.editOverlay(armsFreeBigButton, { visible: false } ); - return; - - case armsFreeBigButtonSelected: - armsFree = false; - Overlays.editOverlay(armsFreeBigButtonSelected, { visible: false } ); - Overlays.editOverlay(armsFreeBigButton, { visible: true } ); - return; - - case maleBigButton: - case femaleBigButtonSelected: - avatarGender = MALE; - selectedWalk = maleStrutWalk; - selectedStand = maleStandOne; - selectedFlyUp = maleFlyingUp; - selectedFly = maleFlying; - selectedFlyDown = maleFlyingDown; - selectedSideStepLeft = maleSideStepLeft; - selectedSideStepRight = maleSideStepRight; - Overlays.editOverlay(femaleBigButton, { visible: true } ); - Overlays.editOverlay(femaleBigButtonSelected, { visible: false } ); - Overlays.editOverlay(maleBigButtonSelected, { visible: true } ); - Overlays.editOverlay(maleBigButton, { visible: false } ); - return; - - - case strutWalkBigButton: - if(avatarGender===FEMALE) selectedWalk = femaleStrutWalk; - else selectedWalk = maleStrutWalk; - currentAnimation = selectedWalk; - showWalkStyleButtons(true); - return; - - case strutWalkBigButtonSelected: - - // toggle forwards / backwards walk display - if(principleDirection===DIRECTION_FORWARDS) { - principleDirection=DIRECTION_BACKWARDS; - } else principleDirection=DIRECTION_FORWARDS; - return; - - case sliderOne: - movingSliderOne = true; - return; - - case sliderTwo: - movingSliderTwo = true; - return; - - case sliderThree: - movingSliderThree = true; - return; - - case sliderFour: - movingSliderFour = true; - return; - - case sliderFive: - movingSliderFive = true; - return; - - case sliderSix: - movingSliderSix = true; - return; - - case sliderSeven: - movingSliderSeven = true; - return; - - case sliderEight: - movingSliderEight = true; - return; - - case sliderNine: - movingSliderNine = true; - return; - } - - if( INTERNAL_STATE===CONFIG_WALK_JOINTS || - INTERNAL_STATE===CONFIG_STANDING || - INTERNAL_STATE===CONFIG_FLYING || - INTERNAL_STATE===CONFIG_FLYING_UP || - INTERNAL_STATE===CONFIG_FLYING_DOWN || - INTERNAL_STATE===CONFIG_SIDESTEP_LEFT || - INTERNAL_STATE===CONFIG_SIDESTEP_RIGHT ) { - - // check for new joint selection and update display accordingly - var clickX = event.x - backgroundX - 75; - var clickY = event.y - backgroundY - 92; - - if(clickX>60&&clickX<120&&clickY>123&&clickY<155) { - initialiseJointsEditingPanel(0); - return; - } - else if(clickX>63&&clickX<132&&clickY>156&&clickY<202) { - initialiseJointsEditingPanel(1); - return; - } - else if(clickX>58&&clickX<137&&clickY>203&&clickY<250) { - initialiseJointsEditingPanel(2); - return; - } - else if(clickX>58&&clickX<137&&clickY>250&&clickY<265) { - initialiseJointsEditingPanel(3); - return; - } - else if(clickX>58&&clickX<137&&clickY>265&&clickY<280) { - initialiseJointsEditingPanel(4); - return; - } - else if(clickX>78&&clickX<121&&clickY>111&&clickY<128) { - initialiseJointsEditingPanel(5); - return; - } - else if(clickX>78&&clickX<128&&clickY>89&&clickY<111) { - initialiseJointsEditingPanel(6); - return; - } - else if(clickX>85&&clickX<118&&clickY>77&&clickY<94) { - initialiseJointsEditingPanel(7); - return; - } - else if(clickX>64&&clickX<125&&clickY>55&&clickY<77) { - initialiseJointsEditingPanel(8); - return; - } - else if((clickX>44&&clickX<73&&clickY>71&&clickY<94) - ||(clickX>125&&clickX<144&&clickY>71&&clickY<94)) { - initialiseJointsEditingPanel(9); - return; - } - else if((clickX>28&&clickX<57&&clickY>94&&clickY<119) - ||(clickX>137&&clickX<170&&clickY>97&&clickY<114)) { - initialiseJointsEditingPanel(10); - return; - } - else if((clickX>18&&clickX<37&&clickY>115&&clickY<136) - ||(clickX>157&&clickX<182&&clickY>115&&clickY<136)) { - initialiseJointsEditingPanel(11); - return; - } - else if(clickX>81&&clickX<116&&clickY>12&&clickY<53) { - initialiseJointsEditingPanel(12); - return; - } - } -} -function mouseMoveEvent(event) { - - // only need deal with slider changes - if(powerOn) { - - if( INTERNAL_STATE===CONFIG_WALK_JOINTS || - INTERNAL_STATE===CONFIG_STANDING || - INTERNAL_STATE===CONFIG_FLYING || - INTERNAL_STATE===CONFIG_FLYING_UP || - INTERNAL_STATE===CONFIG_FLYING_DOWN || - INTERNAL_STATE===CONFIG_SIDESTEP_LEFT || - INTERNAL_STATE===CONFIG_SIDESTEP_RIGHT ) { - - var thumbClickOffsetX = event.x - minSliderX; - var thumbPositionNormalised = thumbClickOffsetX / sliderRangeX; - if(thumbPositionNormalised<0) thumbPositionNormalised = 0; - if(thumbPositionNormalised>1) thumbPositionNormalised = 1; - var sliderX = thumbPositionNormalised * sliderRangeX ; // sets range - - if(movingSliderOne) { // currently selected joint pitch - Overlays.editOverlay(sliderOne, { x: sliderX + minSliderX} ); - currentAnimation.joints[selectedJointIndex].pitch = thumbPositionNormalised * sliderRanges.joints[selectedJointIndex].pitchRange; - } - else if(movingSliderTwo) { // currently selected joint yaw - Overlays.editOverlay(sliderTwo, { x: sliderX + minSliderX} ); - currentAnimation.joints[selectedJointIndex].yaw = thumbPositionNormalised * sliderRanges.joints[selectedJointIndex].yawRange; - } - else if(movingSliderThree) { // currently selected joint roll - Overlays.editOverlay(sliderThree, { x: sliderX + minSliderX} ); - currentAnimation.joints[selectedJointIndex].roll = thumbPositionNormalised * sliderRanges.joints[selectedJointIndex].rollRange; - } - else if(movingSliderFour) { // currently selected joint pitch phase - Overlays.editOverlay(sliderFour, { x: sliderX + minSliderX} ); - var newPhase = 360 * thumbPositionNormalised - 180; - currentAnimation.joints[selectedJointIndex].pitchPhase = newPhase; - } - else if(movingSliderFive) { // currently selected joint yaw phase; - Overlays.editOverlay(sliderFive, { x: sliderX + minSliderX} ); - var newPhase = 360 * thumbPositionNormalised - 180; - currentAnimation.joints[selectedJointIndex].yawPhase = newPhase; - } - else if(movingSliderSix) { // currently selected joint roll phase - Overlays.editOverlay(sliderSix, { x: sliderX + minSliderX} ); - var newPhase = 360 * thumbPositionNormalised - 180; - currentAnimation.joints[selectedJointIndex].rollPhase = newPhase; - } - else if(movingSliderSeven) { // currently selected joint pitch offset - Overlays.editOverlay(sliderSeven, { x: sliderX + minSliderX} ); // currently selected joint pitch offset - var newOffset = (thumbPositionNormalised-0.5) * 2 * sliderRanges.joints[selectedJointIndex].pitchOffsetRange; - currentAnimation.joints[selectedJointIndex].pitchOffset = newOffset; - } - else if(movingSliderEight) { // currently selected joint yaw offset - Overlays.editOverlay(sliderEight, { x: sliderX + minSliderX} ); // currently selected joint yaw offset - var newOffset = (thumbPositionNormalised-0.5) * 2 * sliderRanges.joints[selectedJointIndex].yawOffsetRange; - currentAnimation.joints[selectedJointIndex].yawOffset = newOffset; - } - else if(movingSliderNine) { // currently selected joint roll offset - Overlays.editOverlay(sliderNine, { x: sliderX + minSliderX} ); // currently selected joint roll offset - var newOffset = (thumbPositionNormalised-0.5) * 2 * sliderRanges.joints[selectedJointIndex].rollOffsetRange; - currentAnimation.joints[selectedJointIndex].rollOffset = newOffset; - } - } - else if(INTERNAL_STATE===CONFIG_WALK_TWEAKS) { - - var thumbClickOffsetX = event.x - minSliderX; - var thumbPositionNormalised = thumbClickOffsetX / sliderRangeX; - if(thumbPositionNormalised<0) thumbPositionNormalised = 0; - if(thumbPositionNormalised>1) thumbPositionNormalised = 1; - var sliderX = thumbPositionNormalised * sliderRangeX ; // sets range - - if(movingSliderOne) { // walk speed - paused = true; // avoid nasty jittering - Overlays.editOverlay(sliderOne, { x: sliderX + minSliderX} ); - currentAnimation.settings.baseFrequency = thumbPositionNormalised * MAX_WALK_SPEED; - } - else if(movingSliderTwo) { // take flight speed - Overlays.editOverlay(sliderTwo, { x: sliderX + minSliderX} ); - //currentAnimation.settings.takeFlightVelocity = thumbPositionNormalised * 300; - } - else if(movingSliderThree) { // hips sway - Overlays.editOverlay(sliderThree, { x: sliderX + minSliderX} ); - currentAnimation.joints[0].sway = thumbPositionNormalised * sliderRanges.joints[0].swayRange; - } - else if(movingSliderFour) { // hips bob - Overlays.editOverlay(sliderFour, { x: sliderX + minSliderX} ); - currentAnimation.joints[0].bob = thumbPositionNormalised * sliderRanges.joints[0].bobRange; - } - else if(movingSliderFive) { // hips thrust - Overlays.editOverlay(sliderFive, { x: sliderX + minSliderX} ); - currentAnimation.joints[0].thrust = thumbPositionNormalised * sliderRanges.joints[0].thrustRange; - } - else if(movingSliderSix) { // legs separation - Overlays.editOverlay(sliderSix, { x: sliderX + minSliderX} ); - currentAnimation.joints[1].rollOffset = (thumbPositionNormalised-0.5) * 2 * sliderRanges.joints[1].rollOffsetRange; - } - else if(movingSliderSeven) { // stride - Overlays.editOverlay(sliderSeven, { x: sliderX + minSliderX} ); - currentAnimation.joints[1].pitch = thumbPositionNormalised * sliderRanges.joints[1].pitchRange; - } - else if(movingSliderEight) { // arms swing = upper arms yaw - Overlays.editOverlay(sliderEight, { x: sliderX + minSliderX} ); - currentAnimation.joints[9].yaw = thumbPositionNormalised * sliderRanges.joints[9].yawRange; - } - else if(movingSliderNine) { // arms out = upper arms pitch offset - Overlays.editOverlay(sliderNine, { x: sliderX + minSliderX} ); - currentAnimation.joints[9].pitchOffset = (thumbPositionNormalised-0.5) * -2 * sliderRanges.joints[9].pitchOffsetRange; - } - } - } -} -function mouseReleaseEvent(event) { - - var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); - - if(paused) paused = false; - - if(clickedOverlay === offButton) { - powerOn = true; - Overlays.editOverlay(offButton, { visible: false } ); - Overlays.editOverlay(onButton, { visible: true } ); - stand(); - } - else if(clickedOverlay === hideButton || clickedOverlay === hideButtonSelected){ - Overlays.editOverlay(hideButton, { visible: true } ); - Overlays.editOverlay(hideButtonSelected, { visible: false } ); - minimised = true; - minimiseDialog(); - } - else if(clickedOverlay === controlsMinimisedTab) { - minimised = false; - minimiseDialog(); - } - else if(powerOn) { - - if(movingSliderOne) movingSliderOne = false; - else if(movingSliderTwo) movingSliderTwo = false; - else if(movingSliderThree) movingSliderThree = false; - else if(movingSliderFour) movingSliderFour = false; - else if(movingSliderFive) movingSliderFive = false; - else if(movingSliderSix) movingSliderSix = false; - else if(movingSliderSeven) movingSliderSeven = false; - else if(movingSliderEight) movingSliderEight = false; - else if(movingSliderNine) movingSliderNine = false; - else { - - switch(clickedOverlay) { - - case configWalkButtonSelected: - case configStandButtonSelected: - case configSideStepLeftButtonSelected: - case configSideStepRightButtonSelected: - case configFlyingButtonSelected: - case configFlyingUpButtonSelected: - case configFlyingDownButtonSelected: - case configWalkStylesButtonSelected: - case configWalkTweaksButtonSelected: - case configWalkJointsButtonSelected: - setInternalState(STANDING); - break; - - case onButton: - powerOn = false; - setInternalState(STANDING); - Overlays.editOverlay(offButton, { visible: true } ); - Overlays.editOverlay(onButton, { visible: false } ); - resetJoints(); - break; - - case backButton: - case backButtonSelected: - Overlays.editOverlay(backButton, { visible: false } ); - Overlays.editOverlay(backButtonSelected, { visible: false } ); - setInternalState(STANDING); - break; - - case configWalkStylesButton: - setInternalState(CONFIG_WALK_STYLES); - break; - - case configWalkTweaksButton: - setInternalState(CONFIG_WALK_TWEAKS); - break; - - case configWalkJointsButton: - setInternalState(CONFIG_WALK_JOINTS); - break; - - case configWalkButton: - setInternalState(CONFIG_WALK_STYLES); // set the default walk adjustment panel here (i.e. first panel shown when Walk button clicked) - break; - - case configStandButton: - setInternalState(CONFIG_STANDING); - break; - - case configSideStepLeftButton: - setInternalState(CONFIG_SIDESTEP_LEFT); - break; - - case configSideStepRightButton: - setInternalState(CONFIG_SIDESTEP_RIGHT); - break; - - case configFlyingButton: - setInternalState(CONFIG_FLYING); - break; - - case configFlyingUpButton: - setInternalState(CONFIG_FLYING_UP); - break; - - case configFlyingDownButton: - setInternalState(CONFIG_FLYING_DOWN); - break; - } - } - } -} -Controller.mouseMoveEvent.connect(mouseMoveEvent); -Controller.mousePressEvent.connect(mousePressEvent); -Controller.mouseReleaseEvent.connect(mouseReleaseEvent); - -// Script ending -Script.scriptEnding.connect(function() { - - // remove the background overlays - for(var i in backgroundOverlays) { - Overlays.deleteOverlay(backgroundOverlays[i]); - } - // remove the button overlays - for(var i in buttonOverlays) { - Overlays.deleteOverlay(buttonOverlays[i]); - } - // remove the slider thumb overlays - for(var i in sliderThumbOverlays) { - Overlays.deleteOverlay(sliderThumbOverlays[i]); - } - // remove the character joint control overlays - for(var i in bigButtonOverlays) { - Overlays.deleteOverlay(jointsControlOverlays[i]); - } - // remove the big button overlays - for(var i in bigButtonOverlays) { - Overlays.deleteOverlay(bigButtonOverlays[i]); - } - // remove the mimimised tab - Overlays.deleteOverlay(controlsMinimisedTab); - - // remove the walk wheel overlays - Overlays.deleteOverlay(walkWheelYLine); - Overlays.deleteOverlay(walkWheelZLine); - Overlays.deleteOverlay(walkWheelStats); - - // remove the debug stats overlays - Overlays.deleteOverlay(debugStats); - Overlays.deleteOverlay(debugStatsPeriodic); -}); - -var sideStep = 0.002; // i.e. 2mm increments whilst sidestepping - JS movement keys don't work well :-( -function keyPressEvent(event) { - - if (event.text == "q") { - // export currentAnimation as json string when q key is pressed. reformat result at http://www.freeformatter.com/json-formatter.html - print('\n'); - print('walk.js dumping animation: '+currentAnimation.name+'\n'); - print('\n'); - print(JSON.stringify(currentAnimation), null, '\t'); - } - else if (event.text == "t") { - statsOn = !statsOn; - Overlays.editOverlay(debugStats, {visible: statsOn}); - Overlays.editOverlay(debugStatsPeriodic, {visible: statsOn}); - Overlays.editOverlay(walkWheelStats, {visible: statsOn}); - Overlays.editOverlay(walkWheelYLine, {visible: statsOn}); - Overlays.editOverlay(walkWheelZLine, {visible: statsOn}); - } -} -Controller.keyPressEvent.connect(keyPressEvent); - -// get the list of joint names -var jointList = MyAvatar.getJointNames(); - -// clear the joint data so can calculate hips to feet distance -for(var i = 0 ; i < 5 ; i++) { - MyAvatar.setJointData(i, Quat.fromPitchYawRollDegrees(0,0,0)); -} -// used to position the visual representation of the walkwheel only -var hipsToFeetDistance = MyAvatar.getJointPosition("Hips").y - MyAvatar.getJointPosition("RightFoot").y; - -// This script is designed around the Finite State Machine (FSM) model, so to start things up we just select the STANDING state. -setInternalState(STANDING); \ No newline at end of file +// Begin by setting an internal state +state.setInternalState(state.STANDING); \ No newline at end of file diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 623631d5e5..53454d3d3b 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -49,7 +49,7 @@ const float PITCH_SPEED = 100.0f; // degrees/sec const float COLLISION_RADIUS_SCALAR = 1.2f; // pertains to avatar-to-avatar collisions const float COLLISION_RADIUS_SCALE = 0.125f; -const float MAX_WALKING_SPEED = 4.5f; +const float MAX_WALKING_SPEED = 2.5f; // human walking speed const float MAX_BOOST_SPEED = 0.5f * MAX_WALKING_SPEED; // keyboard motor gets additive boost below this speed const float MIN_AVATAR_SPEED = 0.05f; // speed is set to zero below this From a4db2441822a05ed5b7ff859830accc3642bfba9 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 7 Nov 2014 13:57:20 -0800 Subject: [PATCH 02/20] Mirror/warning fixes. --- interface/src/Application.cpp | 18 +++++++----------- interface/src/ui/RearMirrorTools.cpp | 7 +++++-- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e58f79cb5e..0740e424a1 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -108,7 +108,7 @@ static unsigned STARFIELD_SEED = 1; static const int BANDWIDTH_METER_CLICK_MAX_DRAG_LENGTH = 6; // farther dragged clicks are ignored -const unsigned MAXIMUM_CACHE_SIZE = 10737418240; // 10GB +const qint64 MAXIMUM_CACHE_SIZE = 10737418240L; // 10GB static QTimer* idleTimer = NULL; @@ -724,11 +724,11 @@ void Application::paintGL() { displaySide(*whichCamera); glPopMatrix(); - if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { - renderRearViewMirror(_mirrorViewRect); - - } else if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { + if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { _rearMirrorTools->render(true); + + } else if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { + renderRearViewMirror(_mirrorViewRect); } _glowEffect.render(); @@ -4314,8 +4314,6 @@ bool Application::isVSyncOn() const { if (wglewGetExtension("WGL_EXT_swap_control")) { int swapInterval = wglGetSwapIntervalEXT(); return (swapInterval > 0); - } else { - return true; } #elif defined(Q_OS_LINUX) // TODO: write the poper code for linux @@ -4326,10 +4324,9 @@ bool Application::isVSyncOn() const { } else { return true; } - */ -#else - return true; + */ #endif + return true; } bool Application::isVSyncEditable() const { @@ -4344,7 +4341,6 @@ bool Application::isVSyncEditable() const { return true; } */ -#else #endif return false; } diff --git a/interface/src/ui/RearMirrorTools.cpp b/interface/src/ui/RearMirrorTools.cpp index f4b0bb82b5..8423a9c432 100644 --- a/interface/src/ui/RearMirrorTools.cpp +++ b/interface/src/ui/RearMirrorTools.cpp @@ -40,7 +40,7 @@ RearMirrorTools::RearMirrorTools(QGLWidget* parent, QRect& bounds, QSettings* se _zoomHeadTextureId = _parent->bindTexture(QImage(Application::resourcesPath() + "images/plus.svg")); _zoomBodyTextureId = _parent->bindTexture(QImage(Application::resourcesPath() + "images/minus.svg")); - _shrinkIconRect = QRect(ICON_PADDING, ICON_PADDING, ICON_SIZE, ICON_SIZE); + _shrinkIconRect = QRect(ICON_PADDING, ICON_SIZE + ICON_PADDING, ICON_SIZE, ICON_SIZE); _closeIconRect = QRect(_bounds.left() + ICON_PADDING, _bounds.top() + ICON_PADDING, ICON_SIZE, ICON_SIZE); _resetIconRect = QRect(_bounds.width() - ICON_SIZE - ICON_PADDING, _bounds.top() + ICON_PADDING, ICON_SIZE, ICON_SIZE); _bodyZoomIconRect = QRect(_bounds.width() - ICON_SIZE - ICON_PADDING, _bounds.bottom() - ICON_PADDING - ICON_SIZE, ICON_SIZE, ICON_SIZE); @@ -106,7 +106,7 @@ bool RearMirrorTools::mousePressEvent(int x, int y) { } if (_fullScreen) { - if (_shrinkIconRect.contains(x, y)) { + if (_shrinkIconRect.contains(x, 2 * _shrinkIconRect.top() - y)) { _fullScreen = false; emit shrinkView(); return true; @@ -156,6 +156,9 @@ void RearMirrorTools::displayIcon(QRect bounds, QRect iconBounds, GLuint texture } glEnd(); glPopMatrix(); + + glMatrixMode(GL_MODELVIEW); + glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); } From 61e0660d6542dd196b62f96bfb75c0ee0f065e6d Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 7 Nov 2014 14:01:28 -0800 Subject: [PATCH 03/20] This actually seems to work differently on OS X versus Linux. --- interface/src/ui/RearMirrorTools.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/RearMirrorTools.cpp b/interface/src/ui/RearMirrorTools.cpp index 8423a9c432..fb6ef63647 100644 --- a/interface/src/ui/RearMirrorTools.cpp +++ b/interface/src/ui/RearMirrorTools.cpp @@ -40,7 +40,7 @@ RearMirrorTools::RearMirrorTools(QGLWidget* parent, QRect& bounds, QSettings* se _zoomHeadTextureId = _parent->bindTexture(QImage(Application::resourcesPath() + "images/plus.svg")); _zoomBodyTextureId = _parent->bindTexture(QImage(Application::resourcesPath() + "images/minus.svg")); - _shrinkIconRect = QRect(ICON_PADDING, ICON_SIZE + ICON_PADDING, ICON_SIZE, ICON_SIZE); + _shrinkIconRect = QRect(ICON_PADDING, ICON_PADDING, ICON_SIZE, ICON_SIZE); _closeIconRect = QRect(_bounds.left() + ICON_PADDING, _bounds.top() + ICON_PADDING, ICON_SIZE, ICON_SIZE); _resetIconRect = QRect(_bounds.width() - ICON_SIZE - ICON_PADDING, _bounds.top() + ICON_PADDING, ICON_SIZE, ICON_SIZE); _bodyZoomIconRect = QRect(_bounds.width() - ICON_SIZE - ICON_PADDING, _bounds.bottom() - ICON_PADDING - ICON_SIZE, ICON_SIZE, ICON_SIZE); @@ -106,7 +106,7 @@ bool RearMirrorTools::mousePressEvent(int x, int y) { } if (_fullScreen) { - if (_shrinkIconRect.contains(x, 2 * _shrinkIconRect.top() - y)) { + if (_shrinkIconRect.contains(x, y)) { _fullScreen = false; emit shrinkView(); return true; From b421ee92432e87e25aa0835ac14855c8fd21dd6f Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 7 Nov 2014 14:09:40 -0800 Subject: [PATCH 04/20] Fix for audio toolbox. --- interface/src/ui/ApplicationOverlay.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 4d2c710be7..e0aa1f3020 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -984,7 +984,9 @@ void ApplicationOverlay::renderAudioMeter() { const int AUDIO_METER_X = MIRROR_VIEW_LEFT_PADDING + MUTE_ICON_SIZE + AUDIO_METER_INSET + AUDIO_METER_GAP; int audioMeterY; - if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { + bool boxed = Menu::getInstance()->isOptionChecked(MenuOption::Mirror) && + !Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror); + if (boxed) { audioMeterY = MIRROR_VIEW_HEIGHT + AUDIO_METER_GAP + MUTE_ICON_PADDING; } else { audioMeterY = AUDIO_METER_GAP + MUTE_ICON_PADDING; @@ -1022,9 +1024,7 @@ void ApplicationOverlay::renderAudioMeter() { renderCollisionOverlay(glWidget->width(), glWidget->height(), magnitude, 1.0f); } - audio->renderToolBox(MIRROR_VIEW_LEFT_PADDING + AUDIO_METER_GAP, - audioMeterY, - Menu::getInstance()->isOptionChecked(MenuOption::Mirror)); + audio->renderToolBox(MIRROR_VIEW_LEFT_PADDING + AUDIO_METER_GAP, audioMeterY, boxed); audio->renderScope(glWidget->width(), glWidget->height()); From 70080124928ceb8875eeade003ac423591e7eace Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 7 Nov 2014 14:20:31 -0800 Subject: [PATCH 05/20] Trigger fixes. --- interface/src/Application.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0740e424a1..a2cfc8f024 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2009,25 +2009,17 @@ void Application::init() { void Application::closeMirrorView() { if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { - Menu::getInstance()->triggerOption(MenuOption::Mirror);; + Menu::getInstance()->triggerOption(MenuOption::Mirror); } } void Application::restoreMirrorView() { - if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { - Menu::getInstance()->triggerOption(MenuOption::Mirror);; - } - if (!Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { Menu::getInstance()->triggerOption(MenuOption::FullscreenMirror); } } void Application::shrinkMirrorView() { - if (!Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { - Menu::getInstance()->triggerOption(MenuOption::Mirror);; - } - if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { Menu::getInstance()->triggerOption(MenuOption::FullscreenMirror); } From cd110d60482feeddcf9a9b91ecdecba5ea354928 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 7 Nov 2014 14:35:01 -0800 Subject: [PATCH 06/20] Fix for invalid projection matrix on startup. --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a2cfc8f024..0afe011cd6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -786,7 +786,7 @@ void Application::updateProjectionMatrix(Camera& camera, bool updateViewFrustum) // Tell our viewFrustum about this change, using the application camera if (updateViewFrustum) { loadViewFrustum(camera, _viewFrustum); - computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); + _viewFrustum.computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); // If we're in Display Frustum mode, then we want to use the slightly adjust near/far clip values of the // _viewFrustumOffsetCamera, so that we can see more of the application content in the application's frustum From 6445b3aa5d46e4ff4d69211b6d00c924ddeb3197 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 7 Nov 2014 15:59:16 -0800 Subject: [PATCH 07/20] Linux warnings fixes. --- interface/src/Audio.cpp | 2 +- interface/src/Menu.cpp | 2 +- interface/src/gpu/Batch.cpp | 2 +- interface/src/gpu/GLBackend.cpp | 53 ++++++++++++++++--------------- interface/src/gpu/Resource.cpp | 2 ++ interface/src/renderer/Model.cpp | 4 --- interface/src/ui/TextRenderer.cpp | 6 ++-- libraries/avatars/src/Player.cpp | 6 ++-- libraries/avatars/src/Player.h | 6 ++-- 9 files changed, 41 insertions(+), 42 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 3039b7adfb..98ad76dcd2 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -544,7 +544,7 @@ void Audio::addReverb(int16_t* samplesData, int numSamples, QAudioFormat& audioF gverb_do(_gverb, value, &lValue, &rValue); // Mix, accounting for clipping, the left and right channels. Ignore the rest. - for (unsigned int j = sample; j < sample + audioFormat.channelCount(); j++) { + for (int j = sample; j < sample + audioFormat.channelCount(); j++) { if (j == sample) { // left channel int lResult = glm::clamp((int)(samplesData[j] * dryFraction + lValue * wetFraction), -32768, 32767); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 21c1cded88..cd074805b6 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -386,7 +386,7 @@ Menu::Menu() : #if defined(Q_OS_MAC) #else - QAction* vsyncAction = addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::RenderTargetFramerateVSyncOn, 0, true, this, SLOT(changeVSync())); + addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::RenderTargetFramerateVSyncOn, 0, true, this, SLOT(changeVSync())); #endif } diff --git a/interface/src/gpu/Batch.cpp b/interface/src/gpu/Batch.cpp index e02a0a551e..e176e1641a 100644 --- a/interface/src/gpu/Batch.cpp +++ b/interface/src/gpu/Batch.cpp @@ -106,7 +106,7 @@ void Batch::setInputStream(Slot startChannel, const BufferStream& stream) { const Buffers& buffers = stream.getBuffers(); const Offsets& offsets = stream.getOffsets(); const Offsets& strides = stream.getStrides(); - for (int i = 0; i < buffers.size(); i++) { + for (unsigned int i = 0; i < buffers.size(); i++) { setInputBuffer(startChannel + i, buffers[i], offsets[i], strides[i]); } } diff --git a/interface/src/gpu/GLBackend.cpp b/interface/src/gpu/GLBackend.cpp index 5e13d03ff4..5c2451d81f 100644 --- a/interface/src/gpu/GLBackend.cpp +++ b/interface/src/gpu/GLBackend.cpp @@ -31,15 +31,15 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = (&::gpu::GLBackend::do_glEnable), (&::gpu::GLBackend::do_glDisable), - + (&::gpu::GLBackend::do_glEnableClientState), (&::gpu::GLBackend::do_glDisableClientState), (&::gpu::GLBackend::do_glCullFace), (&::gpu::GLBackend::do_glAlphaFunc), - (&::gpu::GLBackend::do_glDepthFunc), - (&::gpu::GLBackend::do_glDepthMask), + (&::gpu::GLBackend::do_glDepthFunc), + (&::gpu::GLBackend::do_glDepthMask), (&::gpu::GLBackend::do_glDepthRange), (&::gpu::GLBackend::do_glBindBuffer), @@ -57,18 +57,18 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = (&::gpu::GLBackend::do_glPushMatrix), (&::gpu::GLBackend::do_glPopMatrix), (&::gpu::GLBackend::do_glMultMatrixf), - (&::gpu::GLBackend::do_glLoadMatrixf), - (&::gpu::GLBackend::do_glLoadIdentity), - (&::gpu::GLBackend::do_glRotatef), - (&::gpu::GLBackend::do_glScalef), - (&::gpu::GLBackend::do_glTranslatef), + (&::gpu::GLBackend::do_glLoadMatrixf), + (&::gpu::GLBackend::do_glLoadIdentity), + (&::gpu::GLBackend::do_glRotatef), + (&::gpu::GLBackend::do_glScalef), + (&::gpu::GLBackend::do_glTranslatef), - (&::gpu::GLBackend::do_glDrawArrays), + (&::gpu::GLBackend::do_glDrawArrays), (&::gpu::GLBackend::do_glDrawRangeElements), - - (&::gpu::GLBackend::do_glColorPointer), - (&::gpu::GLBackend::do_glNormalPointer), - (&::gpu::GLBackend::do_glTexCoordPointer), + + (&::gpu::GLBackend::do_glColorPointer), + (&::gpu::GLBackend::do_glNormalPointer), + (&::gpu::GLBackend::do_glTexCoordPointer), (&::gpu::GLBackend::do_glVertexPointer), (&::gpu::GLBackend::do_glVertexAttribPointer), @@ -77,7 +77,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = (&::gpu::GLBackend::do_glColor4f), - (&::gpu::GLBackend::do_glMaterialf), + (&::gpu::GLBackend::do_glMaterialf), (&::gpu::GLBackend::do_glMaterialfv), }; @@ -112,9 +112,8 @@ static const GLenum _elementTypeToGLType[NUM_TYPES]= { GLBackend::GLBackend() : - _inputFormat(0), - _inputAttributeActivation(0), _needInputFormatUpdate(true), + _inputFormat(0), _inputBuffersState(0), _inputBuffers(_inputBuffersState.size(), BufferPointer(0)), @@ -122,7 +121,8 @@ GLBackend::GLBackend() : _inputBufferStrides(_inputBuffersState.size(), 0), _indexBuffer(0), - _indexBufferOffset(0) + _indexBufferOffset(0), + _inputAttributeActivation(0) { } @@ -138,7 +138,7 @@ void GLBackend::renderBatch(Batch& batch) { GLBackend backend; - for (int i = 0; i < numCommands; i++) { + for (unsigned int i = 0; i < numCommands; i++) { CommandCall call = _commandCalls[(*command)]; (backend.*(call))(batch, *offset); command++; @@ -203,7 +203,7 @@ void GLBackend::do_drawIndexed(Batch& batch, uint32 paramOffset) { GLenum glType = _elementTypeToGLType[_indexBufferType]; - glDrawElements(mode, numIndices, glType, (GLvoid*)(startIndex + _indexBufferOffset)); + glDrawElements(mode, numIndices, glType, reinterpret_cast(startIndex + _indexBufferOffset)); CHECK_GL_ERROR(); } @@ -265,7 +265,7 @@ void GLBackend::updateInput() { } // Manage Activation what was and what is expected now - for (int i = 0; i < newActivation.size(); i++) { + for (unsigned int i = 0; i < newActivation.size(); i++) { bool newState = newActivation[i]; if (newState != _inputAttributeActivation[i]) { #if defined(SUPPORT_LEGACY_OPENGL) @@ -314,7 +314,7 @@ void GLBackend::updateInput() { CHECK_GL_ERROR(); _inputBuffersState[bufferNum] = false; - for (int i = 0; i < channel._slots.size(); i++) { + for (unsigned int i = 0; i < channel._slots.size(); i++) { const Stream::Attribute& attrib = attributes.at(channel._slots[i]); GLuint slot = attrib._slot; GLuint count = attrib._element.getDimensionCount(); @@ -325,16 +325,16 @@ void GLBackend::updateInput() { if (slot < NUM_CLASSIC_ATTRIBS) { switch (slot) { case Stream::POSITION: - glVertexPointer(count, type, stride, (GLvoid*)pointer); + glVertexPointer(count, type, stride, reinterpret_cast(pointer)); break; case Stream::NORMAL: - glNormalPointer(type, stride, (GLvoid*)pointer); + glNormalPointer(type, stride, reinterpret_cast(pointer)); break; case Stream::COLOR: - glColorPointer(count, type, stride, (GLvoid*)pointer); + glColorPointer(count, type, stride, reinterpret_cast(pointer)); break; case Stream::TEXCOORD: - glTexCoordPointer(count, type, stride, (GLvoid*)pointer); + glTexCoordPointer(count, type, stride, reinterpret_cast(pointer)); break; }; } else { @@ -342,7 +342,8 @@ void GLBackend::updateInput() { { #endif GLboolean isNormalized = attrib._element.isNormalized(); - glVertexAttribPointer(slot, count, type, isNormalized, stride, (GLvoid*)pointer); + glVertexAttribPointer(slot, count, type, isNormalized, stride, + reinterpret_cast(pointer)); } CHECK_GL_ERROR(); } diff --git a/interface/src/gpu/Resource.cpp b/interface/src/gpu/Resource.cpp index cd1b4ef84b..3a6e47a7ba 100644 --- a/interface/src/gpu/Resource.cpp +++ b/interface/src/gpu/Resource.cpp @@ -8,6 +8,8 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // + +#include "Context.h" #include "Resource.h" #include diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 38562df696..3137ab8369 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -479,9 +479,7 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g float bestDistance = std::numeric_limits::max(); float distanceToSubMesh; BoxFace subMeshFace; - BoxFace bestSubMeshFace; int subMeshIndex = 0; - int bestSubMeshIndex = -1; // If we hit the models box, then consider the submeshes... foreach(const AABox& subMeshBox, _calculatedMeshBoxes) { @@ -489,9 +487,7 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g if (subMeshBox.findRayIntersection(origin, direction, distanceToSubMesh, subMeshFace)) { if (distanceToSubMesh < bestDistance) { - bestSubMeshIndex = subMeshIndex; bestDistance = distanceToSubMesh; - bestSubMeshFace = subMeshFace; intersectedSomething = true; extraInfo = geometry.getModelNameOfMesh(subMeshIndex); } diff --git a/interface/src/ui/TextRenderer.cpp b/interface/src/ui/TextRenderer.cpp index 69df609ba9..fed041d6ea 100644 --- a/interface/src/ui/TextRenderer.cpp +++ b/interface/src/ui/TextRenderer.cpp @@ -129,7 +129,7 @@ int TextRenderer::draw(int x, int y, const char* str) { leftBottom.x, rightTop.y, ls, tt, }; const int NUM_COLOR_SCALARS_PER_GLYPH = 4; - unsigned int colorBuffer[NUM_COLOR_SCALARS_PER_GLYPH] = { compactColor, compactColor, compactColor, compactColor }; + int colorBuffer[NUM_COLOR_SCALARS_PER_GLYPH] = { compactColor, compactColor, compactColor, compactColor }; gpu::Buffer::Size offset = sizeof(vertexBuffer) * _numGlyphsBatched; gpu::Buffer::Size colorOffset = sizeof(colorBuffer) * _numGlyphsBatched; @@ -181,9 +181,9 @@ TextRenderer::TextRenderer(const Properties& properties) : _color(properties.color), _glyphsBuffer(new gpu::Buffer()), _glyphsColorBuffer(new gpu::Buffer()), - _numGlyphsBatched(0), _glyphsStreamFormat(new gpu::Stream::Format()), - _glyphsStream(new gpu::BufferStream()) + _glyphsStream(new gpu::BufferStream()), + _numGlyphsBatched(0) { _glyphsStreamFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::POS_XYZ), 0); const int NUM_POS_COORDS = 2; diff --git a/libraries/avatars/src/Player.cpp b/libraries/avatars/src/Player.cpp index 47d1b04421..56f820ab97 100644 --- a/libraries/avatars/src/Player.cpp +++ b/libraries/avatars/src/Player.cpp @@ -297,7 +297,7 @@ void Player::play() { _injector->setOptions(_options); } -void Player::setCurrentFrame(unsigned int currentFrame) { +void Player::setCurrentFrame(int currentFrame) { if (_recording && currentFrame >= _recording->getFrameNumber()) { stopPlaying(); return; @@ -314,7 +314,7 @@ void Player::setCurrentFrame(unsigned int currentFrame) { } } -void Player::setCurrentTime(unsigned int currentTime) { +void Player::setCurrentTime(int currentTime) { if (currentTime >= _recording->getLength()) { stopPlaying(); return; @@ -393,7 +393,7 @@ bool Player::computeCurrentFrame() { _currentFrame = 0; } - quint64 elapsed = glm::clamp(Player::elapsed() - _audioOffset, (qint64)0, (qint64)_recording->getLength()); + qint64 elapsed = glm::clamp(Player::elapsed() - _audioOffset, (qint64)0, (qint64)_recording->getLength()); while(_currentFrame >= 0 && _recording->getFrameTimestamp(_currentFrame) > elapsed) { --_currentFrame; diff --git a/libraries/avatars/src/Player.h b/libraries/avatars/src/Player.h index 043fcc4a25..7ed76fa495 100644 --- a/libraries/avatars/src/Player.h +++ b/libraries/avatars/src/Player.h @@ -44,8 +44,8 @@ public slots: void loadRecording(RecordingPointer recording); void play(); - void setCurrentFrame(unsigned int currentFrame); - void setCurrentTime(unsigned int currentTime); + void setCurrentFrame(int currentFrame); + void setCurrentTime(int currentTime); void setVolume(float volume); void setAudioOffset(int audioOffset); @@ -87,4 +87,4 @@ private: bool _useSkeletonURL; }; -#endif // hifi_Player_h \ No newline at end of file +#endif // hifi_Player_h From ef325db052aa4ec933c7e40c245753298ece25cb Mon Sep 17 00:00:00 2001 From: DaveDubUK Date: Sat, 8 Nov 2014 11:47:57 +0000 Subject: [PATCH 08/20] Formatting changes to walk.js 1.1 Minor formatting changes for HiFi coding standard compliance --- examples/libraries/walkApi.js | 51 ++-- examples/libraries/walkFilters.js | 48 ++-- examples/libraries/walkInterface.js | 156 ++++++------ examples/walk.js | 358 ++++++++++++++++------------ 4 files changed, 321 insertions(+), 292 deletions(-) diff --git a/examples/libraries/walkApi.js b/examples/libraries/walkApi.js index 90b9dad623..8f9bbfc36c 100644 --- a/examples/libraries/walkApi.js +++ b/examples/libraries/walkApi.js @@ -90,25 +90,22 @@ Motion = function() { for (var i = 0; i < this.avatarJointNames.length; i++) { - if (i > 17 || i < 34) + if (i > 17 || i < 34) { // left hand fingers MyAvatar.setJointData(this.avatarJointNames[i], Quat.fromPitchYawRollDegrees(16, 0, 0)); - - else if (i > 33 || i < 38) + } else if (i > 33 || i < 38) { // left hand thumb MyAvatar.setJointData(this.avatarJointNames[i], Quat.fromPitchYawRollDegrees(4, 0, 0)); - - else if (i > 41 || i < 58) + } else if (i > 41 || i < 58) { // right hand fingers MyAvatar.setJointData(this.avatarJointNames[i], Quat.fromPitchYawRollDegrees(16, 0, 0)); - - else if (i > 57 || i < 62) + } else if (i > 57 || i < 62) { // right hand thumb MyAvatar.setJointData(this.avatarJointNames[i], Quat.fromPitchYawRollDegrees(4, 0, 0)); - - else + } else { // zero out the remaining joints MyAvatar.clearJointData(this.avatarJointNames[i]); + } } } @@ -123,15 +120,16 @@ Motion = function() { this.walkWheelPos = 0; this.advanceWalkWheel = function(angle){ - this.walkWheelPos += angle; - if (motion.walkWheelPos >= 360) + if (motion.walkWheelPos >= 360) { this.walkWheelPos = this.walkWheelPos % 360; + } } // last frame history this.lastDirection = 0; this.lastVelocity = 0; + this.lastStrideLength = 0; // kept for use during transitions }; // end Motion constructor @@ -159,7 +157,7 @@ state = (function () { // status vars powerOn: true, minimised: true, - editing:false, + editing: false, editingTranslation: false, setInternalState: function(newInternalState) { @@ -284,10 +282,11 @@ state = (function () { if (motion.strideLength === 0) { motion.setGender(MALE); - if (motion.direction === BACKWARDS) + if (motion.direction === BACKWARDS) { motion.strideLength = motion.selWalk.calibration.strideLengthBackwards; - else + } else { motion.strideLength = motion.selWalk.calibration.strideLengthForwards; + } } return; } @@ -299,26 +298,30 @@ state = (function () { Transition = function(lastAnimation, nextAnimation, reachPoses, transitionDuration, easingLower, easingUpper) { this.lastAnim = lastAnimation; // name of last animation + this.nextAnimation = nextAnimation; // name of next animation if (lastAnimation === motion.selWalk || nextAnimation === motion.selSideStepLeft || - nextAnimation === motion.selSideStepRight) - this.walkingAtStart = true; // boolean - is the last animation a walking animation? - else - this.walkingAtStart = false; // boolean - is the last animation a walking animation? - this.nextAnimation = nextAnimation; // name of next animation + nextAnimation === motion.selSideStepRight) { + // boolean - is the last animation a walking animation? + this.walkingAtStart = true; + } else { + this.walkingAtStart = false; + } if (nextAnimation === motion.selWalk || nextAnimation === motion.selSideStepLeft || - nextAnimation === motion.selSideStepRight) - this.walkingAtEnd = true; // boolean - is the next animation a walking animation? - else - this.walkingAtEnd = false; // boolean - is the next animation a walking animation? + nextAnimation === motion.selSideStepRight) { + // boolean - is the next animation a walking animation? + this.walkingAtEnd = true; + } else { + this.walkingAtEnd = false; + } this.reachPoses = reachPoses; // placeholder / stub: array of reach poses for squash and stretch techniques this.transitionDuration = transitionDuration; // length of transition (seconds) this.easingLower = easingLower; // Bezier curve handle (normalised) this.easingUpper = easingUpper; // Bezier curve handle (normalised) this.startTime = new Date().getTime(); // Starting timestamp (seconds) this.progress = 0; // how far are we through the transition? - this.walkWheelIncrement = 6; // how much to turn the walkwheel each frame when transitioning to / from walking + this.walkWheelIncrement = 3; // how much to turn the walkwheel each frame when transitioning to / from walking this.walkWheelAdvance = 0; // how many degrees the walk wheel has been advanced during the transition this.walkStopAngle = 0; // what angle should we stop the walk cycle? diff --git a/examples/libraries/walkFilters.js b/examples/libraries/walkFilters.js index 608618e580..d587aea447 100644 --- a/examples/libraries/walkFilters.js +++ b/examples/libraries/walkFilters.js @@ -17,7 +17,6 @@ AveragingFilter = function(length) { this.pastValues = []; for(var i = 0; i < length; i++) { - this.pastValues.push(0); } @@ -26,17 +25,14 @@ AveragingFilter = function(length) { if (this.pastValues.length === 0 && arguments[0]) { return arguments[0]; - } - else if (arguments[0]) { - + } else if (arguments[0]) { // apply quick and simple LP filtering this.pastValues.push(arguments[0]); this.pastValues.shift(); var nextOutputValue = 0; for (var ea in this.pastValues) nextOutputValue += this.pastValues[ea]; return nextOutputValue / this.pastValues.length; - } - else return 0; + } else return 0; }; }; @@ -44,15 +40,10 @@ AveragingFilter = function(length) { // provides LP filtering with a more stable frequency / phase response ButterworthFilter = function(cutOff) { - switch(cutOff) { - - case 5: - - this.gain = 20.20612010; - this.coeffOne = -0.4775922501; - this.coeffTwo = 1.2796324250; - break; - } + // cut off frequency = 5Hz + this.gain = 20.20612010; + this.coeffOne = -0.4775922501; + this.coeffTwo = 1.2796324250; // initialise the arrays this.xv = []; @@ -95,39 +86,42 @@ WaveSynth = function(waveShape, numHarmonics, smoothing) { var harmonics = 0; var multiplier = 0; var iterations = this.numHarmonics * 2 + 2; - if (this.waveShape === TRIANGLE) iterations++; + if (this.waveShape === TRIANGLE) { + iterations++; + } for(var n = 2; n < iterations; n++) { switch(this.waveShape) { - case SAWTOOTH: + case SAWTOOTH: { multiplier = 1 / n; harmonics += multiplier * Math.sin(n * frequency); break; + } - case TRIANGLE: + case TRIANGLE: { if (n % 2 === 1) { - var mulitplier = 1 / (n * n); - - // multiply every (4n-1)th harmonic by -1 - if (n === 3 || n === 7 || n === 11 || n === 15) + // multiply (4n-1)th harmonics by -1 + if (n === 3 || n === 7 || n === 11 || n === 15) { mulitplier *= -1; + } harmonics += mulitplier * Math.sin(n * frequency); } break; + } - case SQUARE: + case SQUARE: { if (n % 2 === 1) { - multiplier = 1 / n; harmonics += multiplier * Math.sin(n * frequency); } break; + } } } @@ -216,13 +210,13 @@ filter = (function() { return pos; }, - // simple clipping filter (faster way to make square waveforms) + // simple clipping filter (clips bottom of wave only, special case for hips y-axis skeleton offset) clipTrough: function(inputValue, peak, strength) { var outputValue = inputValue * strength; - if (outputValue < -peak) + if (outputValue < -peak) { outputValue = -peak; - + } return outputValue; } } diff --git a/examples/libraries/walkInterface.js b/examples/libraries/walkInterface.js index 71e4462933..76b28498d8 100644 --- a/examples/libraries/walkInterface.js +++ b/examples/libraries/walkInterface.js @@ -1363,22 +1363,20 @@ walkInterface = (function() { function setBackground(backgroundID) { for (var i in _backgroundOverlays) { - if (_backgroundOverlays[i] === backgroundID) + if (_backgroundOverlays[i] === backgroundID) { Overlays.editOverlay(_backgroundOverlays[i], { visible: true }); - else Overlays.editOverlay(_backgroundOverlays[i], { - visible: false - }); + } else { + Overlays.editOverlay(_backgroundOverlays[i], { visible: false }); + } } }; // top row menu type buttons (on | walk | stand | fly | hide) function hideMenuButtons() { for (var i in _buttonOverlays) { - Overlays.editOverlay(_buttonOverlays[i], { - visible: false - }); + Overlays.editOverlay(_buttonOverlays[i], { visible: false }); } }; @@ -1401,9 +1399,7 @@ walkInterface = (function() { function setButtonOverlayVisible(buttonOverlayName) { for (var i in _buttonOverlays) { if (_buttonOverlays[i] === buttonOverlayName) { - Overlays.editOverlay(buttonOverlayName, { - visible: true - }); + Overlays.editOverlay(buttonOverlayName, { visible: true }); } } }; @@ -1484,13 +1480,13 @@ walkInterface = (function() { }); } - if (!showButtons) return; + if (!showButtons) { + return; + } // set all the non-selected ones to showing for (var i = 8; i < _bigbuttonOverlays.length; i += 2) { - Overlays.editOverlay(_bigbuttonOverlays[i], { - visible: true - }); + Overlays.editOverlay(_bigbuttonOverlays[i], { visible: true }); } // set the currently selected one @@ -1877,6 +1873,7 @@ walkInterface = (function() { _motion.curJointIndex = 4; initialiseJointsEditingPanel(); return; + } else if (clickX > 78 && clickX < 121 && clickY > 111 && clickY < 128) { _motion.curJointIndex = 5; initialiseJointsEditingPanel(); @@ -1962,7 +1959,7 @@ walkInterface = (function() { return; case _hideButton: - _hideButtonSelected: + case _hideButtonSelected: Overlays.editOverlay(_hideButton, { visible: false @@ -2084,8 +2081,11 @@ walkInterface = (function() { case _standardWalkBigButton: - if (_motion.avatarGender === FEMALE) _motion.selWalk = _motion.femaleStandardWalk; - else _motion.selWalk = _motion.maleStandardWalk; + if (_motion.avatarGender === FEMALE) { + _motion.selWalk = _motion.femaleStandardWalk; + } else { + _motion.selWalk = _motion.maleStandardWalk; + } _motion.curAnim = _motion.selWalk; initialiseWalkStylesPanel(true); return; @@ -2095,7 +2095,9 @@ walkInterface = (function() { // toggle forwards / backwards walk display if (_motion.direction === FORWARDS) { _motion.direction = BACKWARDS; - } else _motion.direction = FORWARDS; + } else { + _motion.direction = FORWARDS; + } return; case _sliderOne: @@ -2240,7 +2242,9 @@ walkInterface = (function() { // workaround for bug (https://worklist.net/20160) if ((event.x > 310 && event.x < 318 && event.y > 1350 && event.y < 1355) || - (event.x > 423 && event.x < 428 && event.y > 1505 && event.y < 1508 )) return; + (event.x > 423 && event.x < 428 && event.y > 1505 && event.y < 1508 )) { + return; + } if (_state.currentState === _state.EDIT_WALK_JOINTS || _state.currentState === _state.EDIT_STANDING || @@ -2252,8 +2256,11 @@ walkInterface = (function() { var thumbClickOffsetX = event.x - _minSliderX; var thumbPositionNormalised = thumbClickOffsetX / _sliderRangeX; - if (thumbPositionNormalised < 0) thumbPositionNormalised = 0; - if (thumbPositionNormalised > 1) thumbPositionNormalised = 1; + if (thumbPositionNormalised < 0) { + thumbPositionNormalised = 0; + } else if (thumbPositionNormalised > 1) { + thumbPositionNormalised = 1; + } var sliderX = thumbPositionNormalised * _sliderRangeX; // sets range if (_movingSliderOne) { @@ -2263,12 +2270,9 @@ walkInterface = (function() { x: sliderX + _minSliderX }); if (_state.editingTranslation) { - _motion.curAnim.joints[0].sway = thumbPositionNormalised * _sliderRanges.joints[0].swayRange; - } else { - _motion.curAnim.joints[_motion.curJointIndex].pitch = thumbPositionNormalised * _sliderRanges.joints[_motion.curJointIndex].pitchRange; } @@ -2280,12 +2284,9 @@ walkInterface = (function() { x: sliderX + _minSliderX }); if (_state.editingTranslation) { - _motion.curAnim.joints[0].bob = thumbPositionNormalised * _sliderRanges.joints[0].bobRange; - } else { - _motion.curAnim.joints[_motion.curJointIndex].yaw = thumbPositionNormalised * _sliderRanges.joints[_motion.curJointIndex].yawRange; } @@ -2297,12 +2298,9 @@ walkInterface = (function() { x: sliderX + _minSliderX }); if (_state.editingTranslation) { - _motion.curAnim.joints[0].thrust = thumbPositionNormalised * _sliderRanges.joints[0].thrustRange; - } else { - _motion.curAnim.joints[_motion.curJointIndex].roll = thumbPositionNormalised * _sliderRanges.joints[_motion.curJointIndex].rollRange; } @@ -2317,11 +2315,8 @@ walkInterface = (function() { var newPhase = 360 * thumbPositionNormalised - 180; if (_state.editingTranslation) { - _motion.curAnim.joints[0].swayPhase = newPhase; - } else { - _motion.curAnim.joints[_motion.curJointIndex].pitchPhase = newPhase; } @@ -2335,11 +2330,8 @@ walkInterface = (function() { var newPhase = 360 * thumbPositionNormalised - 180; if (_state.editingTranslation) { - _motion.curAnim.joints[0].bobPhase = newPhase; - } else { - _motion.curAnim.joints[_motion.curJointIndex].yawPhase = newPhase; } @@ -2353,11 +2345,8 @@ walkInterface = (function() { var newPhase = 360 * thumbPositionNormalised - 180; if (_state.editingTranslation) { - _motion.curAnim.joints[0].thrustPhase = newPhase; - } else { - _motion.curAnim.joints[_motion.curJointIndex].rollPhase = newPhase; } @@ -2368,13 +2357,10 @@ walkInterface = (function() { x: sliderX + _minSliderX }); if (_state.editingTranslation) { - var newOffset = (thumbPositionNormalised - 0.5) * 2 * _sliderRanges.joints[0].swayOffsetRange; _motion.curAnim.joints[0].swayOffset = newOffset; - } else { - var newOffset = (thumbPositionNormalised - 0.5) * 2 * _sliderRanges.joints[_motion.curJointIndex].pitchOffsetRange; _motion.curAnim.joints[_motion.curJointIndex].pitchOffset = newOffset; @@ -2387,13 +2373,10 @@ walkInterface = (function() { x: sliderX + _minSliderX }); if (_state.editingTranslation) { - var newOffset = (thumbPositionNormalised - 0.5) * 2 *_sliderRanges.joints[0].bobOffsetRange; _motion.curAnim.joints[0].bobOffset = newOffset; - } else { - var newOffset = (thumbPositionNormalised - 0.5) * 2 * _sliderRanges.joints[_motion.curJointIndex].yawOffsetRange; _motion.curAnim.joints[_motion.curJointIndex].yawOffset = newOffset; @@ -2406,21 +2389,19 @@ walkInterface = (function() { x: sliderX + _minSliderX }); if (_state.editingTranslation) { - var newOffset = (thumbPositionNormalised - 0.5) * 2 * _sliderRanges.joints[0].thrustOffsetRange; _motion.curAnim.joints[0].thrustOffset = newOffset; - } else { - var newOffset = (thumbPositionNormalised - 0.5) * 2 * _sliderRanges.joints[_motion.curJointIndex].rollOffsetRange; _motion.curAnim.joints[_motion.curJointIndex].rollOffset = newOffset; } } - } // end if editing joints - else if (_state.currentState === _state.EDIT_WALK_TWEAKS) { + // end if editing joints + + } else if (_state.currentState === _state.EDIT_WALK_TWEAKS) { // sliders for commonly required walk adjustments var thumbClickOffsetX = event.x - _minSliderX; @@ -2430,50 +2411,39 @@ walkInterface = (function() { var sliderX = thumbPositionNormalised * _sliderRangeX; // sets range if (_movingSliderOne) { - // walk speed Overlays.editOverlay(_sliderOne, { x: sliderX + _minSliderX }); _motion.curAnim.calibration.frequency = thumbPositionNormalised * MAX_WALK_SPEED; - } else if (_movingSliderTwo) { - // lean (hips pitch offset) Overlays.editOverlay(_sliderTwo, { x: sliderX + _minSliderX }); var newOffset = (thumbPositionNormalised - 0.5) * 2 * _sliderRanges.joints[0].pitchOffsetRange; _motion.curAnim.joints[0].pitchOffset = newOffset; - } else if (_movingSliderThree) { - // stride (upper legs pitch) Overlays.editOverlay(_sliderThree, { x: sliderX + _minSliderX }); _motion.curAnim.joints[1].pitch = thumbPositionNormalised * _sliderRanges.joints[1].pitchRange; - } else if (_movingSliderFour) { - // legs separation (upper legs roll) Overlays.editOverlay(_sliderFour, { x: sliderX + _minSliderX }); _motion.curAnim.joints[1].rollOffset = (thumbPositionNormalised - 0.5) * 2 * _sliderRanges.joints[1].rollOffsetRange; - } else if (_movingSliderFive) { - // legs forward (lower legs pitch offset) Overlays.editOverlay(_sliderFive, { x: sliderX + _minSliderX }); _motion.curAnim.joints[1].pitchOffset = (thumbPositionNormalised - 0.5) * 2 * _sliderRanges.joints[1].pitchOffsetRange; - } else if (_movingSliderSix) { - // lower legs splay (lower legs roll offset) Overlays.editOverlay(_sliderSix, { x: sliderX + _minSliderX @@ -2482,25 +2452,20 @@ walkInterface = (function() { 2 * _sliderRanges.joints[2].rollOffsetRange; } else if (_movingSliderSeven) { - // arms forward (upper arms yaw offset) Overlays.editOverlay(_sliderSeven, { x: sliderX + _minSliderX }); _motion.curAnim.joints[9].yawOffset = (thumbPositionNormalised - 0.5) * 2 * _sliderRanges.joints[9].yawOffsetRange; - } else if (_movingSliderEight) { - // arms out (upper arm pitch offset) Overlays.editOverlay(_sliderEight, { x: sliderX + _minSliderX }); _motion.curAnim.joints[9].pitchOffset = (thumbPositionNormalised - 0.5) * -2 * _sliderRanges.joints[9].pitchOffsetRange; - } else if (_movingSliderNine) { - // lower arms splay (lower arm pitch offset) Overlays.editOverlay(_sliderNine, { x: sliderX + _minSliderX @@ -2508,21 +2473,30 @@ walkInterface = (function() { _motion.curAnim.joints[10].pitchOffset = (thumbPositionNormalised - 0.5) * -2 * _sliderRanges.joints[10].pitchOffsetRange; } - } // if tweaking }; function mouseReleaseEvent(event) { - if (_movingSliderOne) _movingSliderOne = false; - else if (_movingSliderTwo) _movingSliderTwo = false; - else if (_movingSliderThree) _movingSliderThree = false; - else if (_movingSliderFour) _movingSliderFour = false; - else if (_movingSliderFive) _movingSliderFive = false; - else if (_movingSliderSix) _movingSliderSix = false; - else if (_movingSliderSeven) _movingSliderSeven = false; - else if (_movingSliderEight) _movingSliderEight = false; - else if (_movingSliderNine) _movingSliderNine = false; + if (_movingSliderOne) { + _movingSliderOne = false; + } else if (_movingSliderTwo) { + _movingSliderTwo = false; + } else if (_movingSliderThree) { + _movingSliderThree = false; + } else if (_movingSliderFour) { + _movingSliderFour = false; + } else if (_movingSliderFive) { + _movingSliderFive = false; + } else if (_movingSliderSix) { + _movingSliderSix = false; + } else if (_movingSliderSeven) { + _movingSliderSeven = false; + } else if (_movingSliderEight) { + _movingSliderEight = false; + } else if (_movingSliderNine) { + _movingSliderNine = false; + } }; Controller.mousePressEvent.connect(mousePressEvent); @@ -2575,7 +2549,7 @@ walkInterface = (function() { case _state.EDIT_WALK_STYLES: case _state.EDIT_WALK_TWEAKS: - case _state.EDIT_WALK_JOINTS: + case _state.EDIT_WALK_JOINTS: { hideMenuButtons(); initialiseFrontPanel(false); @@ -2604,10 +2578,11 @@ walkInterface = (function() { } else if (_state.currentState === _state.EDIT_WALK_JOINTS) { - if (_state.editingTranslation) + if (_state.editingTranslation) { setBackground(_controlsBackgroundWalkEditHipTrans); - else + } else { setBackground(_controlsBackgroundWalkEditJoints); + } initialiseWalkStylesPanel(false); setSliderThumbsVisible(true); @@ -2619,15 +2594,17 @@ walkInterface = (function() { setButtonOverlayVisible(_onButton); setButtonOverlayVisible(_backButton); return; + } case _state.EDIT_STANDING: case _state.EDIT_SIDESTEP_LEFT: - case _state.EDIT_SIDESTEP_RIGHT: + case _state.EDIT_SIDESTEP_RIGHT: { - if (_state.editingTranslation) + if (_state.editingTranslation) { setBackground(_controlsBackgroundWalkEditHipTrans); - else + } else { setBackground(_controlsBackgroundWalkEditJoints); + } hideMenuButtons(); initialiseWalkStylesPanel(false); initialiseFrontPanel(false); @@ -2654,10 +2631,11 @@ walkInterface = (function() { setButtonOverlayVisible(_onButton); setButtonOverlayVisible(_backButton); return; + } case _state.EDIT_FLYING: case _state.EDIT_FLYING_UP: - case _state.EDIT_FLYING_DOWN: + case _state.EDIT_FLYING_DOWN: { setBackground(_controlsBackgroundWalkEditJoints); hideMenuButtons(); @@ -2685,18 +2663,22 @@ walkInterface = (function() { setButtonOverlayVisible(_onButton); setButtonOverlayVisible(_backButton); return; + } case _state.STANDING: case _state.WALKING: case _state.FLYING: case _state.SIDE_STEP: - default: + default: { hideMenuButtons(); hideJointSelectors(); setBackground(_controlsBackground); - if (_state.powerOn) setButtonOverlayVisible(_onButton); - else setButtonOverlayVisible(_offButton); + if (_state.powerOn) { + setButtonOverlayVisible(_onButton); + } else { + setButtonOverlayVisible(_offButton); + } setButtonOverlayVisible(_configWalkButton); setButtonOverlayVisible(_configStandButton); setButtonOverlayVisible(_configFlyingButton); @@ -2705,9 +2687,9 @@ walkInterface = (function() { initialiseFrontPanel(true); initialiseWalkStylesPanel(false); return; + } } } } }; // end public methods (return) - })(); \ No newline at end of file diff --git a/examples/walk.js b/examples/walk.js index 1e1cd7748b..279516aa2a 100644 --- a/examples/walk.js +++ b/examples/walk.js @@ -14,7 +14,7 @@ // constants var MALE = 1; var FEMALE = 2; -var MAX_WALK_SPEED = 2.5; +var MAX_WALK_SPEED = 2.5;//3.919; var TAKE_FLIGHT_SPEED = 4.55; var TOP_SPEED = 300; var UP = 1; @@ -24,7 +24,7 @@ var RIGHT = 8; var FORWARDS = 16; var BACKWARDS = 32; -// ovelay images location +// location of animation files and overlay images var pathToAssets = 'http://s3.amazonaws.com/hifi-public/WalkScript/'; // load the UI @@ -51,7 +51,7 @@ var SAWTOOTH = 1; var TRIANGLE = 2; var SQUARE = 4; -// filters for synthesising more complex, natural waveforms +// various filters for synthesising more complex, natural waveforms var leanPitchFilter = filter.createAveragingFilter(15); var leanRollFilter = filter.createAveragingFilter(15); var hipsYawShaper = filter.createWaveSynth(TRIANGLE, 3, 2); @@ -71,56 +71,65 @@ Script.update.connect(function(deltaTime) { // check for editing modes first, as these require no positioning calculations switch (state.currentState) { - case state.EDIT_WALK_STYLES: + case state.EDIT_WALK_STYLES: { motion.curAnim = motion.selWalk; animateAvatar(deltaTime, speed); break; + } - case state.EDIT_WALK_TWEAKS: + case state.EDIT_WALK_TWEAKS: { motion.curAnim = motion.selWalk; animateAvatar(deltaTime, speed); break; + } - case state.EDIT_WALK_JOINTS: + case state.EDIT_WALK_JOINTS: { motion.curAnim = motion.selWalk; animateAvatar(deltaTime, speed); break; + } - case state.EDIT_STANDING: + case state.EDIT_STANDING: { motion.curAnim = motion.selStand; motion.direction = FORWARDS; animateAvatar(deltaTime, speed); break; + } - case state.EDIT_SIDESTEP_LEFT: + case state.EDIT_SIDESTEP_LEFT: { motion.curAnim = motion.selSideStepLeft; motion.direction = LEFT; animateAvatar(deltaTime, speed); break; + } - case state.EDIT_SIDESTEP_RIGHT: + case state.EDIT_SIDESTEP_RIGHT: { motion.curAnim = motion.selSideStepRight; motion.direction = RIGHT; animateAvatar(deltaTime, speed); break; + } - case state.EDIT_FLYING: + case state.EDIT_FLYING: { motion.curAnim = motion.selFly; motion.direction = FORWARDS; animateAvatar(deltaTime, speed); break; + } - case state.EDIT_FLYING_UP: + case state.EDIT_FLYING_UP: { motion.curAnim = motion.selFlyUp; motion.direction = UP; animateAvatar(deltaTime, speed); break; + } - case state.EDIT_FLYING_DOWN: + case state.EDIT_FLYING_DOWN: { motion.curAnim = motion.selFlyDown; motion.direction = DOWN; animateAvatar(deltaTime, speed); break; + } default: break; @@ -137,60 +146,78 @@ Script.update.connect(function(deltaTime) { return; } var localVelocity = {x: 0, y: 0, z: 0}; - if (speed > 0) + if (speed > 0) { localVelocity = Vec3.multiplyQbyV(Quat.inverse(MyAvatar.orientation), velocity); + } if (!state.editing) { // determine the candidate animation state var actionToTake = undefined; - if (speed < 0.05) actionToTake = state.STANDING; // as per MIN_AVATAR_SPEED, MyAvatar.cpp - else if (speed < TAKE_FLIGHT_SPEED) actionToTake = state.WALKING; - else if (speed >= TAKE_FLIGHT_SPEED) actionToTake = state.FLYING; + if (speed < 0.05) { + actionToTake = state.STANDING; + } else if (speed < TAKE_FLIGHT_SPEED) { + actionToTake = state.WALKING; + } else if (speed >= TAKE_FLIGHT_SPEED) { + actionToTake = state.FLYING; + } // determine the principle direction if (Math.abs(localVelocity.x) > Math.abs(localVelocity.y) && Math.abs(localVelocity.x) > Math.abs(localVelocity.z)) { - if (localVelocity.x < 0) motion.direction = LEFT; - else motion.direction = RIGHT; + if (localVelocity.x < 0) { + motion.direction = LEFT; + } else { + motion.direction = RIGHT; + } } else if (Math.abs(localVelocity.y) > Math.abs(localVelocity.x) && Math.abs(localVelocity.y) > Math.abs(localVelocity.z)) { - if (localVelocity.y > 0) motion.direction = UP; - else motion.direction = DOWN; + if (localVelocity.y > 0) { + motion.direction = UP; + } else { + motion.direction = DOWN; + } } else if (Math.abs(localVelocity.z) > Math.abs(localVelocity.x) && Math.abs(localVelocity.z) > Math.abs(localVelocity.y)) { - if (localVelocity.z < 0) motion.direction = FORWARDS; - else motion.direction = BACKWARDS; + if (localVelocity.z < 0) { + motion.direction = FORWARDS; + } else { + motion.direction = BACKWARDS; + } } // maybe at walking speed, but sideways? if (actionToTake === state.WALKING && - (motion.direction === LEFT || - motion.direction === RIGHT)) - actionToTake = state.SIDE_STEP; + (motion.direction === LEFT || + motion.direction === RIGHT)) { + actionToTake = state.SIDE_STEP; + } // maybe at walking speed, but flying up or down? if (actionToTake === state.WALKING && - (motion.direction === UP))// || - //motion.direction === DOWN)) - actionToTake = state.FLYING; + (motion.direction === UP || + motion.direction === DOWN)) { + actionToTake = state.FLYING; + } // select appropriate animation and initiate Transition if required + // note: The transitions are not compete, and are the most likely + // candidate for the next worklist item switch (actionToTake) { - case state.STANDING: + case state.STANDING: { // do we need to change state? if (state.currentState !== state.STANDING) { switch (motion.curAnim) { - case motion.selWalk: + case motion.selWalk: { // Walking to standing motion.curTransition = new Transition( @@ -200,57 +227,60 @@ Script.update.connect(function(deltaTime) { {x: 0.1, y: 0.5}, {x: -0.25, y: 1.22}); break; + } - case motion.selSideStepLeft: - case motion.selSideStepRight: + case motion.selFly: + case motion.selFlyUp: + case motion.selFlyDown: { - break; - - default: - - // flying to standing + // Flying to Standing motion.curTransition = new Transition( motion.curAnim, motion.selStand, - [], 0.25, + [], 0.5, {x: 0.5, y: 0.08}, {x: 0.28, y: 1}); break; + } + + default: + + break; } state.setInternalState(state.STANDING); motion.curAnim = motion.selStand; } animateAvatar(deltaTime, speed); break; + } - case state.WALKING: + case state.WALKING: { if (state.currentState !== state.WALKING) { - if (motion.direction === BACKWARDS) - motion.walkWheelPos = motion.selWalk.calibration.startAngleBackwards; - - else motion.walkWheelPos = motion.selWalk.calibration.startAngleForwards; + if (motion.direction === BACKWARDS) { + motion.walkWheelPos = motion.selWalk.calibration.startAngleBackwards; + } else { + motion.walkWheelPos = motion.selWalk.calibration.startAngleForwards; + } switch (motion.curAnim) { - case motion.selStand: + case motion.selStand: { // Standing to Walking motion.curTransition = new Transition( motion.curAnim, motion.selWalk, - [], 0.1, - {x: 0.5, y: 0.1}, - {x: 0.5, y: 0.9}); + [], 0.25, + {x: 0.5, y: 0.5}, + {x: 0.5, y: 0.5}); break; + } - case motion.selSideStepLeft: - case motion.selSideStepRight: - - break; - - default: + case motion.selFly: + case motion.selFlyUp: + case motion.selFlyDown: { // Flying to Walking motion.curTransition = new Transition( @@ -260,69 +290,56 @@ Script.update.connect(function(deltaTime) { {x: 0.24, y: 0.03}, {x: 0.42, y: 1.0}); break; + } + + default: + + break; } state.setInternalState(state.WALKING); } motion.curAnim = motion.selWalk; animateAvatar(deltaTime, speed); break; + } - case state.SIDE_STEP: + case state.SIDE_STEP: { var selSideStep = 0; if (motion.direction === LEFT) { - if (motion.lastDirection !== LEFT) + if (motion.lastDirection !== LEFT) { motion.walkWheelPos = motion.selSideStepLeft.calibration.cycleStart; + } selSideStep = motion.selSideStepLeft; } else { - if (motion.lastDirection !== RIGHT) + if (motion.lastDirection !== RIGHT) { motion.walkWheelPos = motion.selSideStepRight.calibration.cycleStart; + } selSideStep = motion.selSideStepRight; } if (state.currentState !== state.SIDE_STEP) { if (motion.direction === LEFT) { - motion.walkWheelPos = motion.selSideStepLeft.calibration.cycleStart; - switch (motion.curAnim) { - - case motion.selStand: - - break; - - default: - - break; - } - } else { - motion.walkWheelPos = motion.selSideStepRight.calibration.cycleStart; - switch (motion.curAnim) { - - case motion.selStand: - - break; - - default: - - break; - } } state.setInternalState(state.SIDE_STEP); } motion.curAnim = selSideStep; animateAvatar(deltaTime, speed); break; + } - case state.FLYING: + case state.FLYING: { - if (state.currentState !== state.FLYING) + if (state.currentState !== state.FLYING) { state.setInternalState(state.FLYING); + } // change animation for flying directly up or down if (motion.direction === UP) { @@ -332,23 +349,21 @@ Script.update.connect(function(deltaTime) { switch (motion.curAnim) { case motion.selStand: - case motion.selWalk: + case motion.selWalk: { // standing | walking to flying up motion.curTransition = new Transition( motion.curAnim, motion.selFlyUp, - [], 0.25, + [], 0.35, {x: 0.5, y: 0.08}, {x: 0.28, y: 1}); break; + } - case motion.selSideStepLeft: - case motion.selSideStepRight: - - break; - - default: + case motion.selFly: + case motion.selFlyUp: + case motion.selFlyDown: { motion.curTransition = new Transition( motion.curAnim, @@ -357,6 +372,11 @@ Script.update.connect(function(deltaTime) { {x: 0.5, y: 0.08}, {x: 0.28, y: 1}); break; + } + + default: + + break; } motion.curAnim = motion.selFlyUp; } @@ -368,7 +388,7 @@ Script.update.connect(function(deltaTime) { switch (motion.curAnim) { case motion.selStand: - case motion.selWalk: + case motion.selWalk: { motion.curTransition = new Transition( motion.curAnim, @@ -377,21 +397,24 @@ Script.update.connect(function(deltaTime) { {x: 0.5, y: 0.08}, {x: 0.28, y: 1}); break; + } - case motion.selSideStepLeft: - case motion.selSideStepRight: - - break; - - default: + case motion.selFly: + case motion.selFlyUp: + case motion.selFlyDown: { motion.curTransition = new Transition( motion.curAnim, motion.selFlyDown, - [], 0.5, + [], 0.45, {x: 0.5, y: 0.08}, {x: 0.28, y: 1}); break; + } + + default: + + break; } motion.curAnim = motion.selFlyDown; } @@ -403,7 +426,7 @@ Script.update.connect(function(deltaTime) { switch (motion.curAnim) { case motion.selStand: - case motion.selWalk: + case motion.selWalk: { motion.curTransition = new Transition( motion.curAnim, @@ -412,13 +435,11 @@ Script.update.connect(function(deltaTime) { {x: 1.44, y:0.24}, {x: 0.61, y:0.92}); break; + } - case motion.selSideStepLeft: - case motion.selSideStepRight: - - break; - - default: + case motion.selFly: + case motion.selFlyUp: + case motion.selFlyDown: { motion.curTransition = new Transition( motion.curAnim, @@ -427,12 +448,18 @@ Script.update.connect(function(deltaTime) { {x: 0.5, y: 0.08}, {x: 0.28, y: 1}); break; + } + + default: + + break; } motion.curAnim = motion.selFly; } } animateAvatar(deltaTime, speed); break; + }// end case state.FLYING } // end switch(actionToTake) @@ -447,17 +474,20 @@ Script.update.connect(function(deltaTime) { // the faster we go, the further we lean forward. the angle is calcualted here function getLeanPitch(speed) { - if (speed > TOP_SPEED) speed = TOP_SPEED; + if (speed > TOP_SPEED) { + speed = TOP_SPEED; + } var leanProgress = speed / TOP_SPEED; if (motion.direction === LEFT || - motion.direction === RIGHT) + motion.direction === RIGHT) { leanProgress = 0; - - else { + } else { var responseSharpness = 1.5; - if (motion.direction == BACKWARDS) responseSharpness = 3.0; + if (motion.direction == BACKWARDS) { + responseSharpness = 3.0; + } leanProgress = filter.bezier((1 - leanProgress), {x: 0, y: 0.0}, @@ -466,10 +496,11 @@ function getLeanPitch(speed) { {x: 1, y: 1}).y; // determine final pitch and adjust for direction of momentum - if (motion.direction === BACKWARDS) + if (motion.direction === BACKWARDS) { leanProgress = -motion.motionPitchMax * leanProgress; - else + } else { leanProgress = motion.motionPitchMax * leanProgress; + } } // return the smoothed response @@ -480,19 +511,26 @@ function getLeanPitch(speed) { function getLeanRoll(deltaTime, speed) { var leanRollProgress = 0; - if (speed > TOP_SPEED) speed = TOP_SPEED; + if (speed > TOP_SPEED) { + speed = TOP_SPEED; + } // what's our our anglular velocity? var angularVelocityMax = 70; // from observation var angularVelocity = filter.radToDeg(MyAvatar.getAngularVelocity().y); - if (angularVelocity > angularVelocityMax) angularVelocity = angularVelocityMax; - if (angularVelocity < -angularVelocityMax) angularVelocity = -angularVelocityMax; + if (angularVelocity > angularVelocityMax) { + angularVelocity = angularVelocityMax; + } + if (angularVelocity < -angularVelocityMax) { + angularVelocity = -angularVelocityMax; + } leanRollProgress = speed / TOP_SPEED; if (motion.direction !== LEFT && - motion.direction !== RIGHT) + motion.direction !== RIGHT) { leanRollProgress *= (Math.abs(angularVelocity) / angularVelocityMax); + } // apply our response curve leanRollProgress = filter.bezier((1 - leanRollProgress), @@ -502,14 +540,17 @@ function getLeanRoll(deltaTime, speed) { {x: 1, y: 1}).y; // which way to lean? var turnSign = -1; - if (angularVelocity < 0.001) turnSign = 1; + if (angularVelocity < 0.001) { + turnSign = 1; + } if (motion.direction === BACKWARDS || - motion.direction === LEFT) + motion.direction === LEFT) { turnSign *= -1; - + } if (motion.direction === LEFT || - motion.direction === RIGHT) + motion.direction === RIGHT) { leanRollProgress *= 2; + } // add damping with simple averaging filter leanRollProgress = leanRollFilter.process(turnSign * leanRollProgress); @@ -520,12 +561,13 @@ function playFootstep(side) { var options = new AudioInjectionOptions(); options.position = Camera.getPosition(); - options.volume = 0.2; + options.volume = 0.3; var soundNumber = 2; // 0 to 2 - if (side === RIGHT && motion.makesFootStepSounds) + if (side === RIGHT && motion.makesFootStepSounds) { Audio.playSound(walkAssets.footsteps[soundNumber + 1], options); - else if (side === LEFT && motion.makesFootStepSounds) + } else if (side === LEFT && motion.makesFootStepSounds) { Audio.playSound(walkAssets.footsteps[soundNumber], options); + } } // animate the avatar using sine wave generators. inspired by Victorian clockwork dolls @@ -545,13 +587,15 @@ function animateAvatar(deltaTime, speed) { // don't lean into the direction of travel if going up var leanMod = 1; - if (motion.direction === UP) + if (motion.direction === UP) { leanMod = 0; + } // adjust leaning direction for flying var flyingModifier = 1; - if (state.currentState.FLYING) + if (state.currentState.FLYING) { flyingModifier = -1; + } if (motion.curTransition !== nullTransition) { @@ -573,20 +617,22 @@ function animateAvatar(deltaTime, speed) { // find the closest stop point from the walk wheel's angle var angleToLeftStop = 180 - Math.abs(Math.abs(motion.walkWheelPos - leftStop) - 180); var angleToRightStop = 180 - Math.abs(Math.abs(motion.walkWheelPos - rightStop) - 180); - if (motion.walkWheelPos > angleToLeftStop) angleToLeftStop = 360 - angleToLeftStop; - if (motion.walkWheelPos > angleToRightStop) angleToRightStop = 360 - angleToRightStop; - + if (motion.walkWheelPos > angleToLeftStop) { + angleToLeftStop = 360 - angleToLeftStop; + } + if (motion.walkWheelPos > angleToRightStop) { + angleToRightStop = 360 - angleToRightStop; + } motion.curTransition.walkWheelIncrement = 3; // keep the walkwheel turning by setting the walkWheelIncrement // until our feet are tucked nicely underneath us. - if (angleToLeftStop < angleToRightStop) - + if (angleToLeftStop < angleToRightStop) { motion.curTransition.walkStopAngle = leftStop; - - else + } else { motion.curTransition.walkStopAngle = rightStop; + } } else { @@ -622,11 +668,9 @@ function animateAvatar(deltaTime, speed) { motion.curTransition.walkWheelIncrement = 0; } // keep turning walk wheel until both feet are below the avi - motion.advanceWalkWheel(motion.curTransition.walkWheelIncrement); - //motion.curTransition.walkWheelAdvance += motion.curTransition.walkWheelIncrement; - } - else motion.curTransition.walkWheelIncrement = 0; // sidestep + + } else motion.curTransition.walkWheelIncrement = 0; // sidestep } } } // end motion.curTransition !== nullTransition @@ -636,8 +680,9 @@ function animateAvatar(deltaTime, speed) { // if the timing's right, take a snapshot of the stride max and recalibrate var strideMaxAt = motion.curAnim.calibration.forwardStrideMaxAt; - if (motion.direction === BACKWARDS) + if (motion.direction === BACKWARDS) { strideMaxAt = motion.curAnim.calibration.backwardsStrideMaxAt; + } var tolerance = 1.0; if (motion.walkWheelPos < (strideMaxAt + tolerance) && @@ -648,18 +693,20 @@ function animateAvatar(deltaTime, speed) { var footLPos = MyAvatar.getJointPosition("LeftFoot"); motion.strideLength = Vec3.distance(footRPos, footLPos); - if (motion.direction === FORWARDS) + if (motion.direction === FORWARDS) { motion.curAnim.calibration.strideLengthForwards = motion.strideLength; - else if (motion.direction === BACKWARDS) + } else if (motion.direction === BACKWARDS) { motion.curAnim.calibration.strideLengthBackwards = motion.strideLength; + } } else { // use the saved value for stride length - if (motion.direction === FORWARDS) + if (motion.direction === FORWARDS) { motion.strideLength = motion.curAnim.calibration.strideLengthForwards; - else if (motion.direction === BACKWARDS) + } else if (motion.direction === BACKWARDS) { motion.strideLength = motion.curAnim.calibration.strideLengthBackwards; + } } } // end get walk stride length @@ -714,8 +761,9 @@ function animateAvatar(deltaTime, speed) { // if we are in an edit mode, we will need fake time to turn the wheel if (state.currentState !== state.WALKING && - state.currentState !== state.SIDE_STEP) + state.currentState !== state.SIDE_STEP) { degreesTurnedSinceLastFrame = motion.curAnim.calibration.frequency / 70; + } // advance the walk wheel the appropriate amount motion.advanceWalkWheel(degreesTurnedSinceLastFrame); @@ -758,12 +806,6 @@ function animateAvatar(deltaTime, speed) { var sideStepFootPitchModifier = 1; var sideStepHandPitchSign = 1; - // The below code should probably be optimised into some sort of loop, where - // the joints are iterated through. However, this has not been done yet, as there - // are still some quite fundamental changes to be made (e.g. turning on the spot - // animation and sidestepping transitions) so it's been left as is for ease of - // understanding and editing. - // calculate hips translation if (motion.curTransition !== nullTransition) { @@ -774,7 +816,9 @@ function animateAvatar(deltaTime, speed) { motion.curAnim.joints[0].swayPhase)) + motion.curAnim.joints[0].swayOffset; var bobPhase = motion.curAnim.joints[0].bobPhase; - if (motion.direction === motion.BACKWARDS) bobPhase += 90; + if (motion.direction === motion.BACKWARDS) { + bobPhase += 90; + } bobOsc = motion.curAnim.joints[0].bob * Math.sin(filter.degToRad(motion.cumulativeTime * motion.curAnim.calibration.frequency + bobPhase)) + @@ -792,7 +836,9 @@ function animateAvatar(deltaTime, speed) { motion.curTransition.lastAnim.joints[0].swayOffset; var bobPhaseLast = motion.curTransition.lastAnim.joints[0].bobPhase; - if (motion.direction === motion.BACKWARDS) bobPhaseLast +=90; + if (motion.direction === motion.BACKWARDS) { + bobPhaseLast +=90; + } bobOscLast = motion.curTransition.lastAnim.joints[0].bob * Math.sin(filter.degToRad(motion.walkWheelPos + bobPhaseLast)); bobOscLast = filter.clipTrough(bobOscLast, motion.curTransition.lastAnim.joints[0].bob , 2); @@ -804,15 +850,18 @@ function animateAvatar(deltaTime, speed) { motion.curTransition.lastAnim.joints[0].thrustPhase)) + motion.curTransition.lastAnim.joints[0].thrustOffset; - } // end if walking at start of transition - else { + // end if walking at start of transition + + } else { swayOsc = motion.curAnim.joints[0].sway * Math.sin(filter.degToRad(cycle * adjFreq + motion.curAnim.joints[0].swayPhase)) + motion.curAnim.joints[0].swayOffset; var bobPhase = motion.curAnim.joints[0].bobPhase; - if (motion.direction === motion.BACKWARDS) bobPhase += 90; + if (motion.direction === motion.BACKWARDS) { + bobPhase += 90; + } bobOsc = motion.curAnim.joints[0].bob * Math.sin(filter.degToRad(cycle * adjFreq * 2 + bobPhase)); if (state.currentState === state.WALKING || @@ -854,8 +903,9 @@ function animateAvatar(deltaTime, speed) { bobOsc = (transProgress * bobOsc) + ((1 - transProgress) * bobOscLast); thrustOsc = (transProgress * thrustOsc) + ((1 - transProgress) * thrustOscLast); - }// if current transition active - else { + // end if walking at start of transition + + } else { swayOsc = motion.curAnim.joints[0].sway * Math.sin(filter.degToRad(cycle * adjFreq + motion.curAnim.joints[0].swayPhase)) + From d0a535aee5ffa917c0195bda8c80b4b583663833 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 10 Nov 2014 10:18:37 -0800 Subject: [PATCH 09/20] Switch members in EntityItemProperties to hack around corruption bug --- libraries/entities/src/EntityItemProperties.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 3ae2aa9c7a..6b22e8cba9 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -383,8 +383,8 @@ private: // NOTE: The following are pseudo client only properties. They are only used in clients which can access // properties of model geometry. But these properties are not serialized like other properties. QVector _sittingPoints; - glm::vec3 _naturalDimensions; QStringList _textureNames; + glm::vec3 _naturalDimensions; }; Q_DECLARE_METATYPE(EntityItemProperties); QScriptValue EntityItemPropertiesToScriptValue(QScriptEngine* engine, const EntityItemProperties& properties); From fda5b0fffdec693a3a0a8cc2b2c6bd593531d5e2 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 10 Nov 2014 11:03:15 -0800 Subject: [PATCH 10/20] fix a bug produced by not setting deleted var to NULL --- libraries/octree/src/Octree.cpp | 5 +++-- libraries/voxels/src/VoxelTreeElement.h | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index ceda91a441..596dd7536c 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -547,11 +547,12 @@ void Octree::deleteOctalCodeFromTreeRecursion(OctreeElement* element, void* extr void Octree::eraseAllOctreeElements(bool createNewRoot) { delete _rootElement; // this will recurse and delete all children + _rootElement = NULL; + if (createNewRoot) { _rootElement = createNewElement(); - } else { - _rootElement = NULL; } + _isDirty = true; } diff --git a/libraries/voxels/src/VoxelTreeElement.h b/libraries/voxels/src/VoxelTreeElement.h index b1bff7dcc9..0ea91d4657 100644 --- a/libraries/voxels/src/VoxelTreeElement.h +++ b/libraries/voxels/src/VoxelTreeElement.h @@ -79,8 +79,8 @@ public: protected: - uint32_t _glBufferIndex : 24, /// Client only, vbo index for this voxel if being rendered, 3 bytes - _voxelSystemIndex : 8; /// Client only, index to the VoxelSystem rendering this voxel, 1 bytes + uint32_t _glBufferIndex : 24; /// Client only, vbo index for this voxel if being rendered, 3 bytes + uint32_t _voxelSystemIndex : 8; /// Client only, index to the VoxelSystem rendering this voxel, 1 bytes // Support for _voxelSystemIndex, we use these static member variables to track the VoxelSystems that are // in use by various voxel nodes. We map the VoxelSystem pointers into an 1 byte key, this limits us to at From 0c1ea784b9263f31726b79371476649e25aaabf7 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 10 Nov 2014 11:49:02 -0800 Subject: [PATCH 11/20] Set face. --- interface/src/renderer/Model.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 3137ab8369..8d426d067b 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -489,6 +489,7 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g if (distanceToSubMesh < bestDistance) { bestDistance = distanceToSubMesh; intersectedSomething = true; + face = subMeshFace; extraInfo = geometry.getModelNameOfMesh(subMeshIndex); } } From 5f89b6e00ea8f48f9b0814d07929a66dc99d61d3 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 10 Nov 2014 11:58:52 -0800 Subject: [PATCH 12/20] The spec actually says that the 'L' (should have been 'LL' anyway) isn't necessary; the compiler will know to read the constant as a long long. --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0afe011cd6..d54a638239 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -108,7 +108,7 @@ static unsigned STARFIELD_SEED = 1; static const int BANDWIDTH_METER_CLICK_MAX_DRAG_LENGTH = 6; // farther dragged clicks are ignored -const qint64 MAXIMUM_CACHE_SIZE = 10737418240L; // 10GB +const qint64 MAXIMUM_CACHE_SIZE = 10737418240; // 10GB static QTimer* idleTimer = NULL; From edec4d1298443c0a881d8776b813bf7d3d2a5c47 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 10 Nov 2014 14:10:29 -0800 Subject: [PATCH 13/20] Mixer send mute when if too noisy --- assignment-client/src/audio/AudioMixer.cpp | 24 +++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index e00d8eb44d..e7f41a2dca 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -141,11 +141,6 @@ int AudioMixer::addStreamToMixForListeningNodeWithStream(AudioMixerClientData* l return 0; } - // if the stream should be muted, bail - if (shouldMute(streamToAdd->getQuietestFrameLoudness())) { - return 0; - } - float bearingRelativeAngleToSource = 0.0f; float attenuationCoefficient = 1.0f; int numSamplesDelay = 0; @@ -722,6 +717,25 @@ void AudioMixer::run() { // That's how the popped audio data will be read for mixing (but only if the pop was successful) nodeData->checkBuffersBeforeFrameSend(); + // if the stream should be muted, send mute packet + if (shouldMute(nodeData->getAvatarAudioStream()->getQuietestFrameLoudness())) { + int headerSize = numBytesForPacketHeaderGivenPacketType(PacketTypeMuteEnvironment); + int packetSize = headerSize + sizeof(glm::vec3) + sizeof(float); + + // Fake data to force mute + glm::vec3 position = nodeData->getAvatarAudioStream()->getPosition(); + float radius = 1.0f; + + char* packet = (char*)malloc(packetSize); + populatePacketHeader(packet, PacketTypeMuteEnvironment); + memcpy(packet + headerSize, &position, sizeof(glm::vec3)); + memcpy(packet + headerSize + sizeof(glm::vec3), &radius, sizeof(float)); + + nodeList->writeDatagram(packet, packetSize, node); + free(packet); + } + + if (node->getType() == NodeType::Agent && node->getActiveSocket() && nodeData->getAvatarAudioStream()) { From 53fb9e9047a8f4c26590ab5746e552576913ed11 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 10 Nov 2014 14:11:17 -0800 Subject: [PATCH 14/20] make mute icon pulsate when muted --- interface/src/Audio.cpp | 19 ++++++++++++++++++- interface/src/Audio.h | 4 +++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 4a488bb296..7ff811b8aa 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -54,6 +54,9 @@ static const int APPROXIMATELY_30_SECONDS_OF_AUDIO_PACKETS = (int)(30.0f * 1000. // Mute icon configration static const int MUTE_ICON_SIZE = 24; +static const float PULSE_MIN = 0.0f; +static const float PULSE_MAX = 1.0f; +static const float PULSE_STEP = 0.05f; static const int RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES = 100; @@ -97,6 +100,9 @@ Audio::Audio(QObject* parent) : _muted(false), _reverb(false), _reverbOptions(&_scriptReverbOptions), + _gverb(NULL), + _iconColor(1.0f), + _iconPulseFactor(-1), _processSpatialAudio(false), _spatialAudioStart(0), _spatialAudioFinish(0), @@ -1390,11 +1396,22 @@ void Audio::renderToolBox(int x, int y, bool boxed) { _iconBounds = QRect(x, y, MUTE_ICON_SIZE, MUTE_ICON_SIZE); if (!_muted) { glBindTexture(GL_TEXTURE_2D, _micTextureId); + _iconColor = 1.0f; + _iconPulseFactor = -1; } else { glBindTexture(GL_TEXTURE_2D, _muteTextureId); + // Make muted icon pulsate + _iconColor += _iconPulseFactor * PULSE_STEP; + if (_iconColor >= PULSE_MAX) { + _iconColor = PULSE_MAX; + _iconPulseFactor = -1; + } else if (_iconColor <= PULSE_MIN) { + _iconColor = PULSE_MIN; + _iconPulseFactor = 1; + } } - glColor3f(1,1,1); + glColor3f(_iconColor, _iconColor, _iconColor); glBegin(GL_QUADS); glTexCoord2f(1, 1); diff --git a/interface/src/Audio.h b/interface/src/Audio.h index 6de7cf8d91..ebdf620121 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -248,11 +248,13 @@ private: AudioEffectOptions _scriptReverbOptions; AudioEffectOptions _zoneReverbOptions; AudioEffectOptions* _reverbOptions; - ty_gverb *_gverb; + ty_gverb* _gverb; GLuint _micTextureId; GLuint _muteTextureId; GLuint _boxTextureId; QRect _iconBounds; + float _iconColor; + int _iconPulseFactor; /// Audio callback in class context. inline void performIO(int16_t* inputLeft, int16_t* outputLeft, int16_t* outputRight); From 125ef0e3e2abc949a498c1a43d2f2640f995fd59 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 10 Nov 2014 15:12:40 -0800 Subject: [PATCH 15/20] make pulsate function into a cos --- interface/src/Audio.cpp | 33 +++++++++++++++++---------------- interface/src/Audio.h | 2 +- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 7ff811b8aa..87f7163cd5 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -54,9 +54,6 @@ static const int APPROXIMATELY_30_SECONDS_OF_AUDIO_PACKETS = (int)(30.0f * 1000. // Mute icon configration static const int MUTE_ICON_SIZE = 24; -static const float PULSE_MIN = 0.0f; -static const float PULSE_MAX = 1.0f; -static const float PULSE_STEP = 0.05f; static const int RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES = 100; @@ -102,7 +99,7 @@ Audio::Audio(QObject* parent) : _reverbOptions(&_scriptReverbOptions), _gverb(NULL), _iconColor(1.0f), - _iconPulseFactor(-1), + _iconPulseTimeReference(usecTimestampNow()), _processSpatialAudio(false), _spatialAudioStart(0), _spatialAudioFinish(0), @@ -1397,33 +1394,37 @@ void Audio::renderToolBox(int x, int y, bool boxed) { if (!_muted) { glBindTexture(GL_TEXTURE_2D, _micTextureId); _iconColor = 1.0f; - _iconPulseFactor = -1; } else { glBindTexture(GL_TEXTURE_2D, _muteTextureId); + // Make muted icon pulsate - _iconColor += _iconPulseFactor * PULSE_STEP; - if (_iconColor >= PULSE_MAX) { - _iconColor = PULSE_MAX; - _iconPulseFactor = -1; - } else if (_iconColor <= PULSE_MIN) { - _iconColor = PULSE_MIN; - _iconPulseFactor = 1; + static const float PULSE_MIN = 0.4f; + static const float PULSE_MAX = 1.0f; + static const float PULSE_FREQUENCY = 1.0f; // in Hz + qint64 now = usecTimestampNow(); + if (now - _iconPulseTimeReference > USECS_PER_SECOND) { + // Prevents t from getting too big, which would diminish glm::cos precision + _iconPulseTimeReference = now - ((now - _iconPulseTimeReference) % USECS_PER_SECOND); } + float t = (float)(now - _iconPulseTimeReference) / (float)USECS_PER_SECOND; + float pulseFactor = (glm::cos(t * PULSE_FREQUENCY * 2.0f * PI) + 1.0f) / 2.0f; + _iconColor = PULSE_MIN + (PULSE_MAX - PULSE_MIN) * pulseFactor; + } glColor3f(_iconColor, _iconColor, _iconColor); glBegin(GL_QUADS); - glTexCoord2f(1, 1); + glTexCoord2f(1.0f, 1.0f); glVertex2f(_iconBounds.left(), _iconBounds.top()); - glTexCoord2f(0, 1); + glTexCoord2f(0.0f, 1.0f); glVertex2f(_iconBounds.right(), _iconBounds.top()); - glTexCoord2f(0, 0); + glTexCoord2f(0.0f, 0.0f); glVertex2f(_iconBounds.right(), _iconBounds.bottom()); - glTexCoord2f(1, 0); + glTexCoord2f(1.0f, 0.0f); glVertex2f(_iconBounds.left(), _iconBounds.bottom()); glEnd(); diff --git a/interface/src/Audio.h b/interface/src/Audio.h index ebdf620121..ecbef026c4 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -254,7 +254,7 @@ private: GLuint _boxTextureId; QRect _iconBounds; float _iconColor; - int _iconPulseFactor; + qint64 _iconPulseTimeReference; /// Audio callback in class context. inline void performIO(int16_t* inputLeft, int16_t* outputLeft, int16_t* outputRight); From 02b401701f4e4770ea7ec71eb20ac07e180c9a81 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 10 Nov 2014 15:46:36 -0800 Subject: [PATCH 16/20] Set a minimum mute intervalle in the mixer --- assignment-client/src/audio/AudioMixer.cpp | 33 +++++++++++-------- .../src/audio/AvatarAudioStream.cpp | 3 +- .../src/audio/AvatarAudioStream.h | 7 +++- interface/src/Audio.cpp | 1 - 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index e7f41a2dca..c01afeda4e 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -719,20 +719,25 @@ void AudioMixer::run() { // if the stream should be muted, send mute packet if (shouldMute(nodeData->getAvatarAudioStream()->getQuietestFrameLoudness())) { - int headerSize = numBytesForPacketHeaderGivenPacketType(PacketTypeMuteEnvironment); - int packetSize = headerSize + sizeof(glm::vec3) + sizeof(float); - - // Fake data to force mute - glm::vec3 position = nodeData->getAvatarAudioStream()->getPosition(); - float radius = 1.0f; - - char* packet = (char*)malloc(packetSize); - populatePacketHeader(packet, PacketTypeMuteEnvironment); - memcpy(packet + headerSize, &position, sizeof(glm::vec3)); - memcpy(packet + headerSize + sizeof(glm::vec3), &radius, sizeof(float)); - - nodeList->writeDatagram(packet, packetSize, node); - free(packet); + static const int TIME_BETWEEN_MUTES = 5; // in secs + if (usecTimestampNow() - nodeData->getAvatarAudioStream()->getLastMuted() > + TIME_BETWEEN_MUTES * USECS_PER_SECOND) { + int headerSize = numBytesForPacketHeaderGivenPacketType(PacketTypeMuteEnvironment); + int packetSize = headerSize + sizeof(glm::vec3) + sizeof(float); + + // Fake data to force mute + glm::vec3 position = nodeData->getAvatarAudioStream()->getPosition(); + float radius = 1.0f; + + char* packet = (char*)malloc(packetSize); + populatePacketHeader(packet, PacketTypeMuteEnvironment); + memcpy(packet + headerSize, &position, sizeof(glm::vec3)); + memcpy(packet + headerSize + sizeof(glm::vec3), &radius, sizeof(float)); + + nodeList->writeDatagram(packet, packetSize, node); + nodeData->getAvatarAudioStream()->setLastMutedNow(); + free(packet); + } } diff --git a/assignment-client/src/audio/AvatarAudioStream.cpp b/assignment-client/src/audio/AvatarAudioStream.cpp index 90dcefa09d..cd67722a2e 100644 --- a/assignment-client/src/audio/AvatarAudioStream.cpp +++ b/assignment-client/src/audio/AvatarAudioStream.cpp @@ -14,7 +14,8 @@ #include "AvatarAudioStream.h" AvatarAudioStream::AvatarAudioStream(bool isStereo, const InboundAudioStream::Settings& settings) : - PositionalAudioStream(PositionalAudioStream::Microphone, isStereo, settings) + PositionalAudioStream(PositionalAudioStream::Microphone, isStereo, settings), + _lastMuted(usecTimestampNow()) { } diff --git a/assignment-client/src/audio/AvatarAudioStream.h b/assignment-client/src/audio/AvatarAudioStream.h index cc2ff1aca7..e1fb6dd486 100644 --- a/assignment-client/src/audio/AvatarAudioStream.h +++ b/assignment-client/src/audio/AvatarAudioStream.h @@ -19,13 +19,18 @@ class AvatarAudioStream : public PositionalAudioStream { public: AvatarAudioStream(bool isStereo, const InboundAudioStream::Settings& settings); - + + qint64 getLastMuted() const { return _lastMuted; } + void setLastMutedNow() { _lastMuted = usecTimestampNow(); } + private: // disallow copying of AvatarAudioStream objects AvatarAudioStream(const AvatarAudioStream&); AvatarAudioStream& operator= (const AvatarAudioStream&); int parseStreamProperties(PacketType type, const QByteArray& packetAfterSeqNum, int& numAudioSamples); + + qint64 _lastMuted; }; #endif // hifi_AvatarAudioStream_h diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 87f7163cd5..726d1e609a 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -1409,7 +1409,6 @@ void Audio::renderToolBox(int x, int y, bool boxed) { float t = (float)(now - _iconPulseTimeReference) / (float)USECS_PER_SECOND; float pulseFactor = (glm::cos(t * PULSE_FREQUENCY * 2.0f * PI) + 1.0f) / 2.0f; _iconColor = PULSE_MIN + (PULSE_MAX - PULSE_MIN) * pulseFactor; - } glColor3f(_iconColor, _iconColor, _iconColor); From a868661a255e875806f6a979cfab8924b56ee541 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 10 Nov 2014 15:51:31 -0800 Subject: [PATCH 17/20] Extra space --- assignment-client/src/audio/AudioMixer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index c01afeda4e..9131c99c6d 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -740,7 +740,6 @@ void AudioMixer::run() { } } - if (node->getType() == NodeType::Agent && node->getActiveSocket() && nodeData->getAvatarAudioStream()) { From dabc2b23a395bda91e4114df65072e0b98269e35 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 10 Nov 2014 15:51:56 -0800 Subject: [PATCH 18/20] add a guard in case local audio cannot be handled --- interface/src/Audio.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 4a488bb296..43ad14aca7 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -1342,8 +1342,11 @@ void Audio::handleAudioByteArray(const QByteArray& audioByteArray, const AudioIn QAudioOutput* localSoundOutput = new QAudioOutput(getNamedAudioDeviceForMode(QAudio::AudioOutput, _outputAudioDeviceName), localFormat, this); QIODevice* localIODevice = localSoundOutput->start(); - qDebug() << "Writing" << audioByteArray.size() << "to" << localIODevice; - localIODevice->write(audioByteArray); + if (localIODevice) { + localIODevice->write(audioByteArray); + } else { + qDebug() << "Unable to handle audio byte array. Error:" << localSoundOutput->error(); + } } else { qDebug() << "Audio::handleAudioByteArray called with an empty byte array. Sound is likely still downloading."; } From 05b361affc1d89bb65558cc66d4db99d93f99390 Mon Sep 17 00:00:00 2001 From: DaveDubUK Date: Tue, 11 Nov 2014 07:34:18 +0000 Subject: [PATCH 19/20] Formatting changes --- examples/libraries/walkApi.js | 28 +++--- examples/libraries/walkFilters.js | 33 +++---- examples/libraries/walkInterface.js | 139 ++++++++++++++-------------- 3 files changed, 100 insertions(+), 100 deletions(-) diff --git a/examples/libraries/walkApi.js b/examples/libraries/walkApi.js index 8f9bbfc36c..0175c56e18 100644 --- a/examples/libraries/walkApi.js +++ b/examples/libraries/walkApi.js @@ -1,7 +1,7 @@ // // walkObjects.js // -// version 1.000 +// version 1.001 // // Created by David Wooldridge, Autumn 2014 // @@ -93,19 +93,19 @@ Motion = function() { if (i > 17 || i < 34) { // left hand fingers MyAvatar.setJointData(this.avatarJointNames[i], Quat.fromPitchYawRollDegrees(16, 0, 0)); - } else if (i > 33 || i < 38) { + } else if (i > 33 || i < 38) { // left hand thumb MyAvatar.setJointData(this.avatarJointNames[i], Quat.fromPitchYawRollDegrees(4, 0, 0)); - } else if (i > 41 || i < 58) { + } else if (i > 41 || i < 58) { // right hand fingers MyAvatar.setJointData(this.avatarJointNames[i], Quat.fromPitchYawRollDegrees(16, 0, 0)); - } else if (i > 57 || i < 62) { + } else if (i > 57 || i < 62) { // right hand thumb MyAvatar.setJointData(this.avatarJointNames[i], Quat.fromPitchYawRollDegrees(4, 0, 0)); } else { // zero out the remaining joints MyAvatar.clearJointData(this.avatarJointNames[i]); - } + } } } @@ -123,7 +123,7 @@ Motion = function() { this.walkWheelPos += angle; if (motion.walkWheelPos >= 360) { this.walkWheelPos = this.walkWheelPos % 360; - } + } } // last frame history @@ -284,9 +284,9 @@ state = (function () { motion.setGender(MALE); if (motion.direction === BACKWARDS) { motion.strideLength = motion.selWalk.calibration.strideLengthBackwards; - } else { + } else { motion.strideLength = motion.selWalk.calibration.strideLengthForwards; - } + } } return; } @@ -302,19 +302,19 @@ Transition = function(lastAnimation, nextAnimation, reachPoses, transitionDurati if (lastAnimation === motion.selWalk || nextAnimation === motion.selSideStepLeft || nextAnimation === motion.selSideStepRight) { - // boolean - is the last animation a walking animation? + // boolean - is the last animation a walking animation? this.walkingAtStart = true; - } else { + } else { this.walkingAtStart = false; - } + } if (nextAnimation === motion.selWalk || nextAnimation === motion.selSideStepLeft || nextAnimation === motion.selSideStepRight) { - // boolean - is the next animation a walking animation? + // boolean - is the next animation a walking animation? this.walkingAtEnd = true; - } else { + } else { this.walkingAtEnd = false; - } + } this.reachPoses = reachPoses; // placeholder / stub: array of reach poses for squash and stretch techniques this.transitionDuration = transitionDuration; // length of transition (seconds) this.easingLower = easingLower; // Bezier curve handle (normalised) diff --git a/examples/libraries/walkFilters.js b/examples/libraries/walkFilters.js index d587aea447..98a7562bb4 100644 --- a/examples/libraries/walkFilters.js +++ b/examples/libraries/walkFilters.js @@ -1,7 +1,7 @@ // // walkFilters.js // -// version 1.000 +// version 1.001 // // Created by David Wooldridge, Autumn 2014 // @@ -32,7 +32,9 @@ AveragingFilter = function(length) { var nextOutputValue = 0; for (var ea in this.pastValues) nextOutputValue += this.pastValues[ea]; return nextOutputValue / this.pastValues.length; - } else return 0; + } else { + return 0; + } }; }; @@ -40,10 +42,10 @@ AveragingFilter = function(length) { // provides LP filtering with a more stable frequency / phase response ButterworthFilter = function(cutOff) { - // cut off frequency = 5Hz - this.gain = 20.20612010; - this.coeffOne = -0.4775922501; - this.coeffTwo = 1.2796324250; + // cut off frequency = 5Hz + this.gain = 20.20612010; + this.coeffOne = -0.4775922501; + this.coeffTwo = 1.2796324250; // initialise the arrays this.xv = []; @@ -87,8 +89,8 @@ WaveSynth = function(waveShape, numHarmonics, smoothing) { var multiplier = 0; var iterations = this.numHarmonics * 2 + 2; if (this.waveShape === TRIANGLE) { - iterations++; - } + iterations++; + } for(var n = 2; n < iterations; n++) { @@ -99,7 +101,7 @@ WaveSynth = function(waveShape, numHarmonics, smoothing) { multiplier = 1 / n; harmonics += multiplier * Math.sin(n * frequency); break; - } + } case TRIANGLE: { @@ -108,11 +110,11 @@ WaveSynth = function(waveShape, numHarmonics, smoothing) { // multiply (4n-1)th harmonics by -1 if (n === 3 || n === 7 || n === 11 || n === 15) { mulitplier *= -1; - } + } harmonics += mulitplier * Math.sin(n * frequency); } break; - } + } case SQUARE: { @@ -121,7 +123,7 @@ WaveSynth = function(waveShape, numHarmonics, smoothing) { harmonics += multiplier * Math.sin(n * frequency); } break; - } + } } } @@ -141,10 +143,9 @@ HarmonicsFilter = function(magnitudes, phaseAngles) { var harmonics = 0; var numHarmonics = magnitudes.length; - for(var n = 0; n < numHarmonics; n++) - + for(var n = 0; n < numHarmonics; n++) { harmonics += this.magnitudes[n] * Math.cos(n * twoPiFT - this.phaseAngles[n]); - + } return harmonics; }; }; @@ -216,7 +217,7 @@ filter = (function() { var outputValue = inputValue * strength; if (outputValue < -peak) { outputValue = -peak; - } + } return outputValue; } } diff --git a/examples/libraries/walkInterface.js b/examples/libraries/walkInterface.js index 76b28498d8..7b7a23a584 100644 --- a/examples/libraries/walkInterface.js +++ b/examples/libraries/walkInterface.js @@ -1,7 +1,7 @@ // // walkInterface.js // -// version 1.000 +// version 1.001 // // Created by David Wooldridge, Autumn 2014 // @@ -1367,9 +1367,9 @@ walkInterface = (function() { Overlays.editOverlay(_backgroundOverlays[i], { visible: true }); - } else { - Overlays.editOverlay(_backgroundOverlays[i], { visible: false }); - } + } else { + Overlays.editOverlay(_backgroundOverlays[i], { visible: false }); + } } }; @@ -1481,8 +1481,8 @@ walkInterface = (function() { } if (!showButtons) { - return; - } + return; + } // set all the non-selected ones to showing for (var i = 8; i < _bigbuttonOverlays.length; i += 2) { @@ -2082,10 +2082,10 @@ walkInterface = (function() { case _standardWalkBigButton: if (_motion.avatarGender === FEMALE) { - _motion.selWalk = _motion.femaleStandardWalk; - } else { - _motion.selWalk = _motion.maleStandardWalk; - } + _motion.selWalk = _motion.femaleStandardWalk; + } else { + _motion.selWalk = _motion.maleStandardWalk; + } _motion.curAnim = _motion.selWalk; initialiseWalkStylesPanel(true); return; @@ -2096,8 +2096,8 @@ walkInterface = (function() { if (_motion.direction === FORWARDS) { _motion.direction = BACKWARDS; } else { - _motion.direction = FORWARDS; - } + _motion.direction = FORWARDS; + } return; case _sliderOne: @@ -2159,7 +2159,7 @@ walkInterface = (function() { // exit edit modes _motion.curAnim = _motion.selStand; _state.setInternalState(_state.STANDING); - break; + return; case _onButton: @@ -2171,8 +2171,7 @@ walkInterface = (function() { Overlays.editOverlay(_onButton, { visible: false }); - //resetJoints(); - break; + return; case _backButton: case _backButtonSelected: @@ -2184,57 +2183,57 @@ walkInterface = (function() { visible: false }); _state.setInternalState(_state.STANDING); - break; + return; case _configWalkStylesButton: _state.setInternalState(_state.EDIT_WALK_STYLES); - break; + return; case _configWalkTweaksButton: _state.setInternalState(_state.EDIT_WALK_TWEAKS); - break; + return; case _configWalkJointsButton: _state.setInternalState(_state.EDIT_WALK_JOINTS); - break; + return; case _configWalkButton: _state.setInternalState(_state.EDIT_WALK_STYLES); - break; + return; case _configStandButton: _state.setInternalState(_state.EDIT_STANDING); - break; + return; case _configSideStepLeftButton: - _state.setInternalState(_state.EDIT_SIDESTEP_LEFT); - break; + _state.setInternalState(_state.EDIT_SIDESTEP_LEFT); + return; case _configSideStepRightButton: _state.setInternalState(_state.EDIT_SIDESTEP_RIGHT); - break; + return; case _configFlyingButton: _state.setInternalState(_state.EDIT_FLYING); - break; + return; case _configFlyingUpButton: _state.setInternalState(_state.EDIT_FLYING_UP); - break; + return; case _configFlyingDownButton: _state.setInternalState(_state.EDIT_FLYING_DOWN); - break; + return; } }; @@ -2243,8 +2242,8 @@ walkInterface = (function() { // workaround for bug (https://worklist.net/20160) if ((event.x > 310 && event.x < 318 && event.y > 1350 && event.y < 1355) || (event.x > 423 && event.x < 428 && event.y > 1505 && event.y < 1508 )) { - return; - } + return; + } if (_state.currentState === _state.EDIT_WALK_JOINTS || _state.currentState === _state.EDIT_STANDING || @@ -2257,10 +2256,10 @@ walkInterface = (function() { var thumbClickOffsetX = event.x - _minSliderX; var thumbPositionNormalised = thumbClickOffsetX / _sliderRangeX; if (thumbPositionNormalised < 0) { - thumbPositionNormalised = 0; - } else if (thumbPositionNormalised > 1) { - thumbPositionNormalised = 1; - } + thumbPositionNormalised = 0; + } else if (thumbPositionNormalised > 1) { + thumbPositionNormalised = 1; + } var sliderX = thumbPositionNormalised * _sliderRangeX; // sets range if (_movingSliderOne) { @@ -2358,11 +2357,11 @@ walkInterface = (function() { }); if (_state.editingTranslation) { var newOffset = (thumbPositionNormalised - 0.5) * - 2 * _sliderRanges.joints[0].swayOffsetRange; + 2 * _sliderRanges.joints[0].swayOffsetRange; _motion.curAnim.joints[0].swayOffset = newOffset; } else { var newOffset = (thumbPositionNormalised - 0.5) * - 2 * _sliderRanges.joints[_motion.curJointIndex].pitchOffsetRange; + 2 * _sliderRanges.joints[_motion.curJointIndex].pitchOffsetRange; _motion.curAnim.joints[_motion.curJointIndex].pitchOffset = newOffset; } @@ -2374,11 +2373,11 @@ walkInterface = (function() { }); if (_state.editingTranslation) { var newOffset = (thumbPositionNormalised - 0.5) * - 2 *_sliderRanges.joints[0].bobOffsetRange; + 2 *_sliderRanges.joints[0].bobOffsetRange; _motion.curAnim.joints[0].bobOffset = newOffset; } else { var newOffset = (thumbPositionNormalised - 0.5) * - 2 * _sliderRanges.joints[_motion.curJointIndex].yawOffsetRange; + 2 * _sliderRanges.joints[_motion.curJointIndex].yawOffsetRange; _motion.curAnim.joints[_motion.curJointIndex].yawOffset = newOffset; } @@ -2390,16 +2389,16 @@ walkInterface = (function() { }); if (_state.editingTranslation) { var newOffset = (thumbPositionNormalised - 0.5) * - 2 * _sliderRanges.joints[0].thrustOffsetRange; + 2 * _sliderRanges.joints[0].thrustOffsetRange; _motion.curAnim.joints[0].thrustOffset = newOffset; } else { var newOffset = (thumbPositionNormalised - 0.5) * - 2 * _sliderRanges.joints[_motion.curJointIndex].rollOffsetRange; + 2 * _sliderRanges.joints[_motion.curJointIndex].rollOffsetRange; _motion.curAnim.joints[_motion.curJointIndex].rollOffset = newOffset; } } - // end if editing joints + // end if editing joints } else if (_state.currentState === _state.EDIT_WALK_TWEAKS) { @@ -2479,24 +2478,24 @@ walkInterface = (function() { function mouseReleaseEvent(event) { if (_movingSliderOne) { - _movingSliderOne = false; - } else if (_movingSliderTwo) { - _movingSliderTwo = false; - } else if (_movingSliderThree) { - _movingSliderThree = false; - } else if (_movingSliderFour) { - _movingSliderFour = false; - } else if (_movingSliderFive) { - _movingSliderFive = false; - } else if (_movingSliderSix) { - _movingSliderSix = false; - } else if (_movingSliderSeven) { - _movingSliderSeven = false; - } else if (_movingSliderEight) { - _movingSliderEight = false; - } else if (_movingSliderNine) { - _movingSliderNine = false; - } + _movingSliderOne = false; + } else if (_movingSliderTwo) { + _movingSliderTwo = false; + } else if (_movingSliderThree) { + _movingSliderThree = false; + } else if (_movingSliderFour) { + _movingSliderFour = false; + } else if (_movingSliderFive) { + _movingSliderFive = false; + } else if (_movingSliderSix) { + _movingSliderSix = false; + } else if (_movingSliderSeven) { + _movingSliderSeven = false; + } else if (_movingSliderEight) { + _movingSliderEight = false; + } else if (_movingSliderNine) { + _movingSliderNine = false; + } }; Controller.mousePressEvent.connect(mousePressEvent); @@ -2580,9 +2579,9 @@ walkInterface = (function() { if (_state.editingTranslation) { setBackground(_controlsBackgroundWalkEditHipTrans); - } else { + } else { setBackground(_controlsBackgroundWalkEditJoints); - } + } initialiseWalkStylesPanel(false); setSliderThumbsVisible(true); @@ -2594,7 +2593,7 @@ walkInterface = (function() { setButtonOverlayVisible(_onButton); setButtonOverlayVisible(_backButton); return; - } + } case _state.EDIT_STANDING: case _state.EDIT_SIDESTEP_LEFT: @@ -2602,9 +2601,9 @@ walkInterface = (function() { if (_state.editingTranslation) { setBackground(_controlsBackgroundWalkEditHipTrans); - } else { + } else { setBackground(_controlsBackgroundWalkEditJoints); - } + } hideMenuButtons(); initialiseWalkStylesPanel(false); initialiseFrontPanel(false); @@ -2631,7 +2630,7 @@ walkInterface = (function() { setButtonOverlayVisible(_onButton); setButtonOverlayVisible(_backButton); return; - } + } case _state.EDIT_FLYING: case _state.EDIT_FLYING_UP: @@ -2663,7 +2662,7 @@ walkInterface = (function() { setButtonOverlayVisible(_onButton); setButtonOverlayVisible(_backButton); return; - } + } case _state.STANDING: case _state.WALKING: @@ -2675,10 +2674,10 @@ walkInterface = (function() { hideJointSelectors(); setBackground(_controlsBackground); if (_state.powerOn) { - setButtonOverlayVisible(_onButton); - } else { - setButtonOverlayVisible(_offButton); - } + setButtonOverlayVisible(_onButton); + } else { + setButtonOverlayVisible(_offButton); + } setButtonOverlayVisible(_configWalkButton); setButtonOverlayVisible(_configStandButton); setButtonOverlayVisible(_configFlyingButton); @@ -2687,7 +2686,7 @@ walkInterface = (function() { initialiseFrontPanel(true); initialiseWalkStylesPanel(false); return; - } + } } } } From 3f1897d6b2e7142b7feafa74a155cee88b374f32 Mon Sep 17 00:00:00 2001 From: DaveDubUK Date: Tue, 11 Nov 2014 13:21:37 +0000 Subject: [PATCH 20/20] Minor formatting change --- examples/libraries/walkInterface.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/examples/libraries/walkInterface.js b/examples/libraries/walkInterface.js index 7b7a23a584..aa0b533101 100644 --- a/examples/libraries/walkInterface.js +++ b/examples/libraries/walkInterface.js @@ -1961,12 +1961,8 @@ walkInterface = (function() { case _hideButton: case _hideButtonSelected: - Overlays.editOverlay(_hideButton, { - visible: false - }); - Overlays.editOverlay(_hideButtonSelected, { - visible: true - }); + Overlays.editOverlay(_hideButton, {visible: false}); + Overlays.editOverlay(_hideButtonSelected, {visible: true}); _state.minimised = true; momentaryButtonTimer = Script.setInterval(function() { minimiseDialog(_state.minimised);