mirror of
https://github.com/overte-org/overte.git
synced 2025-04-18 14:16:42 +02:00
2540 lines
No EOL
117 KiB
JavaScript
2540 lines
No EOL
117 KiB
JavaScript
//
|
||
// walk.js
|
||
//
|
||
//
|
||
// Created by Davedub, August / September 2014
|
||
//
|
||
//
|
||
// Distributed under the Apache License, Version 2.0.
|
||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||
//
|
||
|
||
|
||
// Set asset paths here:
|
||
|
||
// path to the animation files
|
||
//var pathToAnimFiles = 'http://localhost/downloads/hf/scripts/animation-files/'; // loads fine (files must be present on localhost)
|
||
//var pathToAnimFiles = 'http://highfidelity.davedub.co.uk/procedural/walk/animation-files/'; // files present, but load with errors - weird
|
||
var pathToAnimFiles = 'http://s3-us-west-1.amazonaws.com/highfidelity-public/procedural-animator/files/'; // working (but only without https)
|
||
|
||
// path to the images used for the overlays
|
||
//var pathToOverlays = 'http://localhost/downloads/hf/overlays/'; // loads fine (files must be present on localhost)
|
||
//var pathToOverlays = 'http://highfidelity.davedub.co.uk/procedural/walk/overlays/'; // files present, but won't load - weird
|
||
var pathToOverlays = 'http://s3-us-west-1.amazonaws.com/highfidelity-public/procedural-animator/images/'; // 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/';
|
||
//var pathToSounds = 'http://localhost/downloads/hf/sounds/Footsteps/';
|
||
|
||
|
||
// load all the animation datafiles ( 15 female, 15 male ~ 240k )
|
||
Script.include(pathToAnimFiles+"dd-female-cool-walk-animation.js");
|
||
Script.include(pathToAnimFiles+"dd-female-elderly-walk-animation.js");
|
||
Script.include(pathToAnimFiles+"dd-female-power-walk-animation.js");
|
||
Script.include(pathToAnimFiles+"dd-female-run-animation.js");
|
||
Script.include(pathToAnimFiles+"dd-female-sexy-walk-animation.js");
|
||
Script.include(pathToAnimFiles+"dd-female-shuffle-animation.js");
|
||
Script.include(pathToAnimFiles+"dd-female-random-walk-animation.js");
|
||
Script.include(pathToAnimFiles+"dd-female-strut-walk-animation.js");
|
||
Script.include(pathToAnimFiles+"dd-female-tough-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-standing-two-animation.js");
|
||
Script.include(pathToAnimFiles+"dd-female-standing-three-animatiom.js");
|
||
Script.include(pathToAnimFiles+"dd-male-cool-walk-animation.js");
|
||
Script.include(pathToAnimFiles+"dd-male-elderly-walk-animation.js");
|
||
Script.include(pathToAnimFiles+"dd-male-power-walk-animation.js");
|
||
Script.include(pathToAnimFiles+"dd-male-run-animation.js");
|
||
Script.include(pathToAnimFiles+"dd-male-sexy-walk-animation.js");
|
||
Script.include(pathToAnimFiles+"dd-male-shuffle-animation.js");
|
||
Script.include(pathToAnimFiles+"dd-male-random-walk-animation.js");
|
||
Script.include(pathToAnimFiles+"dd-male-strut-walk-animation.js");
|
||
Script.include(pathToAnimFiles+"dd-male-tough-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-standing-two-animation.js");
|
||
Script.include(pathToAnimFiles+"dd-male-standing-three-animation.js");
|
||
|
||
// read in the data from the animation files
|
||
var FemaleCoolWalkFile = new FemaleCoolWalk();
|
||
var femaleCoolWalk = FemaleCoolWalkFile.loadAnimation();
|
||
var FemaleElderlyWalkFile = new FemaleElderlyWalk();
|
||
var femaleElderlyWalk = FemaleElderlyWalkFile.loadAnimation();
|
||
var FemalePowerWalkFile = new FemalePowerWalk();
|
||
var femalePowerWalk = FemalePowerWalkFile.loadAnimation();
|
||
var FemaleRunFile = new FemaleRun();
|
||
var femaleRun = FemaleRunFile.loadAnimation();
|
||
var FemaleSexyWalkFile = new FemaleSexyWalk();
|
||
var femaleSexyWalk = FemaleSexyWalkFile.loadAnimation();
|
||
var FemaleShuffleFile = new FemaleShuffle();
|
||
var femaleShuffle = FemaleShuffleFile.loadAnimation();
|
||
var FemaleRandomWalkFile = new FemaleRandomWalk();
|
||
var femaleRandomWalk = FemaleRandomWalkFile.loadAnimation();
|
||
var FemaleStrutWalkFile = new FemaleStrutWalk();
|
||
var femaleStrutWalk = FemaleStrutWalkFile.loadAnimation();
|
||
var FemaleToughWalkFile = new FemaleToughWalk();
|
||
var femaleToughWalk = FemaleToughWalkFile.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 FemaleStandTwoFile = new FemaleStandingTwo();
|
||
var femaleStandTwo = FemaleStandTwoFile.loadAnimation();
|
||
var FemaleStandThreeFile = new FemaleStandingThree();
|
||
var femaleStandThree = FemaleStandThreeFile.loadAnimation();
|
||
var MaleCoolWalkFile = new MaleCoolWalk();
|
||
var maleCoolWalk = MaleCoolWalkFile.loadAnimation();
|
||
var MaleElderlyWalkFile = new MaleElderlyWalk();
|
||
var maleElderlyWalk = MaleElderlyWalkFile.loadAnimation();
|
||
var MalePowerWalkFile = new MalePowerWalk();
|
||
var malePowerWalk = MalePowerWalkFile.loadAnimation();
|
||
var MaleRunFile = new MaleRun();
|
||
var maleRun = MaleRunFile.loadAnimation();
|
||
var MaleSexyWalkFile = new MaleSexyWalk();
|
||
var maleSexyWalk = MaleSexyWalkFile.loadAnimation();
|
||
var MaleShuffleFile = new MaleShuffle();
|
||
var maleShuffle = MaleShuffleFile.loadAnimation();
|
||
var MaleRandomWalkFile = new MaleRandomWalk();
|
||
var maleRandomWalk = MaleRandomWalkFile.loadAnimation();
|
||
var MaleStrutWalkFile = new MaleStrutWalk();
|
||
var maleStrutWalk = MaleStrutWalkFile.loadAnimation();
|
||
var MaleToughWalkFile = new MaleToughWalk();
|
||
var maleToughWalk = MaleToughWalkFile.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 MaleStandTwoFile = new MaleStandingTwo();
|
||
var maleStandTwo = MaleStandTwoFile.loadAnimation();
|
||
var MaleStandThreeFile = new MaleStandingThree();
|
||
var maleStandThree = MaleStandThreeFile.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 (always +-180))
|
||
var sliderRanges =
|
||
{
|
||
"joints":[
|
||
{
|
||
"name":"hips",
|
||
"pitchRange":25,
|
||
"yawRange":25,
|
||
"rollRange":25,
|
||
"pitchOffsetRange":25,
|
||
"yawOffsetRange":25,
|
||
"rollOffsetRange":25,
|
||
"thrustRange":0.1,
|
||
"bobRange":0.5,
|
||
"swayRange":0.08
|
||
},
|
||
{
|
||
"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 = 2;
|
||
var WALKING = 4;
|
||
var FLYING = 8;
|
||
var CONFIG_WALK_STYLES = 16;
|
||
var CONFIG_WALK_TWEAKS = 32;
|
||
var CONFIG_WALK_JOINTS = 64;
|
||
var CONFIG_STANDING = 128;
|
||
var CONFIG_FLYING = 256;
|
||
var INTERNAL_STATE = STANDING;
|
||
|
||
// status
|
||
var powerOn = true;
|
||
var paused = false; // pause animation playback whilst adjusting certain parameters
|
||
var minimised = false;
|
||
var armsFree = false; // set true for hydra support - experimental
|
||
var statsOn = false;
|
||
|
||
// constants
|
||
var MAX_WALK_SPEED = 1257; // max oscillation speed
|
||
var FLYING_SPEED = 12.5; // m/s - real humans can't run any faster
|
||
var TERMINAL_VELOCITY = 300;
|
||
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 MALE = 64;
|
||
var FEMALE = 128;
|
||
|
||
// start of animation control section
|
||
var cumulativeTime = 0.0;
|
||
var lastOrientation;
|
||
var movementDirection = DIRECTION_FORWARDS;
|
||
var playFootStepSounds = true;
|
||
var avatarGender = FEMALE;
|
||
var selectedWalk = femaleStrutWalk; // the currently selected animation walk file
|
||
var selectedStand = femaleStandOne;
|
||
var selectedFlyUp = femaleFlyingUp;
|
||
var selectedFly = femaleFlying;
|
||
var selectedFlyDown = femaleFlyingDown;
|
||
var currentAnimation = selectedStand; // the current animation
|
||
var selectedJointIndex = 0; // the index of the joint currently selected for editing
|
||
// stride calibration
|
||
var maxFootForward = 0;
|
||
var maxFootBackwards = 0;
|
||
var strideLength = 0;
|
||
// walkwheel (foot / ground speed matching)
|
||
var walkCycleStart = 105; // best foot forwards - TODO: if different for different anims, add as setting to anim files
|
||
var walkWheelPosition = walkCycleStart;
|
||
|
||
|
||
// for showing walk wheel stats
|
||
var nFrames = 0;
|
||
|
||
// convert hips translations to global (i.e. take account of avi orientation)
|
||
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.addThrust(AviTranslationOffset * 10);
|
||
MyAvatar.position = {x: MyAvatar.position.x + AviTranslationOffset.x,
|
||
y: MyAvatar.position.y + AviTranslationOffset.y,
|
||
z: MyAvatar.position.z + AviTranslationOffset.z };
|
||
}
|
||
|
||
// convert a local (to the avi) translation to a global one
|
||
function globalToLocal(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;
|
||
}
|
||
|
||
// zero out all joints
|
||
function resetJoints() {
|
||
var avatarJointNames = MyAvatar.getJointNames();
|
||
for (var i = 0; i < avatarJointNames.length; i++) {
|
||
//MyAvatar.setJointData(avatarJointNames[i], Quat.fromPitchYawRollDegrees(0,0,0));
|
||
MyAvatar.clearJointData(avatarJointNames[i]);
|
||
}
|
||
}
|
||
// play footstep sound
|
||
function playFootstep(side) {
|
||
var options = new AudioInjectionOptions();
|
||
options.position = Camera.getPosition();
|
||
options.volume = 0.7;
|
||
var walkNumber = 2; // 0 to 2
|
||
if(side===DIRECTION_RIGHT && playFootStepSounds) {
|
||
//print('playing right footstep - if you can not hear sound, try turning your mic on then off again.');
|
||
Audio.playSound(footsteps[walkNumber+1], options);
|
||
}
|
||
else if(side===DIRECTION_LEFT && playFootStepSounds) {
|
||
//print('playing left footstep - if you can not hear sound, try turning your mic on then off again.');
|
||
Audio.playSound(footsteps[walkNumber], options);
|
||
}
|
||
}
|
||
|
||
// this is work in progress
|
||
// currently, it's not known if there are working finger joints on the avi
|
||
function curlFingers() {
|
||
MyAvatar.setJointData("RightHandMiddle1", Quat.fromPitchYawRollDegrees(90,0,0));
|
||
for(var i = 24 ; i < 44 ; i++) {
|
||
MyAvatar.setJointData(jointList[i], Quat.fromPitchYawRollDegrees(0,90,0));
|
||
}
|
||
for(var i = 48 ; i < 68 ; i++) {
|
||
MyAvatar.setJointData(jointList[i], Quat.fromPitchYawRollDegrees(10,0,90));
|
||
}
|
||
}
|
||
|
||
// maths functions
|
||
function toRadians(degreesValue) {
|
||
return degreesValue * Math.PI / 180;
|
||
}
|
||
function toDegrees(radiansValue) {
|
||
return radiansValue * 180 / Math.PI;
|
||
}
|
||
function cubicRoot(x) {
|
||
var y = Math.pow(Math.abs(x), 1/3);
|
||
return x < 0 ? -y : y;
|
||
}
|
||
|
||
// animateAvatar - animates the avatar - TODO doxygen comments?
|
||
var nextStep = DIRECTION_RIGHT; // first step is always right, because the sine waves say so
|
||
|
||
function animateAvatar(deltaTime, velocity, principleDirection) {
|
||
|
||
// some slider adjustemnts cause a nasty flicker when adjusting
|
||
// pausing the animation stops this
|
||
if(paused) return;
|
||
|
||
var adjustedFrequency = currentAnimation.settings.baseFrequency; // now only relevant for standing and flying
|
||
|
||
// simple legs phase reversal for walking backwards
|
||
var forwardModifier = 1;
|
||
if(principleDirection===DIRECTION_BACKWARDS) {
|
||
forwardModifier = -1;
|
||
}
|
||
|
||
// no need to lean forwards with speed increase if going directly upwards
|
||
var leanPitchModifier = 1;
|
||
if(principleDirection===DIRECTION_UP) {
|
||
leanPitchModifier = 0;
|
||
}
|
||
|
||
|
||
if(currentAnimation === selectedWalk) {
|
||
|
||
if(INTERNAL_STATE===CONFIG_WALK_STYLES ||
|
||
INTERNAL_STATE===CONFIG_WALK_TWEAKS ||
|
||
INTERNAL_STATE===CONFIG_WALK_JOINTS) {
|
||
|
||
var footPos = globalToLocal(MyAvatar.getJointPosition("RightFoot"));
|
||
var hipsPos = globalToLocal(MyAvatar.getJointPosition("Hips"));
|
||
|
||
// calibrate stride length whilst not actually moving (for accuracy)
|
||
if((hipsPos.z - footPos.z)<maxFootBackwards) maxFootBackwards = (hipsPos.z - footPos.z);
|
||
else if ((hipsPos.z - footPos.z)>maxFootForward) maxFootForward = (hipsPos.z - footPos.z);
|
||
|
||
strideLength = 2 * (maxFootForward-maxFootBackwards);
|
||
|
||
// TODO: take note of the avi's stride length (can store in anim file or recalculate each time worn or edited)
|
||
print('Stride length calibration: Your stride length is ' + strideLength + ' metres'); // ~ 0.8211
|
||
}
|
||
else {
|
||
|
||
if(strideLength===0) strideLength = 1.6422; // default for if not calibrated yet
|
||
|
||
// 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
|
||
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 = toDegrees(radiansTurnedSinceLastFrame);
|
||
|
||
// advance the walk wheel the appropriate amount
|
||
// TODO: use radians, as Math.sin needs radians below anyway!
|
||
walkWheelPosition += degreesTurnedSinceLastFrame;
|
||
if( walkWheelPosition >= 360 )
|
||
walkWheelPosition = walkWheelPosition % 360;
|
||
|
||
// set the new value for the exact correct walking speed for this velocity
|
||
adjustedFrequency = 1;
|
||
cumulativeTime = walkWheelPosition;
|
||
|
||
// show stats and walk wheel?
|
||
if(statsOn) {
|
||
|
||
nFrames++;
|
||
var distanceTravelled = velocity * deltaTime;
|
||
var deltaTimeMS = deltaTime * 1000;
|
||
|
||
// draw the walk wheel
|
||
var yOffset = hipsToFeetDistance - wheelRadius;
|
||
var sinWalkWheelPosition = wheelRadius * Math.sin(toRadians((forwardModifier*-1) * walkWheelPosition));
|
||
var cosWalkWheelPosition = wheelRadius * Math.cos(toRadians((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(toRadians(forwardModifier * walkWheelPosition+90));
|
||
cosWalkWheelPosition = wheelRadius * Math.cos(toRadians(forwardModifier * walkWheelPosition+90));
|
||
var wheelYPos = {x:0, y:sinWalkWheelPosition - yOffset, z: cosWalkWheelPosition};
|
||
var wheelYEnd = {x:0, y:-sinWalkWheelPosition - yOffset, z: -cosWalkWheelPosition};
|
||
Overlays.editOverlay(walkWheelYLine, {position:wheelYPos, end:wheelYEnd});
|
||
Overlays.editOverlay(walkWheelZLine, {position:wheelZPos, end:wheelZEnd});
|
||
|
||
// populate debug overlay
|
||
var debugInfo = 'Frame number: '+nFrames
|
||
+ '\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\nStride: '+strideLength.toFixed(3)
|
||
+ ' m\nWheel position: '+cumulativeTime.toFixed(1)
|
||
+ ' deg\n';
|
||
Overlays.editOverlay(debugText, {text: debugInfo});
|
||
|
||
//print('strideLength '+strideLength.toFixed(4)+' deltaTime '+deltaTimeMS.toFixed(4)+' distanceTravelled '+distanceTravelled.toFixed(3)+' velocity '+velocity.toFixed(3)+' angularVelocity '+angularVelocity.toFixed(3)+' degreesTurnedSinceLastFrame '+degreesTurnedSinceLastFrame.toFixed(3) + ' cumulativeTime '+cumulativeTime.toFixed(3));
|
||
}
|
||
}
|
||
|
||
} else {
|
||
nFrames = 0;
|
||
walkWheelPosition = walkCycleStart; // best foot forwards for next time we walk
|
||
}
|
||
|
||
// TODO: optimise by precalculating and re-using Math.sin((cumulativeTime * femaleSexyWalk.settings.baseFrequency) when there is no phase to be applied
|
||
// TODO: optimise by 'baking' offsets and phases after editing and use during normal playback
|
||
|
||
// calcualte hips translation
|
||
//var motorOscillation = Math.sin(toRadians((cumulativeTime * adjustedFrequency * 2) + currentAnimation.joints[0].thrustPhase)) + currentAnimation.joints[0].thrustOffset;
|
||
//var swayOscillation = Math.sin(toRadians((cumulativeTime * adjustedFrequency ) + currentAnimation.joints[0].swayPhase)) + currentAnimation.joints[0].swayOffset;
|
||
//var bobOscillation = Math.sin(toRadians((cumulativeTime * adjustedFrequency * 2) + currentAnimation.joints[0].bobPhase)) + currentAnimation.joints[0].bobOffset;
|
||
|
||
// calculate hips rotation
|
||
var pitchOscillation = currentAnimation.joints[0].pitch * Math.sin(toRadians((cumulativeTime * adjustedFrequency * 2)
|
||
+ currentAnimation.joints[0].pitchPhase)) + currentAnimation.joints[0].pitchOffset;
|
||
var yawOscillation = currentAnimation.joints[0].yaw * Math.sin(toRadians((cumulativeTime * adjustedFrequency )
|
||
+ currentAnimation.joints[0].yawPhase)) + currentAnimation.joints[0].yawOffset;
|
||
var rollOscillation = (currentAnimation.joints[0].roll * Math.sin(toRadians((cumulativeTime * adjustedFrequency )
|
||
+ currentAnimation.joints[0].rollPhase)) + currentAnimation.joints[0].rollOffset);
|
||
|
||
// apply hips translation TODO: get this working!
|
||
//translateHips({x:swayOscillation*currentAnimation.joints[0].sway, y:motorOscillation*currentAnimation.joints[0].thrust, z:bobOscillation*currentAnimation.joints[0].bob});
|
||
|
||
// apply hips rotation
|
||
MyAvatar.setJointData("Hips", Quat.fromPitchYawRollDegrees(-pitchOscillation + (forwardModifier * (leanPitchModifier*getLeanPitch(velocity))), // getLeanPitch - lean forwards as velocity increased
|
||
yawOscillation, // Yup, that's correct ;-)
|
||
rollOscillation + getLeanRoll(deltaTime,velocity))); // getLeanRoll - banking on cornering
|
||
|
||
// calculate upper leg rotations
|
||
|
||
// TODO: clean up here - increase stride a bit as velocity increases
|
||
var runningModifier = velocity / currentAnimation.settings.takeFlightVelocity;
|
||
if(runningModifier>1) {
|
||
runningModifier *= 2;
|
||
runningModifier += 0.5;
|
||
}
|
||
else if(runningModifier>0) {
|
||
runningModifier *= 2;
|
||
runningModifier += 0.5;
|
||
}
|
||
else runningModifier = 1; // standing
|
||
|
||
runningModifier = 1; // TODO - remove this little disabling hack!
|
||
|
||
pitchOscillation = runningModifier * currentAnimation.joints[1].pitch * Math.sin(toRadians((cumulativeTime * adjustedFrequency ) + (forwardModifier * currentAnimation.joints[1].pitchPhase)));
|
||
yawOscillation = currentAnimation.joints[1].yaw * Math.sin(toRadians((cumulativeTime * adjustedFrequency ) + currentAnimation.joints[1].yawPhase));
|
||
rollOscillation = currentAnimation.joints[1].roll * Math.sin(toRadians((cumulativeTime * adjustedFrequency ) + currentAnimation.joints[1].rollPhase));
|
||
|
||
// apply upper leg rotations
|
||
var strideAdjusterPitch = 0;
|
||
var strideAdjusterPitchOffset = 0;
|
||
var strideAdjusterSeparationAngle = 0;
|
||
if(INTERNAL_STATE===WALKING ||
|
||
INTERNAL_STATE===CONFIG_WALK_STYLES ||
|
||
INTERNAL_STATE===CONFIG_WALK_TWEAKS ||
|
||
INTERNAL_STATE===CONFIG_WALK_JOINTS) {
|
||
strideAdjusterPitch = currentAnimation.adjusters.stride.strength*currentAnimation.adjusters.stride.upperLegsPitch;
|
||
strideAdjusterPitchOffset = currentAnimation.adjusters.stride.strength*currentAnimation.adjusters.stride.upperLegsPitchOffset;
|
||
strideAdjusterSeparationAngle = currentAnimation.adjusters.legsSeparation.strength * currentAnimation.adjusters.legsSeparation.separationAngle;
|
||
}
|
||
MyAvatar.setJointData("RightUpLeg", Quat.fromPitchYawRollDegrees(
|
||
pitchOscillation + currentAnimation.joints[1].pitchOffset + strideAdjusterPitch * (Math.sin(toRadians((cumulativeTime * adjustedFrequency) + currentAnimation.joints[1].pitchPhase)) + strideAdjusterPitchOffset),
|
||
yawOscillation + currentAnimation.joints[1].yawOffset,
|
||
-rollOscillation - strideAdjusterSeparationAngle - currentAnimation.joints[1].rollOffset ));
|
||
MyAvatar.setJointData("LeftUpLeg", Quat.fromPitchYawRollDegrees(
|
||
- pitchOscillation + currentAnimation.joints[1].pitchOffset - strideAdjusterPitch * (Math.sin(toRadians((cumulativeTime * adjustedFrequency) + currentAnimation.joints[1].pitchPhase)) - strideAdjusterPitchOffset),
|
||
yawOscillation - currentAnimation.joints[1].yawOffset,
|
||
-rollOscillation + strideAdjusterSeparationAngle + currentAnimation.joints[1].rollOffset ));
|
||
|
||
// calculate lower leg joint rotations
|
||
strideAdjusterPitch = 0;
|
||
strideAdjusterPitchOffset = 0;
|
||
if(INTERNAL_STATE===WALKING ||
|
||
INTERNAL_STATE===CONFIG_WALK_STYLES ||
|
||
INTERNAL_STATE===CONFIG_WALK_TWEAKS ||
|
||
INTERNAL_STATE===CONFIG_WALK_JOINTS) {
|
||
strideAdjusterPitch = currentAnimation.adjusters.stride.strength * currentAnimation.adjusters.stride.lowerLegsPitch;
|
||
strideAdjusterPitchOffset = currentAnimation.adjusters.stride.strength*currentAnimation.adjusters.stride.lowerLegsPitchOffset;
|
||
}
|
||
pitchOscillation = currentAnimation.joints[2].pitch * Math.sin(toRadians((cumulativeTime * adjustedFrequency ) + currentAnimation.joints[2].pitchPhase));
|
||
yawOscillation = currentAnimation.joints[2].yaw * Math.sin(toRadians((cumulativeTime * adjustedFrequency ) + currentAnimation.joints[2].yawPhase));
|
||
rollOscillation = currentAnimation.joints[2].roll * Math.sin(toRadians((cumulativeTime * adjustedFrequency ) + currentAnimation.joints[2].rollPhase));
|
||
|
||
// apply lower leg joint rotations
|
||
MyAvatar.setJointData("RightLeg", Quat.fromPitchYawRollDegrees(
|
||
-pitchOscillation + currentAnimation.joints[2].pitchOffset - strideAdjusterPitch * (Math.sin(toRadians((cumulativeTime * adjustedFrequency) + currentAnimation.joints[2].pitchPhase)) + strideAdjusterPitchOffset),
|
||
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 + strideAdjusterPitch * (Math.sin(toRadians((cumulativeTime * adjustedFrequency) + currentAnimation.joints[2].pitchPhase)) - strideAdjusterPitchOffset),
|
||
yawOscillation + currentAnimation.joints[2].yawOffset,
|
||
rollOscillation + currentAnimation.joints[2].rollOffset));
|
||
|
||
// foot joint oscillation is a hard curve to replicate
|
||
var wave = 1;//(baseOscillation + 1)/2; // TODO: finish this - +ve num between 0 and 1 gives a kick at the forward part of the swing
|
||
pitchOscillation = wave * currentAnimation.joints[3].pitch * Math.sin(toRadians((cumulativeTime * adjustedFrequency ) + currentAnimation.joints[3].pitchPhase));
|
||
yawOscillation = currentAnimation.joints[3].yaw * Math.sin(toRadians((cumulativeTime * adjustedFrequency ) + currentAnimation.joints[3].yawPhase));
|
||
rollOscillation = currentAnimation.joints[3].roll * Math.sin(toRadians((cumulativeTime * adjustedFrequency ) + currentAnimation.joints[3].rollPhase));
|
||
MyAvatar.setJointData("RightFoot", Quat.fromPitchYawRollDegrees( pitchOscillation + currentAnimation.joints[3].pitchOffset, yawOscillation + currentAnimation.joints[3].yawOffset, rollOscillation + currentAnimation.joints[3].rollOffset));
|
||
MyAvatar.setJointData("LeftFoot", Quat.fromPitchYawRollDegrees(-pitchOscillation + currentAnimation.joints[3].pitchOffset, yawOscillation - currentAnimation.joints[3].yawOffset, rollOscillation - currentAnimation.joints[3].rollOffset));
|
||
|
||
if(INTERNAL_STATE===WALKING ||
|
||
INTERNAL_STATE===CONFIG_WALK_STYLES ||
|
||
INTERNAL_STATE===CONFIG_WALK_TWEAKS ||
|
||
INTERNAL_STATE===CONFIG_WALK_JOINTS) {
|
||
// 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. As luck would have it, we're using a sine wave, so finding dy/dx is as
|
||
// simple as determining the cosine wave for the foot's pitch function...
|
||
var feetPitchDifferential = Math.cos(toRadians((cumulativeTime * 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 joint oscillation
|
||
pitchOscillation = currentAnimation.joints[4].pitch * Math.sin(toRadians((cumulativeTime * adjustedFrequency) + currentAnimation.joints[4].pitchPhase));
|
||
yawOscillation = currentAnimation.joints[4].yaw * Math.sin(toRadians((cumulativeTime * adjustedFrequency) + currentAnimation.joints[4].yawPhase)) + currentAnimation.joints[4].yawOffset;
|
||
rollOscillation = currentAnimation.joints[4].roll * Math.sin(toRadians((cumulativeTime * adjustedFrequency) + currentAnimation.joints[4].rollPhase)) + currentAnimation.joints[4].rollOffset;
|
||
MyAvatar.setJointData("RightToeBase", Quat.fromPitchYawRollDegrees(-pitchOscillation + currentAnimation.joints[4].pitchOffset, yawOscillation, rollOscillation));
|
||
MyAvatar.setJointData("LeftToeBase", Quat.fromPitchYawRollDegrees( pitchOscillation + currentAnimation.joints[4].pitchOffset, yawOscillation, rollOscillation));
|
||
|
||
// calculate spine joint rotations
|
||
pitchOscillation = currentAnimation.joints[5].pitch * Math.sin(toRadians(( cumulativeTime * adjustedFrequency * 2) + currentAnimation.joints[5].pitchPhase)) + currentAnimation.joints[5].pitchOffset;
|
||
yawOscillation = currentAnimation.joints[5].yaw * Math.sin(toRadians(( cumulativeTime * adjustedFrequency ) + currentAnimation.joints[5].yawPhase)) + currentAnimation.joints[5].yawOffset;
|
||
rollOscillation = currentAnimation.joints[5].roll * Math.sin(toRadians(( cumulativeTime * adjustedFrequency ) + currentAnimation.joints[5].rollPhase)) + currentAnimation.joints[5].rollOffset;
|
||
|
||
// apply spine joint rotations
|
||
MyAvatar.setJointData("Spine", Quat.fromPitchYawRollDegrees(-pitchOscillation, yawOscillation, rollOscillation));
|
||
|
||
// calcualte spine 1 rotatations
|
||
pitchOscillation = currentAnimation.joints[6].pitch * Math.sin(toRadians(( cumulativeTime * adjustedFrequency * 2) + currentAnimation.joints[6].pitchPhase)) + currentAnimation.joints[6].pitchOffset;
|
||
yawOscillation = currentAnimation.joints[6].yaw * Math.sin(toRadians(( cumulativeTime * adjustedFrequency ) + currentAnimation.joints[6].yawPhase)) + currentAnimation.joints[6].yawOffset;
|
||
rollOscillation = currentAnimation.joints[6].roll * Math.sin(toRadians(( cumulativeTime * adjustedFrequency ) + currentAnimation.joints[6].rollPhase)) + currentAnimation.joints[6].rollOffset;
|
||
|
||
// apply spine1 joint rotations
|
||
MyAvatar.setJointData("Spine1", Quat.fromPitchYawRollDegrees( pitchOscillation, -yawOscillation, rollOscillation));
|
||
|
||
// spine 2
|
||
pitchOscillation = currentAnimation.joints[7].pitch * Math.sin(toRadians(( cumulativeTime * adjustedFrequency * 2) + currentAnimation.joints[7].pitchPhase)) + currentAnimation.joints[7].pitchOffset;
|
||
yawOscillation = currentAnimation.joints[7].yaw * Math.sin(toRadians(( cumulativeTime * adjustedFrequency ) + currentAnimation.joints[7].yawPhase)) + currentAnimation.joints[7].yawOffset;
|
||
rollOscillation = currentAnimation.joints[7].roll * Math.sin(toRadians(( cumulativeTime * adjustedFrequency ) + currentAnimation.joints[7].rollPhase)) + currentAnimation.joints[7].rollOffset;
|
||
|
||
// apply spine2 joint rotations
|
||
MyAvatar.setJointData("Spine2", Quat.fromPitchYawRollDegrees(-pitchOscillation, yawOscillation, -rollOscillation));
|
||
|
||
if(!armsFree) {
|
||
|
||
// shoulders
|
||
pitchOscillation = currentAnimation.joints[8].pitch * Math.sin(toRadians(( cumulativeTime * adjustedFrequency ) + currentAnimation.joints[8].pitchPhase)) + currentAnimation.joints[8].pitchOffset;
|
||
yawOscillation = currentAnimation.joints[8].yaw * Math.sin(toRadians(( cumulativeTime * adjustedFrequency ) + currentAnimation.joints[8].yawPhase));
|
||
rollOscillation = currentAnimation.joints[8].roll * Math.sin(toRadians(( cumulativeTime * adjustedFrequency * 2) + currentAnimation.joints[8].rollPhase)) + currentAnimation.joints[8].rollOffset;
|
||
MyAvatar.setJointData("RightShoulder", Quat.fromPitchYawRollDegrees(pitchOscillation, yawOscillation + currentAnimation.joints[8].yawOffset, rollOscillation ));
|
||
MyAvatar.setJointData("LeftShoulder", Quat.fromPitchYawRollDegrees(pitchOscillation, yawOscillation - currentAnimation.joints[8].yawOffset, -rollOscillation ));
|
||
|
||
// upper arms
|
||
pitchOscillation = currentAnimation.joints[9].pitch * Math.sin(toRadians(( cumulativeTime * adjustedFrequency ) + currentAnimation.joints[9].pitchPhase)) + currentAnimation.joints[9].pitchOffset;
|
||
yawOscillation = currentAnimation.joints[9].yaw * Math.sin(toRadians(( cumulativeTime * adjustedFrequency ) + currentAnimation.joints[9].yawPhase));
|
||
rollOscillation = currentAnimation.joints[9].roll * Math.sin(toRadians(( cumulativeTime * adjustedFrequency * 2) + currentAnimation.joints[9].rollPhase)) + currentAnimation.joints[9].rollOffset;
|
||
MyAvatar.setJointData("RightArm", Quat.fromPitchYawRollDegrees( pitchOscillation, yawOscillation - currentAnimation.joints[9].yawOffset, rollOscillation ));
|
||
MyAvatar.setJointData("LeftArm", Quat.fromPitchYawRollDegrees( pitchOscillation, yawOscillation + currentAnimation.joints[9].yawOffset, -rollOscillation ));
|
||
|
||
// forearms
|
||
pitchOscillation = currentAnimation.joints[10].pitch * Math.sin(toRadians(( cumulativeTime * adjustedFrequency ) + currentAnimation.joints[10].pitchPhase)) + currentAnimation.joints[10].pitchOffset;
|
||
yawOscillation = currentAnimation.joints[10].yaw * Math.sin(toRadians(( cumulativeTime * adjustedFrequency ) + currentAnimation.joints[10].yawPhase));
|
||
rollOscillation = currentAnimation.joints[10].roll * Math.sin(toRadians(( cumulativeTime * adjustedFrequency ) + currentAnimation.joints[10].rollPhase));
|
||
MyAvatar.setJointData("RightForeArm", Quat.fromPitchYawRollDegrees( pitchOscillation, yawOscillation + currentAnimation.joints[10].yawOffset, rollOscillation + currentAnimation.joints[10].rollOffset ));
|
||
MyAvatar.setJointData("LeftForeArm", Quat.fromPitchYawRollDegrees( pitchOscillation, yawOscillation - currentAnimation.joints[10].yawOffset, rollOscillation - currentAnimation.joints[10].rollOffset ));
|
||
|
||
// hands
|
||
pitchOscillation = currentAnimation.joints[11].pitch * Math.sin(toRadians(( cumulativeTime * adjustedFrequency ) + currentAnimation.joints[11].pitchPhase)) + currentAnimation.joints[11].pitchOffset;
|
||
yawOscillation = currentAnimation.joints[11].yaw * Math.sin(toRadians(( cumulativeTime * adjustedFrequency ) + currentAnimation.joints[11].yawPhase)) + currentAnimation.joints[11].yawOffset;
|
||
rollOscillation = currentAnimation.joints[11].roll * Math.sin(toRadians(( cumulativeTime * adjustedFrequency ) + currentAnimation.joints[11].rollPhase)) ;
|
||
MyAvatar.setJointData("RightHand", Quat.fromPitchYawRollDegrees( pitchOscillation, yawOscillation, rollOscillation + currentAnimation.joints[11].rollOffset));
|
||
MyAvatar.setJointData("LeftHand", Quat.fromPitchYawRollDegrees( pitchOscillation, -yawOscillation, rollOscillation - currentAnimation.joints[11].rollOffset));
|
||
|
||
} // if(!armsFree)
|
||
|
||
// head
|
||
pitchOscillation = 0.5 * currentAnimation.joints[12].pitch * Math.sin(toRadians(( cumulativeTime * adjustedFrequency * 2) + currentAnimation.joints[12].pitchPhase)) + currentAnimation.joints[12].pitchOffset;
|
||
yawOscillation = 0.5 * currentAnimation.joints[12].yaw * Math.sin(toRadians(( cumulativeTime * adjustedFrequency ) + currentAnimation.joints[12].yawPhase)) + currentAnimation.joints[12].yawOffset;
|
||
rollOscillation = 0.5 * currentAnimation.joints[12].roll * Math.sin(toRadians(( cumulativeTime * 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));
|
||
}
|
||
|
||
|
||
|
||
// getBezier from: http://13thparallel.com/archive/bezier-curves/
|
||
//====================================\\
|
||
// 13thParallel.org Bezi<7A>r Curve Code \\
|
||
// by Dan Pupius (www.pupius.net) \\
|
||
//====================================\\
|
||
/*
|
||
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;
|
||
}
|
||
*/
|
||
|
||
|
||
// the faster we go, the further we lean forward. the angle is calcualted here
|
||
var leanAngles = [0,0,0,0,0,0,0,0,0,0]; // smooth out and add damping with simple averaging filter. 20 tap = too much damping, 10 pretty good
|
||
function getLeanPitch(velocity) {
|
||
|
||
if(velocity>TERMINAL_VELOCITY) velocity=TERMINAL_VELOCITY;
|
||
|
||
var leanAngle = velocity / TERMINAL_VELOCITY * currentAnimation.settings.flyingHipsPitch;
|
||
|
||
// simple averaging filter
|
||
leanAngles.push(leanAngle);
|
||
leanAngles.shift(); // FIFO
|
||
var totalLeanAngles = 0;
|
||
for(ea in leanAngles) totalLeanAngles += leanAngles[ea];
|
||
var finalLeanAngle = totalLeanAngles / leanAngles.length;
|
||
|
||
//print('final lean angle '+finalLeanAngle); // we found that native support already follows a curve - see graph in forum post
|
||
|
||
return finalLeanAngle;
|
||
|
||
// work in progress - apply bezier curve to lean / velocity response
|
||
|
||
/*var percentTotalLean = velocity / TERMINAL_VELOCITY;
|
||
|
||
no curve applied - used for checking results only
|
||
var linearLeanAngle = percentTotalLean * currentAnimation.settings.flyingHipsPitch;
|
||
|
||
// make the hips pitch / velocity curve follow a nice bezier
|
||
// bezier control points
|
||
Q1 = coord(0,0);
|
||
Q2 = coord(0.2,0.8);
|
||
Q3 = coord(0.8,0.2);
|
||
Q4 = coord(1,1);
|
||
|
||
var easedLean = getBezier(percentTotalLean, Q1, Q2, Q3, Q4);
|
||
var leanAngle = (1-easedLean.x) * currentAnimation.settings.flyingHipsPitch;
|
||
//print('before bezier: '+linearLeanAngle.toFixed(4)+' after bezier '+leanAngle.toFixed(4));
|
||
|
||
// simple averaging filter
|
||
leanAngles.push(leanAngle);
|
||
leanAngles.shift(); // FIFO
|
||
var totalLeanAngles = 0;
|
||
for(ea in leanAngles) totalLeanAngles += leanAngles[ea];
|
||
var finalLeanAngle = totalLeanAngles / leanAngles.length;
|
||
|
||
print('before bezier: '+linearLeanAngle.toFixed(4));//+' after bezier '+leanAngle.toFixed(4));
|
||
|
||
return finalLeanAngle;
|
||
*/
|
||
}
|
||
|
||
// calculate the angle at which to bank into corners when turning
|
||
var angularVelocities = [0,0,0,0,0,0,0,0,0,0]; // smooth out and add damping with simple averaging filter
|
||
function getLeanRoll(deltaTime,velocity) {
|
||
|
||
var angularVelocityMax = 70;
|
||
var currentOrientationVec3 = Quat.safeEulerAngles(MyAvatar.orientation);
|
||
var lastOrientationVec3 = Quat.safeEulerAngles(lastOrientation);
|
||
var deltaYaw = lastOrientationVec3.y-currentOrientationVec3.y;
|
||
var angularVelocity = deltaYaw / deltaTime;
|
||
if(angularVelocity>70) angularVelocity = angularVelocityMax;
|
||
if(angularVelocity<-70) angularVelocity = -angularVelocityMax;
|
||
angularVelocities.push(angularVelocity);
|
||
angularVelocities.shift(); // FIFO
|
||
var totalAngularVelocities = 0;
|
||
for(ea in angularVelocities) totalAngularVelocities += angularVelocities[ea];
|
||
var averageAngularVelocity = totalAngularVelocities / angularVelocities.length;
|
||
var velocityAdjuster = Math.sqrt(velocity/TERMINAL_VELOCITY); // put a little curvature on our otherwise linear velocity modifier
|
||
if(velocityAdjuster>1) velocityAdjuster = 1;
|
||
if(velocityAdjuster<0) velocityAdjuster = 0;
|
||
var leanRoll = velocityAdjuster * (averageAngularVelocity/angularVelocityMax) * currentAnimation.settings.maxBankingAngle;
|
||
//print('delta time is '+deltaTime.toFixed(4)+' and delta yaw is '+deltaYaw+' angular velocity is '+angularVelocity+' and average angular velocity is '+averageAngularVelocity+' and velocityAdjuster is '+velocityAdjuster+' and final value is '+leanRoll);
|
||
//print('array: '+angularVelocities.toString());
|
||
lastOrientation = MyAvatar.orientation;
|
||
return leanRoll;
|
||
}
|
||
|
||
// sets up the interface componenets and updates the internal state
|
||
function setInternalState(newInternalState) {
|
||
|
||
switch(newInternalState) {
|
||
|
||
case WALKING:
|
||
print('WALKING');
|
||
if(!minimised) doStandardMenu();
|
||
INTERNAL_STATE = WALKING;
|
||
currentAnimation = selectedWalk;
|
||
break;
|
||
|
||
case FLYING:
|
||
print('FLYING');
|
||
if(!minimised) doStandardMenu();
|
||
INTERNAL_STATE = FLYING;
|
||
currentAnimation = selectedFly;
|
||
break;
|
||
|
||
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);
|
||
}
|
||
break;
|
||
|
||
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();
|
||
}
|
||
break;
|
||
|
||
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);
|
||
Overlays.editOverlay(hipsJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} );
|
||
initialiseWalkJointsPanel(selectedJointIndex);
|
||
}
|
||
break;
|
||
|
||
case CONFIG_STANDING:
|
||
INTERNAL_STATE = CONFIG_STANDING;
|
||
currentAnimation = selectedStand;
|
||
if(!minimised) {
|
||
hidebuttonOverlays();
|
||
hideJointControls();
|
||
doStandardMenu();
|
||
showFrontPanelButtons(false);
|
||
showWalkStyleButtons(false);
|
||
setBackground(controlsBackgroundWalkEditJoints);
|
||
setButtonOverlayVisible(configStandButtonSelected);
|
||
Overlays.editOverlay(hipsJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} );
|
||
initialiseWalkJointsPanel(selectedJointIndex);
|
||
}
|
||
break;
|
||
|
||
case CONFIG_FLYING:
|
||
INTERNAL_STATE = CONFIG_FLYING;
|
||
currentAnimation = selectedFly;
|
||
if(!minimised) {
|
||
hidebuttonOverlays();
|
||
hideJointControls();
|
||
doStandardMenu();
|
||
showFrontPanelButtons(false);
|
||
showWalkStyleButtons(false);
|
||
setBackground(controlsBackgroundWalkEditJoints);
|
||
setButtonOverlayVisible(configFlyingButtonSelected);
|
||
Overlays.editOverlay(hipsJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} );
|
||
initialiseWalkJointsPanel(selectedJointIndex);
|
||
}
|
||
break;
|
||
|
||
case STANDING:
|
||
default:
|
||
print('STANDING');
|
||
INTERNAL_STATE = STANDING;
|
||
if(!minimised) doStandardMenu();
|
||
currentAnimation = selectedStand;
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 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 - a system very similar to switch debouncing in electronics design
|
||
var standHints = 0;
|
||
var walkHints = 0;
|
||
var flyHints = 0;
|
||
var requiredHints = 3; // debounce state changes - how many times do we get a state change request before we actually change state?
|
||
var lastDirection = DIRECTION_FORWARDS;
|
||
|
||
Script.update.connect(function(deltaTime) {
|
||
|
||
if(powerOn) {
|
||
|
||
cumulativeTime += deltaTime;
|
||
|
||
// firstly test for user configuration states
|
||
switch(INTERNAL_STATE) {
|
||
|
||
case CONFIG_WALK_STYLES:
|
||
currentAnimation = selectedWalk;
|
||
animateAvatar(deltaTime, 0, DIRECTION_FORWARDS);
|
||
return;
|
||
case CONFIG_WALK_TWEAKS:
|
||
currentAnimation = selectedWalk;
|
||
animateAvatar(deltaTime, 0, DIRECTION_FORWARDS);
|
||
return;
|
||
case CONFIG_WALK_JOINTS:
|
||
currentAnimation = selectedWalk;
|
||
animateAvatar(deltaTime, 0, DIRECTION_FORWARDS);
|
||
return;
|
||
case CONFIG_STANDING:
|
||
currentAnimation = selectedStand;
|
||
animateAvatar(deltaTime, 0, DIRECTION_FORWARDS);
|
||
return;
|
||
case CONFIG_FLYING:
|
||
currentAnimation = selectedFly;
|
||
animateAvatar(deltaTime, 0, DIRECTION_FORWARDS);
|
||
return;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
// calcualte (local) change in position and velocity
|
||
var velocityVector = MyAvatar.getVelocity();
|
||
var velocity = Vec3.length(velocityVector);
|
||
|
||
// determine the candidate animation to play
|
||
var actionToTake = 0;
|
||
if( velocity < 0.1) {
|
||
actionToTake = STANDING;
|
||
standHints++;
|
||
}
|
||
else if(velocity<FLYING_SPEED) {
|
||
actionToTake = WALKING;
|
||
walkHints++;
|
||
}
|
||
else if(velocity>=FLYING_SPEED) {
|
||
actionToTake = FLYING;
|
||
flyHints++;
|
||
}
|
||
|
||
// calculate overriding (local) direction of translation for use later when decide which animation should be played
|
||
var principleDirection = 0;
|
||
var localVelocity = globalToLocal(velocityVector);
|
||
var deltaX = localVelocity.x;
|
||
var deltaY = -localVelocity.y;
|
||
var deltaZ = -localVelocity.z;
|
||
|
||
// TODO: find out why there is a reported high up / down velocity as we near walking -> standing...
|
||
var directionChangeThreshold = 0.3; // this little hack makes it a bit better, but at the cost of delayed updated chagne in direction etc :-(
|
||
if(velocity<directionChangeThreshold)
|
||
principleDirection = lastDirection;
|
||
else {
|
||
// who's the biggest out of the x, y and z components taken from the difference vector?
|
||
if(Math.abs(deltaX)>Math.abs(deltaY)
|
||
&&Math.abs(deltaX)>Math.abs(deltaZ)) {
|
||
if(deltaX<0) {
|
||
principleDirection = DIRECTION_RIGHT;//print('velocity = '+velocity + ' DIRECTION_RIGHT: deltaX '+deltaX+' deltaY '+deltaY+' deltaZ '+deltaZ);
|
||
} else {
|
||
principleDirection = DIRECTION_LEFT;//print('velocity = '+velocity + ' DIRECTION_LEFT: deltaX '+deltaX+' deltaY '+deltaY+' deltaZ '+deltaZ);
|
||
}
|
||
}
|
||
else if(Math.abs(deltaY)>Math.abs(deltaX)
|
||
&&Math.abs(deltaY)>Math.abs(deltaZ)) {
|
||
if(deltaY>0) {
|
||
principleDirection = DIRECTION_DOWN;//print('velocity = '+velocity + ' DIRECTION_DOWN: deltaX '+deltaX+' deltaY '+deltaY+' deltaZ '+deltaZ);
|
||
}
|
||
else {
|
||
principleDirection = DIRECTION_UP;//print('velocity = '+velocity + ' DIRECTION_UP: deltaX '+deltaX+' deltaY '+deltaY+' deltaZ '+deltaZ);
|
||
}
|
||
}
|
||
else if(Math.abs(deltaZ)>Math.abs(deltaX)
|
||
&&Math.abs(deltaZ)>Math.abs(deltaY)) {
|
||
if(deltaZ>0) {
|
||
principleDirection = DIRECTION_BACKWARDS;//print('velocity = '+velocity + ' DIRECTION_BACKWARDS: deltaX '+deltaX+' deltaY '+deltaY+' deltaZ '+deltaZ);
|
||
} else {
|
||
principleDirection = DIRECTION_FORWARDS;//print('velocity = '+velocity + ' DIRECTION_FORWARDS: deltaX '+deltaX+' deltaY '+deltaY+' deltaZ '+deltaZ);
|
||
}
|
||
}
|
||
}
|
||
lastDirection = principleDirection;
|
||
|
||
// select appropriate animation
|
||
switch(actionToTake) {
|
||
|
||
case STANDING:
|
||
if( standHints > requiredHints || INTERNAL_STATE===STANDING) { // wait for a few consecutive hints (17mS each)
|
||
|
||
standHints = 0;
|
||
walkHints = 0;
|
||
flyHints = 0;
|
||
if(INTERNAL_STATE!==STANDING) setInternalState(STANDING);
|
||
currentAnimation = selectedStand;
|
||
animateAvatar(1,0,principleDirection);
|
||
}
|
||
return;
|
||
|
||
case WALKING:
|
||
if( walkHints > requiredHints || INTERNAL_STATE===WALKING) { // wait for few consecutive hints (17mS each)
|
||
|
||
standHints = 0;
|
||
walkHints = 0;
|
||
flyHints = 0;
|
||
if(INTERNAL_STATE!==WALKING) setInternalState(WALKING);
|
||
|
||
// change animation for flying directly up or down
|
||
if(principleDirection===DIRECTION_UP) {
|
||
currentAnimation = selectedFlyUp;
|
||
}
|
||
else if(principleDirection===DIRECTION_DOWN) {
|
||
currentAnimation = selectedFlyDown;
|
||
}
|
||
else {
|
||
currentAnimation = selectedWalk;
|
||
}
|
||
animateAvatar(deltaTime, velocity, principleDirection);
|
||
}
|
||
return;
|
||
|
||
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
|
||
if(principleDirection===DIRECTION_UP) {
|
||
currentAnimation = selectedFlyUp;
|
||
}
|
||
else if(principleDirection===DIRECTION_DOWN) {
|
||
currentAnimation = selectedFlyDown;
|
||
}
|
||
else currentAnimation = selectedFly;
|
||
animateAvatar(deltaTime, velocity, principleDirection);
|
||
}
|
||
return;
|
||
}
|
||
}
|
||
});
|
||
|
||
|
||
// overlays start
|
||
|
||
// controller dimensions
|
||
var backgroundWidth = 350;
|
||
var backgroundHeight = 700;
|
||
var backgroundX = Window.innerWidth-backgroundWidth-50;
|
||
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/2 - jointsControlWidth/2;
|
||
var jointsControlY = backgroundY/2 - jointsControlHeight/2;
|
||
var buttonsY = 20; // distance from top of panel to buttons
|
||
|
||
// arrays of overlay names
|
||
var sliderthumbOverlays = []; // thumb sliders
|
||
var backgroundOverlays = [];
|
||
var buttonOverlays = [];
|
||
var jointsControlOverlays = [];
|
||
var bigButtonOverlays = [];
|
||
|
||
|
||
// take a deep breath then load up the overlays
|
||
// UI backgrounds
|
||
var controlsBackground = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX, y: backgroundY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-background.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
backgroundOverlays.push(controlsBackground);
|
||
|
||
var controlsBackgroundWalkEditStyles = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX, y: backgroundY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-background-edit-styles.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
backgroundOverlays.push(controlsBackgroundWalkEditStyles);
|
||
|
||
var controlsBackgroundWalkEditTweaks = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX, y: backgroundY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-background-edit-tweaks.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
backgroundOverlays.push(controlsBackgroundWalkEditTweaks);
|
||
|
||
var controlsBackgroundWalkEditJoints = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX, y: backgroundY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-background-edit-joints.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
backgroundOverlays.push(controlsBackgroundWalkEditJoints);
|
||
|
||
var controlsBackgroundFlyingEdit = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX, y: backgroundY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-background-flying-edit.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
backgroundOverlays.push(controlsBackgroundFlyingEdit);
|
||
|
||
|
||
// minimised tab - not put in array, as is a one off
|
||
var controlsMinimisedTab = Overlays.addOverlay("image", {
|
||
bounds: { x: Window.innerWidth - 35, y: Window.innerHeight/2 - 175, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-tab.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
|
||
// load character joint selection control images
|
||
var hipsJointControl = Overlays.addOverlay("image", {
|
||
bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-background-edit-hips.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
jointsControlOverlays.push(hipsJointControl);
|
||
|
||
var upperLegsJointControl = Overlays.addOverlay("image", {
|
||
bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-background-edit-upper-legs.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
jointsControlOverlays.push(upperLegsJointControl);
|
||
|
||
var lowerLegsJointControl = Overlays.addOverlay("image", {
|
||
bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-background-edit-lower-legs.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
jointsControlOverlays.push(lowerLegsJointControl);
|
||
|
||
var feetJointControl = Overlays.addOverlay("image", {
|
||
bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-background-edit-feet.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
jointsControlOverlays.push(feetJointControl);
|
||
|
||
var toesJointControl = Overlays.addOverlay("image", {
|
||
bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-background-edit-toes.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
jointsControlOverlays.push(toesJointControl);
|
||
|
||
var spineJointControl = Overlays.addOverlay("image", {
|
||
bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-background-edit-spine.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
jointsControlOverlays.push(spineJointControl);
|
||
|
||
var spine1JointControl = Overlays.addOverlay("image", {
|
||
bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-background-edit-spine1.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
jointsControlOverlays.push(spine1JointControl);
|
||
|
||
var spine2JointControl = Overlays.addOverlay("image", {
|
||
bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-background-edit-spine2.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
jointsControlOverlays.push(spine2JointControl);
|
||
|
||
var shouldersJointControl = Overlays.addOverlay("image", {
|
||
bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-background-edit-shoulders.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
jointsControlOverlays.push(shouldersJointControl);
|
||
|
||
var upperArmsJointControl = Overlays.addOverlay("image", {
|
||
bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-background-edit-upper-arms.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
jointsControlOverlays.push(upperArmsJointControl);
|
||
|
||
var forearmsJointControl = Overlays.addOverlay("image", {
|
||
bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-background-edit-forearms.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
jointsControlOverlays.push(forearmsJointControl);
|
||
|
||
var handsJointControl = Overlays.addOverlay("image", {
|
||
bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-background-edit-hands.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
jointsControlOverlays.push(handsJointControl);
|
||
|
||
var headJointControl = Overlays.addOverlay("image", {
|
||
bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-background-edit-head.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
jointsControlOverlays.push(headJointControl);
|
||
|
||
|
||
// sider thumb overlays
|
||
var sliderOne = Overlays.addOverlay("image", {
|
||
bounds: { x: 0, y: 0, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-slider-handle.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
sliderthumbOverlays.push(sliderOne);
|
||
var sliderTwo = Overlays.addOverlay("image", {
|
||
bounds: { x: 0, y: 0, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-slider-handle.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
sliderthumbOverlays.push(sliderTwo);
|
||
var sliderThree = Overlays.addOverlay("image", {
|
||
bounds: { x: 0, y: 0, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-slider-handle.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
sliderthumbOverlays.push(sliderThree);
|
||
var sliderFour = Overlays.addOverlay("image", {
|
||
bounds: { x: 0, y: 0, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-slider-handle.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
sliderthumbOverlays.push(sliderFour);
|
||
var sliderFive = Overlays.addOverlay("image", {
|
||
bounds: { x: 0, y: 0, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-slider-handle.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
sliderthumbOverlays.push(sliderFive);
|
||
var sliderSix = Overlays.addOverlay("image", {
|
||
bounds: { x: 0, y: 0, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-slider-handle.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
sliderthumbOverlays.push(sliderSix);
|
||
var sliderSeven = Overlays.addOverlay("image", {
|
||
bounds: { x: 0, y: 0, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-slider-handle.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
sliderthumbOverlays.push(sliderSeven);
|
||
var sliderEight = Overlays.addOverlay("image", {
|
||
bounds: { x: 0, y: 0, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-slider-handle.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
sliderthumbOverlays.push(sliderEight);
|
||
var sliderNine = Overlays.addOverlay("image", {
|
||
bounds: { x: 0, y: 0, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-slider-handle.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
sliderthumbOverlays.push(sliderNine);
|
||
|
||
|
||
// button overlays
|
||
var onButton = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX+20, y: backgroundY+buttonsY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-on-button.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
buttonOverlays.push(onButton);
|
||
var offButton = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX+20, y: backgroundY+buttonsY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-off-button.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
buttonOverlays.push(offButton);
|
||
var configWalkButton = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-edit-walk-button.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
buttonOverlays.push(configWalkButton);
|
||
var configWalkButtonSelected = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-edit-walk-button-selected.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
buttonOverlays.push(configWalkButtonSelected);
|
||
var configStandButton = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX+146, y: backgroundY+buttonsY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-edit-stand-button.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
buttonOverlays.push(configStandButton);
|
||
var configStandButtonSelected = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX+146, y: backgroundY+buttonsY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-edit-stand-button-selected.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
buttonOverlays.push(configStandButtonSelected);
|
||
var configFlyingButton = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX+209, y: backgroundY+buttonsY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-edit-fly-button.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
buttonOverlays.push(configFlyingButton);
|
||
var configFlyingButtonSelected = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX+209, y: backgroundY+buttonsY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-edit-fly-button-selected.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
buttonOverlays.push(configFlyingButtonSelected);
|
||
var hideButton = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX+272, y: backgroundY+buttonsY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-hide-button.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
buttonOverlays.push(hideButton);
|
||
var hideButtonSelected = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX+272, y: backgroundY+buttonsY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-hide-button-selected.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
buttonOverlays.push(hideButtonSelected);
|
||
var configWalkStylesButton = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-walk-styles-button.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
buttonOverlays.push(configWalkStylesButton);
|
||
var configWalkStylesButtonSelected = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-walk-styles-button-selected.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
buttonOverlays.push(configWalkStylesButtonSelected);
|
||
var configWalkTweaksButton = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX+146, y: backgroundY+buttonsY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-walk-tweaks-button.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
buttonOverlays.push(configWalkTweaksButton);
|
||
var configWalkTweaksButtonSelected = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX+146, y: backgroundY+buttonsY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-walk-tweaks-button-selected.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
buttonOverlays.push(configWalkTweaksButtonSelected);
|
||
var configWalkJointsButton = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX+209, y: backgroundY+buttonsY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-bones-button.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
buttonOverlays.push(configWalkJointsButton);
|
||
var configWalkJointsButtonSelected = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX+209, y: backgroundY+buttonsY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-bones-button-selected.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
buttonOverlays.push(configWalkJointsButtonSelected);
|
||
var backButton = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX+272, y: backgroundY+buttonsY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-back-button.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
buttonOverlays.push(backButton);
|
||
var backButtonSelected = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX+272, y: backgroundY+buttonsY, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-back-button-selected.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
buttonOverlays.push(backButtonSelected);
|
||
|
||
// big button overlays - front panel
|
||
var bigButtonYOffset = 408; // distance from top of panel to top of first button
|
||
|
||
var femaleBigButton = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-female-big-button.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
bigButtonOverlays.push(femaleBigButton);
|
||
|
||
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
|
||
});
|
||
bigButtonOverlays.push(femaleBigButtonSelected);
|
||
|
||
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
|
||
});
|
||
bigButtonOverlays.push(maleBigButton);
|
||
|
||
var maleBigButtonSelected = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset + 60, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-male-big-button-selected.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
bigButtonOverlays.push(maleBigButtonSelected);
|
||
|
||
var armsFreeBigButton = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset + 120, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-arms-free-button.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
bigButtonOverlays.push(armsFreeBigButton);
|
||
|
||
var armsFreeBigButtonSelected = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset + 120, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-arms-free-button-selected.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
bigButtonOverlays.push(armsFreeBigButtonSelected);
|
||
|
||
var footstepsBigButton = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset + 180, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-footsteps-big-button.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
bigButtonOverlays.push(footstepsBigButton);
|
||
|
||
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
|
||
});
|
||
bigButtonOverlays.push(footstepsBigButtonSelected);
|
||
|
||
|
||
// walk styles
|
||
bigButtonYOffset = 121;
|
||
var strutWalkBigButton = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-walk-select-button-strut.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
bigButtonOverlays.push(strutWalkBigButton);
|
||
|
||
var strutWalkBigButtonSelected = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-walk-select-button-strut-selected.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
bigButtonOverlays.push(strutWalkBigButtonSelected);
|
||
|
||
bigButtonYOffset += 60
|
||
var sexyWalkBigButton = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-walk-select-button-sexy.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
bigButtonOverlays.push(sexyWalkBigButton);
|
||
|
||
var sexyWalkBigButtonSelected = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-walk-select-button-sexy-selected.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
bigButtonOverlays.push(sexyWalkBigButtonSelected);
|
||
|
||
bigButtonYOffset += 60;
|
||
var powerWalkBigButton = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-walk-select-button-power-walk.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
bigButtonOverlays.push(powerWalkBigButton);
|
||
|
||
var powerWalkBigButtonSelected = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-walk-select-button-power-walk-selected.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
bigButtonOverlays.push(powerWalkBigButtonSelected);
|
||
|
||
bigButtonYOffset += 60;
|
||
var shuffleBigButton = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-walk-select-button-shuffle.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
bigButtonOverlays.push(shuffleBigButton);
|
||
|
||
var shuffleBigButtonSelected = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-walk-select-button-shuffle-selected.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
bigButtonOverlays.push(shuffleBigButtonSelected);
|
||
|
||
bigButtonYOffset += 60;
|
||
var runBigButton = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-walk-select-button-run.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
bigButtonOverlays.push(runBigButton);
|
||
|
||
var runBigButtonSelected = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-walk-select-button-run-selected.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
bigButtonOverlays.push(runBigButtonSelected);
|
||
|
||
bigButtonYOffset += 60;
|
||
var sneakyWalkBigButton = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-walk-select-button-sneaky.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
bigButtonOverlays.push(sneakyWalkBigButton);
|
||
|
||
var sneakyWalkBigButtonSelected = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-walk-select-button-sneaky-selected.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
bigButtonOverlays.push(sneakyWalkBigButtonSelected);
|
||
|
||
bigButtonYOffset += 60;
|
||
var toughWalkBigButton = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-walk-select-button-tough.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
bigButtonOverlays.push(toughWalkBigButton);
|
||
|
||
var toughWalkBigButtonSelected = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-walk-select-button-tough-selected.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
bigButtonOverlays.push(toughWalkBigButtonSelected);
|
||
|
||
bigButtonYOffset += 60;
|
||
var coolWalkBigButton = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-walk-select-button-cool.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
bigButtonOverlays.push(coolWalkBigButton);
|
||
|
||
var coolWalkBigButtonSelected = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-walk-select-button-cool-selected.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
bigButtonOverlays.push(coolWalkBigButtonSelected);
|
||
|
||
bigButtonYOffset += 60;
|
||
var elderlyWalkBigButton = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-walk-select-button-elderly.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
bigButtonOverlays.push(elderlyWalkBigButton);
|
||
|
||
var elderlyWalkBigButtonSelected = Overlays.addOverlay("image", {
|
||
bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1},
|
||
imageURL: pathToOverlays+"ddao-walk-select-button-elderly-selected.png",
|
||
color: { red: 255, green: 255, blue: 255},
|
||
alpha: 1
|
||
});
|
||
bigButtonOverlays.push(elderlyWalkBigButtonSelected);
|
||
|
||
// 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: false,
|
||
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: false,
|
||
anchor: "MyAvatar"
|
||
});
|
||
|
||
var debugText = Overlays.addOverlay("text", {
|
||
x: Window.innerWidth/2 + 200,
|
||
y: Window.innerHeight/2 - 300,
|
||
width: 200,
|
||
height: 130,
|
||
color: { red: 255, green: 255, blue: 255},
|
||
textColor: { red: 255, green: 255, blue: 255},
|
||
topMargin: 5,
|
||
leftMargin: 5,
|
||
visible: false,
|
||
backgroundColor: { red: 255, green: 255, blue: 255},
|
||
text: "Debug area\nNothing to report yet."
|
||
});
|
||
|
||
// 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) {
|
||
|
||
var bigButtonWidth = 1;
|
||
var bigButtonHeight = 1;
|
||
|
||
if(showButtons) {
|
||
var bigButtonWidth = 230;
|
||
var bigButtonHeight = 36;
|
||
}
|
||
if(avatarGender===FEMALE) {
|
||
Overlays.editOverlay(femaleBigButtonSelected, { width: bigButtonWidth, height: bigButtonHeight } );
|
||
Overlays.editOverlay(femaleBigButton, { width: 1, height: 1 } );
|
||
Overlays.editOverlay(maleBigButtonSelected, { width: 1, height: 1 } );
|
||
Overlays.editOverlay(maleBigButton, { width: bigButtonWidth, height: bigButtonHeight } );
|
||
} else {
|
||
Overlays.editOverlay(femaleBigButtonSelected, { width: 1, height: 1 } );
|
||
Overlays.editOverlay(femaleBigButton, { width: bigButtonWidth, height: bigButtonHeight } );
|
||
Overlays.editOverlay(maleBigButtonSelected, { width: bigButtonWidth, height: bigButtonHeight } );
|
||
Overlays.editOverlay(maleBigButton, { width: 1, height: 1 } );
|
||
}
|
||
if(armsFree) {
|
||
Overlays.editOverlay(armsFreeBigButtonSelected, { width: bigButtonWidth, height: bigButtonHeight } );
|
||
Overlays.editOverlay(armsFreeBigButton, { width: 1, height: 1 } );
|
||
} else {
|
||
Overlays.editOverlay(armsFreeBigButtonSelected, { width: 1, height: 1 } );
|
||
Overlays.editOverlay(armsFreeBigButton, { width: bigButtonWidth, height: bigButtonHeight } );
|
||
}
|
||
if(playFootStepSounds) {
|
||
Overlays.editOverlay(footstepsBigButtonSelected, { width: bigButtonWidth, height: bigButtonHeight } );
|
||
Overlays.editOverlay(footstepsBigButton, { width: 1, height: 1 } );
|
||
} else {
|
||
Overlays.editOverlay(footstepsBigButtonSelected, { width: 1, height: 1 } );
|
||
Overlays.editOverlay(footstepsBigButton, { width: bigButtonWidth, height: bigButtonHeight } );
|
||
}
|
||
}
|
||
function minimiseDialog() {
|
||
|
||
if(minimised) {
|
||
setBackground();
|
||
hidebuttonOverlays();
|
||
setSliderthumbsVisible(false);
|
||
hideJointControls();
|
||
showFrontPanelButtons(false);
|
||
Overlays.editOverlay(controlsMinimisedTab, { width: 36, height: 351 } );
|
||
} else {
|
||
setInternalState(STANDING); // show all the controls again
|
||
Overlays.editOverlay(controlsMinimisedTab, { width: 1, height: 1 } );
|
||
}
|
||
}
|
||
function setBackground(backgroundName) {
|
||
for(var i in backgroundOverlays) {
|
||
if(backgroundOverlays[i] === backgroundName)
|
||
Overlays.editOverlay(backgroundName, {width: backgroundWidth, height: backgroundHeight } );
|
||
else Overlays.editOverlay(backgroundOverlays[i], { width: 1, height: 1} );
|
||
}
|
||
}
|
||
function setButtonOverlayVisible(buttonOverlayName) {
|
||
for(var i in buttonOverlays) {
|
||
if(buttonOverlays[i] === buttonOverlayName) {
|
||
Overlays.editOverlay(buttonOverlayName, { width: 60, height: 47 } );
|
||
}
|
||
}
|
||
}
|
||
// top row menu type buttons (smaller)
|
||
function hidebuttonOverlays() {
|
||
for(var i in buttonOverlays) {
|
||
Overlays.editOverlay(buttonOverlays[i], { width: 1, height: 1 } );
|
||
}
|
||
}
|
||
function hideJointControls() {
|
||
for(var i in jointsControlOverlays) {
|
||
Overlays.editOverlay(jointsControlOverlays[i], { width: 1, height: 1 } );
|
||
}
|
||
}
|
||
function setSliderthumbsVisible(visible) {
|
||
var sliderThumbSize = 0;
|
||
if(visible) sliderThumbSize = 25;
|
||
for(var i = 0 ; i < sliderthumbOverlays.length ; i++) {
|
||
Overlays.editOverlay(sliderthumbOverlays[i], { width: sliderThumbSize, height: sliderThumbSize} );
|
||
}
|
||
}
|
||
function initialiseWalkJointsPanel(propertyIndex) {
|
||
|
||
selectedJointIndex = propertyIndex;
|
||
|
||
// set the image for the selected joint on the character control
|
||
hideJointControls();
|
||
switch (selectedJointIndex) {
|
||
case 0:
|
||
Overlays.editOverlay(hipsJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} );
|
||
break;
|
||
case 1:
|
||
Overlays.editOverlay(upperLegsJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} );
|
||
break;
|
||
case 2:
|
||
Overlays.editOverlay(lowerLegsJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} );
|
||
break;
|
||
case 3:
|
||
Overlays.editOverlay(feetJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} );
|
||
break;
|
||
case 4:
|
||
Overlays.editOverlay(toesJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} );
|
||
break;
|
||
case 5:
|
||
Overlays.editOverlay(spineJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} );
|
||
break;
|
||
case 6:
|
||
Overlays.editOverlay(spine1JointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} );
|
||
break;
|
||
case 7:
|
||
Overlays.editOverlay(spine2JointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} );
|
||
break;
|
||
case 8:
|
||
Overlays.editOverlay(shouldersJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} );
|
||
break;
|
||
case 9:
|
||
Overlays.editOverlay(upperArmsJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} );
|
||
break;
|
||
case 10:
|
||
Overlays.editOverlay(forearmsJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} );
|
||
break;
|
||
case 11:
|
||
Overlays.editOverlay(handsJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} );
|
||
break;
|
||
case 12:
|
||
Overlays.editOverlay(headJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} );
|
||
break;
|
||
}
|
||
|
||
// 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], { bounds: { x: minSliderX + sliderXPos, y: yLocation+=30, width: 25, height: 25}} );
|
||
sliderXPos = currentAnimation.joints[selectedJointIndex].yaw / sliderRanges.joints[selectedJointIndex].yawRange * sliderRangeX;
|
||
Overlays.editOverlay(sliderthumbOverlays[++i], { bounds: { x: minSliderX + sliderXPos, y: yLocation+=30, width: 25, height: 25}} );
|
||
sliderXPos = currentAnimation.joints[selectedJointIndex].roll / sliderRanges.joints[selectedJointIndex].rollRange * sliderRangeX;
|
||
Overlays.editOverlay(sliderthumbOverlays[++i], { bounds: { x: minSliderX + sliderXPos, y: yLocation+=30, width: 25, height: 25}} );
|
||
|
||
// set phases (full range, -180 to 180)
|
||
sliderXPos = (90 + currentAnimation.joints[selectedJointIndex].pitchPhase/2)/180 * sliderRangeX;
|
||
Overlays.editOverlay(sliderthumbOverlays[++i], { bounds: { x: minSliderX + sliderXPos, y: yLocation+=30, width: 25, height: 25}} );
|
||
sliderXPos = (90 + currentAnimation.joints[selectedJointIndex].yawPhase/2)/180 * sliderRangeX;
|
||
Overlays.editOverlay(sliderthumbOverlays[++i], { bounds: { x: minSliderX + sliderXPos, y: yLocation+=30, width: 25, height: 25}} );
|
||
sliderXPos = (90 + currentAnimation.joints[selectedJointIndex].rollPhase/2)/180 * sliderRangeX;
|
||
Overlays.editOverlay(sliderthumbOverlays[++i], { bounds: { x: minSliderX + sliderXPos, y: yLocation+=30, width: 25, height: 25}} );
|
||
|
||
// 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], { bounds: { x: minSliderX + sliderXPos, y: yLocation+=30, width: 25, height: 25}} );
|
||
sliderXPos = (((sliderRanges.joints[selectedJointIndex].yawOffsetRange+currentAnimation.joints[selectedJointIndex].yawOffset)/2)/sliderRanges.joints[selectedJointIndex].yawOffsetRange) * sliderRangeX;
|
||
Overlays.editOverlay(sliderthumbOverlays[++i], { bounds: { x: minSliderX + sliderXPos, y: yLocation+=30, width: 25, height: 25}} );
|
||
sliderXPos = (((sliderRanges.joints[selectedJointIndex].rollOffsetRange+currentAnimation.joints[selectedJointIndex].rollOffset)/2)/sliderRanges.joints[selectedJointIndex].rollOffsetRange) * sliderRangeX;
|
||
Overlays.editOverlay(sliderthumbOverlays[++i], { bounds: { x: minSliderX + sliderXPos, y: yLocation+=30, width: 25, height: 25}} );
|
||
}
|
||
|
||
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], { bounds: { x: minSliderX + sliderXPos, y: yLocation+=60, width: 25, height: 25}} );
|
||
sliderXPos = currentAnimation.settings.takeFlightVelocity / 300 * sliderRangeX; // start flying speed
|
||
Overlays.editOverlay(sliderthumbOverlays[++i], { bounds: { x: minSliderX + sliderXPos, y: yLocation+=60, width: 25, height: 25}} );
|
||
sliderXPos = currentAnimation.joints[0].sway / sliderRanges.joints[0].swayRange * sliderRangeX; // Hips sway
|
||
Overlays.editOverlay(sliderthumbOverlays[++i], { bounds: { x: minSliderX + sliderXPos, y: yLocation+=60, width: 25, height: 25}} );
|
||
sliderXPos = currentAnimation.joints[0].bob / sliderRanges.joints[0].bobRange * sliderRangeX; // Hips bob
|
||
Overlays.editOverlay(sliderthumbOverlays[++i], { bounds: { x: minSliderX + sliderXPos, y: yLocation+=60, width: 25, height: 25}} );
|
||
sliderXPos = currentAnimation.joints[0].thrust / sliderRanges.joints[0].thrustRange * sliderRangeX; // Hips thrust
|
||
Overlays.editOverlay(sliderthumbOverlays[++i], { bounds: { x: minSliderX + sliderXPos, y: yLocation+=60, width: 25, height: 25}} );
|
||
sliderXPos = (0.5+(currentAnimation.adjusters.legsSeparation.strength/2)) * sliderRangeX; // legs separation
|
||
Overlays.editOverlay(sliderthumbOverlays[++i], { bounds: { x: minSliderX + sliderXPos, y: yLocation+=60, width: 25, height: 25}} );
|
||
sliderXPos = currentAnimation.adjusters.stride.strength * sliderRangeX; // stride
|
||
Overlays.editOverlay(sliderthumbOverlays[++i], { bounds: { x: minSliderX + sliderXPos, y: yLocation+=60, width: 25, height: 25}} );
|
||
sliderXPos = currentAnimation.joints[9].yaw / sliderRanges.joints[9].yawRange * sliderRangeX; // arms swing - is just upper arms yaw
|
||
Overlays.editOverlay(sliderthumbOverlays[++i], { bounds: { x: minSliderX + sliderXPos, y: yLocation+=60, width: 25, height: 25}} );
|
||
sliderXPos = (((sliderRanges.joints[9].pitchOffsetRange-currentAnimation.joints[9].pitchOffset)/2)/sliderRanges.joints[9].pitchOffsetRange) * sliderRangeX; // arms out - is just upper arms pitch offset
|
||
Overlays.editOverlay(sliderthumbOverlays[++i], { bounds: { x: minSliderX + sliderXPos, y: yLocation+=60, width: 25, height: 25}} );
|
||
}
|
||
|
||
function showWalkStyleButtons(showButtons) {
|
||
|
||
var bigButtonWidth = 230;
|
||
var bigButtonHeight = 36;
|
||
|
||
if(!showButtons) {
|
||
bigButtonWidth = 1;
|
||
bigButtonHeight = 1;
|
||
}
|
||
|
||
// 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], {width: 1, height: 1});
|
||
}
|
||
|
||
if(!showButtons) return;
|
||
|
||
// set all the non-selected ones to showing
|
||
for(var i = 8 ; i < bigButtonOverlays.length ; i+=2) {
|
||
Overlays.editOverlay(bigButtonOverlays[i], {width: bigButtonWidth, height: bigButtonHeight});
|
||
}
|
||
|
||
// set the currently selected one
|
||
if(selectedWalk === femaleSexyWalk || selectedWalk === maleSexyWalk) {
|
||
Overlays.editOverlay(sexyWalkBigButtonSelected, {width: bigButtonWidth, height: bigButtonHeight});
|
||
Overlays.editOverlay(sexyWalkBigButton, {width: 1, height: 1});
|
||
}
|
||
else if(selectedWalk === femaleStrutWalk || selectedWalk === maleStrutWalk) {
|
||
Overlays.editOverlay(strutWalkBigButtonSelected, {width: bigButtonWidth, height: bigButtonHeight});
|
||
Overlays.editOverlay(strutWalkBigButton, {width: 1, height: 1});
|
||
}
|
||
else if(selectedWalk === femalePowerWalk || selectedWalk === malePowerWalk) {
|
||
Overlays.editOverlay(powerWalkBigButtonSelected, {width: bigButtonWidth, height: bigButtonHeight});
|
||
Overlays.editOverlay(powerWalkBigButton, {width: 1, height: 1});
|
||
}
|
||
else if(selectedWalk === femaleShuffle || selectedWalk === maleShuffle) {
|
||
Overlays.editOverlay(shuffleBigButtonSelected, {width: bigButtonWidth, height: bigButtonHeight});
|
||
Overlays.editOverlay(shuffleBigButton, {width: 1, height: 1});
|
||
}
|
||
else if(selectedWalk === femaleRun || selectedWalk === maleRun) {
|
||
Overlays.editOverlay(runBigButtonSelected, {width: bigButtonWidth, height: bigButtonHeight});
|
||
Overlays.editOverlay(runBigButton, {width: 1, height: 1});
|
||
}
|
||
else if(selectedWalk === femaleRandomWalk || selectedWalk === maleRandomWalk) {
|
||
Overlays.editOverlay(sneakyWalkBigButtonSelected, {width: bigButtonWidth, height: bigButtonHeight});
|
||
Overlays.editOverlay(sneakyWalkBigButton, {width: 1, height: 1});
|
||
}
|
||
else if(selectedWalk === femaleToughWalk || selectedWalk === maleToughWalk) {
|
||
Overlays.editOverlay(toughWalkBigButtonSelected, {width: bigButtonWidth, height: bigButtonHeight});
|
||
Overlays.editOverlay(toughWalkBigButton, {width: 1, height: 1});
|
||
}
|
||
else if(selectedWalk === femaleCoolWalk || selectedWalk === maleCoolWalk) {
|
||
Overlays.editOverlay(coolWalkBigButtonSelected, {width: bigButtonWidth, height: bigButtonHeight});
|
||
Overlays.editOverlay(coolWalkBigButton, {width: 1, height: 1});
|
||
}
|
||
else if(selectedWalk === femaleElderlyWalk || selectedWalk === maleElderlyWalk) {
|
||
Overlays.editOverlay(elderlyWalkBigButtonSelected, {width: bigButtonWidth, height: bigButtonHeight});
|
||
Overlays.editOverlay(elderlyWalkBigButton, {width: 1, height: 1});
|
||
}
|
||
}
|
||
|
||
// 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, { width: 1, height: 1 } );
|
||
Overlays.editOverlay(hideButtonSelected, { width: 60, height: 47 } );
|
||
return;
|
||
|
||
case backButton:
|
||
Overlays.editOverlay(backButton, { width: 1, height: 1 } );
|
||
Overlays.editOverlay(backButtonSelected, { width: 60, height: 47 } );
|
||
return;
|
||
|
||
case controlsMinimisedTab:
|
||
// TODO: add visual user feedback for tab click
|
||
return;
|
||
|
||
case footstepsBigButton:
|
||
playFootStepSounds = true;
|
||
Overlays.editOverlay(footstepsBigButtonSelected, { width: 230, height: 36 } );
|
||
Overlays.editOverlay(footstepsBigButton, { width: 1, height: 1 } );
|
||
return;
|
||
|
||
case footstepsBigButtonSelected:
|
||
playFootStepSounds = false;
|
||
Overlays.editOverlay(footstepsBigButton, { width: 230, height: 36 } );
|
||
Overlays.editOverlay(footstepsBigButtonSelected, { width: 1, height: 1 } );
|
||
return;
|
||
|
||
case femaleBigButton:
|
||
case maleBigButtonSelected:
|
||
avatarGender = FEMALE;
|
||
selectedWalk = femaleStrutWalk;
|
||
selectedStand = femaleStandOne;
|
||
selectedFlyUp = femaleFlyingUp;
|
||
selectedFly = femaleFlying;
|
||
selectedFlyDown = femaleFlyingDown;
|
||
Overlays.editOverlay(femaleBigButtonSelected, { width: 230, height: 36 } );
|
||
Overlays.editOverlay(femaleBigButton, { width: 1, height: 1 } );
|
||
Overlays.editOverlay(maleBigButton, { width: 230, height: 36 } );
|
||
Overlays.editOverlay(maleBigButtonSelected, { width: 1, height: 1 } );
|
||
return;
|
||
|
||
case armsFreeBigButton:
|
||
armsFree = true;
|
||
Overlays.editOverlay(armsFreeBigButtonSelected, { width: 230, height: 36 } );
|
||
Overlays.editOverlay(armsFreeBigButton, { width: 1, height: 1 } );
|
||
return;
|
||
|
||
case armsFreeBigButtonSelected:
|
||
armsFree = false;
|
||
Overlays.editOverlay(armsFreeBigButtonSelected, { width: 1, height: 1 } );
|
||
Overlays.editOverlay(armsFreeBigButton, { width: 230, height: 36 } );
|
||
return;
|
||
|
||
case maleBigButton:
|
||
case femaleBigButtonSelected:
|
||
avatarGender = MALE;
|
||
selectedWalk = maleStrutWalk;
|
||
selectedStand = maleStandOne;
|
||
selectedFlyUp = maleFlyingUp;
|
||
selectedFly = maleFlying;
|
||
selectedFlyDown = maleFlyingDown;
|
||
Overlays.editOverlay(femaleBigButton, { width: 230, height: 36 } );
|
||
Overlays.editOverlay(femaleBigButtonSelected, { width: 1, height: 1 } );
|
||
Overlays.editOverlay(maleBigButtonSelected, { width: 230, height: 36 } );
|
||
Overlays.editOverlay(maleBigButton, { width: 1, height: 1 } );
|
||
return;
|
||
|
||
case coolWalkBigButton:
|
||
if(avatarGender===FEMALE) selectedWalk = femaleCoolWalk;
|
||
else selectedWalk = maleCoolWalk;
|
||
currentAnimation = selectedWalk;
|
||
showWalkStyleButtons(true);
|
||
maxFootForward = 0;
|
||
maxFootBackwards = 0;
|
||
break;
|
||
|
||
case coolWalkBigButton:
|
||
if(avatarGender===FEMALE) selectedWalk = femaleCoolWalk;
|
||
else selectedWalk = maleCoolWalk;
|
||
currentAnimation = selectedWalk;
|
||
showWalkStyleButtons(true);
|
||
maxFootForward = 0;
|
||
maxFootBackwards = 0;
|
||
break;
|
||
|
||
case elderlyWalkBigButton:
|
||
if(avatarGender===FEMALE) selectedWalk = femaleElderlyWalk;
|
||
else selectedWalk = maleElderlyWalk;
|
||
currentAnimation = selectedWalk;
|
||
showWalkStyleButtons(true);
|
||
maxFootForward = 0;
|
||
maxFootBackwards = 0;
|
||
break;
|
||
|
||
case powerWalkBigButton:
|
||
if(avatarGender===FEMALE) selectedWalk = femalePowerWalk;
|
||
else selectedWalk = malePowerWalk;
|
||
currentAnimation = selectedWalk;
|
||
showWalkStyleButtons(true);
|
||
maxFootForward = 0;
|
||
maxFootBackwards = 0;
|
||
break;
|
||
|
||
case runBigButton:
|
||
if(avatarGender===FEMALE) selectedWalk = femaleRun;
|
||
else selectedWalk = maleRun;
|
||
currentAnimation = selectedWalk;
|
||
showWalkStyleButtons(true);
|
||
maxFootForward = 0;
|
||
maxFootBackwards = 0;
|
||
break;
|
||
|
||
case sexyWalkBigButton:
|
||
if(avatarGender===FEMALE) selectedWalk = femaleSexyWalk;
|
||
else selectedWalk = maleSexyWalk;
|
||
currentAnimation = selectedWalk;
|
||
showWalkStyleButtons(true);
|
||
maxFootForward = 0;
|
||
maxFootBackwards = 0;
|
||
break;
|
||
|
||
case shuffleBigButton:
|
||
if(avatarGender===FEMALE) selectedWalk = femaleShuffle;
|
||
else selectedWalk = maleShuffle;
|
||
currentAnimation = selectedWalk;
|
||
showWalkStyleButtons(true);
|
||
maxFootForward = 0;
|
||
maxFootBackwards = 0;
|
||
break;
|
||
|
||
case sneakyWalkBigButton:
|
||
if(avatarGender===FEMALE) selectedWalk = femaleRandomWalk;
|
||
else selectedWalk = maleRandomWalk;
|
||
currentAnimation = selectedWalk;
|
||
showWalkStyleButtons(true);
|
||
maxFootForward = 0;
|
||
maxFootBackwards = 0;
|
||
break;
|
||
|
||
case strutWalkBigButton:
|
||
if(avatarGender===FEMALE) selectedWalk = femaleStrutWalk;
|
||
else selectedWalk = maleStrutWalk;
|
||
currentAnimation = selectedWalk;
|
||
showWalkStyleButtons(true);
|
||
maxFootForward = 0;
|
||
maxFootBackwards = 0;
|
||
break;
|
||
|
||
case toughWalkBigButton:
|
||
if(avatarGender===FEMALE) selectedWalk = femaleToughWalk;
|
||
else selectedWalk = maleToughWalk;
|
||
currentAnimation = selectedWalk;
|
||
showWalkStyleButtons(true);
|
||
maxFootForward = 0;
|
||
maxFootBackwards = 0;
|
||
break;
|
||
|
||
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) {
|
||
|
||
// 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) {
|
||
initialiseWalkJointsPanel(0);
|
||
return;
|
||
}
|
||
else if(clickX>63&&clickX<132&&clickY>156&&clickY<202) {
|
||
initialiseWalkJointsPanel(1);
|
||
return;
|
||
}
|
||
else if(clickX>58&&clickX<137&&clickY>203&&clickY<250) {
|
||
initialiseWalkJointsPanel(2);
|
||
return;
|
||
}
|
||
else if(clickX>58&&clickX<137&&clickY>250&&clickY<265) {
|
||
initialiseWalkJointsPanel(3);
|
||
return;
|
||
}
|
||
else if(clickX>58&&clickX<137&&clickY>265&&clickY<280) {
|
||
initialiseWalkJointsPanel(4);
|
||
return;
|
||
}
|
||
else if(clickX>78&&clickX<121&&clickY>111&&clickY<128) {
|
||
initialiseWalkJointsPanel(5);
|
||
return;
|
||
}
|
||
else if(clickX>78&&clickX<128&&clickY>89&&clickY<111) {
|
||
initialiseWalkJointsPanel(6);
|
||
return;
|
||
}
|
||
else if(clickX>85&&clickX<118&&clickY>77&&clickY<94) {
|
||
initialiseWalkJointsPanel(7);
|
||
return;
|
||
}
|
||
else if(clickX>64&&clickX<125&&clickY>55&&clickY<77) {
|
||
initialiseWalkJointsPanel(8);
|
||
return;
|
||
}
|
||
else if((clickX>44&&clickX<73&&clickY>71&&clickY<94)
|
||
||(clickX>125&&clickX<144&&clickY>71&&clickY<94)) {
|
||
initialiseWalkJointsPanel(9);
|
||
return;
|
||
}
|
||
else if((clickX>28&&clickX<57&&clickY>94&&clickY<119)
|
||
||(clickX>137&&clickX<170&&clickY>97&&clickY<114)) {
|
||
initialiseWalkJointsPanel(10);
|
||
return;
|
||
}
|
||
else if((clickX>18&&clickX<37&&clickY>115&&clickY<136)
|
||
||(clickX>157&&clickX<182&&clickY>115&&clickY<136)) {
|
||
initialiseWalkJointsPanel(11);
|
||
return;
|
||
}
|
||
else if(clickX>81&&clickX<116&&clickY>12&&clickY<53) {
|
||
initialiseWalkJointsPanel(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) {
|
||
|
||
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.adjusters.legsSeparation.strength = (thumbPositionNormalised-0.5)/2;
|
||
}
|
||
else if(movingSliderSeven) { // stride
|
||
Overlays.editOverlay(sliderSeven, { x: sliderX + minSliderX} );
|
||
currentAnimation.adjusters.stride.strength = thumbPositionNormalised;
|
||
}
|
||
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, {width: 0, height: 0} );
|
||
Overlays.editOverlay(onButton, {width: 60, height: 47 } );
|
||
stand();
|
||
}
|
||
else if(clickedOverlay === hideButton || clickedOverlay === hideButtonSelected){
|
||
Overlays.editOverlay(hideButton, { width: 60, height: 47 } );
|
||
Overlays.editOverlay(hideButtonSelected, { width: 1, height: 1 } );
|
||
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 configFlyingButtonSelected:
|
||
case configWalkStylesButtonSelected:
|
||
case configWalkTweaksButtonSelected:
|
||
case configWalkJointsButtonSelected:
|
||
setInternalState(STANDING);
|
||
break;
|
||
|
||
case onButton:
|
||
powerOn = false;
|
||
setInternalState(STANDING);
|
||
Overlays.editOverlay(offButton, {width: 60, height: 47 } );
|
||
Overlays.editOverlay(onButton, {width: 0, height: 0} );
|
||
resetJoints();
|
||
break;
|
||
|
||
case backButton:
|
||
case backButtonSelected:
|
||
Overlays.editOverlay(backButton, { width: 1, height: 1 } );
|
||
Overlays.editOverlay(backButtonSelected, { width: 1, height: 1 } );
|
||
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
|
||
break;
|
||
|
||
case configStandButton:
|
||
setInternalState(CONFIG_STANDING);
|
||
break;
|
||
|
||
case configFlyingButton:
|
||
setInternalState(CONFIG_FLYING);
|
||
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(debugText);
|
||
});
|
||
|
||
|
||
function keyPressEvent(event) {
|
||
|
||
//print('keyPressEvent: '+event.text);
|
||
|
||
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');
|
||
}
|
||
if (event.text == "t") {
|
||
statsOn = !statsOn;
|
||
if(statsOn) {
|
||
print('wheel stats on (t to turn off again)');
|
||
Overlays.editOverlay(debugText, {visible: true});
|
||
Overlays.editOverlay(walkWheelYLine, {visible: true});
|
||
Overlays.editOverlay(walkWheelZLine, {visible: true});
|
||
} else {
|
||
print('wheel stats off (t to turn on again)');
|
||
Overlays.editOverlay(debugText, {visible: false});
|
||
Overlays.editOverlay(walkWheelYLine, {visible: false});
|
||
Overlays.editOverlay(walkWheelZLine, {visible: false});
|
||
}
|
||
}
|
||
}
|
||
Controller.keyPressEvent.connect(keyPressEvent);
|
||
|
||
|
||
|
||
|
||
|
||
// debug and other info
|
||
var VERBOSE = false;
|
||
|
||
// TODO: implement joint mapping using reg expressions to cover a wide range of avi bone structures
|
||
var jointList = MyAvatar.getJointNames();
|
||
var jointMappings = "\n# Avatar joint list start";
|
||
for (var i = 0; i < jointList.length; i++) {
|
||
jointMappings = jointMappings + "\njointIndex = " + jointList[i] + " = " + i;
|
||
}
|
||
print(jointMappings + "\n# walk.js avatar joint list end");
|
||
|
||
// 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));
|
||
MyAvatar.clearJointData(jointList[i]);
|
||
}
|
||
var hipsToFeetDistance = MyAvatar.getJointPosition("Hips").y - MyAvatar.getJointPosition("RightFoot").y;
|
||
print('\nwalk.js: Hips to feet: '+hipsToFeetDistance);
|
||
|
||
|
||
////////////////////////////////////////////
|
||
// begin by setting the to state STANDING //
|
||
////////////////////////////////////////////
|
||
|
||
//curlFingers();
|
||
setInternalState(STANDING); |