From 552427061303986c4df53a5282e1d3e3cd96f8b3 Mon Sep 17 00:00:00 2001 From: DaveDubUK Date: Wed, 10 Sep 2014 23:57:10 +0700 Subject: [PATCH 001/179] walk.js script for https://worklist.net/19970 walk.js script for https://worklist.net/19970 --- examples/walk.js | 2540 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2540 insertions(+) create mode 100644 examples/walk.js diff --git a/examples/walk.js b/examples/walk.js new file mode 100644 index 0000000000..de349a95b8 --- /dev/null +++ b/examples/walk.js @@ -0,0 +1,2540 @@ +// +// 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)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é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 = 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(velocityMath.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); \ No newline at end of file From 80aa5e45f8f65eb83ae3972974812b80b9064a2b Mon Sep 17 00:00:00 2001 From: DaveDubUK Date: Thu, 25 Sep 2014 11:51:11 +0700 Subject: [PATCH 002/179] Update to walk.js 1.006b Update to walk.js 1.006b --- examples/walk.js | 3976 +++++++++++++++++++++++++++++++++------------- 1 file changed, 2885 insertions(+), 1091 deletions(-) diff --git a/examples/walk.js b/examples/walk.js index de349a95b8..17091b7f36 100644 --- a/examples/walk.js +++ b/examples/walk.js @@ -1,6 +1,7 @@ // // walk.js // +// version 1.006b // // Created by Davedub, August / September 2014 // @@ -15,19 +16,19 @@ // 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) +var pathToAnimFiles = 'http://s3-us-west-1.amazonaws.com/highfidelity-public/procedural-animator/animation-files/'; // working (but only without https) // path to the images used for the overlays -//var pathToOverlays = 'http://localhost/downloads/hf/overlays/'; // loads fine (files must be present on localhost) +//var pathToOverlays = 'http://localhost/downloads/hf/scripts/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) +var pathToOverlays = 'http://s3-us-west-1.amazonaws.com/highfidelity-public/procedural-animator/overlays/'; // working (but only without https) // path to the sounds used for the footsteps var pathToSounds = 'http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Footsteps/'; //var pathToSounds = 'http://localhost/downloads/hf/sounds/Footsteps/'; -// load all the animation datafiles ( 15 female, 15 male ~ 240k ) +// load all the animation datafiles 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"); @@ -41,8 +42,8 @@ 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-female-sidestep-left-animation.js"); +Script.include(pathToAnimFiles+"dd-female-sidestep-right-animation.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"); @@ -56,8 +57,8 @@ 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"); +Script.include(pathToAnimFiles+"dd-male-sidestep-left-animation.js"); +Script.include(pathToAnimFiles+"dd-male-sidestep-right-animation.js"); // read in the data from the animation files var FemaleCoolWalkFile = new FemaleCoolWalk(); @@ -86,10 +87,10 @@ 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 FemaleSideStepLeftFile = new FemaleSideStepLeft(); +var femaleSideStepLeft = FemaleSideStepLeftFile.loadAnimation(); +var FemaleSideStepRightFile = new FemaleSideStepRight(); +var femaleSideStepRight = FemaleSideStepRightFile.loadAnimation(); var MaleCoolWalkFile = new MaleCoolWalk(); var maleCoolWalk = MaleCoolWalkFile.loadAnimation(); var MaleElderlyWalkFile = new MaleElderlyWalk(); @@ -116,10 +117,10 @@ 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(); +var MaleSideStepLeftFile = new MaleSideStepLeft(); +var maleSideStepLeft = MaleSideStepLeftFile.loadAnimation(); +var MaleSideStepRightFile = new MaleSideStepRight(); +var maleSideStepRight = MaleSideStepRightFile.loadAnimation(); // read in the sounds var footsteps = []; @@ -130,230 +131,218 @@ 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 - } - ] -} +// all slider controls have a range (with the exception of phase controls that are always +-180) so we store them all here +var sliderRanges = {"joints":[{"name":"hips","pitchRange":25,"yawRange":25,"rollRange":25,"pitchOffsetRange":25,"yawOffsetRange":25,"rollOffsetRange":25,"thrustRange":0.01,"bobRange":0.02,"swayRange":0.01},{"name":"upperLegs","pitchRange":90,"yawRange":35,"rollRange":35,"pitchOffsetRange":60,"yawOffsetRange":20,"rollOffsetRange":20},{"name":"lowerLegs","pitchRange":90,"yawRange":20,"rollRange":20,"pitchOffsetRange":90,"yawOffsetRange":20,"rollOffsetRange":20},{"name":"feet","pitchRange":60,"yawRange":20,"rollRange":20,"pitchOffsetRange":60,"yawOffsetRange":50,"rollOffsetRange":50},{"name":"toes","pitchRange":90,"yawRange":20,"rollRange":20,"pitchOffsetRange":90,"yawOffsetRange":20,"rollOffsetRange":20},{"name":"spine","pitchRange":40,"yawRange":40,"rollRange":40,"pitchOffsetRange":90,"yawOffsetRange":50,"rollOffsetRange":50},{"name":"spine1","pitchRange":20,"yawRange":40,"rollRange":20,"pitchOffsetRange":90,"yawOffsetRange":50,"rollOffsetRange":50},{"name":"spine2","pitchRange":20,"yawRange":40,"rollRange":20,"pitchOffsetRange":90,"yawOffsetRange":50,"rollOffsetRange":50},{"name":"shoulders","pitchRange":35,"yawRange":40,"rollRange":20,"pitchOffsetRange":180,"yawOffsetRange":180,"rollOffsetRange":180},{"name":"upperArms","pitchRange":90,"yawRange":90,"rollRange":90,"pitchOffsetRange":180,"yawOffsetRange":180,"rollOffsetRange":180},{"name":"lowerArms","pitchRange":90,"yawRange":90,"rollRange":120,"pitchOffsetRange":180,"yawOffsetRange":180,"rollOffsetRange":180},{"name":"hands","pitchRange":90,"yawRange":180,"rollRange":90,"pitchOffsetRange":180,"yawOffsetRange":180,"rollOffsetRange":180},{"name":"head","pitchRange":20,"yawRange":20,"rollRange":20,"pitchOffsetRange":90,"yawOffsetRange":90,"rollOffsetRange":90}]}; // internal state (FSM based) constants -var STANDING = 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 STANDING = 1; +var WALKING = 2; +var SIDE_STEPPING = 3; +var FLYING = 4; +var CONFIG_WALK_STYLES = 5; +var CONFIG_WALK_TWEAKS = 6; +var CONFIG_WALK_JOINTS = 7; +var CONFIG_STANDING = 8; +var CONFIG_FLYING = 9; +var CONFIG_FLYING_UP = 10; +var CONFIG_FLYING_DOWN = 11; +var CONFIG_SIDESTEP_LEFT = 12; +var CONFIG_SIDESTEP_RIGHT = 14; var INTERNAL_STATE = STANDING; // status var powerOn = true; var paused = false; // pause animation playback whilst adjusting certain parameters -var minimised = false; -var armsFree = false; // set true for hydra support - experimental +var minimised = true; +var armsFree = true; // set true for hydra support - temporary fix for Hydras var statsOn = false; +var playFootStepSounds = true; // constants var MAX_WALK_SPEED = 1257; // max oscillation speed -var FLYING_SPEED = 12.5; // m/s - real humans can't run any faster -var TERMINAL_VELOCITY = 300; +var FLYING_SPEED = 6.4;// 12.4; // m/s - real humans can't run any faster than 12.4 m/s +var TERMINAL_VELOCITY = 300; // max speed imposed by Interface var DIRECTION_UP = 1; var DIRECTION_DOWN = 2; var DIRECTION_LEFT = 4; var DIRECTION_RIGHT = 8; var DIRECTION_FORWARDS = 16; var DIRECTION_BACKWARDS = 32; -var MALE = 64; -var FEMALE = 128; +var DIRECTION_NONE = 64; +var MALE = 1; +var FEMALE = 2; // 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; + +// avi gender and default animations +var avatarGender = MALE; +var selectedWalk = maleStrutWalk; // the currently selected animation walk file (to edit any animation, paste it's name here and select walk editing mode) +var selectedStand = maleStandOne; +var selectedFlyUp = maleFlyingUp; +var selectedFly = maleFlying; +var selectedFlyDown = maleFlyingDown; +var selectedSideStepLeft = maleSideStepLeft; +var selectedSideStepRight = maleSideStepRight; +if(avatarGender===FEMALE) { + + // to make toggling the default quick + selectedWalk = femaleStrutWalk; + selectedStand = femaleStandOne; + selectedFlyUp = femaleFlyingUp; + selectedFly = femaleFlying; + selectedFlyDown = femaleFlyingDown; + selectedSideStepLeft = femaleSideStepLeft; + selectedSideStepRight = femaleSideStepRight; +} var currentAnimation = selectedStand; // the current animation var selectedJointIndex = 0; // the index of the joint currently selected for editing -// stride calibration -var maxFootForward = 0; -var maxFootBackwards = 0; -var strideLength = 0; +var currentTransition = null; // used as a pointer to a Transition + // 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; +//var walkCycleStart = 140; // 105 for female strut... best foot forwards - TODO: if found to be different for different anims, add as setting to anim files +var sideStepCycleStartLeft = 270; +var sideStepCycleStartRight = 90; +var walkWheelPosition = 0; +var nextStep = DIRECTION_RIGHT; // first step is always right, because the sine waves say so. Unless you're mirrored. +var nFrames = 0; // counts number of frames +var strideLength = 0; // stride calibration +var aviFootSize = {x:0.1, y:0.1, z:0.25}; // experimental values for addition to stride length - TODO: analyse and confirm is increasing smaller stride lengths accuracy once we have better ground detection +// stats +var frameStartTime = 0; // when the frame first starts we take a note of the time +var frameExecutionTimeMax = 0; // keep track of the longest frame execution time -// for showing walk wheel stats -var nFrames = 0; +// constructor for recent RecentMotion (i.e. frame data) class +function RecentMotion(velocity, acceleration, principleDirection, state) { + this.velocity = velocity; + this.acceleration = acceleration; + this.principleDirection = principleDirection; + this.state = state; + // TODO: add INTERNAL_STATE so can remove 'hints' system for state changes +} -// 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); +// constructor for the FramesHistory object +function FramesHistory() { + this.recentMotions = []; + for(var i = 0 ; i < 10 ; i++) { + var blank = new RecentMotion({ x:0, y:0, z:0 }, { x:0, y:0, z:0 }, DIRECTION_FORWARDS, STANDING ); + this.recentMotions.push(blank); + } - //MyAvatar.addThrust(AviTranslationOffset * 10); - MyAvatar.position = {x: MyAvatar.position.x + AviTranslationOffset.x, - y: MyAvatar.position.y + AviTranslationOffset.y, - z: MyAvatar.position.z + AviTranslationOffset.z }; + // recentDirection 'method' + // args: (direction enum, number of steps back to compare) + this.recentDirection = function () { + + if( arguments[0] && arguments[1] ) { + + var directionCount = 0; + if( arguments[1] > this.recentMotions.length ) + arguments[1] = this.recentMotions.length; + + for(var i = 0 ; i < arguments[1] ; i++ ) { + if( this.recentMotions[i].principleDirection === arguments[0] ) + directionCount++; + //print('looking for '+directionAsString(arguments[0])+' directionCount '+directionCount+' count '+i+' dircetion '+directionAsString(this.recentMotions[i].principleDirection)); + } + return directionCount / arguments[1] === 1 ? true : false; + } + return false; + } + + // recentState 'method' + // args: (state enum, number of steps back to compare) + this.recentState = function () { + + if( arguments[0] && arguments[1] ) { + + var stateCount = 0; + if( arguments[1] > this.recentMotions.length ) + arguments[1] = this.recentMotions.length; + + for(var i = 0 ; i < arguments[1] ; i++ ) { + if( this.recentMotions[i].state === arguments[0] ) + stateCount++; + } + return stateCount / arguments[1] === 1 ? true : false; + } + return false; + } + this.lastWalkStartTime = 0; // short walks and long walks need different handling +} +var framesHistory = new FramesHistory(); + +// constructor for animation Transition class +function Transition(lastAnimation, nextAnimation, reachPoses, transitionDuration, easingLower, easingUpper) { + this.lastAnimation = lastAnimation; // name of last animation + if(lastAnimation === selectedWalk || + nextAnimation === selectedSideStepLeft || + nextAnimation === selectedSideStepRight) + this.walkingAtStart = true; // boolean - is the last animation a walking animation? + else + this.walkingAtStart = false; // boolean - is the last animation a walking animation? + this.nextAnimation = nextAnimation; // name of next animation + if(nextAnimation === selectedWalk || + nextAnimation === selectedSideStepLeft || + nextAnimation === selectedSideStepRight) + this.walkingAtEnd = true; // boolean - is the next animation a walking animation? + else + this.walkingAtEnd = false; // boolean - is the next animation a walking animation? + this.reachPoses = reachPoses; // array of reach poses - am very much looking forward to putting these in! + this.transitionDuration = transitionDuration; // length of transition (seconds) + this.easingLower = easingLower; // Bezier curve handle (normalised) + this.easingUpper = easingUpper; // Bezier curve handle (normalised) + this.startTime = new Date().getTime(); // Starting timestamp (seconds) + this.progress = 0; // how far are we through the transition? + this.walkWheelIncrement = 3; // how much to turn the walkwheel each frame when coming to a halt. Get's set to 0 once the feet are under the avi + this.walkWheelAdvance = 0; // how many degrees the walk wheel has been advanced during the transition + this.walkStopAngle = 0; // what angle should we stop the walk cycle? (calculated on the fly) + + //print('Transition initiated from '+this.lastAnimation.name+' to '+this.nextAnimation.name+' duration '+transitionDuration.toFixed(2)); } // convert a local (to the avi) translation to a global one -function globalToLocal(localTranslation) { +function localToGlobal(localTranslation) { - var aviOrientation = MyAvatar.orientation; - var front = Quat.getFront(aviOrientation); - var right = Quat.getRight(aviOrientation); - var up = Quat.getUp (aviOrientation); - var aviFront = Vec3.multiply(front,localTranslation.z); - var aviRight = Vec3.multiply(right,localTranslation.x); - var aviUp = Vec3.multiply(up ,localTranslation.y); - var globalTranslation = {x:0,y:0,z:0}; // final value - - globalTranslation = Vec3.sum(globalTranslation, aviFront); - globalTranslation = Vec3.sum(globalTranslation, aviRight); - globalTranslation = Vec3.sum(globalTranslation, aviUp); - - return globalTranslation; + 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 +// similar ot above - convert hips translations to global and apply +function translateHips(localHipsTranslation) { + + var aviOrientation = MyAvatar.orientation; + var front = Quat.getFront(aviOrientation); + var right = Quat.getRight(aviOrientation); + var up = Quat.getUp (aviOrientation); + var aviFront = Vec3.multiply(front,localHipsTranslation.y); + var aviRight = Vec3.multiply(right,localHipsTranslation.x); + var aviUp = Vec3.multiply(up ,localHipsTranslation.z); + var AviTranslationOffset = {x:0,y:0,z:0}; // final value + AviTranslationOffset = Vec3.sum(AviTranslationOffset, aviFront); + AviTranslationOffset = Vec3.sum(AviTranslationOffset, aviRight); + AviTranslationOffset = Vec3.sum(AviTranslationOffset, aviUp); + + //MyAvatar.addThrust(AviTranslationOffset * 10); + MyAvatar.position = {x: MyAvatar.position.x + AviTranslationOffset.x, + y: MyAvatar.position.y + AviTranslationOffset.y, + z: MyAvatar.position.z + AviTranslationOffset.z }; +} + +// clear all joint data function resetJoints() { + var avatarJointNames = MyAvatar.getJointNames(); for (var i = 0; i < avatarJointNames.length; i++) { //MyAvatar.setJointData(avatarJointNames[i], Quat.fromPitchYawRollDegrees(0,0,0)); @@ -362,9 +351,10 @@ function resetJoints() { } // play footstep sound function playFootstep(side) { + var options = new AudioInjectionOptions(); options.position = Camera.getPosition(); - options.volume = 0.7; + options.volume = 0.5; 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.'); @@ -376,338 +366,1420 @@ function playFootstep(side) { } } -// this is work in progress -// currently, it's not known if there are working finger joints on the avi +// put the fingers into a relaxed pose 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)); + + // left hand fingers + for(var i = 18 ; i < 34 ; i++) { + MyAvatar.setJointData(jointList[i], Quat.fromPitchYawRollDegrees(8,0,0)); } - for(var i = 48 ; i < 68 ; i++) { - MyAvatar.setJointData(jointList[i], Quat.fromPitchYawRollDegrees(10,0,90)); + // left hand thumb + for(var i = 34 ; i < 38 ; i++) { + MyAvatar.setJointData(jointList[i], Quat.fromPitchYawRollDegrees(0,0,0)); + } + // right hand fingers + for(var i = 42 ; i < 58 ; i++) { + MyAvatar.setJointData(jointList[i], Quat.fromPitchYawRollDegrees(8,0,0)); + } + // right hand thumb + for(var i = 58 ; i < 62 ; i++) { + MyAvatar.setJointData(jointList[i], Quat.fromPitchYawRollDegrees(0,0,0)); } } -// 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 +// additional maths functions +function degToRad(degreesValue) { return degreesValue * Math.PI / 180; } +function radToDeg(radiansValue) { return radiansValue * 180 / Math.PI; } +//function cubicRoot(x) { var y = Math.pow(Math.abs(x), 1/3); return x < 0 ? -y : y; } +// animateAvatar - sine wave generators working like clockwork function animateAvatar(deltaTime, velocity, principleDirection) { - // some slider adjustemnts cause a nasty flicker when adjusting + // adjusting the walk speed in edit mode causes a nasty flicker // pausing the animation stops this if(paused) return; - var adjustedFrequency = currentAnimation.settings.baseFrequency; // now only relevant for standing and flying + var cycle = cumulativeTime; + var transitionProgress = 1; + var adjustedFrequency = currentAnimation.settings.baseFrequency; - // simple legs phase reversal for walking backwards + // upper legs phase reversal for walking backwards var forwardModifier = 1; - if(principleDirection===DIRECTION_BACKWARDS) { + if(principleDirection===DIRECTION_BACKWARDS) forwardModifier = -1; - } - // no need to lean forwards with speed increase if going directly upwards + // don't want to lean forwards if going directly upwards var leanPitchModifier = 1; - if(principleDirection===DIRECTION_UP) { + if(principleDirection===DIRECTION_UP) leanPitchModifier = 0; - } + // is there a Transition to include? + if(currentTransition!==null) { - if(currentAnimation === selectedWalk) { + // if is a new transiton + if(currentTransition.progress===0) { - if(INTERNAL_STATE===CONFIG_WALK_STYLES || - INTERNAL_STATE===CONFIG_WALK_TWEAKS || - INTERNAL_STATE===CONFIG_WALK_JOINTS) { + if( currentTransition.walkingAtStart ) { - var footPos = globalToLocal(MyAvatar.getJointPosition("RightFoot")); - var hipsPos = globalToLocal(MyAvatar.getJointPosition("Hips")); + if( INTERNAL_STATE !== SIDE_STEPPING ) { - // calibrate stride length whilst not actually moving (for accuracy) - if((hipsPos.z - footPos.z)maxFootForward) maxFootForward = (hipsPos.z - footPos.z); + // work out where we want the walk cycle to stop + var leftStop = selectedWalk.settings.stopAngleForwards + 180; + var rightStop = selectedWalk.settings.stopAngleForwards; + if( principleDirection === DIRECTION_BACKWARDS ) { + leftStop = selectedWalk.settings.stopAngleBackwards + 180; + rightStop = selectedWalk.settings.stopAngleBackwards; + } - strideLength = 2 * (maxFootForward-maxFootBackwards); + // find the closest stop point from the walk wheel's angle + var angleToLeftStop = 180 - Math.abs( Math.abs( walkWheelPosition - leftStop ) - 180); + var angleToRightStop = 180 - Math.abs( Math.abs( walkWheelPosition - rightStop ) - 180); + if( walkWheelPosition > angleToLeftStop ) angleToLeftStop = 360 - angleToLeftStop; + if( walkWheelPosition > angleToRightStop ) angleToRightStop = 360 - angleToRightStop; - // 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 { + currentTransition.walkWheelIncrement = 6; - if(strideLength===0) strideLength = 1.6422; // default for if not calibrated yet + // keep the walkwheel turning by setting the walkWheelIncrement until our feet are tucked nicely underneath us. + // fold back (reverse walk) if we just missed our stop target on the walkwheel when we stopped walking - depricated + //var stepIncrement = 2; // just used to set currentTransition.walkWheelIncrement in multiple locations + if( angleToLeftStop < angleToRightStop ) { - // 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; + //if(angleToLeftStop<270) currentTransition.walkStopAngle = rightStop; + //else if(walkWheelPosition>angleToLeftStop) currentTransition.walkStopAngle = rightStop; + //else currentTransition.walkStopAngle = leftStop; - // calculate the degrees turned (at this angular velocity) since last frame - var radiansTurnedSinceLastFrame = deltaTime * angularVelocity; - var degreesTurnedSinceLastFrame = toDegrees(radiansTurnedSinceLastFrame); + currentTransition.walkStopAngle = leftStop; - // 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; + //if( leftStop > 270 && walkWheelPosition < 90 ) currentTransition.walkWheelIncrement = -stepIncrement; + //else if( walkWheelPosition > 270 && leftStop < 90 ) currentTransition.walkWheelIncrement = stepIncrement; + //else if( walkWheelPosition < leftStop ) currentTransition.walkWheelIncrement = stepIncrement; + //else if( walkWheelPosition >= leftStop ) currentTransition.walkWheelIncrement = -stepIncrement; + //currentTransition.walkWheelIncrement = stepIncrement; - // set the new value for the exact correct walking speed for this velocity - adjustedFrequency = 1; - cumulativeTime = walkWheelPosition; + } else { - // show stats and walk wheel? - if(statsOn) { + //if(angleToRightStop<270) currentTransition.walkStopAngle = leftStop; + //else if(walkWheelPosition>angleToRightStop) currentTransition.walkStopAngle = leftStop; + //else currentTransition.walkStopAngle = rightStop; + currentTransition.walkStopAngle = rightStop; - nFrames++; - var distanceTravelled = velocity * deltaTime; - var deltaTimeMS = deltaTime * 1000; + //currentTransition.walkStopAngle = rightStop; + //if( rightStop > 270 && walkWheelPosition < 90 ) currentTransition.walkWheelIncrement = -stepIncrement; + //else if( walkWheelPosition > 270 && rightStop < 90 ) currentTransition.walkWheelIncrement = stepIncrement; + //else if( walkWheelPosition < rightStop ) currentTransition.walkWheelIncrement = stepIncrement; + //else if( walkWheelPosition >= rightStop ) currentTransition.walkWheelIncrement = -stepIncrement; + //currentTransition.walkWheelIncrement = stepIncrement; + } - // 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}); + //print('walkWheelPosition '+walkWheelPosition.toFixed(2)+' leftStop '+leftStop+' rightStop '+rightStop+' angleToLeftStop '+angleToLeftStop.toFixed(2)+' angleToRightStop '+angleToRightStop.toFixed(2)+' stop angle '+currentTransition.walkStopAngle) - // 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}); + } else { - //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)); + // just freeze wheel for sidestepping + currentTransition.walkWheelIncrement = 0; + } + } + } // end if( currentTransition.walkingAtStart ) + + // calculate the Transition progress + var elapasedTime = (new Date().getTime() - currentTransition.startTime) / 1000; + currentTransition.progress = elapasedTime / currentTransition.transitionDuration; + transitionProgress = getBezier((1-currentTransition.progress), {x:0,y:0}, currentTransition.easingLower, currentTransition.easingUpper, {x:1,y:1}).y; + + if(currentTransition.progress>=1) { + + // time to kill off the transition + delete currentTransition; + currentTransition = null; + + } else { + + if( currentTransition.walkingAtStart ) { + + if( INTERNAL_STATE !== SIDE_STEPPING ) { + + // if at a stop angle, hold the walk wheel position for remainder of transition + var tolerance = 10; // must be greater than the walkWheel increment + if(( walkWheelPosition > (currentTransition.walkStopAngle - tolerance )) && + ( walkWheelPosition < (currentTransition.walkStopAngle + tolerance ))) { + + //print('stop now? walkWheelAdvance '+currentTransition.walkWheelAdvance); + + //if( currentTransition.walkWheelAdvance < 45 ) { + + // currentTransition.walkStopAngle += 180; // not enough of a transition - keep moving... + // if( currentTransition.walkStopAngle > 360 ) currentTransition.walkStopAngle %= 360; + + // print('walkStopAngle incremented '); + //} + //else + currentTransition.walkWheelIncrement = 0; + } + // keep turning walk wheel until both feet are below the avi + + //print('walkWheelAdvance '+currentTransition.walkWheelAdvance); + walkWheelPosition += currentTransition.walkWheelIncrement; + currentTransition.walkWheelAdvance += currentTransition.walkWheelIncrement; + } } } + } + + // will we need to use the walk wheel this frame? + if(currentAnimation === selectedWalk || + currentAnimation === selectedSideStepLeft || + currentAnimation === selectedSideStepRight || + currentTransition !== null) { + + // set the stride length + if( INTERNAL_STATE!==SIDE_STEPPING && + INTERNAL_STATE!==CONFIG_SIDESTEP_LEFT && + INTERNAL_STATE!==CONFIG_SIDESTEP_RIGHT && + currentTransition===null ) { + + // if the timing's right, take a snapshot of the stride max and recalibrate + var tolerance = 1.0; // higher the number, the higher the chance of a calibration taking place, but is traded off with lower accuracy + var strideOne = 40; // 130 + var strideTwo = 220; // 300 + + if( principleDirection === DIRECTION_BACKWARDS ) { + strideOne = 130; + strideTwo = 300; + } + + if(( walkWheelPosition < (strideOne+tolerance) && walkWheelPosition > (strideOne-tolerance) ) || + ( walkWheelPosition < (strideTwo+tolerance) && walkWheelPosition > (strideTwo-tolerance) )) { + + // calculate the feet's offset from each other (in local Z only) + var footRPos = localToGlobal(MyAvatar.getJointPosition("RightFoot")); + var footLPos = localToGlobal(MyAvatar.getJointPosition("LeftFoot")); + var footOffsetZ = Math.abs(footRPos.z - footLPos.z); + if(footOffsetZ>1) strideLength = 2 * footOffsetZ + aviFootSize.z; // sometimes getting very low value here - just ignore for now + //if(statsOn) print('Stride length calibrated to '+strideLength.toFixed(4)+' metres at '+walkWheelPosition.toFixed(1)+' degrees'); + if(principleDirection===DIRECTION_FORWARDS) { + currentAnimation.calibration.strideLengthForwards = strideLength; + } else if (principleDirection===DIRECTION_BACKWARDS) { + currentAnimation.calibration.strideLengthBackwards = strideLength; + } + } + else { + + if(principleDirection===DIRECTION_FORWARDS) { + strideLength = currentAnimation.calibration.strideLengthForwards; + } else if (principleDirection===DIRECTION_BACKWARDS) { + strideLength = currentAnimation.calibration.strideLengthBackwards; + } + } + } + else if(( INTERNAL_STATE===SIDE_STEPPING || + INTERNAL_STATE===CONFIG_SIDESTEP_LEFT || + INTERNAL_STATE===CONFIG_SIDESTEP_RIGHT ) ) { + + // calculate lateral stride - same same, but different + // if the timing's right, take a snapshot of the stride max and recalibrate the stride length + var tolerance = 1.0; // higher the number, the higher the chance of a calibration taking place, but is traded off with lower accuracy + if(principleDirection===DIRECTION_LEFT) { + + if( walkWheelPosition < (3+tolerance) && walkWheelPosition > (3-tolerance) ) { + + // calculate the feet's offset from the hips (in local X only) + var footRPos = localToGlobal(MyAvatar.getJointPosition("RightFoot")); + var footLPos = localToGlobal(MyAvatar.getJointPosition("LeftFoot")); + var footOffsetX = Math.abs(footRPos.x - footLPos.x); + strideLength = footOffsetX; + //if(statsOn) print('Stride width calibrated to '+strideLength.toFixed(4)+ ' metres at '+walkWheelPosition.toFixed(1)+' degrees'); + //print('Stride width calibrated to '+strideLength.toFixed(4)+ ' metres at '+walkWheelPosition.toFixed(1)+' degrees. footRPos '+footRPos.x.toFixed(3)+' footLPos '+footLPos.x.toFixed(3)+' footOffsetX '+footOffsetX.toFixed(3)); + currentAnimation.calibration.strideLengthLeft = strideLength; + + } else { + + strideLength = currentAnimation.calibration.strideLengthLeft; + } + } + else if (principleDirection===DIRECTION_RIGHT) { + + if( walkWheelPosition < (170+tolerance) && walkWheelPosition > (170-tolerance) ) { + + // calculate the feet's offset from the hips (in local X only) + var footRPos = localToGlobal(MyAvatar.getJointPosition("RightFoot")); + var footLPos = localToGlobal(MyAvatar.getJointPosition("LeftFoot")); + var footOffsetX = Math.abs(footRPos.x - footLPos.x); + strideLength = footOffsetX; + //if(statsOn) print('Stride width calibrated to '+strideLength.toFixed(4)+ ' metres at '+walkWheelPosition.toFixed(1)+' degrees'); + //print('Stride width calibrated to '+strideLength.toFixed(4)+ ' metres at '+walkWheelPosition.toFixed(1)+' degrees. footRPos '+footRPos.x.toFixed(3)+' footLPos '+footLPos.x.toFixed(3)+' footOffsetX '+footOffsetX.toFixed(3)); + currentAnimation.calibration.strideLengthRight = strideLength; + + } else { + + strideLength = currentAnimation.calibration.strideLengthRight; + } + } + } // end stride length calculations + + // wrap the stride length around a 'surveyor's wheel' twice and calculate the angular velocity at the given (linear) velocity + // omega = v / r , where r = circumference / 2 PI , where circumference = 2 * stride length + var wheelRadius = strideLength / Math.PI; + var angularVelocity = velocity / wheelRadius; + + // calculate the degrees turned (at this angular velocity) since last frame + var radiansTurnedSinceLastFrame = deltaTime * angularVelocity; + var degreesTurnedSinceLastFrame = radToDeg(radiansTurnedSinceLastFrame); + + // if we are in an edit mode, we will need fake time to turn the wheel + if( INTERNAL_STATE!==WALKING && + INTERNAL_STATE!==SIDE_STEPPING ) + degreesTurnedSinceLastFrame = currentAnimation.settings.baseFrequency / 70; + + if( walkWheelPosition >= 360 ) + walkWheelPosition = walkWheelPosition % 360; + + // advance the walk wheel the appropriate amount + if( currentTransition===null || currentTransition.walkingAtEnd ) + walkWheelPosition += degreesTurnedSinceLastFrame; + + // set the new values for the exact correct walk cycle speed at this velocity + adjustedFrequency = 1; + cycle = walkWheelPosition; + + // show stats and walk wheel? + if(statsOn) { + + var distanceTravelled = velocity * deltaTime; + var deltaTimeMS = deltaTime * 1000; + + if( INTERNAL_STATE===SIDE_STEPPING || + INTERNAL_STATE===CONFIG_SIDESTEP_LEFT || + INTERNAL_STATE===CONFIG_SIDESTEP_RIGHT ) { + + // draw the walk wheel turning around the z axis for sidestepping + var directionSign = 1; + if(principleDirection===DIRECTION_RIGHT) directionSign = -1; + var yOffset = hipsToFeetDistance - (wheelRadius/1.2); // /1.2 is a visual kludge, probably necessary because of either the 'avi feet penetrate floor' issue - TODO - once ground plane following is in Interface, lock this down + var sinWalkWheelPosition = wheelRadius * Math.sin(degToRad( directionSign * walkWheelPosition )); + var cosWalkWheelPosition = wheelRadius * Math.cos(degToRad( directionSign * -walkWheelPosition )); + var wheelXPos = {x: cosWalkWheelPosition, y:-sinWalkWheelPosition - yOffset, z: 0}; + var wheelXEnd = {x: -cosWalkWheelPosition, y:sinWalkWheelPosition - yOffset, z: 0}; + sinWalkWheelPosition = wheelRadius * Math.sin(degToRad( -directionSign * walkWheelPosition+90 )); + cosWalkWheelPosition = wheelRadius * Math.cos(degToRad( -directionSign * walkWheelPosition+90 )); + var wheelYPos = {x:cosWalkWheelPosition, y:sinWalkWheelPosition - yOffset, z: 0}; + var wheelYEnd = {x:-cosWalkWheelPosition, y:-sinWalkWheelPosition - yOffset, z: 0}; + Overlays.editOverlay(walkWheelYLine, {visible: true, position:wheelYPos, end:wheelYEnd}); + Overlays.editOverlay(walkWheelZLine, {visible: true, position:wheelXPos, end:wheelXEnd}); + + } else { + + // draw the walk wheel turning around the x axis for walking forwards or backwards + var yOffset = hipsToFeetDistance - (wheelRadius/1.2); // /1.2 is a visual kludge, probably necessary because of either the 'avi feet penetrate floor' issue - TODO - once ground plane following is in Interface, lock this down + var sinWalkWheelPosition = wheelRadius * Math.sin(degToRad((forwardModifier*-1) * walkWheelPosition)); + var cosWalkWheelPosition = wheelRadius * Math.cos(degToRad((forwardModifier*-1) * -walkWheelPosition)); + var wheelZPos = {x:0, y:-sinWalkWheelPosition - yOffset, z: cosWalkWheelPosition}; + var wheelZEnd = {x:0, y:sinWalkWheelPosition - yOffset, z: -cosWalkWheelPosition}; + sinWalkWheelPosition = wheelRadius * Math.sin(degToRad(forwardModifier * walkWheelPosition+90)); + cosWalkWheelPosition = wheelRadius * Math.cos(degToRad(forwardModifier * walkWheelPosition+90)); + var wheelYPos = {x:0, y:sinWalkWheelPosition - yOffset, z: cosWalkWheelPosition}; + var wheelYEnd = {x:0, y:-sinWalkWheelPosition - yOffset, z: -cosWalkWheelPosition}; + Overlays.editOverlay(walkWheelYLine, { visible: true, position:wheelYPos, end:wheelYEnd }); + Overlays.editOverlay(walkWheelZLine, { visible: true, position:wheelZPos, end:wheelZEnd }); + } + + // populate stats overlay + var walkWheelInfo = + ' Walk Wheel Stats\n--------------------------------------\n \n \n' + + '\nFrame time: '+deltaTimeMS.toFixed(2) + + ' mS\nVelocity: '+velocity.toFixed(2) + + ' m/s\nDistance: '+distanceTravelled.toFixed(3) + + ' m\nOmega: '+angularVelocity.toFixed(3) + + ' rad / s\nDeg to turn: '+degreesTurnedSinceLastFrame.toFixed(2) + + ' deg\nWheel position: '+cycle.toFixed(1) + + ' deg\nWheel radius: '+wheelRadius.toFixed(3) + + ' m\nHips To Feet: '+hipsToFeetDistance.toFixed(3) + + ' m\nStride: '+strideLength.toFixed(3) + + ' m\n'; + Overlays.editOverlay(walkWheelStats, {text: walkWheelInfo}); + } + } // end of walk wheel and stride length calculation + + + // Start applying motion + var pitchOscillation = 0; + var yawOscillation = 0; + var rollOscillation = 0; + var pitchOscillationLast = 0; + var yawOscillationLast = 0; + var rollOscillationLast = 0; + var pitchOffset = 0; + var yawOffset = 0; + var rollOffset = 0; + var pitchOffsetLast = 0; + var yawOffsetLast = 0; + var rollOffsetLast = 0; + + + // calcualte any hips translation + // Note: can only apply hips translations whilst in a config (edit) mode at present, not whilst under locomotion + if( INTERNAL_STATE===CONFIG_WALK_STYLES || + INTERNAL_STATE===CONFIG_WALK_TWEAKS || + INTERNAL_STATE===CONFIG_WALK_JOINTS || + INTERNAL_STATE===CONFIG_SIDESTEP_LEFT || + INTERNAL_STATE===CONFIG_SIDESTEP_RIGHT || + INTERNAL_STATE===CONFIG_FLYING || + INTERNAL_STATE===CONFIG_FLYING_UP || + INTERNAL_STATE===CONFIG_FLYING_DOWN ) { + + // calculate hips translation TODO: get this working in normal motion! + var motorOscillation = Math.sin(degToRad((cycle * adjustedFrequency * 2) + currentAnimation.joints[0].thrustPhase)) + currentAnimation.joints[0].thrustOffset; + var swayOscillation = Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[0].swayPhase)) + currentAnimation.joints[0].swayOffset; + var bobOscillation = Math.sin(degToRad((cycle * adjustedFrequency * 2) + currentAnimation.joints[0].bobPhase)) + currentAnimation.joints[0].bobOffset; + + // apply hips translation TODO: get this working! + translateHips({x:swayOscillation*currentAnimation.joints[0].sway, y:motorOscillation*currentAnimation.joints[0].thrust, z:bobOscillation*currentAnimation.joints[0].bob}); + } + + // hips rotation + // apply the current Transition? + if(currentTransition!==null) { + + if( currentTransition.walkingAtStart ) { + + pitchOscillation = currentAnimation.joints[0].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency * 2) + + currentAnimation.joints[0].pitchPhase)) + currentAnimation.joints[0].pitchOffset; + + yawOscillation = currentAnimation.joints[0].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + + currentAnimation.joints[0].yawPhase)) + currentAnimation.joints[0].yawOffset; + + rollOscillation = (currentAnimation.joints[0].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + + currentAnimation.joints[0].rollPhase)) + currentAnimation.joints[0].rollOffset); + + pitchOscillationLast = currentTransition.lastAnimation.joints[0].pitch * Math.sin(degToRad(( walkWheelPosition * 2) + + currentTransition.lastAnimation.joints[0].pitchPhase)) + currentTransition.lastAnimation.joints[0].pitchOffset; + + yawOscillationLast = currentTransition.lastAnimation.joints[0].yaw * Math.sin(degToRad(( walkWheelPosition ) + + currentTransition.lastAnimation.joints[0].yawPhase)) + currentTransition.lastAnimation.joints[0].yawOffset; + + rollOscillationLast = (currentTransition.lastAnimation.joints[0].roll * Math.sin(degToRad(( walkWheelPosition ) + + currentTransition.lastAnimation.joints[0].rollPhase)) + currentTransition.lastAnimation.joints[0].rollOffset); + + } else {//if( currentTransition.walkingAtEnd ) { + + pitchOscillation = currentAnimation.joints[0].pitch * Math.sin(degToRad((cycle * adjustedFrequency * 2) + + currentAnimation.joints[0].pitchPhase)) + currentAnimation.joints[0].pitchOffset; + + yawOscillation = currentAnimation.joints[0].yaw * Math.sin(degToRad((cycle * adjustedFrequency ) + + currentAnimation.joints[0].yawPhase)) + currentAnimation.joints[0].yawOffset; + + rollOscillation = (currentAnimation.joints[0].roll * Math.sin(degToRad((cycle * adjustedFrequency ) + + currentAnimation.joints[0].rollPhase)) + currentAnimation.joints[0].rollOffset); + + pitchOscillationLast = currentTransition.lastAnimation.joints[0].pitch * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency * 2) + + currentTransition.lastAnimation.joints[0].pitchPhase)) + currentTransition.lastAnimation.joints[0].pitchOffset; + + yawOscillationLast = currentTransition.lastAnimation.joints[0].yaw * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) + + currentTransition.lastAnimation.joints[0].yawPhase)) + currentTransition.lastAnimation.joints[0].yawOffset; + + rollOscillationLast = (currentTransition.lastAnimation.joints[0].roll * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) + + currentTransition.lastAnimation.joints[0].rollPhase)) + currentTransition.lastAnimation.joints[0].rollOffset); + + } + + pitchOscillation = (transitionProgress * pitchOscillation) + ((1-transitionProgress) * pitchOscillationLast); + yawOscillation = (transitionProgress * yawOscillation) + ((1-transitionProgress) * yawOscillationLast); + rollOscillation = (transitionProgress * rollOscillation) + ((1-transitionProgress) * rollOscillationLast); + + //print('Hips: '+pitchOscillation+' '+yawOscillation+' '+rollOscillation); } else { - nFrames = 0; - walkWheelPosition = walkCycleStart; // best foot forwards for next time we walk + + pitchOscillation = currentAnimation.joints[0].pitch * Math.sin(degToRad((cycle * adjustedFrequency * 2) + + currentAnimation.joints[0].pitchPhase)) + currentAnimation.joints[0].pitchOffset; + + yawOscillation = currentAnimation.joints[0].yaw * Math.sin(degToRad((cycle * adjustedFrequency ) + + currentAnimation.joints[0].yawPhase)) + currentAnimation.joints[0].yawOffset; + + rollOscillation = (currentAnimation.joints[0].roll * Math.sin(degToRad((cycle * adjustedFrequency ) + + currentAnimation.joints[0].rollPhase)) + currentAnimation.joints[0].rollOffset); } - // 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 + MyAvatar.setJointData("Hips", Quat.fromPitchYawRollDegrees(-pitchOscillation + (leanPitchModifier * getLeanPitch(velocity)), // getLeanPitch - lean forwards as velocity increases + yawOscillation, // Yup, that's correct ;-) + rollOscillation + getLeanRoll(deltaTime, velocity))); // getLeanRoll - banking on cornering - // calculate upper leg rotations + // upper legs + if( INTERNAL_STATE!==SIDE_STEPPING && + INTERNAL_STATE!==CONFIG_SIDESTEP_LEFT && + INTERNAL_STATE!==CONFIG_SIDESTEP_RIGHT ) { - // 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; + // apply the current Transition to the upper legs? + if(currentTransition!==null) { + + if(currentTransition.walkingAtStart) { + + pitchOscillation = currentAnimation.joints[1].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + (forwardModifier * currentAnimation.joints[1].pitchPhase))); + yawOscillation = currentAnimation.joints[1].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[1].yawPhase)); + rollOscillation = currentAnimation.joints[1].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[1].rollPhase)); + + pitchOffset = currentAnimation.joints[1].pitchOffset; + yawOffset = currentAnimation.joints[1].yawOffset; + rollOffset = currentAnimation.joints[1].rollOffset; + + pitchOscillationLast = currentTransition.lastAnimation.joints[1].pitch + * Math.sin(degToRad( walkWheelPosition + (forwardModifier * currentTransition.lastAnimation.joints[1].pitchPhase ))); + + yawOscillationLast = currentTransition.lastAnimation.joints[1].yaw + * Math.sin(degToRad( walkWheelPosition + currentTransition.lastAnimation.joints[1].yawPhase )); + + rollOscillationLast = currentTransition.lastAnimation.joints[1].roll + * Math.sin(degToRad( walkWheelPosition + currentTransition.lastAnimation.joints[1].rollPhase )); + + pitchOffsetLast = currentTransition.lastAnimation.joints[1].pitchOffset; + yawOffsetLast = currentTransition.lastAnimation.joints[1].yawOffset; + rollOffsetLast = currentTransition.lastAnimation.joints[1].rollOffset; + + } else { + + pitchOscillation = currentAnimation.joints[1].pitch * Math.sin(degToRad((cycle * adjustedFrequency ) + (forwardModifier * currentAnimation.joints[1].pitchPhase))); + yawOscillation = currentAnimation.joints[1].yaw * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[1].yawPhase)); + rollOscillation = currentAnimation.joints[1].roll * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[1].rollPhase)); + + pitchOffset = currentAnimation.joints[1].pitchOffset; + yawOffset = currentAnimation.joints[1].yawOffset; + rollOffset = currentAnimation.joints[1].rollOffset; + + pitchOscillationLast = currentTransition.lastAnimation.joints[1].pitch + * Math.sin(degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency + + (forwardModifier * currentTransition.lastAnimation.joints[1].pitchPhase ))); + + yawOscillationLast = currentTransition.lastAnimation.joints[1].yaw + * Math.sin(degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency + + currentTransition.lastAnimation.joints[1].yawPhase )); + + rollOscillationLast = currentTransition.lastAnimation.joints[1].roll + * Math.sin(degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency + + currentTransition.lastAnimation.joints[1].rollPhase )); + + pitchOffsetLast = currentTransition.lastAnimation.joints[1].pitchOffset; + yawOffsetLast = currentTransition.lastAnimation.joints[1].yawOffset; + rollOffsetLast = currentTransition.lastAnimation.joints[1].rollOffset; + } + + pitchOscillation = (transitionProgress * pitchOscillation ) + ((1-transitionProgress) * pitchOscillationLast); + yawOscillation = (transitionProgress * yawOscillation ) + ((1-transitionProgress) * yawOscillationLast); + rollOscillation = (transitionProgress * rollOscillation ) + ((1-transitionProgress) * rollOscillationLast); + + pitchOffset = (transitionProgress * pitchOffset) + ((1-transitionProgress) * pitchOffsetLast); + yawOffset = (transitionProgress * yawOffset) + ((1-transitionProgress) * yawOffsetLast); + rollOffset = (transitionProgress * rollOffset) + ((1-transitionProgress) * rollOffsetLast); + + } else { + + pitchOscillation = currentAnimation.joints[1].pitch * Math.sin(degToRad((cycle * adjustedFrequency ) + (forwardModifier * currentAnimation.joints[1].pitchPhase))); + yawOscillation = currentAnimation.joints[1].yaw * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[1].yawPhase)); + rollOscillation = currentAnimation.joints[1].roll * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[1].rollPhase)); + + pitchOffset = currentAnimation.joints[1].pitchOffset; + yawOffset = currentAnimation.joints[1].yawOffset; + rollOffset = currentAnimation.joints[1].rollOffset; + } + + // apply the upper leg rotations + MyAvatar.setJointData("RightUpLeg", Quat.fromPitchYawRollDegrees( pitchOscillation + pitchOffset, yawOscillation + yawOffset, -rollOscillation - rollOffset )); + MyAvatar.setJointData("LeftUpLeg", Quat.fromPitchYawRollDegrees( -pitchOscillation + pitchOffset, yawOscillation - yawOffset, -rollOscillation + rollOffset )); + + + // lower leg + if(currentTransition!==null) { + + if(currentTransition.walkingAtStart) { + + pitchOscillation = currentAnimation.joints[2].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[2].pitchPhase)); + yawOscillation = currentAnimation.joints[2].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[2].yawPhase)); + rollOscillation = currentAnimation.joints[2].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[2].rollPhase)); + + pitchOffset = currentAnimation.joints[2].pitchOffset; + yawOffset = currentAnimation.joints[2].yawOffset; + rollOffset = currentAnimation.joints[2].rollOffset; + + pitchOscillationLast = currentTransition.lastAnimation.joints[2].pitch * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[2].pitchPhase)); + yawOscillationLast = currentTransition.lastAnimation.joints[2].yaw * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[2].yawPhase)); + rollOscillationLast = currentTransition.lastAnimation.joints[2].roll * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[2].rollPhase)); + + pitchOffsetLast = currentTransition.lastAnimation.joints[2].pitchOffset; + yawOffsetLast = currentTransition.lastAnimation.joints[2].yawOffset; + rollOffsetLast = currentTransition.lastAnimation.joints[2].rollOffset; + + } else { + + pitchOscillation = currentAnimation.joints[2].pitch * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[2].pitchPhase)); + yawOscillation = currentAnimation.joints[2].yaw * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[2].yawPhase)); + rollOscillation = currentAnimation.joints[2].roll * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[2].rollPhase)); + + pitchOffset = currentAnimation.joints[2].pitchOffset; + yawOffset = currentAnimation.joints[2].yawOffset; + rollOffset = currentAnimation.joints[2].rollOffset; + + pitchOscillationLast = currentTransition.lastAnimation.joints[2].pitch + * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) + + currentTransition.lastAnimation.joints[2].pitchPhase)); + yawOscillationLast = currentTransition.lastAnimation.joints[2].yaw + * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) + + currentTransition.lastAnimation.joints[2].yawPhase)); + rollOscillationLast = currentTransition.lastAnimation.joints[2].roll + * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) + + currentTransition.lastAnimation.joints[2].rollPhase)); + + pitchOffsetLast = currentTransition.lastAnimation.joints[2].pitchOffset; + yawOffsetLast = currentTransition.lastAnimation.joints[2].yawOffset; + rollOffsetLast = currentTransition.lastAnimation.joints[2].rollOffset; + } + + pitchOscillation = ( transitionProgress * pitchOscillation ) + ( (1-transitionProgress) * pitchOscillationLast ); + yawOscillation = ( transitionProgress * yawOscillation ) + ( (1-transitionProgress) * yawOscillationLast ); + rollOscillation = ( transitionProgress * rollOscillation ) + ( (1-transitionProgress) * rollOscillationLast ); + + pitchOffset = ( transitionProgress * pitchOffset ) + ( (1-transitionProgress) * pitchOffsetLast ); + yawOffset = ( transitionProgress * yawOffset ) + ( (1-transitionProgress) * yawOffsetLast ); + rollOffset = ( transitionProgress * rollOffset ) + ( (1-transitionProgress) * rollOffsetLast ); + + } else { + + pitchOscillation = currentAnimation.joints[2].pitch * Math.sin( degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[2].pitchPhase )); + yawOscillation = currentAnimation.joints[2].yaw * Math.sin( degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[2].yawPhase )); + rollOscillation = currentAnimation.joints[2].roll * Math.sin( degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[2].rollPhase )); + + pitchOffset = currentAnimation.joints[2].pitchOffset; + yawOffset = currentAnimation.joints[2].yawOffset; + rollOffset = currentAnimation.joints[2].rollOffset; + } + + // apply lower leg joint rotations + MyAvatar.setJointData("RightLeg", Quat.fromPitchYawRollDegrees( -pitchOscillation + pitchOffset, yawOscillation - yawOffset, rollOscillation - rollOffset )); + MyAvatar.setJointData("LeftLeg", Quat.fromPitchYawRollDegrees( pitchOscillation + pitchOffset, yawOscillation + yawOffset, rollOscillation + rollOffset )); + + } // end if !SIDE_STEPPING + + else if( INTERNAL_STATE===SIDE_STEPPING || + INTERNAL_STATE===CONFIG_SIDESTEP_LEFT || + INTERNAL_STATE===CONFIG_SIDESTEP_RIGHT ) { + + // sidestepping uses the sinewave generators slightly differently for the legs + pitchOscillation = currentAnimation.joints[1].pitch * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[1].pitchPhase)); + yawOscillation = currentAnimation.joints[1].yaw * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[1].yawPhase)); + rollOscillation = currentAnimation.joints[1].roll * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[1].rollPhase)); + + // apply upper leg rotations for sidestepping + MyAvatar.setJointData("RightUpLeg", Quat.fromPitchYawRollDegrees( + -pitchOscillation + currentAnimation.joints[1].pitchOffset, + yawOscillation + currentAnimation.joints[1].yawOffset, + rollOscillation + currentAnimation.joints[1].rollOffset )); + MyAvatar.setJointData("LeftUpLeg", Quat.fromPitchYawRollDegrees( + pitchOscillation + currentAnimation.joints[1].pitchOffset, + yawOscillation - currentAnimation.joints[1].yawOffset, + -rollOscillation - currentAnimation.joints[1].rollOffset )); + + // calculate lower leg joint rotations for sidestepping + pitchOscillation = currentAnimation.joints[2].pitch * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[2].pitchPhase)); + yawOscillation = currentAnimation.joints[2].yaw * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[2].yawPhase)); + rollOscillation = currentAnimation.joints[2].roll * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[2].rollPhase)); + + // apply lower leg joint rotations + MyAvatar.setJointData("RightLeg", Quat.fromPitchYawRollDegrees( + -pitchOscillation + currentAnimation.joints[2].pitchOffset, + yawOscillation - currentAnimation.joints[2].yawOffset, + rollOscillation - currentAnimation.joints[2].rollOffset)); // TODO: needs a kick just before fwd peak + MyAvatar.setJointData("LeftLeg", Quat.fromPitchYawRollDegrees( + pitchOscillation + currentAnimation.joints[2].pitchOffset, + yawOscillation + currentAnimation.joints[2].yawOffset, + rollOscillation + currentAnimation.joints[2].rollOffset)); + } + + // feet + if(currentTransition!==null) { + + if(currentTransition.walkingAtStart) { + + pitchOscillation = currentAnimation.joints[3].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[3].pitchPhase)); + yawOscillation = currentAnimation.joints[3].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[3].yawPhase)); + rollOscillation = currentAnimation.joints[3].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[3].rollPhase)); + + pitchOffset = currentAnimation.joints[3].pitchOffset; + yawOffset = currentAnimation.joints[3].yawOffset; + rollOffset = currentAnimation.joints[3].rollOffset; + + pitchOscillationLast = currentTransition.lastAnimation.joints[3].pitch * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[3].pitchPhase)); + yawOscillationLast = currentTransition.lastAnimation.joints[3].yaw * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[3].yawPhase)); + rollOscillationLast = currentTransition.lastAnimation.joints[3].roll * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[3].rollPhase)); + + pitchOffsetLast = currentTransition.lastAnimation.joints[3].pitchOffset; + yawOffsetLast = currentTransition.lastAnimation.joints[3].yawOffset; + rollOffsetLast = currentTransition.lastAnimation.joints[3].rollOffset; + + } else { //if( currentTransition.walkingAtEnd ) { + + pitchOscillation = currentAnimation.joints[3].pitch * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[3].pitchPhase)); + yawOscillation = currentAnimation.joints[3].yaw * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[3].yawPhase)); + rollOscillation = currentAnimation.joints[3].roll * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[3].rollPhase)); + + pitchOffset = currentAnimation.joints[3].pitchOffset; + yawOffset = currentAnimation.joints[3].yawOffset; + rollOffset = currentAnimation.joints[3].rollOffset; + + pitchOscillationLast = currentTransition.lastAnimation.joints[3].pitch + * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) + + currentTransition.lastAnimation.joints[3].pitchPhase)); + + yawOscillationLast = currentTransition.lastAnimation.joints[3].yaw + * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) + + currentTransition.lastAnimation.joints[3].yawPhase)); + + rollOscillationLast = currentTransition.lastAnimation.joints[3].roll + * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) + + currentTransition.lastAnimation.joints[3].rollPhase)); + + pitchOffsetLast = currentTransition.lastAnimation.joints[3].pitchOffset; + yawOffsetLast = currentTransition.lastAnimation.joints[3].yawOffset; + rollOffsetLast = currentTransition.lastAnimation.joints[3].rollOffset; + } + + pitchOscillation = (transitionProgress * pitchOscillation ) + ((1-transitionProgress) * pitchOscillationLast); + yawOscillation = (transitionProgress * yawOscillation ) + ((1-transitionProgress) * yawOscillationLast); + rollOscillation = (transitionProgress * rollOscillation ) + ((1-transitionProgress) * rollOscillationLast); + + pitchOffset = (transitionProgress * pitchOffset) + ((1-transitionProgress) * pitchOffsetLast); + yawOffset = (transitionProgress * yawOffset) + ((1-transitionProgress) * yawOffsetLast); + rollOffset = (transitionProgress * rollOffset) + ((1-transitionProgress) * rollOffsetLast); + + } else { + + pitchOscillation = currentAnimation.joints[3].pitch * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[3].pitchPhase)); + yawOscillation = currentAnimation.joints[3].yaw * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[3].yawPhase)); + rollOscillation = currentAnimation.joints[3].roll * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[3].rollPhase)); + + pitchOffset = currentAnimation.joints[3].pitchOffset; + yawOffset = currentAnimation.joints[3].yawOffset; + rollOffset = currentAnimation.joints[3].rollOffset; } - else if(runningModifier>0) { - runningModifier *= 2; - runningModifier += 0.5; + + // apply foot rotations + MyAvatar.setJointData("RightFoot", Quat.fromPitchYawRollDegrees( pitchOscillation + pitchOffset, yawOscillation + yawOffset, rollOscillation + rollOffset )); + MyAvatar.setJointData("LeftFoot", Quat.fromPitchYawRollDegrees( -pitchOscillation + pitchOffset, yawOscillation - yawOffset, rollOscillation - rollOffset )); + + + // play footfall sound yet? To determine this, we take the differential of + // the foot's pitch curve to decide when the foot hits the ground. + if( INTERNAL_STATE===WALKING || + INTERNAL_STATE===SIDE_STEPPING || + INTERNAL_STATE===CONFIG_WALK_STYLES || + INTERNAL_STATE===CONFIG_WALK_TWEAKS || + INTERNAL_STATE===CONFIG_WALK_JOINTS || + INTERNAL_STATE===CONFIG_SIDESTEP_LEFT || + INTERNAL_STATE===CONFIG_SIDESTEP_RIGHT ) { + + // As luck would have it, we're using sine waves, so finding dy/dx is as + // simple as determining the cosine wave for the foot's pitch function. + var feetPitchDifferential = Math.cos(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[3].pitchPhase)); + var threshHold = 0.9; // sets the audio trigger point. with accuracy. + if(feetPitchDifferential<-threshHold && + nextStep===DIRECTION_LEFT && + principleDirection!==DIRECTION_UP && + principleDirection!==DIRECTION_DOWN) { + + playFootstep(DIRECTION_LEFT); + nextStep = DIRECTION_RIGHT; + } + else if(feetPitchDifferential>threshHold && + nextStep===DIRECTION_RIGHT && + principleDirection!==DIRECTION_UP && + principleDirection!==DIRECTION_DOWN) { + + playFootstep(DIRECTION_RIGHT); + nextStep = DIRECTION_LEFT; + } } - else runningModifier = 1; // standing - runningModifier = 1; // TODO - remove this little disabling hack! + // toes + if(currentTransition!==null) { - 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)); + if(currentTransition.walkingAtStart) { - // 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 )); + pitchOscillation = currentAnimation.joints[4].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[4].pitchPhase)); + yawOscillation = currentAnimation.joints[4].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[4].yawPhase)) + currentAnimation.joints[4].yawOffset; + rollOscillation = currentAnimation.joints[4].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[4].rollPhase)) + currentAnimation.joints[4].rollOffset; - // 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)); + pitchOffset = currentAnimation.joints[4].pitchOffset; - // 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)); + pitchOscillationLast = currentTransition.lastAnimation.joints[4].pitch * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[4].pitchPhase)); + yawOscillationLast = currentTransition.lastAnimation.joints[4].yaw * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[4].yawPhase)) + currentTransition.lastAnimation.joints[4].yawOffset;; + rollOscillationLast = currentTransition.lastAnimation.joints[4].roll * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[4].rollPhase))+ currentTransition.lastAnimation.joints[4].rollOffset; - // 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)); + pitchOffsetLast = currentTransition.lastAnimation.joints[4].pitchOffset; - 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; - } - } + } else { //if( currentTransition.walkingAtEnd ) { - // 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)); + pitchOscillation = currentAnimation.joints[4].pitch * Math.sin(degToRad((cycle * adjustedFrequency) + currentAnimation.joints[4].pitchPhase)); + yawOscillation = currentAnimation.joints[4].yaw * Math.sin(degToRad((cycle * adjustedFrequency) + currentAnimation.joints[4].yawPhase)) + currentAnimation.joints[4].yawOffset; + rollOscillation = currentAnimation.joints[4].roll * Math.sin(degToRad((cycle * adjustedFrequency) + currentAnimation.joints[4].rollPhase)) + currentAnimation.joints[4].rollOffset; - // 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; + pitchOffset = currentAnimation.joints[4].pitchOffset; + + pitchOscillationLast = currentTransition.lastAnimation.joints[4].pitch + * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) + + currentTransition.lastAnimation.joints[4].pitchPhase)); + + yawOscillationLast = currentTransition.lastAnimation.joints[4].yaw + * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) + + currentTransition.lastAnimation.joints[4].yawPhase)) + currentTransition.lastAnimation.joints[4].yawOffset;; + + rollOscillationLast = currentTransition.lastAnimation.joints[4].roll + * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) + + currentTransition.lastAnimation.joints[4].rollPhase))+ currentTransition.lastAnimation.joints[4].rollOffset; + + pitchOffsetLast = currentTransition.lastAnimation.joints[4].pitchOffset; + } + + pitchOscillation = (transitionProgress * pitchOscillation) + ((1-transitionProgress) * pitchOscillationLast); + yawOscillation = (transitionProgress * yawOscillation) + ((1-transitionProgress) * yawOscillationLast); + rollOscillation = (transitionProgress * rollOscillation) + ((1-transitionProgress) * rollOscillationLast); + + pitchOffset = (transitionProgress * pitchOffset) + ((1-transitionProgress) * pitchOffsetLast); + + } else { + + pitchOscillation = currentAnimation.joints[4].pitch * Math.sin(degToRad((cycle * adjustedFrequency) + currentAnimation.joints[4].pitchPhase)); + yawOscillation = currentAnimation.joints[4].yaw * Math.sin(degToRad((cycle * adjustedFrequency) + currentAnimation.joints[4].yawPhase)) + currentAnimation.joints[4].yawOffset; + rollOscillation = currentAnimation.joints[4].roll * Math.sin(degToRad((cycle * adjustedFrequency) + currentAnimation.joints[4].rollPhase)) + currentAnimation.joints[4].rollOffset; + + pitchOffset = currentAnimation.joints[4].pitchOffset; + } + + // apply toe rotations + MyAvatar.setJointData("RightToeBase", Quat.fromPitchYawRollDegrees(-pitchOscillation + pitchOffset, yawOscillation, rollOscillation)); + MyAvatar.setJointData("LeftToeBase", Quat.fromPitchYawRollDegrees( pitchOscillation + pitchOffset, yawOscillation, rollOscillation)); + + + // spine + if( currentTransition !== null ) { + + if( currentTransition.walkingAtStart ) { + + pitchOscillation = currentAnimation.joints[5].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency * 2 ) + currentAnimation.joints[5].pitchPhase)) + currentAnimation.joints[5].pitchOffset; + yawOscillation = currentAnimation.joints[5].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[5].yawPhase)) + currentAnimation.joints[5].yawOffset; + rollOscillation = currentAnimation.joints[5].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[5].rollPhase)) + currentAnimation.joints[5].rollOffset; + + // calculate where we would have been if we'd continued in the last state + pitchOscillationLast = currentTransition.lastAnimation.joints[5].pitch + * Math.sin(degToRad(( walkWheelPosition * 2 ) + currentTransition.lastAnimation.joints[5].pitchPhase)) + + currentTransition.lastAnimation.joints[5].pitchOffset; + yawOscillationLast = currentTransition.lastAnimation.joints[5].yaw + * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[5].yawPhase)) + + currentTransition.lastAnimation.joints[5].yawOffset; + rollOscillationLast = currentTransition.lastAnimation.joints[5].roll + * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[5].rollPhase)) + + currentTransition.lastAnimation.joints[5].rollOffset; + + } else { //if( currentTransition.walkingAtEnd ) { + + pitchOscillation = currentAnimation.joints[5].pitch * Math.sin( degToRad(( cycle * adjustedFrequency * 2) + + currentAnimation.joints[5].pitchPhase)) + currentAnimation.joints[5].pitchOffset; + + yawOscillation = currentAnimation.joints[5].yaw * Math.sin( degToRad(( cycle * adjustedFrequency ) + + currentAnimation.joints[5].yawPhase)) + currentAnimation.joints[5].yawOffset; + + rollOscillation = currentAnimation.joints[5].roll * Math.sin( degToRad(( cycle * adjustedFrequency ) + + currentAnimation.joints[5].rollPhase)) + currentAnimation.joints[5].rollOffset; + + pitchOscillationLast = currentTransition.lastAnimation.joints[5].pitch + * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency * 2 ) + + currentTransition.lastAnimation.joints[5].pitchPhase)) + + currentTransition.lastAnimation.joints[5].pitchOffset; + + yawOscillationLast = currentTransition.lastAnimation.joints[5].yaw + * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) + + currentTransition.lastAnimation.joints[5].yawPhase)) + + currentTransition.lastAnimation.joints[5].yawOffset; + + rollOscillationLast = currentTransition.lastAnimation.joints[5].roll + * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) + + currentTransition.lastAnimation.joints[5].rollPhase)) + + currentTransition.lastAnimation.joints[5].rollOffset; + } + + pitchOscillation = (transitionProgress * pitchOscillation ) + ((1-transitionProgress) * pitchOscillationLast); + yawOscillation = (transitionProgress * yawOscillation ) + ((1-transitionProgress) * yawOscillationLast); + rollOscillation = (transitionProgress * rollOscillation ) + ((1-transitionProgress) * rollOscillationLast); + + } else { + + pitchOscillation = currentAnimation.joints[5].pitch * Math.sin(degToRad(( cycle * adjustedFrequency * 2) + currentAnimation.joints[5].pitchPhase)) + currentAnimation.joints[5].pitchOffset; + yawOscillation = currentAnimation.joints[5].yaw * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[5].yawPhase)) + currentAnimation.joints[5].yawOffset; + rollOscillation = currentAnimation.joints[5].roll * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[5].rollPhase)) + currentAnimation.joints[5].rollOffset; + } // apply spine joint rotations - MyAvatar.setJointData("Spine", Quat.fromPitchYawRollDegrees(-pitchOscillation, yawOscillation, rollOscillation)); + 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; + // spine 1 + if(currentTransition!==null) { + + if(currentTransition.walkingAtStart) { + + pitchOscillation = currentAnimation.joints[6].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency * 2) + currentAnimation.joints[6].pitchPhase)) + currentAnimation.joints[6].pitchOffset; + yawOscillation = currentAnimation.joints[6].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[6].yawPhase)) + currentAnimation.joints[6].yawOffset; + rollOscillation = currentAnimation.joints[6].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[6].rollPhase)) + currentAnimation.joints[6].rollOffset; + + pitchOscillationLast = currentTransition.lastAnimation.joints[6].pitch + * Math.sin(degToRad(( walkWheelPosition * 2 ) + currentTransition.lastAnimation.joints[6].pitchPhase)) + + currentTransition.lastAnimation.joints[6].pitchOffset; + yawOscillationLast = currentTransition.lastAnimation.joints[6].yaw + * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[6].yawPhase)) + + currentTransition.lastAnimation.joints[6].yawOffset; + rollOscillationLast = currentTransition.lastAnimation.joints[6].roll + * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[6].rollPhase)) + + currentTransition.lastAnimation.joints[6].rollOffset; + + } else { //if( currentTransition.walkingAtEnd ) { + + pitchOscillation = currentAnimation.joints[6].pitch * Math.sin( degToRad(( cycle * adjustedFrequency * 2) + + currentAnimation.joints[6].pitchPhase)) + currentAnimation.joints[6].pitchOffset; + + yawOscillation = currentAnimation.joints[6].yaw * Math.sin( degToRad(( cycle * adjustedFrequency ) + + currentAnimation.joints[6].yawPhase)) + currentAnimation.joints[6].yawOffset; + + rollOscillation = currentAnimation.joints[6].roll * Math.sin( degToRad(( cycle * adjustedFrequency ) + + currentAnimation.joints[6].rollPhase)) + currentAnimation.joints[6].rollOffset; + + pitchOscillationLast = currentTransition.lastAnimation.joints[6].pitch + * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency * 2 ) + + currentTransition.lastAnimation.joints[6].pitchPhase)) + + currentTransition.lastAnimation.joints[6].pitchOffset; + + yawOscillationLast = currentTransition.lastAnimation.joints[6].yaw + * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) + + currentTransition.lastAnimation.joints[6].yawPhase)) + + currentTransition.lastAnimation.joints[6].yawOffset; + + rollOscillationLast = currentTransition.lastAnimation.joints[6].roll + * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) + + currentTransition.lastAnimation.joints[6].rollPhase)) + + currentTransition.lastAnimation.joints[6].rollOffset; + } + + pitchOscillation = (transitionProgress * pitchOscillation) + ((1-transitionProgress) * pitchOscillationLast); + yawOscillation = (transitionProgress * yawOscillation) + ((1-transitionProgress) * yawOscillationLast); + rollOscillation = (transitionProgress * rollOscillation) + ((1-transitionProgress) * rollOscillationLast); + + } else { + + pitchOscillation = currentAnimation.joints[6].pitch * Math.sin(degToRad(( cycle * adjustedFrequency * 2) + currentAnimation.joints[6].pitchPhase)) + currentAnimation.joints[6].pitchOffset; + yawOscillation = currentAnimation.joints[6].yaw * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[6].yawPhase)) + currentAnimation.joints[6].yawOffset; + rollOscillation = currentAnimation.joints[6].roll * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[6].rollPhase)) + currentAnimation.joints[6].rollOffset; + } // apply spine1 joint rotations - MyAvatar.setJointData("Spine1", Quat.fromPitchYawRollDegrees( pitchOscillation, -yawOscillation, rollOscillation)); + 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; + if(currentTransition!==null) { + if(currentTransition.walkingAtStart) { + pitchOscillation = currentAnimation.joints[7].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency * 2) + currentAnimation.joints[7].pitchPhase)) + currentAnimation.joints[7].pitchOffset; + yawOscillation = currentAnimation.joints[7].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[7].yawPhase)) + currentAnimation.joints[7].yawOffset; + rollOscillation = currentAnimation.joints[7].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[7].rollPhase)) + currentAnimation.joints[7].rollOffset; + + pitchOscillationLast = currentTransition.lastAnimation.joints[7].pitch + * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[7].pitchPhase)) + + currentTransition.lastAnimation.joints[7].pitchOffset; + + yawOscillationLast = currentTransition.lastAnimation.joints[7].yaw + * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[7].yawPhase)) + + currentTransition.lastAnimation.joints[7].yawOffset; + + rollOscillationLast = currentTransition.lastAnimation.joints[7].roll + * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[7].rollPhase)) + + currentTransition.lastAnimation.joints[7].rollOffset; + + } else { //if( currentTransition.walkingAtEnd ) { + + pitchOscillation = currentAnimation.joints[7].pitch + * Math.sin( degToRad(( cycle * adjustedFrequency * 2) + + currentAnimation.joints[7].pitchPhase)) + + currentAnimation.joints[7].pitchOffset; + + yawOscillation = currentAnimation.joints[7].yaw + * Math.sin( degToRad(( cycle * adjustedFrequency ) + + currentAnimation.joints[7].yawPhase)) + + currentAnimation.joints[7].yawOffset; + + rollOscillation = currentAnimation.joints[7].roll + * Math.sin( degToRad(( cycle * adjustedFrequency ) + + currentAnimation.joints[7].rollPhase)) + + currentAnimation.joints[7].rollOffset; + + pitchOscillationLast = currentTransition.lastAnimation.joints[7].pitch + * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) + + currentTransition.lastAnimation.joints[7].pitchPhase)) + + currentTransition.lastAnimation.joints[7].pitchOffset; + + yawOscillationLast = currentTransition.lastAnimation.joints[7].yaw + * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) + + currentTransition.lastAnimation.joints[7].yawPhase)) + + currentTransition.lastAnimation.joints[7].yawOffset; + + rollOscillationLast = currentTransition.lastAnimation.joints[7].roll + * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) + + currentTransition.lastAnimation.joints[7].rollPhase)) + + currentTransition.lastAnimation.joints[7].rollOffset; + } + + pitchOscillation = (transitionProgress * pitchOscillation ) + ((1-transitionProgress) * pitchOscillationLast); + yawOscillation = (transitionProgress * yawOscillation ) + ((1-transitionProgress) * yawOscillationLast); + rollOscillation = (transitionProgress * rollOscillation ) + ((1-transitionProgress) * rollOscillationLast); + + } else { + + pitchOscillation = currentAnimation.joints[7].pitch * Math.sin(degToRad(( cycle * adjustedFrequency * 2) + currentAnimation.joints[7].pitchPhase)) + + currentAnimation.joints[7].pitchOffset; + + yawOscillation = currentAnimation.joints[7].yaw * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[7].yawPhase)) + + currentAnimation.joints[7].yawOffset; + + rollOscillation = currentAnimation.joints[7].roll * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[7].rollPhase)) + + currentAnimation.joints[7].rollOffset; + } // apply spine2 joint rotations - MyAvatar.setJointData("Spine2", Quat.fromPitchYawRollDegrees(-pitchOscillation, yawOscillation, -rollOscillation)); + 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 )); + if(currentTransition!==null) { + + if(currentTransition.walkingAtStart) { + pitchOscillation = currentAnimation.joints[8].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + + currentAnimation.joints[8].pitchPhase)) + currentAnimation.joints[8].pitchOffset; + + yawOscillation = currentAnimation.joints[8].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + + currentAnimation.joints[8].yawPhase)); + + rollOscillation = currentAnimation.joints[8].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency * 2) + + currentAnimation.joints[8].rollPhase)) + currentAnimation.joints[8].rollOffset; + + yawOffset = currentAnimation.joints[8].yawOffset; + + + pitchOscillationLast = currentTransition.lastAnimation.joints[8].pitch + * Math.sin(degToRad( walkWheelPosition + currentTransition.lastAnimation.joints[8].pitchPhase)) + + currentTransition.lastAnimation.joints[8].pitchOffset; + + yawOscillationLast = currentTransition.lastAnimation.joints[8].yaw + * Math.sin(degToRad( walkWheelPosition + currentTransition.lastAnimation.joints[8].yawPhase)) + + rollOscillationLast = currentTransition.lastAnimation.joints[8].roll + * Math.sin(degToRad( walkWheelPosition + currentTransition.lastAnimation.joints[8].rollPhase)) + + currentTransition.lastAnimation.joints[8].rollOffset; + + yawOffsetLast = currentTransition.lastAnimation.joints[8].yawOffset; + + } else { //if( currentTransition.walkingAtEnd ) { + + pitchOscillation = currentAnimation.joints[8].pitch * Math.sin( degToRad(( cycle * adjustedFrequency ) + + currentAnimation.joints[8].pitchPhase)) + currentAnimation.joints[8].pitchOffset; + + yawOscillation = currentAnimation.joints[8].yaw * Math.sin( degToRad(( cycle * adjustedFrequency ) + + currentAnimation.joints[8].yawPhase)); + + rollOscillation = currentAnimation.joints[8].roll * Math.sin( degToRad(( cycle * adjustedFrequency * 2) + + currentAnimation.joints[8].rollPhase)) + currentAnimation.joints[8].rollOffset; + + yawOffset = currentAnimation.joints[8].yawOffset; + + pitchOscillationLast = currentTransition.lastAnimation.joints[8].pitch + * Math.sin( degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency + + currentTransition.lastAnimation.joints[8].pitchPhase)) + + currentTransition.lastAnimation.joints[8].pitchOffset; + + yawOscillationLast = currentTransition.lastAnimation.joints[8].yaw + * Math.sin( degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency + + currentTransition.lastAnimation.joints[8].yawPhase)) + + rollOscillationLast = currentTransition.lastAnimation.joints[8].roll + * Math.sin( degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency + + currentTransition.lastAnimation.joints[8].rollPhase)) + + currentTransition.lastAnimation.joints[8].rollOffset; + + yawOffsetLast = currentTransition.lastAnimation.joints[8].yawOffset; + } + + pitchOscillation = (transitionProgress * pitchOscillation) + ((1-transitionProgress) * pitchOscillationLast); + yawOscillation = (transitionProgress * yawOscillation) + ((1-transitionProgress) * yawOscillationLast); + rollOscillation = (transitionProgress * rollOscillation) + ((1-transitionProgress) * rollOscillationLast); + + yawOffset = (transitionProgress * yawOffset) + ((1-transitionProgress) * yawOffsetLast); + + } else { + + pitchOscillation = currentAnimation.joints[8].pitch * Math.sin(degToRad(( cycle * adjustedFrequency ) + + currentAnimation.joints[8].pitchPhase)) + currentAnimation.joints[8].pitchOffset; + + yawOscillation = currentAnimation.joints[8].yaw * Math.sin(degToRad(( cycle * adjustedFrequency ) + + currentAnimation.joints[8].yawPhase)); + + rollOscillation = currentAnimation.joints[8].roll * Math.sin(degToRad(( cycle * adjustedFrequency * 2) + + currentAnimation.joints[8].rollPhase)) + currentAnimation.joints[8].rollOffset; + + yawOffset = currentAnimation.joints[8].yawOffset; + } + + MyAvatar.setJointData("RightShoulder", Quat.fromPitchYawRollDegrees(pitchOscillation, yawOscillation + yawOffset, rollOscillation )); + MyAvatar.setJointData("LeftShoulder", Quat.fromPitchYawRollDegrees(pitchOscillation, yawOscillation - yawOffset, -rollOscillation )); // upper arms - 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 )); + if(currentTransition!==null) { + + if(currentTransition.walkingAtStart) { + + pitchOscillation = currentAnimation.joints[9].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[9].pitchPhase)); + yawOscillation = currentAnimation.joints[9].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[9].yawPhase)); + rollOscillation = currentAnimation.joints[9].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency * 2) + currentAnimation.joints[9].rollPhase)) + currentAnimation.joints[9].rollOffset; + + pitchOffset = currentAnimation.joints[9].pitchOffset; + yawOffset = currentAnimation.joints[9].yawOffset; + + pitchOscillationLast = currentTransition.lastAnimation.joints[9].pitch + * Math.sin(degToRad( walkWheelPosition + currentTransition.lastAnimation.joints[9].pitchPhase)) + + yawOscillationLast = currentTransition.lastAnimation.joints[9].yaw + * Math.sin(degToRad( walkWheelPosition + currentTransition.lastAnimation.joints[9].yawPhase)) + + rollOscillationLast = currentTransition.lastAnimation.joints[9].roll + * Math.sin(degToRad( walkWheelPosition + currentTransition.lastAnimation.joints[9].rollPhase)) + + currentTransition.lastAnimation.joints[9].rollOffset; + + pitchOffsetLast = currentTransition.lastAnimation.joints[9].pitchOffset; + yawOffsetLast = currentTransition.lastAnimation.joints[9].yawOffset; + + } else { //if( currentTransition.walkingAtEnd ) { + + pitchOscillation = currentAnimation.joints[9].pitch + * Math.sin( degToRad(( cycle * adjustedFrequency ) + + currentAnimation.joints[9].pitchPhase)); + + yawOscillation = currentAnimation.joints[9].yaw + * Math.sin( degToRad(( cycle * adjustedFrequency ) + + currentAnimation.joints[9].yawPhase)); + + rollOscillation = currentAnimation.joints[9].roll + * Math.sin(degToRad(( cycle * adjustedFrequency * 2) + + currentAnimation.joints[9].rollPhase)) + + currentAnimation.joints[9].rollOffset; + + pitchOffset = currentAnimation.joints[9].pitchOffset; + yawOffset = currentAnimation.joints[9].yawOffset; + + pitchOscillationLast = currentTransition.lastAnimation.joints[9].pitch + * Math.sin( degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency + + currentTransition.lastAnimation.joints[9].pitchPhase)) + + yawOscillationLast = currentTransition.lastAnimation.joints[9].yaw + * Math.sin( degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency + + currentTransition.lastAnimation.joints[9].yawPhase)) + + rollOscillationLast = currentTransition.lastAnimation.joints[9].roll + * Math.sin( degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency + + currentTransition.lastAnimation.joints[9].rollPhase)) + + currentTransition.lastAnimation.joints[9].rollOffset; + + pitchOffsetLast = currentTransition.lastAnimation.joints[9].pitchOffset; + yawOffsetLast = currentTransition.lastAnimation.joints[9].yawOffset; + } + + pitchOscillation = (transitionProgress * pitchOscillation) + ((1-transitionProgress) * pitchOscillationLast); + yawOscillation = (transitionProgress * yawOscillation) + ((1-transitionProgress) * yawOscillationLast); + rollOscillation = (transitionProgress * rollOscillation) + ((1-transitionProgress) * rollOscillationLast); + + pitchOffset = (transitionProgress * pitchOffset) + ((1-transitionProgress) * pitchOffsetLast); + yawOffset = (transitionProgress * yawOffset) + ((1-transitionProgress) * yawOffsetLast); + + } else { + + pitchOscillation = currentAnimation.joints[9].pitch + * Math.sin( degToRad(( cycle * adjustedFrequency ) + + currentAnimation.joints[9].pitchPhase)); + + yawOscillation = currentAnimation.joints[9].yaw + * Math.sin( degToRad(( cycle * adjustedFrequency ) + + currentAnimation.joints[9].yawPhase)); + + rollOscillation = currentAnimation.joints[9].roll + * Math.sin( degToRad(( cycle * adjustedFrequency * 2) + + currentAnimation.joints[9].rollPhase)) + + currentAnimation.joints[9].rollOffset; + + pitchOffset = currentAnimation.joints[9].pitchOffset; + yawOffset = currentAnimation.joints[9].yawOffset; + + } + MyAvatar.setJointData("RightArm", Quat.fromPitchYawRollDegrees( -pitchOscillation + pitchOffset, yawOscillation - yawOffset, rollOscillation )); + MyAvatar.setJointData("LeftArm", Quat.fromPitchYawRollDegrees( pitchOscillation + pitchOffset, yawOscillation + yawOffset, -rollOscillation )); // forearms - 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 )); + if(currentTransition!==null) { + + if(currentTransition.walkingAtStart) { + + pitchOscillation = currentAnimation.joints[10].pitch + * Math.sin( degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + + currentAnimation.joints[10].pitchPhase )) + + currentAnimation.joints[10].pitchOffset; + + yawOscillation = currentAnimation.joints[10].yaw + * Math.sin( degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + + currentAnimation.joints[10].yawPhase )); + + rollOscillation = currentAnimation.joints[10].roll + * Math.sin( degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + + currentAnimation.joints[10].rollPhase )); + + yawOffset = currentAnimation.joints[10].yawOffset; + rollOffset = currentAnimation.joints[10].rollOffset; + + pitchOscillationLast = currentTransition.lastAnimation.joints[10].pitch + * Math.sin( degToRad(( walkWheelPosition ) + + currentTransition.lastAnimation.joints[10].pitchPhase)) + + currentTransition.lastAnimation.joints[10].pitchOffset; + + yawOscillationLast = currentTransition.lastAnimation.joints[10].yaw + * Math.sin( degToRad(( walkWheelPosition ) + + currentTransition.lastAnimation.joints[10].yawPhase)); + + rollOscillationLast = currentTransition.lastAnimation.joints[10].roll + * Math.sin( degToRad(( walkWheelPosition ) + + currentTransition.lastAnimation.joints[10].rollPhase)); + + yawOffsetLast = currentTransition.lastAnimation.joints[10].yawOffset; + rollOffsetLast = currentTransition.lastAnimation.joints[10].rollOffset; + + } else { //if( currentTransition.walkingAtEnd ) { + + pitchOscillation = currentAnimation.joints[10].pitch + * Math.sin( degToRad(( cycle * adjustedFrequency ) + + currentAnimation.joints[10].pitchPhase )) + + currentAnimation.joints[10].pitchOffset; + + yawOscillation = currentAnimation.joints[10].yaw + * Math.sin( degToRad(( cycle * adjustedFrequency ) + + currentAnimation.joints[10].yawPhase )); + + rollOscillation = currentAnimation.joints[10].roll + * Math.sin( degToRad(( cycle * adjustedFrequency ) + + currentAnimation.joints[10].rollPhase )); + + yawOffset = currentAnimation.joints[10].yawOffset; + rollOffset = currentAnimation.joints[10].rollOffset; + + pitchOscillationLast = currentTransition.lastAnimation.joints[10].pitch + * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) + + currentTransition.lastAnimation.joints[10].pitchPhase)) + + currentTransition.lastAnimation.joints[10].pitchOffset; + + yawOscillationLast = currentTransition.lastAnimation.joints[10].yaw + * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) + + currentTransition.lastAnimation.joints[10].yawPhase)); + + rollOscillationLast = currentTransition.lastAnimation.joints[10].roll + * Math.sin( degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) + + currentTransition.lastAnimation.joints[10].rollPhase)); + + yawOffsetLast = currentTransition.lastAnimation.joints[10].yawOffset; + rollOffsetLast = currentTransition.lastAnimation.joints[10].rollOffset; + } + + // blend the previous and next + pitchOscillation = (transitionProgress * pitchOscillation) + ((1-transitionProgress) * pitchOscillationLast); + yawOscillation = -(transitionProgress * yawOscillation) + ((1-transitionProgress) * yawOscillationLast); + rollOscillation = (transitionProgress * rollOscillation) + ((1-transitionProgress) * rollOscillationLast); + + yawOffset = (transitionProgress * yawOffset) + ((1-transitionProgress) * yawOffsetLast); + rollOffset = (transitionProgress * rollOffset) + ((1-transitionProgress) * rollOffsetLast); + + } else { + + pitchOscillation = currentAnimation.joints[10].pitch + * Math.sin( degToRad(( cycle * adjustedFrequency ) + + currentAnimation.joints[10].pitchPhase )) + + currentAnimation.joints[10].pitchOffset; + + yawOscillation = currentAnimation.joints[10].yaw + * Math.sin( degToRad(( cycle * adjustedFrequency ) + + currentAnimation.joints[10].yawPhase )); + + rollOscillation = currentAnimation.joints[10].roll + * Math.sin( degToRad(( cycle * adjustedFrequency ) + + currentAnimation.joints[10].rollPhase )); + + yawOffset = currentAnimation.joints[10].yawOffset; + rollOffset = currentAnimation.joints[10].rollOffset; + } + + // transitionProgress pitchOscillation yawOscillation rollOscillation + //print(transitionProgress+' '+pitchOscillation+' '+yawOscillation+' '+rollOscillation); + + // apply forearms rotations + MyAvatar.setJointData("RightForeArm", Quat.fromPitchYawRollDegrees( pitchOscillation, yawOscillation + yawOffset, rollOscillation + rollOffset )); + MyAvatar.setJointData("LeftForeArm", Quat.fromPitchYawRollDegrees( pitchOscillation, yawOscillation - yawOffset, rollOscillation - 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)); + var sideStepSign = 1; + if(INTERNAL_STATE===SIDE_STEPPING) { + sideStepSign = 1; + } // TODO: check status of hand rotations + if(currentTransition!==null) { - } // if(!armsFree) + if(currentTransition.walkingAtStart) { - // 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)); + pitchOscillation = currentAnimation.joints[11].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[11].pitchPhase)) + currentAnimation.joints[11].pitchOffset; + yawOscillation = currentAnimation.joints[11].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[11].yawPhase)) + currentAnimation.joints[11].yawOffset; + rollOscillation = currentAnimation.joints[11].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + currentAnimation.joints[11].rollPhase)) ; + + pitchOscillationLast = currentTransition.lastAnimation.joints[11].pitch + * Math.sin(degToRad( walkWheelPosition + currentTransition.lastAnimation.joints[11].pitchPhase)) + + currentTransition.lastAnimation.joints[11].pitchOffset; + + yawOscillationLast = currentTransition.lastAnimation.joints[11].yaw + * Math.sin(degToRad( walkWheelPosition + currentTransition.lastAnimation.joints[11].yawPhase)) + + currentTransition.lastAnimation.joints[11].yawOffset; + + rollOscillationLast = currentTransition.lastAnimation.joints[11].roll + * Math.sin(degToRad( walkWheelPosition + currentTransition.lastAnimation.joints[11].rollPhase)) + + rollOffset = currentAnimation.joints[11].rollOffset; + rollOffsetLast = currentTransition.lastAnimation.joints[11].rollOffset; + + } else { //if( currentTransition.walkingAtEnd ) { + + pitchOscillation = currentAnimation.joints[11].pitch + * Math.sin( degToRad(( cycle * adjustedFrequency ) + + currentAnimation.joints[11].pitchPhase)) + + currentAnimation.joints[11].pitchOffset; + + yawOscillation = currentAnimation.joints[11].yaw + * Math.sin( degToRad(( cycle * adjustedFrequency ) + + currentAnimation.joints[11].yawPhase)) + + currentAnimation.joints[11].yawOffset; + + rollOscillation = currentAnimation.joints[11].roll + * Math.sin( degToRad(( cycle * adjustedFrequency ) + + currentAnimation.joints[11].rollPhase)); + + rollOffset = currentAnimation.joints[11].rollOffset; + + pitchOscillationLast = currentTransition.lastAnimation.joints[11].pitch + * Math.sin(degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency + + currentTransition.lastAnimation.joints[11].pitchPhase)) + + currentTransition.lastAnimation.joints[11].pitchOffset; + + yawOscillationLast = currentTransition.lastAnimation.joints[11].yaw + * Math.sin(degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency + + currentTransition.lastAnimation.joints[11].yawPhase)) + + currentTransition.lastAnimation.joints[11].yawOffset; + + rollOscillationLast = currentTransition.lastAnimation.joints[11].roll + * Math.sin(degToRad( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency + + currentTransition.lastAnimation.joints[11].rollPhase)) + + rollOffset = currentAnimation.joints[11].rollOffset; + rollOffsetLast = currentTransition.lastAnimation.joints[11].rollOffset; + } + + pitchOscillation = (transitionProgress * pitchOscillation) + ((1-transitionProgress) * pitchOscillationLast); + yawOscillation = (transitionProgress * yawOscillation) + ((1-transitionProgress) * yawOscillationLast); + rollOscillation = (transitionProgress * rollOscillation) + ((1-transitionProgress) * rollOscillationLast); + + rollOffset = (transitionProgress * rollOffset) + ((1-transitionProgress) * rollOffsetLast); + + } else { + + pitchOscillation = currentAnimation.joints[11].pitch * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[11].pitchPhase)) + currentAnimation.joints[11].pitchOffset; + yawOscillation = currentAnimation.joints[11].yaw * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[11].yawPhase)) + currentAnimation.joints[11].yawOffset; + rollOscillation = currentAnimation.joints[11].roll * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[11].rollPhase)); + + rollOffset = currentAnimation.joints[11].rollOffset; + } + + // set the hand rotations + MyAvatar.setJointData("RightHand", Quat.fromPitchYawRollDegrees( sideStepSign * pitchOscillation, yawOscillation, rollOscillation + rollOffset)); + MyAvatar.setJointData("LeftHand", Quat.fromPitchYawRollDegrees( pitchOscillation, -yawOscillation, rollOscillation - rollOffset)); + + } // end if(!armsFree) + + // head (includes neck joint) - currently zeroed out in STANDING by request + if( currentTransition !== null ) { + + if(currentTransition.walkingAtStart) { + + pitchOscillation = 0.5 * currentAnimation.joints[12].pitch * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency * 2) + + currentAnimation.joints[12].pitchPhase)) + currentAnimation.joints[12].pitchOffset; + + yawOscillation = 0.5 * currentAnimation.joints[12].yaw * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + + currentAnimation.joints[12].yawPhase)) + currentAnimation.joints[12].yawOffset; + + rollOscillation = 0.5 * currentAnimation.joints[12].roll * Math.sin(degToRad(( cumulativeTime * currentAnimation.settings.baseFrequency ) + + currentAnimation.joints[12].rollPhase)) + currentAnimation.joints[12].rollOffset; + + pitchOscillationLast = 0.5 * currentTransition.lastAnimation.joints[12].pitch + * Math.sin(degToRad(( walkWheelPosition * 2) + currentTransition.lastAnimation.joints[12].pitchPhase)) + + currentTransition.lastAnimation.joints[12].pitchOffset; + + yawOscillationLast = 0.5 * currentTransition.lastAnimation.joints[12].yaw + * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[12].yawPhase)) + + currentTransition.lastAnimation.joints[12].yawOffset; + + rollOscillationLast = 0.5 * currentTransition.lastAnimation.joints[12].roll + * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[12].rollPhase)) + + currentTransition.lastAnimation.joints[12].rollOffset; + + } else { //if( currentTransition.walkingAtEnd ) { + + pitchOscillation = 0.5 * currentAnimation.joints[12].pitch * Math.sin(degToRad(( cycle * adjustedFrequency * 2) + currentAnimation.joints[12].pitchPhase)) + currentAnimation.joints[12].pitchOffset; + yawOscillation = 0.5 * currentAnimation.joints[12].yaw * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[12].yawPhase)) + currentAnimation.joints[12].yawOffset; + rollOscillation = 0.5 * currentAnimation.joints[12].roll * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[12].rollPhase)) + currentAnimation.joints[12].rollOffset; + + pitchOscillationLast = 0.5 * currentTransition.lastAnimation.joints[12].pitch + * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency * 2) + + currentTransition.lastAnimation.joints[12].pitchPhase)) + + currentTransition.lastAnimation.joints[12].pitchOffset; + + yawOscillationLast = 0.5 * currentTransition.lastAnimation.joints[12].yaw + * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) + + currentTransition.lastAnimation.joints[12].yawPhase)) + + currentTransition.lastAnimation.joints[12].yawOffset; + + rollOscillationLast = 0.5 * currentTransition.lastAnimation.joints[12].roll + * Math.sin(degToRad(( cumulativeTime * currentTransition.lastAnimation.settings.baseFrequency ) + + currentTransition.lastAnimation.joints[12].rollPhase)) + + currentTransition.lastAnimation.joints[12].rollOffset; + } + + // TODO: see if can animate separate heads in any way... + pitchOscillation = (transitionProgress * pitchOscillation) + ((1-transitionProgress) * pitchOscillationLast); + yawOscillation = (transitionProgress * yawOscillation) + ((1-transitionProgress) * yawOscillationLast); + rollOscillation = (transitionProgress * rollOscillation) + ((1-transitionProgress) * rollOscillationLast); + + } else { + + pitchOscillation = 0.5 * currentAnimation.joints[12].pitch * Math.sin(degToRad(( cycle * adjustedFrequency * 2) + currentAnimation.joints[12].pitchPhase)) + currentAnimation.joints[12].pitchOffset; + yawOscillation = 0.5 * currentAnimation.joints[12].yaw * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[12].yawPhase)) + currentAnimation.joints[12].yawOffset; + rollOscillation = 0.5 * currentAnimation.joints[12].roll * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[12].rollPhase)) + currentAnimation.joints[12].rollOffset; + } + + MyAvatar.setJointData( "Head", Quat.fromPitchYawRollDegrees( pitchOscillation, yawOscillation, rollOscillation )); + MyAvatar.setJointData( "Neck", Quat.fromPitchYawRollDegrees( pitchOscillation, yawOscillation, rollOscillation )); } -// getBezier from: http://13thparallel.com/archive/bezier-curves/ -//====================================\\ -// 13thParallel.org Beziér Curve Code \\ -// by Dan Pupius (www.pupius.net) \\ -//====================================\\ -/* -coord = function (x,y) { +// getBezier - src: Dan Pupius (www.pupius.net) http://13thparallel.com/archive/bezier-curves/ +Coord = function (x,y) { if(!x) var x=0; if(!y) var y=0; return {x: x, y: y}; @@ -719,110 +1791,168 @@ 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(); + var pos = new Coord(); pos.x = C1.x*B1(percent) + C2.x*B2(percent) + C3.x*B3(percent) + C4.x*B4(percent); pos.y = C1.y*B1(percent) + C2.y*B2(percent) + C3.y*B3(percent) + C4.y*B4(percent); return pos; } -*/ + +// Butterworth LP filter - coeffs calculated using: http://www-users.cs.york.ac.uk/~fisher/mkfilter/trad.html +var NZEROS = 8; +var NPOLES = 8; +var GAIN = 17.40692157; +var xv = [0,0,0,0,0,0,0,0,0]; +//xv.length = NZEROS+1; +var yv = [0,0,0,0,0,0,0,0,0]; +//yv.length = NPOLES+1; + +function filterButterworth(nextInputValue) +{ + xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4]; xv[4] = xv[5]; xv[5] = xv[6]; xv[6] = xv[7]; xv[7] = xv[8]; + xv[8] = nextInputValue / GAIN; + yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4]; yv[4] = yv[5]; yv[5] = yv[6]; yv[6] = yv[7]; yv[7] = yv[8]; + yv[8] = (xv[0] + xv[8]) + 8 * (xv[1] + xv[7]) + 28 * (xv[2] + xv[6]) + + 56 * (xv[3] + xv[5]) + 70 * xv[4] + + ( -0.0033008230 * yv[0]) + ( -0.0440409341 * yv[1]) + + ( -0.2663485333 * yv[2]) + ( -0.9570250765 * yv[3]) + + ( -2.2596729000 * yv[4]) + ( -3.6088345059 * yv[5]) + + ( -3.9148571397 * yv[6]) + ( -2.6527135283 * yv[7]); + return yv[8]; +} // the faster we go, the further we lean forward. the angle is calcualted here -var leanAngles = [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 +var leanAngles = []; // smooth out and add damping with simple averaging filter. +leanAngles.length = 15; + function getLeanPitch(velocity) { +/* + // lean backwards when decelerating a lot. skid to a halt. working, but I don't like the effect - will use a reach pose later instead + var accelerationResponse = recentMotions[0].acceleration.z; + var accelerationResponseMax = 45; // max degrees hip pitch + + if(velocityaccelerationResponseMax) + accelerationResponse = accelerationResponseMax; + else if(accelerationResponse<-accelerationResponseMax) + accelerationResponse = -accelerationResponseMax; + // apply yet another averaging filter... + accelerationResponseAngles.push(accelerationResponse); + accelerationResponseAngles.shift(); + var finalAccelerationResponse = 0; + for(ea in accelerationResponseAngles) finalAccelerationResponse += accelerationResponseAngles[ea]; + finalAccelerationResponse /= accelerationResponseAngles.length; + + // calculate any skid for this frame and apply it + var skidDistance = -0.01 * hipsToFeetDistance * Math.sin(degToRad(finalAccelerationResponse)); + if(Math.abs(skidDistance)>0.001 && INTERNAL_STATE===STANDING) { // show skids when stopping + var skidVector = localToGlobal({ x:0, y:0, z:skidDistance }); + print('skidDistance '+skidDistance+' metres'); + MyAvatar.position = Vec3.sum(MyAvatar.position, skidVector); + } + if(Math.abs(accelerationResponse)>0) print('accelerationResponse '+accelerationResponse.toFixed(3)+' recent acceleration '+recentMotions[0].acceleration.z.toFixed(3)); +*/ if(velocity>TERMINAL_VELOCITY) velocity=TERMINAL_VELOCITY; + var leanProgress = velocity / TERMINAL_VELOCITY; + var responseSharpness = 1.8; + if(principleDirection==DIRECTION_BACKWARDS) responseSharpness = 3.6; // lean back a bit extra when walking backwards + var leanProgressBezier = getBezier((1-leanProgress),{x:0,y:0},{x:0,y:responseSharpness},{x:0,y:1},{x:1,y:1}).y; + //var leanProgressButterworth = filterButterworth(leanProgressBezier); - var leanAngle = velocity / TERMINAL_VELOCITY * currentAnimation.settings.flyingHipsPitch; - - // simple averaging filter - leanAngles.push(leanAngle); + // simple averaging filter seems to give best results + leanAngles.push(leanProgressBezier); leanAngles.shift(); // FIFO var totalLeanAngles = 0; for(ea in leanAngles) totalLeanAngles += leanAngles[ea]; - var finalLeanAngle = totalLeanAngles / leanAngles.length; + var leanProgressAverageFiltered = 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 final return value + var leanPitchFinal = 0; + if(principleDirection===DIRECTION_BACKWARDS) { + leanPitchFinal = -currentAnimation.settings.flyingHipsPitch * leanProgressAverageFiltered;// + finalAccelerationResponse; + } else { + leanPitchFinal = currentAnimation.settings.flyingHipsPitch * leanProgressAverageFiltered;// + finalAccelerationResponse; + } + return leanPitchFinal; } // calculate the angle at which to bank into corners when turning -var 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 leanRollAngles = []; // smooth out and add damping with simple averaging filter +leanRollAngles.length = 25; - var angularVelocityMax = 70; +var angularVelocities = []; // keep a record of the last few so can filter out spurious values +angularVelocities.length = 5; + +function getLeanRoll(deltaTime, velocity) { + + // what's our current anglular velocity? + var angularVelocityMax = 70; // from observation var currentOrientationVec3 = Quat.safeEulerAngles(MyAvatar.orientation); var lastOrientationVec3 = Quat.safeEulerAngles(lastOrientation); var deltaYaw = lastOrientationVec3.y-currentOrientationVec3.y; - 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; + + var angularVelocity = deltaYaw / deltaTime; + if(angularVelocity>angularVelocityMax) angularVelocity = angularVelocityMax; + if(angularVelocity<-angularVelocityMax) angularVelocity = -angularVelocityMax; + + // filter the angular velocity for a nicer response and a bit of wobble (intentional overshoot / ringing) + angularVelocity = filterButterworth(angularVelocity); + + var turnSign = 1; + if(angularVelocity<0) turnSign = -1; + if(principleDirection===DIRECTION_BACKWARDS) + turnSign *= -1; + + // calculate the amount of roll based on both angular and linear velocities + if(velocity>TERMINAL_VELOCITY) velocity = TERMINAL_VELOCITY; + var leanRollProgress = (velocity / TERMINAL_VELOCITY) * (Math.abs(angularVelocity) / angularVelocityMax); + + // apply our response curve + var leanRollProgressBezier = getBezier((1-leanRollProgress),{x:0,y:0},{x:0,y:2.5},{x:0,y:1},{x:1,y:1}).y; + + // simple averaging filter + leanRollAngles.push(turnSign * leanRollProgressBezier); + leanRollAngles.shift(); // FIFO + var totalLeanRollAngles = 0; + for(var ea in leanRollAngles) totalLeanRollAngles += leanRollAngles[ea]; + var leanRollProgressAverageFiltered = totalLeanRollAngles / leanRollAngles.length; + + return currentAnimation.settings.maxBankingAngle * leanRollProgressAverageFiltered; } -// sets up the interface componenets and updates the internal state +// set up the interface components, update the internal state and kick off any transitions function setInternalState(newInternalState) { + var debugShowStateChanges = false; + switch(newInternalState) { case WALKING: - print('WALKING'); + + if(debugShowStateChanges) print('WALKING'); if(!minimised) doStandardMenu(); INTERNAL_STATE = WALKING; - currentAnimation = selectedWalk; - break; + return; case FLYING: - print('FLYING'); + + if(debugShowStateChanges) print('FLYING'); if(!minimised) doStandardMenu(); INTERNAL_STATE = FLYING; - currentAnimation = selectedFly; - break; + return; + + case SIDE_STEPPING: + + if(debugShowStateChanges) print('SIDE_STEPPING'); + if(!minimised) doStandardMenu(); + INTERNAL_STATE = SIDE_STEPPING; + return; case CONFIG_WALK_STYLES: + INTERNAL_STATE = CONFIG_WALK_STYLES; currentAnimation = selectedWalk; if(!minimised) { @@ -836,11 +1966,12 @@ function setInternalState(newInternalState) { setButtonOverlayVisible(configWalkTweaksButton); setButtonOverlayVisible(configWalkJointsButton); setButtonOverlayVisible(backButton); - setSliderthumbsVisible(false); + setSliderThumbsVisible(false); } - break; + return; case CONFIG_WALK_TWEAKS: + INTERNAL_STATE = CONFIG_WALK_TWEAKS; currentAnimation = selectedWalk; if(!minimised) { @@ -856,9 +1987,10 @@ function setInternalState(newInternalState) { setButtonOverlayVisible(backButton); initialiseWalkTweaks(); } - break; + return; case CONFIG_WALK_JOINTS: + INTERNAL_STATE = CONFIG_WALK_JOINTS; currentAnimation = selectedWalk; if(!minimised) { @@ -871,50 +2003,136 @@ function setInternalState(newInternalState) { setButtonOverlayVisible(configWalkTweaksButton); setButtonOverlayVisible(configWalkJointsButtonSelected); setButtonOverlayVisible(backButton); - Overlays.editOverlay(hipsJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} ); - initialiseWalkJointsPanel(selectedJointIndex); + initialiseJointsEditingPanel(selectedJointIndex); } - break; + return; case CONFIG_STANDING: + INTERNAL_STATE = CONFIG_STANDING; currentAnimation = selectedStand; if(!minimised) { hidebuttonOverlays(); - hideJointControls(); - doStandardMenu(); showFrontPanelButtons(false); showWalkStyleButtons(false); setBackground(controlsBackgroundWalkEditJoints); + setButtonOverlayVisible(onButton); + setButtonOverlayVisible(configSideStepRightButton); + setButtonOverlayVisible(configSideStepLeftButton); setButtonOverlayVisible(configStandButtonSelected); - Overlays.editOverlay(hipsJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} ); - initialiseWalkJointsPanel(selectedJointIndex); + setButtonOverlayVisible(backButton); + initialiseJointsEditingPanel(selectedJointIndex); } - break; + return; + + case CONFIG_SIDESTEP_LEFT: + + INTERNAL_STATE = CONFIG_SIDESTEP_LEFT; + currentAnimation = selectedSideStepLeft; + if(!minimised) { + hidebuttonOverlays(); + showFrontPanelButtons(false); + showWalkStyleButtons(false); + setBackground(controlsBackgroundWalkEditJoints); + setButtonOverlayVisible(onButton); + setButtonOverlayVisible(configSideStepRightButton); + setButtonOverlayVisible(configSideStepLeftButtonSelected); + setButtonOverlayVisible(configStandButton); + setButtonOverlayVisible(backButton); + initialiseJointsEditingPanel(selectedJointIndex); + } + return; + + case CONFIG_SIDESTEP_RIGHT: + + INTERNAL_STATE = CONFIG_SIDESTEP_RIGHT; + currentAnimation = selectedSideStepRight; + if(!minimised) { + hidebuttonOverlays(); + showFrontPanelButtons(false); + showWalkStyleButtons(false); + setBackground(controlsBackgroundWalkEditJoints); + setButtonOverlayVisible(onButton); + setButtonOverlayVisible(configSideStepRightButtonSelected); + setButtonOverlayVisible(configSideStepLeftButton); + setButtonOverlayVisible(configStandButton); + setButtonOverlayVisible(backButton); + initialiseJointsEditingPanel(selectedJointIndex); + } + return; case CONFIG_FLYING: + INTERNAL_STATE = CONFIG_FLYING; currentAnimation = selectedFly; if(!minimised) { hidebuttonOverlays(); - hideJointControls(); - doStandardMenu(); showFrontPanelButtons(false); showWalkStyleButtons(false); setBackground(controlsBackgroundWalkEditJoints); + setButtonOverlayVisible(onButton); + setButtonOverlayVisible(configFlyingUpButton); + setButtonOverlayVisible(configFlyingDownButton); setButtonOverlayVisible(configFlyingButtonSelected); - Overlays.editOverlay(hipsJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} ); - initialiseWalkJointsPanel(selectedJointIndex); + setButtonOverlayVisible(backButton); + initialiseJointsEditingPanel(selectedJointIndex); } - break; + return; + + case CONFIG_FLYING_UP: + + INTERNAL_STATE = CONFIG_FLYING_UP; + currentAnimation = selectedFlyUp; + if(!minimised) { + hidebuttonOverlays(); + showFrontPanelButtons(false); + showWalkStyleButtons(false); + setBackground(controlsBackgroundWalkEditJoints); + setButtonOverlayVisible(onButton); + setButtonOverlayVisible(configFlyingUpButtonSelected); + setButtonOverlayVisible(configFlyingDownButton); + setButtonOverlayVisible(configFlyingButton); + setButtonOverlayVisible(backButton); + initialiseJointsEditingPanel(selectedJointIndex); + } + return; + + case CONFIG_FLYING_DOWN: + + INTERNAL_STATE = CONFIG_FLYING_DOWN; + currentAnimation = selectedFlyDown; + if(!minimised) { + hidebuttonOverlays(); + showFrontPanelButtons(false); + showWalkStyleButtons(false); + setBackground(controlsBackgroundWalkEditJoints); + setButtonOverlayVisible(onButton); + setButtonOverlayVisible(configFlyingUpButton); + setButtonOverlayVisible(configFlyingDownButtonSelected); + setButtonOverlayVisible(configFlyingButton); + setButtonOverlayVisible(backButton); + initialiseJointsEditingPanel(selectedJointIndex); + } + return; case STANDING: default: - print('STANDING'); + + if(debugShowStateChanges) print('STANDING'); INTERNAL_STATE = STANDING; if(!minimised) doStandardMenu(); - currentAnimation = selectedStand; - break; + + // initialisation - runs at script startup only + if(strideLength===0) { + + if(principleDirection===DIRECTION_BACKWARDS) + strideLength = selectedWalk.calibration.strideLengthBackwards; + else + strideLength = selectedWalk.calibration.strideLengthForwards; + + curlFingers(); + } + return; } } @@ -926,159 +2144,516 @@ function setInternalState(newInternalState) { 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; +var requiredHints = 2; // tweakable - debounce state changes - how many times do we get a state change request in a row before we actually change state? (used to be 4 or 5) +var principleDirection = 0; + +// helper function for stats output +function directionAsString(directionEnum) { + + switch(directionEnum) { + case DIRECTION_UP: return 'Up'; + case DIRECTION_DOWN: return 'Down'; + case DIRECTION_LEFT: return 'Left'; + case DIRECTION_RIGHT: return 'Right'; + case DIRECTION_FORWARDS: return 'Forwards'; + case DIRECTION_BACKWARDS: return 'Backwards'; + default: return 'Unknown'; + } +} +// helper function for stats output +function internalStateAsString(internalState) { + + switch(internalState) { + case STANDING: return 'Standing'; + case WALKING: return 'Walking'; + case SIDE_STEPPING: return 'Side Stepping'; + case FLYING: return 'Flying'; + default: return 'Editing'; + } +} Script.update.connect(function(deltaTime) { if(powerOn) { + frameStartTime = new Date().getTime(); cumulativeTime += deltaTime; + nFrames++; + var speed = 0; - // firstly test for user configuration states + // firstly check for editing modes, as these require no positioning calculations + var editing = false; switch(INTERNAL_STATE) { case CONFIG_WALK_STYLES: currentAnimation = selectedWalk; - animateAvatar(deltaTime, 0, DIRECTION_FORWARDS); - return; + animateAvatar(deltaTime, speed, principleDirection); + editing = true; + break; case CONFIG_WALK_TWEAKS: currentAnimation = selectedWalk; - animateAvatar(deltaTime, 0, DIRECTION_FORWARDS); - return; + animateAvatar(deltaTime, speed, DIRECTION_FORWARDS); + editing = true; + break; case CONFIG_WALK_JOINTS: currentAnimation = selectedWalk; - animateAvatar(deltaTime, 0, DIRECTION_FORWARDS); - return; + animateAvatar(deltaTime, speed, DIRECTION_FORWARDS); + editing = true; + break; case CONFIG_STANDING: currentAnimation = selectedStand; - animateAvatar(deltaTime, 0, DIRECTION_FORWARDS); - return; + animateAvatar(deltaTime, speed, DIRECTION_FORWARDS); + editing = true; + break; + case CONFIG_SIDESTEP_LEFT: + currentAnimation = selectedSideStepLeft; + animateAvatar(deltaTime, speed, DIRECTION_LEFT); + editing = true; + break; + case CONFIG_SIDESTEP_RIGHT: + currentAnimation = selectedSideStepRight; + animateAvatar(deltaTime, speed, DIRECTION_RIGHT); + editing = true; + break; case CONFIG_FLYING: currentAnimation = selectedFly; - animateAvatar(deltaTime, 0, DIRECTION_FORWARDS); - return; + animateAvatar(deltaTime, speed, DIRECTION_FORWARDS); + editing = true; + break; + case CONFIG_FLYING_UP: + currentAnimation = selectedFlyUp; + animateAvatar(deltaTime, speed, DIRECTION_UP); + editing = true; + break; + case CONFIG_FLYING_DOWN: + currentAnimation = selectedFlyDown; + animateAvatar(deltaTime, speed, DIRECTION_DOWN); + editing = true; + break; default: break; } - // calcualte (local) change in position and velocity - var velocityVector = MyAvatar.getVelocity(); - var velocity = Vec3.length(velocityVector); + // we have to declare these vars here ( outside 'if(!editing)' ), so they are still in scope + // when we record the frame's data and when we do the stats update at the end + var deltaX = 0; + var deltaY = 0; + var deltaZ = 0; + var acceleration = { x:0, y:0, z:0 }; + var accelerationJS = MyAvatar.getAcceleration(); - // determine the candidate animation to play - var actionToTake = 0; - if( velocity < 0.1) { - actionToTake = STANDING; - standHints++; - } - 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 inverseRotation = Quat.inverse(MyAvatar.orientation); + var localVelocity = Vec3.multiplyQbyV(inverseRotation, MyAvatar.getVelocity()); - // 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; + if(!editing) { - // 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= FLYING_SPEED ) { + actionToTake = FLYING; + flyHints++; + } + + deltaX = localVelocity.x; + deltaY = localVelocity.y; + deltaZ = -localVelocity.z; + + // determine the principle direction 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); + principleDirection = DIRECTION_RIGHT; } else { - principleDirection = DIRECTION_LEFT;//print('velocity = '+velocity + ' DIRECTION_LEFT: deltaX '+deltaX+' deltaY '+deltaY+' deltaZ '+deltaZ); + principleDirection = DIRECTION_LEFT; } } 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); + principleDirection = DIRECTION_UP; } else { - principleDirection = DIRECTION_UP;//print('velocity = '+velocity + ' DIRECTION_UP: deltaX '+deltaX+' deltaY '+deltaY+' deltaZ '+deltaZ); + principleDirection = DIRECTION_DOWN; } } 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); + principleDirection = DIRECTION_FORWARDS; } else { - principleDirection = DIRECTION_FORWARDS;//print('velocity = '+velocity + ' DIRECTION_FORWARDS: deltaX '+deltaX+' deltaY '+deltaY+' deltaZ '+deltaZ); + principleDirection = DIRECTION_BACKWARDS; } } + + // NB: this section will change significantly once we are ground plane aware + // it will change even more once we have uneven surfaces to deal with + // but for now, we have to deal with states like 'standing in the air' + + // maybe at walking speed, but sideways? + if( actionToTake === WALKING && + ( principleDirection === DIRECTION_LEFT || + principleDirection === DIRECTION_RIGHT )) { + + actionToTake = SIDE_STEPPING; + } + + // maybe at walking speed, but flying up? + if( actionToTake === WALKING && + ( principleDirection === DIRECTION_UP )) { + + actionToTake = FLYING; + standHints--; + flyHints++; + } + + // maybe at walking speed, but flying down? + if( actionToTake === WALKING && + ( principleDirection === DIRECTION_DOWN )) { + + actionToTake = FLYING; + standHints--; + flyHints++; + } + + // log this frame's motion for later reference + var accelerationX = ( framesHistory.recentMotions[0].velocity.x - localVelocity.x ) / deltaTime; + var accelerationY = ( localVelocity.y - framesHistory.recentMotions[0].velocity.y ) / deltaTime; + var accelerationZ = ( framesHistory.recentMotions[0].velocity.z - localVelocity.z ) / deltaTime; + acceleration = {x:accelerationX, y:accelerationY, z:accelerationZ}; + + + // select appropriate animation and initiate Transition if required + switch(actionToTake) { + + case STANDING: + + if( standHints > requiredHints || INTERNAL_STATE===STANDING) { // wait for a few consecutive hints (17mS each) + + standHints = 0; + walkHints = 0; + flyHints = 0; + + // do we need to change state? + if( INTERNAL_STATE!==STANDING ) { + + // initiate the transition + if(currentTransition) { + delete currentTransition; + currentTransition = null; + } + + switch(currentAnimation) { + + case selectedWalk: + // Walking to Standing + var timeWalking = new Date().getTime() - framesHistory.lastWalkStartTime; + //print('You were walking for '+timeWalking+' mS'); + + var bezierCoeffsOne = {x:0.0, y:1.0}; + var bezierCoeffsTwo = {x:0.0, y:1.0}; + var transitionTime = 0.4; + + // very different curves for incremental steps + if( timeWalking < 550 ) { + bezierCoeffsOne = {x:0.63, y:0.17}; + bezierCoeffsTwo = {x:0.77, y:0.3}; + transitionTime = 0.75; + } + currentTransition = new Transition( currentAnimation, selectedStand, [], transitionTime, bezierCoeffsOne, bezierCoeffsTwo ); + break; + + + case selectedSideStepLeft: + case selectedSideStepRight: + + //currentTransition = new Transition(currentAnimation, selectedWalk, [], 0.3, {x:0.5,y:0.08}, {x:0.05,y:0.75}); + break; + + default: + + currentTransition = new Transition(currentAnimation, selectedStand, [], 0.3, {x:0.5,y:0.08}, {x:0.28,y:1}); + break; + } + + setInternalState(STANDING); + currentAnimation = selectedStand; + + } + animateAvatar(1,0,principleDirection); + } + break; + + case WALKING: + case SIDE_STEPPING: + if( walkHints > requiredHints || + INTERNAL_STATE===WALKING || + INTERNAL_STATE===SIDE_STEPPING ) { // wait for few consecutive hints (17mS each) + + standHints = 0; + walkHints = 0; + flyHints = 0; + + if( actionToTake === WALKING && INTERNAL_STATE !== WALKING) { + + // initiate the transition + if(currentTransition) { + delete currentTransition; + currentTransition = null; + } + + // set the appropriate start position for the walk wheel + if( principleDirection === DIRECTION_BACKWARDS ) { + + walkWheelPosition = selectedWalk.settings.startAngleBackwards; + + } else { + + walkWheelPosition = selectedWalk.settings.startAngleForwards; + } + + switch(currentAnimation) { + + case selectedStand: + // Standing to Walking + currentTransition = new Transition(currentAnimation, selectedWalk, [], 0.25, {x:0.5,y:0.08}, {x:0.05,y:0.75}); + break; + + case selectedSideStepLeft: + case selectedSideStepRight: + + break; + + default: + + currentTransition = new Transition(currentAnimation, selectedWalk, [], 0.3, {x:0.5,y:0.08}, {x:0.05,y:0.75}); + break; + } + framesHistory.lastWalkStartTime = new Date().getTime(); + setInternalState(WALKING); + currentAnimation = selectedWalk; + } + else if(actionToTake===SIDE_STEPPING) { + + var selectedSideStep = selectedSideStepRight; + if( principleDirection === DIRECTION_LEFT ) { + + selectedSideStep = selectedSideStepLeft; + + } else { + + selectedSideStep = selectedSideStepRight; + } + + if( INTERNAL_STATE !== SIDE_STEPPING ) { + + if( principleDirection === DIRECTION_LEFT ) { + + walkWheelPosition = sideStepCycleStartLeft;//selectedSideStep.calibration.sideStepCycleStartLeft; + + } else { + + walkWheelPosition = sideStepCycleStartRight;//selectedSideStep.calibration.sideStepCycleStartRight; + } + switch(currentAnimation) { + + case selectedStand: + + //currentTransition = new Transition(currentAnimation, selectedSideStep, [], 0.8, {x:0.5,y:0.08}, {x:0.28,y:1}); + break; + + default: + + //currentTransition = new Transition(currentAnimation, selectedSideStep, [], 0.8, {x:0.5,y:0.08}, {x:0.28,y:1}); + break; + } + setInternalState(SIDE_STEPPING); + } + + currentAnimation = selectedSideStep; + } + animateAvatar( deltaTime, speed, principleDirection ); + } + break; + + case FLYING: + + if( flyHints > requiredHints - 1 || INTERNAL_STATE===FLYING ) { // wait for a few consecutive hints (17mS each) + + standHints = 0; + walkHints = 0; + flyHints = 0; + + if(INTERNAL_STATE!==FLYING) setInternalState(FLYING); + + // change animation for flying directly up or down. TODO - check RecentMotions, if is a change then put a transition on it + if(principleDirection===DIRECTION_UP) { + + if(currentAnimation !== selectedFlyUp) { + + // initiate a Transition + if(currentTransition && currentTransition.nextAnimation!==selectedFlyUp) { + delete currentTransition; + currentTransition = null; + } + switch(currentAnimation) { + + case selectedStand: + + currentTransition = new Transition(currentAnimation, selectedFlyUp, [], 0.35, {x:0.5,y:0.08}, {x:0.28,y:1}); + break; + + case selectedSideStepLeft: + case selectedSideStepRight: + + break; + + default: + + currentTransition = new Transition(currentAnimation, selectedFlyUp, [], 0.35, {x:0.5,y:0.08}, {x:0.28,y:1}); + break; + } + currentAnimation = selectedFlyUp; + } + + } else if(principleDirection==DIRECTION_DOWN) { + + if(currentAnimation !== selectedFlyDown) { // TODO: as the locomotion gets cleaner (i.e. less false reports from Interface) this value can be reduced + + // initiate a Transition + if(currentTransition && currentTransition.nextAnimation!==selectedFlyDown) { + delete currentTransition; + currentTransition = null; + } + switch(currentAnimation) { + + case selectedStand: + + currentTransition = new Transition(currentAnimation, selectedFlyDown, [], 0.35, {x:0.5,y:0.08}, {x:0.28,y:1}); + break; + + case selectedSideStepLeft: + case selectedSideStepRight: + + break; + + default: + + currentTransition = new Transition(currentAnimation, selectedFlyDown, [], 0.35, {x:0.5,y:0.08}, {x:0.28,y:1}); + break; + } + currentAnimation = selectedFlyDown; + } + + } else { + + if(currentAnimation !== selectedFly) { // TODO: as the locomotion gets cleaner (i.e. less false reports from Interface) this value can be reduced + + // initiate a Transition + if(currentTransition && currentTransition.nextAnimation!==selectedFly) { + delete currentTransition; + currentTransition = null; + } + switch(currentAnimation) { + + case selectedStand: + + currentTransition = new Transition(currentAnimation, selectedFly, [], 0.35, {x:0.5,y:0.08}, {x:0.28,y:1}); + break; + + case selectedSideStepLeft: + case selectedSideStepRight: + + break; + + default: + + currentTransition = new Transition(currentAnimation, selectedFly, [], 0.35, {x:0.5,y:0.08}, {x:0.28,y:1}); + break; + } + currentAnimation = selectedFly; + } + } + animateAvatar(deltaTime, speed, principleDirection); + } + break; + + } // end switch(actionToTake) + + } // end if(!editing) + + + // record the frame's stats for later reference + var thisMotion = new RecentMotion(localVelocity, acceleration, principleDirection, INTERNAL_STATE); + framesHistory.recentMotions.push(thisMotion); + framesHistory.recentMotions.shift(); + + + // before we go, populate the stats overlay + if( statsOn ) { + + // quick test for the frame execution time measurement + // lots of console logging messes up execution times pretty well! + //for(var doh = 0 ; doh < 10 ; doh++) { + // //var fake = doh * doh * doh; + // print('faking bad coding...'+doh); + //} + + var cumulativeTimeMS = Math.floor(cumulativeTime*1000); + var deltaTimeMS = deltaTime * 1000; + var frameExecutionTime = new Date().getTime() - frameStartTime; + if(frameExecutionTime>frameExecutionTimeMax) frameExecutionTimeMax = frameExecutionTime; + + var angluarVelocity = Vec3.length(MyAvatar.getAngularVelocity()); + + var debugInfo = '\n \n \n \n Stats\n--------------------------------------\n \n \n' + + '\nFrame number: '+nFrames + + '\nFrame time: '+deltaTimeMS.toFixed(2) + + ' mS\nRender time: '+frameExecutionTime.toFixed(0) + + ' mS\nLocalised speed: '+speed.toFixed(3) + + ' m/s\nCumulative Time '+cumulativeTimeMS.toFixed(0) + + ' mS\nState: '+internalStateAsString(INTERNAL_STATE) + + ' \nDirection: '+directionAsString(principleDirection) + + ' \nAngular Velocity: ' + angluarVelocity.toFixed(3) + + ' rad/s'; + Overlays.editOverlay(debugStats, {text: debugInfo}); + + // update these every 250 mS (assuming 60 fps) + if( nFrames % 15 === 0 ) { + var debugInfo = ' Periodic Stats\n--------------------------------------\n \n \n' + + ' \n \nRender time peak hold: '+frameExecutionTimeMax.toFixed(0) + + ' mS\n \n \n(L) MyAvatar.getVelocity()' + + ' \n \nlocalVelocityX: '+deltaX.toFixed(1) + + ' m/s\nlocalVelocityY: '+deltaY.toFixed(1) + + ' m/s\nlocalVelocityZ: '+deltaZ.toFixed(1) + + ' m/s\n \n(G) MyAvatar.getAcceleration()' + + ' \n\nAcceleration X: '+accelerationJS.x.toFixed(1) + + ' m/s/s\nAcceleration Y: '+accelerationJS.y.toFixed(1) + + ' m/s/s\nAcceleration Z: '+accelerationJS.z.toFixed(1) + + ' m/s/s\n \n(L) Acceleration using\nMyAvatar.getVelocity()' + + ' \n \nAcceleration X: '+acceleration.x.toFixed(1) + + ' m/s/s\nAcceleration Y: '+acceleration.y.toFixed(1) + + ' m/s/s\nAcceleration Z: '+acceleration.z.toFixed(1) + + ' m/s/s'; + Overlays.editOverlay(debugStatsPeriodic, {text: debugInfo}); + frameExecutionTimeMax = 0; + } } - 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; - } } }); @@ -1088,373 +2663,498 @@ Script.update.connect(function(deltaTime) { // controller dimensions var backgroundWidth = 350; var backgroundHeight = 700; -var backgroundX = Window.innerWidth-backgroundWidth-50; +var backgroundX = Window.innerWidth-backgroundWidth-58; var backgroundY = Window.innerHeight/2 - backgroundHeight/2; var minSliderX = backgroundX + 30; var maxSliderX = backgroundX + 295; var sliderRangeX = 295 - 30; var jointsControlWidth = 200; var jointsControlHeight = 300; -var jointsControlX = backgroundX/2 - jointsControlWidth/2; -var jointsControlY = backgroundY/2 - jointsControlHeight/2; +var jointsControlX = backgroundX + backgroundWidth/2 - jointsControlWidth/2; +var jointsControlY = backgroundY + 242 - jointsControlHeight/2; var buttonsY = 20; // distance from top of panel to buttons // arrays of overlay names -var sliderthumbOverlays = []; // thumb sliders +var sliderThumbOverlays = []; // thumb sliders var backgroundOverlays = []; var buttonOverlays = []; var jointsControlOverlays = []; var bigButtonOverlays = []; -// take a deep breath then load up the overlays -// UI backgrounds +// take a deep breath and... + +// load UI backgrounds var controlsBackground = Overlays.addOverlay("image", { - bounds: { x: backgroundX, y: backgroundY, width: 1, height: 1}, + bounds: { x: backgroundX, y: backgroundY, width: backgroundWidth, height: backgroundHeight }, imageURL: pathToOverlays+"ddao-background.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); backgroundOverlays.push(controlsBackground); var controlsBackgroundWalkEditStyles = Overlays.addOverlay("image", { - bounds: { x: backgroundX, y: backgroundY, width: 1, height: 1}, + bounds: { x: backgroundX, y: backgroundY, width: backgroundWidth, height: backgroundHeight }, imageURL: pathToOverlays+"ddao-background-edit-styles.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); backgroundOverlays.push(controlsBackgroundWalkEditStyles); var controlsBackgroundWalkEditTweaks = Overlays.addOverlay("image", { - bounds: { x: backgroundX, y: backgroundY, width: 1, height: 1}, + bounds: { x: backgroundX, y: backgroundY, width: backgroundWidth, height: backgroundHeight }, imageURL: pathToOverlays+"ddao-background-edit-tweaks.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); backgroundOverlays.push(controlsBackgroundWalkEditTweaks); var controlsBackgroundWalkEditJoints = Overlays.addOverlay("image", { - bounds: { x: backgroundX, y: backgroundY, width: 1, height: 1}, + bounds: { x: backgroundX, y: backgroundY, width: backgroundWidth, height: backgroundHeight }, imageURL: pathToOverlays+"ddao-background-edit-joints.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); backgroundOverlays.push(controlsBackgroundWalkEditJoints); var controlsBackgroundFlyingEdit = Overlays.addOverlay("image", { - bounds: { x: backgroundX, y: backgroundY, width: 1, height: 1}, + bounds: { x: backgroundX, y: backgroundY, width: backgroundWidth, height: backgroundHeight }, imageURL: pathToOverlays+"ddao-background-flying-edit.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); 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 - }); + x: Window.innerWidth-58, y: Window.innerHeight -145, width: 50, height: 50, + //subImage: { x: 0, y: 50, width: 50, height: 50 }, + imageURL: pathToOverlays + 'ddao-minimise-tab.png', + visible: minimised, + alpha: 0.9 + }); + + // load character joint selection control images var hipsJointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1}, + bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, imageURL: pathToOverlays+"ddao-background-edit-hips.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); jointsControlOverlays.push(hipsJointControl); var upperLegsJointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1}, + bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, imageURL: pathToOverlays+"ddao-background-edit-upper-legs.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); jointsControlOverlays.push(upperLegsJointControl); var lowerLegsJointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1}, + bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, imageURL: pathToOverlays+"ddao-background-edit-lower-legs.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); jointsControlOverlays.push(lowerLegsJointControl); var feetJointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1}, + bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, imageURL: pathToOverlays+"ddao-background-edit-feet.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); jointsControlOverlays.push(feetJointControl); var toesJointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1}, + bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, imageURL: pathToOverlays+"ddao-background-edit-toes.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); jointsControlOverlays.push(toesJointControl); var spineJointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1}, + bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, imageURL: pathToOverlays+"ddao-background-edit-spine.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); jointsControlOverlays.push(spineJointControl); var spine1JointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1}, + bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, imageURL: pathToOverlays+"ddao-background-edit-spine1.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); jointsControlOverlays.push(spine1JointControl); var spine2JointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1}, + bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, imageURL: pathToOverlays+"ddao-background-edit-spine2.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); jointsControlOverlays.push(spine2JointControl); var shouldersJointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1}, + bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, imageURL: pathToOverlays+"ddao-background-edit-shoulders.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); jointsControlOverlays.push(shouldersJointControl); var upperArmsJointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1}, + bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, imageURL: pathToOverlays+"ddao-background-edit-upper-arms.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); jointsControlOverlays.push(upperArmsJointControl); var forearmsJointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1}, + bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, imageURL: pathToOverlays+"ddao-background-edit-forearms.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); jointsControlOverlays.push(forearmsJointControl); var handsJointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1}, + bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, imageURL: pathToOverlays+"ddao-background-edit-hands.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); jointsControlOverlays.push(handsJointControl); var headJointControl = Overlays.addOverlay("image", { - bounds: { x: jointsControlX, y: jointsControlY, width: 1, height: 1}, + bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, imageURL: pathToOverlays+"ddao-background-edit-head.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); jointsControlOverlays.push(headJointControl); // sider thumb overlays var sliderOne = Overlays.addOverlay("image", { - bounds: { x: 0, y: 0, width: 1, height: 1}, + bounds: { x: 0, y: 0, width: 25, height: 25 }, imageURL: pathToOverlays+"ddao-slider-handle.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); -sliderthumbOverlays.push(sliderOne); +sliderThumbOverlays.push(sliderOne); var sliderTwo = Overlays.addOverlay("image", { - bounds: { x: 0, y: 0, width: 1, height: 1}, + bounds: { x: 0, y: 0, width: 25, height: 25 }, imageURL: pathToOverlays+"ddao-slider-handle.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); -sliderthumbOverlays.push(sliderTwo); +sliderThumbOverlays.push(sliderTwo); var sliderThree = Overlays.addOverlay("image", { - bounds: { x: 0, y: 0, width: 1, height: 1}, + bounds: { x: 0, y: 0, width: 25, height: 25 }, imageURL: pathToOverlays+"ddao-slider-handle.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); -sliderthumbOverlays.push(sliderThree); +sliderThumbOverlays.push(sliderThree); var sliderFour = Overlays.addOverlay("image", { - bounds: { x: 0, y: 0, width: 1, height: 1}, + bounds: { x: 0, y: 0, width: 25, height: 25 }, imageURL: pathToOverlays+"ddao-slider-handle.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); -sliderthumbOverlays.push(sliderFour); +sliderThumbOverlays.push(sliderFour); var sliderFive = Overlays.addOverlay("image", { - bounds: { x: 0, y: 0, width: 1, height: 1}, + bounds: { x: 0, y: 0, width: 25, height: 25 }, imageURL: pathToOverlays+"ddao-slider-handle.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); -sliderthumbOverlays.push(sliderFive); +sliderThumbOverlays.push(sliderFive); var sliderSix = Overlays.addOverlay("image", { - bounds: { x: 0, y: 0, width: 1, height: 1}, + bounds: { x: 0, y: 0, width: 25, height: 25 }, imageURL: pathToOverlays+"ddao-slider-handle.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); -sliderthumbOverlays.push(sliderSix); +sliderThumbOverlays.push(sliderSix); var sliderSeven = Overlays.addOverlay("image", { - bounds: { x: 0, y: 0, width: 1, height: 1}, + bounds: { x: 0, y: 0, width: 25, height: 25 }, imageURL: pathToOverlays+"ddao-slider-handle.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); -sliderthumbOverlays.push(sliderSeven); +sliderThumbOverlays.push(sliderSeven); var sliderEight = Overlays.addOverlay("image", { - bounds: { x: 0, y: 0, width: 1, height: 1}, + bounds: { x: 0, y: 0, width: 25, height: 25 }, imageURL: pathToOverlays+"ddao-slider-handle.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); -sliderthumbOverlays.push(sliderEight); +sliderThumbOverlays.push(sliderEight); var sliderNine = Overlays.addOverlay("image", { - bounds: { x: 0, y: 0, width: 1, height: 1}, + bounds: { x: 0, y: 0, width: 25, height: 25 }, imageURL: pathToOverlays+"ddao-slider-handle.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); -sliderthumbOverlays.push(sliderNine); +sliderThumbOverlays.push(sliderNine); // button overlays var onButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+20, y: backgroundY+buttonsY, width: 1, height: 1}, + bounds: { x: backgroundX+20, y: backgroundY+buttonsY, width: 60, height: 47 }, imageURL: pathToOverlays+"ddao-on-button.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); buttonOverlays.push(onButton); var offButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+20, y: backgroundY+buttonsY, width: 1, height: 1}, + bounds: { x: backgroundX+20, y: backgroundY+buttonsY, width: 60, height: 47 }, imageURL: pathToOverlays+"ddao-off-button.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); buttonOverlays.push(offButton); var configWalkButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 1, height: 1}, + bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 60, height: 47 }, imageURL: pathToOverlays+"ddao-edit-walk-button.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); buttonOverlays.push(configWalkButton); var configWalkButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 1, height: 1}, + bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 60, height: 47 }, imageURL: pathToOverlays+"ddao-edit-walk-button-selected.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); buttonOverlays.push(configWalkButtonSelected); var configStandButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+146, y: backgroundY+buttonsY, width: 1, height: 1}, + bounds: { x: backgroundX+146, y: backgroundY+buttonsY, width: 60, height: 47 }, imageURL: pathToOverlays+"ddao-edit-stand-button.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); buttonOverlays.push(configStandButton); var configStandButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX+146, y: backgroundY+buttonsY, width: 1, height: 1}, + bounds: { x: backgroundX+146, y: backgroundY+buttonsY, width: 60, height: 47 }, imageURL: pathToOverlays+"ddao-edit-stand-button-selected.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); buttonOverlays.push(configStandButtonSelected); + var configFlyingButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+209, y: backgroundY+buttonsY, width: 1, height: 1}, + bounds: { x: backgroundX+209, y: backgroundY+buttonsY, width: 60, height: 47 }, imageURL: pathToOverlays+"ddao-edit-fly-button.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); buttonOverlays.push(configFlyingButton); var configFlyingButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX+209, y: backgroundY+buttonsY, width: 1, height: 1}, + bounds: { x: backgroundX+209, y: backgroundY+buttonsY, width: 60, height: 47 }, imageURL: pathToOverlays+"ddao-edit-fly-button-selected.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); buttonOverlays.push(configFlyingButtonSelected); + +var configFlyingUpButton = Overlays.addOverlay("image", { + bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 60, height: 47 }, + imageURL: pathToOverlays+"ddao-edit-fly-up-button.png", + color: { red: 255, green: 255, blue: 255}, + alpha: 1, + visible: false + }); +buttonOverlays.push(configFlyingUpButton); +var configFlyingUpButtonSelected = Overlays.addOverlay("image", { + bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 60, height: 47 }, + imageURL: pathToOverlays+"ddao-edit-fly-up-button-selected.png", + color: { red: 255, green: 255, blue: 255}, + alpha: 1, + visible: false + }); +buttonOverlays.push(configFlyingUpButtonSelected); + +var configFlyingDownButton = Overlays.addOverlay("image", { + bounds: { x: backgroundX+146, y: backgroundY+buttonsY, width: 60, height: 47 }, + imageURL: pathToOverlays+"ddao-edit-fly-down-button.png", + color: { red: 255, green: 255, blue: 255}, + alpha: 1, + visible: false + }); +buttonOverlays.push(configFlyingDownButton); +var configFlyingDownButtonSelected = Overlays.addOverlay("image", { + bounds: { x: backgroundX+146, y: backgroundY+buttonsY, width: 60, height: 47 }, + imageURL: pathToOverlays+"ddao-edit-fly-down-button-selected.png", + color: { red: 255, green: 255, blue: 255}, + alpha: 1, + visible: false + }); +buttonOverlays.push(configFlyingDownButtonSelected); + var hideButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+272, y: backgroundY+buttonsY, width: 1, height: 1}, + bounds: { x: backgroundX+272, y: backgroundY+buttonsY, width: 60, height: 47 }, imageURL: pathToOverlays+"ddao-hide-button.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); buttonOverlays.push(hideButton); var hideButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX+272, y: backgroundY+buttonsY, width: 1, height: 1}, + bounds: { x: backgroundX+272, y: backgroundY+buttonsY, width: 60, height: 47 }, imageURL: pathToOverlays+"ddao-hide-button-selected.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); buttonOverlays.push(hideButtonSelected); var configWalkStylesButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 1, height: 1}, + bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 60, height: 47 }, imageURL: pathToOverlays+"ddao-walk-styles-button.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); buttonOverlays.push(configWalkStylesButton); var configWalkStylesButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 1, height: 1}, + bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 60, height: 47 }, imageURL: pathToOverlays+"ddao-walk-styles-button-selected.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); buttonOverlays.push(configWalkStylesButtonSelected); var configWalkTweaksButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+146, y: backgroundY+buttonsY, width: 1, height: 1}, + bounds: { x: backgroundX+146, y: backgroundY+buttonsY, width: 60, height: 47 }, imageURL: pathToOverlays+"ddao-walk-tweaks-button.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); buttonOverlays.push(configWalkTweaksButton); var configWalkTweaksButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX+146, y: backgroundY+buttonsY, width: 1, height: 1}, + bounds: { x: backgroundX+146, y: backgroundY+buttonsY, width: 60, height: 47 }, imageURL: pathToOverlays+"ddao-walk-tweaks-button-selected.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); buttonOverlays.push(configWalkTweaksButtonSelected); + + + +var configSideStepLeftButton = Overlays.addOverlay("image", { + bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 60, height: 47 }, + imageURL: pathToOverlays+"ddao-edit-sidestep-left-button.png", + color: { red: 255, green: 255, blue: 255}, + alpha: 1, + visible: false + }); +buttonOverlays.push(configSideStepLeftButton); +var configSideStepLeftButtonSelected = Overlays.addOverlay("image", { + bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 60, height: 47 }, + imageURL: pathToOverlays+"ddao-edit-sidestep-left-button-selected.png", + color: { red: 255, green: 255, blue: 255}, + alpha: 1, + visible: false + }); +buttonOverlays.push(configSideStepLeftButtonSelected); + +var configSideStepRightButton = Overlays.addOverlay("image", { + bounds: { x: backgroundX+209, y: backgroundY+buttonsY, width: 60, height: 47 }, + imageURL: pathToOverlays+"ddao-edit-sidestep-right-button.png", + color: { red: 255, green: 255, blue: 255}, + alpha: 1, + visible: false + }); +buttonOverlays.push(configSideStepRightButton); +var configSideStepRightButtonSelected = Overlays.addOverlay("image", { + bounds: { x: backgroundX+209, y: backgroundY+buttonsY, width: 60, height: 47 }, + imageURL: pathToOverlays+"ddao-edit-sidestep-right-button-selected.png", + color: { red: 255, green: 255, blue: 255}, + alpha: 1, + visible: false + }); +buttonOverlays.push(configSideStepRightButtonSelected); + var configWalkJointsButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+209, y: backgroundY+buttonsY, width: 1, height: 1}, + bounds: { x: backgroundX+209, y: backgroundY+buttonsY, width: 60, height: 47 }, imageURL: pathToOverlays+"ddao-bones-button.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); buttonOverlays.push(configWalkJointsButton); var configWalkJointsButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX+209, y: backgroundY+buttonsY, width: 1, height: 1}, + bounds: { x: backgroundX+209, y: backgroundY+buttonsY, width: 60, height: 47 }, imageURL: pathToOverlays+"ddao-bones-button-selected.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); buttonOverlays.push(configWalkJointsButtonSelected); + var backButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX+272, y: backgroundY+buttonsY, width: 1, height: 1}, + bounds: { x: backgroundX+272, y: backgroundY+buttonsY, width: 60, height: 47 }, imageURL: pathToOverlays+"ddao-back-button.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); buttonOverlays.push(backButton); var backButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX+272, y: backgroundY+buttonsY, width: 1, height: 1}, + bounds: { x: backgroundX+272, y: backgroundY+buttonsY, width: 60, height: 47 }, imageURL: pathToOverlays+"ddao-back-button-selected.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); buttonOverlays.push(backButtonSelected); @@ -1462,10 +3162,11 @@ buttonOverlays.push(backButtonSelected); 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}, + bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36}, imageURL: pathToOverlays+"ddao-female-big-button.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); bigButtonOverlays.push(femaleBigButton); @@ -1473,7 +3174,8 @@ 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 + alpha: 1, + visible: false }); bigButtonOverlays.push(femaleBigButtonSelected); @@ -1481,39 +3183,44 @@ 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 + alpha: 1, + visible: false }); bigButtonOverlays.push(maleBigButton); var maleBigButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset + 60, width: 1, height: 1}, + bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset + 60, width: 230, height: 36}, imageURL: pathToOverlays+"ddao-male-big-button-selected.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); bigButtonOverlays.push(maleBigButtonSelected); var armsFreeBigButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset + 120, width: 1, height: 1}, + bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset + 120, width: 230, height: 36}, imageURL: pathToOverlays+"ddao-arms-free-button.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); bigButtonOverlays.push(armsFreeBigButton); var armsFreeBigButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset + 120, width: 1, height: 1}, + bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset + 120, width: 230, height: 36}, imageURL: pathToOverlays+"ddao-arms-free-button-selected.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); bigButtonOverlays.push(armsFreeBigButtonSelected); var footstepsBigButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset + 180, width: 1, height: 1}, + bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset + 180, width: 230, height: 36}, imageURL: pathToOverlays+"ddao-footsteps-big-button.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); bigButtonOverlays.push(footstepsBigButton); @@ -1521,7 +3228,8 @@ 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 + alpha: 1, + visible: false }); bigButtonOverlays.push(footstepsBigButtonSelected); @@ -1529,154 +3237,172 @@ 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}, + bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, imageURL: pathToOverlays+"ddao-walk-select-button-strut.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); bigButtonOverlays.push(strutWalkBigButton); var strutWalkBigButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1}, + bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, imageURL: pathToOverlays+"ddao-walk-select-button-strut-selected.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); bigButtonOverlays.push(strutWalkBigButtonSelected); bigButtonYOffset += 60 var sexyWalkBigButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1}, + bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, imageURL: pathToOverlays+"ddao-walk-select-button-sexy.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); bigButtonOverlays.push(sexyWalkBigButton); var sexyWalkBigButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1}, + bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, imageURL: pathToOverlays+"ddao-walk-select-button-sexy-selected.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); bigButtonOverlays.push(sexyWalkBigButtonSelected); bigButtonYOffset += 60; var powerWalkBigButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1}, + bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, imageURL: pathToOverlays+"ddao-walk-select-button-power-walk.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); bigButtonOverlays.push(powerWalkBigButton); var powerWalkBigButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1}, + bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, imageURL: pathToOverlays+"ddao-walk-select-button-power-walk-selected.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); bigButtonOverlays.push(powerWalkBigButtonSelected); bigButtonYOffset += 60; var shuffleBigButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1}, + bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, imageURL: pathToOverlays+"ddao-walk-select-button-shuffle.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); bigButtonOverlays.push(shuffleBigButton); var shuffleBigButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1}, + bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, imageURL: pathToOverlays+"ddao-walk-select-button-shuffle-selected.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); bigButtonOverlays.push(shuffleBigButtonSelected); bigButtonYOffset += 60; var runBigButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1}, + bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, imageURL: pathToOverlays+"ddao-walk-select-button-run.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); bigButtonOverlays.push(runBigButton); var runBigButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1}, + bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, imageURL: pathToOverlays+"ddao-walk-select-button-run-selected.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); 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", +var randomWalkBigButton = Overlays.addOverlay("image", { + bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, + imageURL: pathToOverlays+"ddao-walk-select-button-random.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); -bigButtonOverlays.push(sneakyWalkBigButton); +bigButtonOverlays.push(randomWalkBigButton); -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", +var randomWalkBigButtonSelected = Overlays.addOverlay("image", { + bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, + imageURL: pathToOverlays+"ddao-walk-select-button-random-selected.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); -bigButtonOverlays.push(sneakyWalkBigButtonSelected); +bigButtonOverlays.push(randomWalkBigButtonSelected); bigButtonYOffset += 60; var toughWalkBigButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1}, + bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, imageURL: pathToOverlays+"ddao-walk-select-button-tough.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); bigButtonOverlays.push(toughWalkBigButton); var toughWalkBigButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1}, + bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, imageURL: pathToOverlays+"ddao-walk-select-button-tough-selected.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); bigButtonOverlays.push(toughWalkBigButtonSelected); bigButtonYOffset += 60; var coolWalkBigButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1}, + bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, imageURL: pathToOverlays+"ddao-walk-select-button-cool.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); bigButtonOverlays.push(coolWalkBigButton); var coolWalkBigButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1}, + bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, imageURL: pathToOverlays+"ddao-walk-select-button-cool-selected.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); bigButtonOverlays.push(coolWalkBigButtonSelected); bigButtonYOffset += 60; var elderlyWalkBigButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1}, + bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, imageURL: pathToOverlays+"ddao-walk-select-button-elderly.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); bigButtonOverlays.push(elderlyWalkBigButton); var elderlyWalkBigButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 1, height: 1}, + bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, imageURL: pathToOverlays+"ddao-walk-select-button-elderly-selected.png", color: { red: 255, green: 255, blue: 255}, - alpha: 1 + alpha: 1, + visible: false }); bigButtonOverlays.push(elderlyWalkBigButtonSelected); @@ -1687,7 +3413,7 @@ var walkWheelZLine = Overlays.addOverlay("line3d", { color: { red: 0, green: 255, blue: 255}, alpha: 1, lineWidth: 5, - visible: false, + visible: statsOn, anchor: "MyAvatar" }); var walkWheelYLine = Overlays.addOverlay("line3d", { @@ -1696,22 +3422,44 @@ var walkWheelYLine = Overlays.addOverlay("line3d", { color: { red: 255, green: 0, blue: 255}, alpha: 1, lineWidth: 5, - visible: false, + visible: statsOn, anchor: "MyAvatar" }); - -var debugText = Overlays.addOverlay("text", { - x: Window.innerWidth/2 + 200, - y: Window.innerHeight/2 - 300, +var debugStats = Overlays.addOverlay("text", { + x: backgroundX-199, y: backgroundY, width: 200, - height: 130, - color: { red: 255, green: 255, blue: 255}, - textColor: { red: 255, green: 255, blue: 255}, + height: 180, + color: { red: 204, green: 204, blue: 204}, + topMargin: 10, + leftMargin: 15, + visible: statsOn, + backgroundColor: { red: 34, green: 34, blue: 34}, + alpha: 1.0, + text: "Debug Stats\n\n\nNothing to report yet." + }); +var debugStatsPeriodic = Overlays.addOverlay("text", { + x: backgroundX-199, y: backgroundY+179, + width: 200, + height: 392, + color: { red: 204, green: 204, blue: 204}, topMargin: 5, - leftMargin: 5, - visible: false, - backgroundColor: { red: 255, green: 255, blue: 255}, - text: "Debug area\nNothing to report yet." + leftMargin: 15, + visible: statsOn, + backgroundColor: { red: 34, green: 34, blue: 34}, + alpha: 1.0, + text: "Debug Stats\n\n\nNothing to report yet." + }); +var walkWheelStats = Overlays.addOverlay("text", { + x: backgroundX-199, y: backgroundY+510, + width: 200, + height: 190, + color: { red: 204, green: 204, blue: 204}, + topMargin: 5, + leftMargin: 15, + visible: statsOn, + backgroundColor: { red: 34, green: 34, blue: 34}, + alpha: 1.0, + text: "WalkWheel Stats\n\n\nNothing to report yet.\n\n\nPlease start walking\nto see the walkwheel." }); // various show / hide GUI element functions @@ -1725,43 +3473,36 @@ function doStandardMenu() { setButtonOverlayVisible(configStandButton); setButtonOverlayVisible(configFlyingButton); setButtonOverlayVisible(hideButton); - setSliderthumbsVisible(false); + 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 } ); + Overlays.editOverlay(femaleBigButtonSelected, { visible: showButtons } ); + Overlays.editOverlay(femaleBigButton, { visible: false } ); + Overlays.editOverlay(maleBigButtonSelected, { visible: false } ); + Overlays.editOverlay(maleBigButton, { visible: showButtons } ); } 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 } ); + Overlays.editOverlay(femaleBigButtonSelected, { visible: false } ); + Overlays.editOverlay(femaleBigButton, { visible: showButtons } ); + Overlays.editOverlay(maleBigButtonSelected, { visible: showButtons } ); + Overlays.editOverlay(maleBigButton, { visible: false } ); } if(armsFree) { - Overlays.editOverlay(armsFreeBigButtonSelected, { width: bigButtonWidth, height: bigButtonHeight } ); - Overlays.editOverlay(armsFreeBigButton, { width: 1, height: 1 } ); + Overlays.editOverlay(armsFreeBigButtonSelected, { visible: showButtons } ); + Overlays.editOverlay(armsFreeBigButton, { visible: false } ); } else { - Overlays.editOverlay(armsFreeBigButtonSelected, { width: 1, height: 1 } ); - Overlays.editOverlay(armsFreeBigButton, { width: bigButtonWidth, height: bigButtonHeight } ); + Overlays.editOverlay(armsFreeBigButtonSelected, { visible: false } ); + Overlays.editOverlay(armsFreeBigButton, { visible: showButtons } ); } if(playFootStepSounds) { - Overlays.editOverlay(footstepsBigButtonSelected, { width: bigButtonWidth, height: bigButtonHeight } ); - Overlays.editOverlay(footstepsBigButton, { width: 1, height: 1 } ); + Overlays.editOverlay(footstepsBigButtonSelected, { visible: showButtons } ); + Overlays.editOverlay(footstepsBigButton, { visible: false } ); } else { - Overlays.editOverlay(footstepsBigButtonSelected, { width: 1, height: 1 } ); - Overlays.editOverlay(footstepsBigButton, { width: bigButtonWidth, height: bigButtonHeight } ); + Overlays.editOverlay(footstepsBigButtonSelected, { visible: false } ); + Overlays.editOverlay(footstepsBigButton, { visible: showButtons } ); } } function minimiseDialog() { @@ -1769,48 +3510,46 @@ function minimiseDialog() { if(minimised) { setBackground(); hidebuttonOverlays(); - setSliderthumbsVisible(false); + setSliderThumbsVisible(false); hideJointControls(); showFrontPanelButtons(false); - Overlays.editOverlay(controlsMinimisedTab, { width: 36, height: 351 } ); + Overlays.editOverlay(controlsMinimisedTab, { visible: true } ); } else { setInternalState(STANDING); // show all the controls again - Overlays.editOverlay(controlsMinimisedTab, { width: 1, height: 1 } ); + Overlays.editOverlay(controlsMinimisedTab, { visible: false } ); } } 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} ); + Overlays.editOverlay(backgroundName, { visible: true } ); + else Overlays.editOverlay(backgroundOverlays[i], { visible: false } ); } } function setButtonOverlayVisible(buttonOverlayName) { for(var i in buttonOverlays) { if(buttonOverlays[i] === buttonOverlayName) { - Overlays.editOverlay(buttonOverlayName, { width: 60, height: 47 } ); + Overlays.editOverlay(buttonOverlayName, { visible: true } ); } } } // top row menu type buttons (smaller) function hidebuttonOverlays() { for(var i in buttonOverlays) { - Overlays.editOverlay(buttonOverlays[i], { width: 1, height: 1 } ); + Overlays.editOverlay(buttonOverlays[i], { visible: false } ); } } function hideJointControls() { for(var i in jointsControlOverlays) { - Overlays.editOverlay(jointsControlOverlays[i], { width: 1, height: 1 } ); + Overlays.editOverlay(jointsControlOverlays[i], { visible: false } ); } } -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 setSliderThumbsVisible(thumbsVisible) { + for(var i = 0 ; i < sliderThumbOverlays.length ; i++) { + Overlays.editOverlay(sliderThumbOverlays[i], { visible: thumbsVisible } ); } } -function initialiseWalkJointsPanel(propertyIndex) { +function initialiseJointsEditingPanel(propertyIndex) { selectedJointIndex = propertyIndex; @@ -1818,43 +3557,43 @@ function initialiseWalkJointsPanel(propertyIndex) { hideJointControls(); switch (selectedJointIndex) { case 0: - Overlays.editOverlay(hipsJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} ); + Overlays.editOverlay(hipsJointControl, { visible: true }); break; case 1: - Overlays.editOverlay(upperLegsJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} ); + Overlays.editOverlay(upperLegsJointControl, { visible: true }); break; case 2: - Overlays.editOverlay(lowerLegsJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} ); + Overlays.editOverlay(lowerLegsJointControl, { visible: true }); break; case 3: - Overlays.editOverlay(feetJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} ); + Overlays.editOverlay(feetJointControl, { visible: true }); break; case 4: - Overlays.editOverlay(toesJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} ); + Overlays.editOverlay(toesJointControl, { visible: true }); break; case 5: - Overlays.editOverlay(spineJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} ); + Overlays.editOverlay(spineJointControl, { visible: true }); break; case 6: - Overlays.editOverlay(spine1JointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} ); + Overlays.editOverlay(spine1JointControl, { visible: true }); break; case 7: - Overlays.editOverlay(spine2JointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} ); + Overlays.editOverlay(spine2JointControl, { visible: true }); break; case 8: - Overlays.editOverlay(shouldersJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} ); + Overlays.editOverlay(shouldersJointControl, { visible: true }); break; case 9: - Overlays.editOverlay(upperArmsJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} ); + Overlays.editOverlay(upperArmsJointControl, { visible: true }); break; case 10: - Overlays.editOverlay(forearmsJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} ); + Overlays.editOverlay(forearmsJointControl, { visible: true }); break; case 11: - Overlays.editOverlay(handsJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} ); + Overlays.editOverlay(handsJointControl, { visible: true }); break; case 12: - Overlays.editOverlay(headJointControl, { bounds: { x: backgroundX+75, y: backgroundY+92, width: 200, height: 300}} ); + Overlays.editOverlay(headJointControl, { visible: true }); break; } @@ -1863,28 +3602,34 @@ function initialiseWalkJointsPanel(propertyIndex) { 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}} ); + var sliderXPos = currentAnimation.joints[selectedJointIndex].pitch + / sliderRanges.joints[selectedJointIndex].pitchRange * sliderRangeX; + Overlays.editOverlay(sliderThumbOverlays[i], { x: minSliderX + sliderXPos, y: yLocation+=30, visible: true }); + sliderXPos = currentAnimation.joints[selectedJointIndex].yaw + / sliderRanges.joints[selectedJointIndex].yawRange * sliderRangeX; + Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=30, visible: true }); + sliderXPos = currentAnimation.joints[selectedJointIndex].roll + / sliderRanges.joints[selectedJointIndex].rollRange * sliderRangeX; + Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=30, visible: true }); // set phases (full range, -180 to 180) sliderXPos = (90 + currentAnimation.joints[selectedJointIndex].pitchPhase/2)/180 * sliderRangeX; - Overlays.editOverlay(sliderthumbOverlays[++i], { bounds: { x: minSliderX + sliderXPos, y: yLocation+=30, width: 25, height: 25}} ); + Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=30, visible: true }); sliderXPos = (90 + currentAnimation.joints[selectedJointIndex].yawPhase/2)/180 * sliderRangeX; - Overlays.editOverlay(sliderthumbOverlays[++i], { bounds: { x: minSliderX + sliderXPos, y: yLocation+=30, width: 25, height: 25}} ); + Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=30, visible: true }); sliderXPos = (90 + currentAnimation.joints[selectedJointIndex].rollPhase/2)/180 * sliderRangeX; - Overlays.editOverlay(sliderthumbOverlays[++i], { bounds: { x: minSliderX + sliderXPos, y: yLocation+=30, width: 25, height: 25}} ); + Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=30, visible: true }); // offset ranges are also -ve thr' zero to +ve, so have to offset - sliderXPos = (((sliderRanges.joints[selectedJointIndex].pitchOffsetRange+currentAnimation.joints[selectedJointIndex].pitchOffset)/2)/sliderRanges.joints[selectedJointIndex].pitchOffsetRange) * sliderRangeX; - Overlays.editOverlay(sliderthumbOverlays[++i], { 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}} ); + sliderXPos = (((sliderRanges.joints[selectedJointIndex].pitchOffsetRange+currentAnimation.joints[selectedJointIndex].pitchOffset)/2) + /sliderRanges.joints[selectedJointIndex].pitchOffsetRange) * sliderRangeX; + Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=30, visible: true }); + sliderXPos = (((sliderRanges.joints[selectedJointIndex].yawOffsetRange+currentAnimation.joints[selectedJointIndex].yawOffset)/2) + /sliderRanges.joints[selectedJointIndex].yawOffsetRange) * sliderRangeX; + Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=30, visible: true }); + sliderXPos = (((sliderRanges.joints[selectedJointIndex].rollOffsetRange+currentAnimation.joints[selectedJointIndex].rollOffset)/2) + /sliderRanges.joints[selectedJointIndex].rollOffsetRange) * sliderRangeX; + Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=30, visible: true }); } function initialiseWalkTweaks() { @@ -1894,83 +3639,77 @@ function initialiseWalkTweaks() { 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}} ); + Overlays.editOverlay(sliderThumbOverlays[i], { x: minSliderX + sliderXPos, y: yLocation+=60, visible: true }); + sliderXPos = 0 * sliderRangeX; // start flying speed - depricated + Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=60, visible: true }); sliderXPos = currentAnimation.joints[0].sway / sliderRanges.joints[0].swayRange * sliderRangeX; // Hips sway - Overlays.editOverlay(sliderthumbOverlays[++i], { bounds: { x: minSliderX + sliderXPos, y: yLocation+=60, width: 25, height: 25}} ); + Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=60, visible: true }); sliderXPos = currentAnimation.joints[0].bob / sliderRanges.joints[0].bobRange * sliderRangeX; // Hips bob - Overlays.editOverlay(sliderthumbOverlays[++i], { bounds: { x: minSliderX + sliderXPos, y: yLocation+=60, width: 25, height: 25}} ); + Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=60, visible: true }); sliderXPos = currentAnimation.joints[0].thrust / sliderRanges.joints[0].thrustRange * sliderRangeX; // Hips thrust - Overlays.editOverlay(sliderthumbOverlays[++i], { 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}} ); + Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=60, visible: true }); + sliderXPos = (((sliderRanges.joints[1].rollOffsetRange+currentAnimation.joints[1].rollOffset)/2) // legs separation - is upper legs roll offset + / sliderRanges.joints[1].rollOffsetRange) * sliderRangeX; + Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=60, visible: true }); + sliderXPos = currentAnimation.joints[1].pitch / sliderRanges.joints[1].pitchRange * sliderRangeX; // stride - is upper legs pitch + Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=60, visible: true }); + sliderXPos = currentAnimation.joints[9].yaw / sliderRanges.joints[9].yawRange * sliderRangeX; // arms swing - is upper arms yaw + Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=60, visible: true }); + sliderXPos = (((sliderRanges.joints[9].pitchOffsetRange-currentAnimation.joints[9].pitchOffset)/2) + / sliderRanges.joints[9].pitchOffsetRange) * sliderRangeX; // arms out - is upper arms pitch offset + Overlays.editOverlay(sliderThumbOverlays[++i], { x: minSliderX + sliderXPos, y: yLocation+=60, visible: true }); } function showWalkStyleButtons(showButtons) { - 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}); + Overlays.editOverlay(bigButtonOverlays[i], { visible: false }); } if(!showButtons) return; // set all the non-selected ones to showing for(var i = 8 ; i < bigButtonOverlays.length ; i+=2) { - Overlays.editOverlay(bigButtonOverlays[i], {width: bigButtonWidth, height: bigButtonHeight}); + Overlays.editOverlay(bigButtonOverlays[i], { visible: showButtons }); } // set the currently selected one if(selectedWalk === femaleSexyWalk || selectedWalk === maleSexyWalk) { - Overlays.editOverlay(sexyWalkBigButtonSelected, {width: bigButtonWidth, height: bigButtonHeight}); - Overlays.editOverlay(sexyWalkBigButton, {width: 1, height: 1}); + Overlays.editOverlay(sexyWalkBigButtonSelected, { visible: showButtons }); + Overlays.editOverlay(sexyWalkBigButton, {visible: false}); } else if(selectedWalk === femaleStrutWalk || selectedWalk === maleStrutWalk) { - Overlays.editOverlay(strutWalkBigButtonSelected, {width: bigButtonWidth, height: bigButtonHeight}); - Overlays.editOverlay(strutWalkBigButton, {width: 1, height: 1}); + Overlays.editOverlay(strutWalkBigButtonSelected, { visible: showButtons }); + Overlays.editOverlay(strutWalkBigButton, {visible: false}); } else if(selectedWalk === femalePowerWalk || selectedWalk === malePowerWalk) { - Overlays.editOverlay(powerWalkBigButtonSelected, {width: bigButtonWidth, height: bigButtonHeight}); - Overlays.editOverlay(powerWalkBigButton, {width: 1, height: 1}); + Overlays.editOverlay(powerWalkBigButtonSelected, { visible: showButtons }); + Overlays.editOverlay(powerWalkBigButton, {visible: false}); } else if(selectedWalk === femaleShuffle || selectedWalk === maleShuffle) { - Overlays.editOverlay(shuffleBigButtonSelected, {width: bigButtonWidth, height: bigButtonHeight}); - Overlays.editOverlay(shuffleBigButton, {width: 1, height: 1}); + Overlays.editOverlay(shuffleBigButtonSelected, { visible: showButtons }); + Overlays.editOverlay(shuffleBigButton, {visible: false}); } else if(selectedWalk === femaleRun || selectedWalk === maleRun) { - Overlays.editOverlay(runBigButtonSelected, {width: bigButtonWidth, height: bigButtonHeight}); - Overlays.editOverlay(runBigButton, {width: 1, height: 1}); + Overlays.editOverlay(runBigButtonSelected, { visible: showButtons }); + Overlays.editOverlay(runBigButton, {visible: false}); } else if(selectedWalk === femaleRandomWalk || selectedWalk === maleRandomWalk) { - Overlays.editOverlay(sneakyWalkBigButtonSelected, {width: bigButtonWidth, height: bigButtonHeight}); - Overlays.editOverlay(sneakyWalkBigButton, {width: 1, height: 1}); + Overlays.editOverlay(randomWalkBigButtonSelected, { visible: showButtons }); + Overlays.editOverlay(randomWalkBigButton, {visible: false}); } else if(selectedWalk === femaleToughWalk || selectedWalk === maleToughWalk) { - Overlays.editOverlay(toughWalkBigButtonSelected, {width: bigButtonWidth, height: bigButtonHeight}); - Overlays.editOverlay(toughWalkBigButton, {width: 1, height: 1}); + Overlays.editOverlay(toughWalkBigButtonSelected, { visible: showButtons }); + Overlays.editOverlay(toughWalkBigButton, {visible: false}); } else if(selectedWalk === femaleCoolWalk || selectedWalk === maleCoolWalk) { - Overlays.editOverlay(coolWalkBigButtonSelected, {width: bigButtonWidth, height: bigButtonHeight}); - Overlays.editOverlay(coolWalkBigButton, {width: 1, height: 1}); + Overlays.editOverlay(coolWalkBigButtonSelected, { visible: showButtons }); + Overlays.editOverlay(coolWalkBigButton, {visible: false}); } else if(selectedWalk === femaleElderlyWalk || selectedWalk === maleElderlyWalk) { - Overlays.editOverlay(elderlyWalkBigButtonSelected, {width: bigButtonWidth, height: bigButtonHeight}); - Overlays.editOverlay(elderlyWalkBigButton, {width: 1, height: 1}); + Overlays.editOverlay(elderlyWalkBigButtonSelected, { visible: showButtons }); + Overlays.editOverlay(elderlyWalkBigButton, {visible: false}); } } @@ -1993,13 +3732,13 @@ function mousePressEvent(event) { switch (clickedOverlay) { case hideButton: - Overlays.editOverlay(hideButton, { width: 1, height: 1 } ); - Overlays.editOverlay(hideButtonSelected, { width: 60, height: 47 } ); + Overlays.editOverlay(hideButton, { visible: false } ); + Overlays.editOverlay(hideButtonSelected, { visible: true } ); return; case backButton: - Overlays.editOverlay(backButton, { width: 1, height: 1 } ); - Overlays.editOverlay(backButtonSelected, { width: 60, height: 47 } ); + Overlays.editOverlay(backButton, { visible: false } ); + Overlays.editOverlay(backButtonSelected, { visible: true } ); return; case controlsMinimisedTab: @@ -2008,14 +3747,14 @@ function mousePressEvent(event) { case footstepsBigButton: playFootStepSounds = true; - Overlays.editOverlay(footstepsBigButtonSelected, { width: 230, height: 36 } ); - Overlays.editOverlay(footstepsBigButton, { width: 1, height: 1 } ); + Overlays.editOverlay(footstepsBigButtonSelected, { visible: true } ); + Overlays.editOverlay(footstepsBigButton, { visible: false } ); return; case footstepsBigButtonSelected: playFootStepSounds = false; - Overlays.editOverlay(footstepsBigButton, { width: 230, height: 36 } ); - Overlays.editOverlay(footstepsBigButtonSelected, { width: 1, height: 1 } ); + Overlays.editOverlay(footstepsBigButton, { visible: true } ); + Overlays.editOverlay(footstepsBigButtonSelected, { visible: false } ); return; case femaleBigButton: @@ -2026,22 +3765,24 @@ function mousePressEvent(event) { 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 } ); + selectedSideStepLeft = femaleSideStepLeft; + selectedSideStepRight = femaleSideStepRight; + Overlays.editOverlay(femaleBigButtonSelected, { visible: true } ); + Overlays.editOverlay(femaleBigButton, { visible: false } ); + Overlays.editOverlay(maleBigButton, { visible: true } ); + Overlays.editOverlay(maleBigButtonSelected, { visible: false } ); return; case armsFreeBigButton: armsFree = true; - Overlays.editOverlay(armsFreeBigButtonSelected, { width: 230, height: 36 } ); - Overlays.editOverlay(armsFreeBigButton, { width: 1, height: 1 } ); + Overlays.editOverlay(armsFreeBigButtonSelected, { visible: true } ); + Overlays.editOverlay(armsFreeBigButton, { visible: false } ); return; case armsFreeBigButtonSelected: armsFree = false; - Overlays.editOverlay(armsFreeBigButtonSelected, { width: 1, height: 1 } ); - Overlays.editOverlay(armsFreeBigButton, { width: 230, height: 36 } ); + Overlays.editOverlay(armsFreeBigButtonSelected, { visible: false } ); + Overlays.editOverlay(armsFreeBigButton, { visible: true } ); return; case maleBigButton: @@ -2052,10 +3793,62 @@ function mousePressEvent(event) { 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 } ); + selectedSideStepLeft = maleSideStepLeft; + selectedSideStepRight = maleSideStepRight; + Overlays.editOverlay(femaleBigButton, { visible: true } ); + Overlays.editOverlay(femaleBigButtonSelected, { visible: false } ); + Overlays.editOverlay(maleBigButtonSelected, { visible: true } ); + Overlays.editOverlay(maleBigButton, { visible: false } ); + return; + + + case strutWalkBigButton: + if(avatarGender===FEMALE) selectedWalk = femaleStrutWalk; + else selectedWalk = maleStrutWalk; + currentAnimation = selectedWalk; + showWalkStyleButtons(true); + return; + +/* case sexyWalkBigButton: + if(avatarGender===FEMALE) selectedWalk = femaleSexyWalk; + else selectedWalk = maleSexyWalk; + currentAnimation = selectedWalk; + showWalkStyleButtons(true); + return; + + case powerWalkBigButton: + if(avatarGender===FEMALE) selectedWalk = femalePowerWalk; + else selectedWalk = malePowerWalk; + currentAnimation = selectedWalk; + showWalkStyleButtons(true); + return; + + case shuffleBigButton: + if(avatarGender===FEMALE) selectedWalk = femaleShuffle; + else selectedWalk = maleShuffle; + currentAnimation = selectedWalk; + showWalkStyleButtons(true); + return; + + case runBigButton: + if(avatarGender===FEMALE) selectedWalk = femaleRun; + else selectedWalk = maleRun; + currentAnimation = selectedWalk; + showWalkStyleButtons(true); + return; + + case randomWalkBigButton: + if(avatarGender===FEMALE) selectedWalk = femaleRandomWalk; + else selectedWalk = maleRandomWalk; + currentAnimation = selectedWalk; + showWalkStyleButtons(true); + return; + + case toughWalkBigButton: + if(avatarGender===FEMALE) selectedWalk = femaleToughWalk; + else selectedWalk = maleToughWalk; + currentAnimation = selectedWalk; + showWalkStyleButtons(true); return; case coolWalkBigButton: @@ -2063,90 +3856,30 @@ function mousePressEvent(event) { 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; + return; case elderlyWalkBigButton: if(avatarGender===FEMALE) selectedWalk = femaleElderlyWalk; else selectedWalk = maleElderlyWalk; currentAnimation = selectedWalk; showWalkStyleButtons(true); - maxFootForward = 0; - maxFootBackwards = 0; - break; + return; - case powerWalkBigButton: - if(avatarGender===FEMALE) selectedWalk = femalePowerWalk; - else selectedWalk = malePowerWalk; - currentAnimation = selectedWalk; - showWalkStyleButtons(true); - maxFootForward = 0; - maxFootBackwards = 0; - break; + case sexyWalkBigButtonSelected: + case elderlyWalkBigButtonSelected: + case powerWalkBigButtonSelected: + case shuffleBigButtonSelected: + case runBigButtonSelected: + case randomWalkBigButtonSelected: + case toughWalkBigButtonSelected: + case coolWalkBigButtonSelected:*/ + case strutWalkBigButtonSelected: - 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; + // toggle forwards / backwards walk display + if(principleDirection===DIRECTION_FORWARDS) { + principleDirection=DIRECTION_BACKWARDS; + } else principleDirection=DIRECTION_FORWARDS; + return; case sliderOne: movingSliderOne = true; @@ -2185,78 +3918,87 @@ function mousePressEvent(event) { return; } - if(INTERNAL_STATE===CONFIG_WALK_JOINTS || - INTERNAL_STATE===CONFIG_STANDING || - INTERNAL_STATE===CONFIG_FLYING) { + if( INTERNAL_STATE===CONFIG_WALK_JOINTS || + INTERNAL_STATE===CONFIG_STANDING || + INTERNAL_STATE===CONFIG_FLYING || + INTERNAL_STATE===CONFIG_FLYING_UP || + INTERNAL_STATE===CONFIG_FLYING_DOWN || + INTERNAL_STATE===CONFIG_SIDESTEP_LEFT || + INTERNAL_STATE===CONFIG_SIDESTEP_RIGHT ) { - // check for new joint selection and update display accordingly + // 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); + initialiseJointsEditingPanel(0); return; } else if(clickX>63&&clickX<132&&clickY>156&&clickY<202) { - initialiseWalkJointsPanel(1); + initialiseJointsEditingPanel(1); return; } else if(clickX>58&&clickX<137&&clickY>203&&clickY<250) { - initialiseWalkJointsPanel(2); + initialiseJointsEditingPanel(2); return; } else if(clickX>58&&clickX<137&&clickY>250&&clickY<265) { - initialiseWalkJointsPanel(3); + initialiseJointsEditingPanel(3); return; } else if(clickX>58&&clickX<137&&clickY>265&&clickY<280) { - initialiseWalkJointsPanel(4); + initialiseJointsEditingPanel(4); return; } else if(clickX>78&&clickX<121&&clickY>111&&clickY<128) { - initialiseWalkJointsPanel(5); + initialiseJointsEditingPanel(5); return; } else if(clickX>78&&clickX<128&&clickY>89&&clickY<111) { - initialiseWalkJointsPanel(6); + initialiseJointsEditingPanel(6); return; } else if(clickX>85&&clickX<118&&clickY>77&&clickY<94) { - initialiseWalkJointsPanel(7); + initialiseJointsEditingPanel(7); return; } else if(clickX>64&&clickX<125&&clickY>55&&clickY<77) { - initialiseWalkJointsPanel(8); + initialiseJointsEditingPanel(8); return; } else if((clickX>44&&clickX<73&&clickY>71&&clickY<94) ||(clickX>125&&clickX<144&&clickY>71&&clickY<94)) { - initialiseWalkJointsPanel(9); + initialiseJointsEditingPanel(9); return; } else if((clickX>28&&clickX<57&&clickY>94&&clickY<119) ||(clickX>137&&clickX<170&&clickY>97&&clickY<114)) { - initialiseWalkJointsPanel(10); + initialiseJointsEditingPanel(10); return; } else if((clickX>18&&clickX<37&&clickY>115&&clickY<136) ||(clickX>157&&clickX<182&&clickY>115&&clickY<136)) { - initialiseWalkJointsPanel(11); + initialiseJointsEditingPanel(11); return; } else if(clickX>81&&clickX<116&&clickY>12&&clickY<53) { - initialiseWalkJointsPanel(12); + initialiseJointsEditingPanel(12); return; } } } function mouseMoveEvent(event) { + // only need deal with slider changes if(powerOn) { - if(INTERNAL_STATE===CONFIG_WALK_JOINTS || - INTERNAL_STATE===CONFIG_STANDING || - INTERNAL_STATE===CONFIG_FLYING) { + if( INTERNAL_STATE===CONFIG_WALK_JOINTS || + INTERNAL_STATE===CONFIG_STANDING || + INTERNAL_STATE===CONFIG_FLYING || + INTERNAL_STATE===CONFIG_FLYING_UP || + INTERNAL_STATE===CONFIG_FLYING_DOWN || + INTERNAL_STATE===CONFIG_SIDESTEP_LEFT || + INTERNAL_STATE===CONFIG_SIDESTEP_RIGHT ) { var thumbClickOffsetX = event.x - minSliderX; var thumbPositionNormalised = thumbClickOffsetX / sliderRangeX; @@ -2322,7 +4064,7 @@ function mouseMoveEvent(event) { } else if(movingSliderTwo) { // take flight speed Overlays.editOverlay(sliderTwo, { x: sliderX + minSliderX} ); - currentAnimation.settings.takeFlightVelocity = thumbPositionNormalised * 300; + //currentAnimation.settings.takeFlightVelocity = thumbPositionNormalised * 300; } else if(movingSliderThree) { // hips sway Overlays.editOverlay(sliderThree, { x: sliderX + minSliderX} ); @@ -2338,11 +4080,11 @@ function mouseMoveEvent(event) { } else if(movingSliderSix) { // legs separation Overlays.editOverlay(sliderSix, { x: sliderX + minSliderX} ); - currentAnimation.adjusters.legsSeparation.strength = (thumbPositionNormalised-0.5)/2; + currentAnimation.joints[1].rollOffset = (thumbPositionNormalised-0.5) * 2 * sliderRanges.joints[1].rollOffsetRange; } else if(movingSliderSeven) { // stride Overlays.editOverlay(sliderSeven, { x: sliderX + minSliderX} ); - currentAnimation.adjusters.stride.strength = thumbPositionNormalised; + currentAnimation.joints[1].pitch = thumbPositionNormalised * sliderRanges.joints[1].pitchRange; } else if(movingSliderEight) { // arms swing = upper arms yaw Overlays.editOverlay(sliderEight, { x: sliderX + minSliderX} ); @@ -2363,13 +4105,13 @@ function mouseReleaseEvent(event) { if(clickedOverlay === offButton) { powerOn = true; - Overlays.editOverlay(offButton, {width: 0, height: 0} ); - Overlays.editOverlay(onButton, {width: 60, height: 47 } ); + Overlays.editOverlay(offButton, { visible: false } ); + Overlays.editOverlay(onButton, { visible: true } ); stand(); } else if(clickedOverlay === hideButton || clickedOverlay === hideButtonSelected){ - Overlays.editOverlay(hideButton, { width: 60, height: 47 } ); - Overlays.editOverlay(hideButtonSelected, { width: 1, height: 1 } ); + Overlays.editOverlay(hideButton, { visible: true } ); + Overlays.editOverlay(hideButtonSelected, { visible: false } ); minimised = true; minimiseDialog(); } @@ -2389,11 +4131,16 @@ function mouseReleaseEvent(event) { else if(movingSliderEight) movingSliderEight = false; else if(movingSliderNine) movingSliderNine = false; else { + switch(clickedOverlay) { case configWalkButtonSelected: case configStandButtonSelected: + case configSideStepLeftButtonSelected: + case configSideStepRightButtonSelected: case configFlyingButtonSelected: + case configFlyingUpButtonSelected: + case configFlyingDownButtonSelected: case configWalkStylesButtonSelected: case configWalkTweaksButtonSelected: case configWalkJointsButtonSelected: @@ -2403,15 +4150,15 @@ function mouseReleaseEvent(event) { case onButton: powerOn = false; setInternalState(STANDING); - Overlays.editOverlay(offButton, {width: 60, height: 47 } ); - Overlays.editOverlay(onButton, {width: 0, height: 0} ); + Overlays.editOverlay(offButton, { visible: true } ); + Overlays.editOverlay(onButton, { visible: false } ); resetJoints(); break; case backButton: case backButtonSelected: - Overlays.editOverlay(backButton, { width: 1, height: 1 } ); - Overlays.editOverlay(backButtonSelected, { width: 1, height: 1 } ); + Overlays.editOverlay(backButton, { visible: false } ); + Overlays.editOverlay(backButtonSelected, { visible: false } ); setInternalState(STANDING); break; @@ -2428,16 +4175,32 @@ function mouseReleaseEvent(event) { break; case configWalkButton: - setInternalState(CONFIG_WALK_STYLES); // set the default walk adjustment panel here + setInternalState(CONFIG_WALK_STYLES); // set the default walk adjustment panel here (i.e. first panel shown when Walk button clicked) break; case configStandButton: setInternalState(CONFIG_STANDING); break; + case configSideStepLeftButton: + setInternalState(CONFIG_SIDESTEP_LEFT); + break; + + case configSideStepRightButton: + setInternalState(CONFIG_SIDESTEP_RIGHT); + break; + case configFlyingButton: setInternalState(CONFIG_FLYING); break; + + case configFlyingUpButton: + setInternalState(CONFIG_FLYING_UP); + break; + + case configFlyingDownButton: + setInternalState(CONFIG_FLYING_DOWN); + break; } } } @@ -2458,8 +4221,8 @@ Script.scriptEnding.connect(function() { Overlays.deleteOverlay(buttonOverlays[i]); } // remove the slider thumb overlays - for(var i in sliderthumbOverlays) { - Overlays.deleteOverlay(sliderthumbOverlays[i]); + for(var i in sliderThumbOverlays) { + Overlays.deleteOverlay(sliderThumbOverlays[i]); } // remove the character joint control overlays for(var i in bigButtonOverlays) { @@ -2475,15 +4238,17 @@ Script.scriptEnding.connect(function() { // remove the walk wheel overlays Overlays.deleteOverlay(walkWheelYLine); Overlays.deleteOverlay(walkWheelZLine); - Overlays.deleteOverlay(debugText); + Overlays.deleteOverlay(walkWheelStats); + + // remove the debug stats overlays + Overlays.deleteOverlay(debugStats); + Overlays.deleteOverlay(debugStatsPeriodic); }); - +var sideStep = 0.002; // i.e. 2mm increments whilst sidestepping - JS movement keys don't work well :-( function keyPressEvent(event) { - //print('keyPressEvent: '+event.text); - - if (event.text == "q") { + 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'); @@ -2491,19 +4256,51 @@ function keyPressEvent(event) { print('\n'); print(JSON.stringify(currentAnimation), null, '\t'); } - if (event.text == "t") { + // advanced editing + else if (event.text == "r") { + // zero out everything + //for(var i= 0 ; i < currentAnimation.joints.length ; i++) { + // currentAnimation.joints[i].pitch = 0; + // currentAnimation.joints[i].yaw = 0; + // currentAnimation.joints[i].roll = 0; + // currentAnimation.joints[i].pitchPhase = 0; + // currentAnimation.joints[i].yawPhase = 0; + // currentAnimation.joints[i].rollPhase = 0; + // currentAnimation.joints[i].pitchOffset = 0; + // currentAnimation.joints[i].yawOffset = 0; + // currentAnimation.joints[i].rollOffset = 0; + // if(i===0) { + // currentAnimation.joints[i].thrust = 0; + // currentAnimation.joints[i].sway = 0; + // currentAnimation.joints[i].bob = 0; + // } + print('...'); + //} + } + else 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}); - } + Overlays.editOverlay(debugStats, {visible: statsOn}); + Overlays.editOverlay(debugStatsPeriodic, {visible: statsOn}); + Overlays.editOverlay(walkWheelStats, {visible: statsOn}); + Overlays.editOverlay(walkWheelYLine, {visible: statsOn}); + Overlays.editOverlay(walkWheelZLine, {visible: statsOn}); + } + // this is a dev tool for tweaking individual values. edit and use freely + else if (event.text == "[") { + var jointNum = 0; + var anim = currentAnimation; + var frequency = currentAnimation.settings.baseFrequency; + frequency-=5; + currentAnimation.settings.baseFrequency = frequency; + //print(anim.name+' thrustPhase is now '+anim.joints[jointNum].thrustPhase+' for the '+anim.joints[jointNum].name+' joint'); + } + else if (event.text == "]") { + var jointNum = 0; + var anim = currentAnimation; + var frequency = currentAnimation.settings.baseFrequency; + frequency+=5; + currentAnimation.settings.baseFrequency = frequency; + //print(anim.name+' bobPhase is now '+anim.joints[jointNum].thrustPhase+' for the '+anim.joints[jointNum].name+' joint'); } } Controller.keyPressEvent.connect(keyPressEvent); @@ -2513,7 +4310,6 @@ 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(); @@ -2525,16 +4321,14 @@ 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]); + MyAvatar.setJointData(i, Quat.fromPitchYawRollDegrees(0,0,0)); + //MyAvatar.clearJointData(jointList[i]); } +// used to position the visual representation of the walkwheel only 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(); +// This script is designed around the Finite State Machine (FSM) +// model, so to start things up we just select the STANDING state. setInternalState(STANDING); \ No newline at end of file From 3581b0d0c3c5ab72cecf3e36726f4dbe7588dece Mon Sep 17 00:00:00 2001 From: DaveDubUK Date: Sat, 27 Sep 2014 22:47:42 +0700 Subject: [PATCH 003/179] update to 1.007b Code cleanup --- examples/walk.js | 587 +++++------------------------------------------ 1 file changed, 52 insertions(+), 535 deletions(-) diff --git a/examples/walk.js b/examples/walk.js index 17091b7f36..a9e8f401d6 100644 --- a/examples/walk.js +++ b/examples/walk.js @@ -1,58 +1,32 @@ // // walk.js // -// version 1.006b +// version 1.007b // // 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/animation-files/'; // working (but only without https) +var pathToAnimFiles = 'http://s3-us-west-1.amazonaws.com/highfidelity-public/procedural-animator/animation-files/'; // working (but only without https) // path to the images used for the overlays -//var pathToOverlays = 'http://localhost/downloads/hf/scripts/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/overlays/'; // working (but only without https) // path to the sounds used for the footsteps var pathToSounds = 'http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Footsteps/'; -//var pathToSounds = 'http://localhost/downloads/hf/sounds/Footsteps/'; - -// load all the animation datafiles -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"); +// load the animation datafiles 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-sidestep-left-animation.js"); Script.include(pathToAnimFiles+"dd-female-sidestep-right-animation.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"); @@ -61,24 +35,8 @@ Script.include(pathToAnimFiles+"dd-male-sidestep-left-animation.js"); Script.include(pathToAnimFiles+"dd-male-sidestep-right-animation.js"); // read in the data from the animation files -var 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(); @@ -91,24 +49,8 @@ var FemaleSideStepLeftFile = new FemaleSideStepLeft(); var femaleSideStepLeft = FemaleSideStepLeftFile.loadAnimation(); var FemaleSideStepRightFile = new FemaleSideStepRight(); var femaleSideStepRight = FemaleSideStepRightFile.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(); @@ -201,7 +143,6 @@ var selectedJointIndex = 0; // the index of the joint currently selected for edi var currentTransition = null; // used as a pointer to a Transition // walkwheel (foot / ground speed matching) -//var walkCycleStart = 140; // 105 for female strut... best foot forwards - TODO: if found to be different for different anims, add as setting to anim files var sideStepCycleStartLeft = 270; var sideStepCycleStartRight = 90; var walkWheelPosition = 0; @@ -220,7 +161,6 @@ function RecentMotion(velocity, acceleration, principleDirection, state) { this.acceleration = acceleration; this.principleDirection = principleDirection; this.state = state; - // TODO: add INTERNAL_STATE so can remove 'hints' system for state changes } // constructor for the FramesHistory object @@ -231,8 +171,7 @@ function FramesHistory() { this.recentMotions.push(blank); } - // recentDirection 'method' - // args: (direction enum, number of steps back to compare) + // recentDirection 'method' args: (direction enum, number of steps back to compare) this.recentDirection = function () { if( arguments[0] && arguments[1] ) { @@ -244,15 +183,13 @@ function FramesHistory() { for(var i = 0 ; i < arguments[1] ; i++ ) { if( this.recentMotions[i].principleDirection === arguments[0] ) directionCount++; - //print('looking for '+directionAsString(arguments[0])+' directionCount '+directionCount+' count '+i+' dircetion '+directionAsString(this.recentMotions[i].principleDirection)); } return directionCount / arguments[1] === 1 ? true : false; } return false; } - // recentState 'method' - // args: (state enum, number of steps back to compare) + // recentState 'method' args: (state enum, number of steps back to compare) this.recentState = function () { if( arguments[0] && arguments[1] ) { @@ -298,8 +235,6 @@ function Transition(lastAnimation, nextAnimation, reachPoses, transitionDuration this.walkWheelIncrement = 3; // how much to turn the walkwheel each frame when coming to a halt. Get's set to 0 once the feet are under the avi this.walkWheelAdvance = 0; // how many degrees the walk wheel has been advanced during the transition this.walkStopAngle = 0; // what angle should we stop the walk cycle? (calculated on the fly) - - //print('Transition initiated from '+this.lastAnimation.name+' to '+this.nextAnimation.name+' duration '+transitionDuration.toFixed(2)); } // convert a local (to the avi) translation to a global one @@ -333,8 +268,6 @@ function translateHips(localHipsTranslation) { 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 }; @@ -345,10 +278,10 @@ 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) { @@ -357,11 +290,9 @@ function playFootstep(side) { options.volume = 0.5; 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); } } @@ -387,17 +318,14 @@ function curlFingers() { } } - // additional maths functions -function degToRad(degreesValue) { return degreesValue * Math.PI / 180; } -function radToDeg(radiansValue) { return radiansValue * 180 / Math.PI; } -//function cubicRoot(x) { var y = Math.pow(Math.abs(x), 1/3); return x < 0 ? -y : y; } +function degToRad( degreesValue ) { return degreesValue * Math.PI / 180; } +function radToDeg( radiansValue ) { return radiansValue * 180 / Math.PI; } // animateAvatar - sine wave generators working like clockwork -function animateAvatar(deltaTime, velocity, principleDirection) { +function animateAvatar( deltaTime, velocity, principleDirection ) { - // adjusting the walk speed in edit mode causes a nasty flicker - // pausing the animation stops this + // adjusting the walk speed in edit mode causes a nasty flicker. pausing the animation stops this if(paused) return; var cycle = cumulativeTime; @@ -441,42 +369,18 @@ function animateAvatar(deltaTime, velocity, principleDirection) { currentTransition.walkWheelIncrement = 6; // keep the walkwheel turning by setting the walkWheelIncrement until our feet are tucked nicely underneath us. - // fold back (reverse walk) if we just missed our stop target on the walkwheel when we stopped walking - depricated - //var stepIncrement = 2; // just used to set currentTransition.walkWheelIncrement in multiple locations if( angleToLeftStop < angleToRightStop ) { - //if(angleToLeftStop<270) currentTransition.walkStopAngle = rightStop; - //else if(walkWheelPosition>angleToLeftStop) currentTransition.walkStopAngle = rightStop; - //else currentTransition.walkStopAngle = leftStop; - currentTransition.walkStopAngle = leftStop; - //if( leftStop > 270 && walkWheelPosition < 90 ) currentTransition.walkWheelIncrement = -stepIncrement; - //else if( walkWheelPosition > 270 && leftStop < 90 ) currentTransition.walkWheelIncrement = stepIncrement; - //else if( walkWheelPosition < leftStop ) currentTransition.walkWheelIncrement = stepIncrement; - //else if( walkWheelPosition >= leftStop ) currentTransition.walkWheelIncrement = -stepIncrement; - //currentTransition.walkWheelIncrement = stepIncrement; - } else { - //if(angleToRightStop<270) currentTransition.walkStopAngle = leftStop; - //else if(walkWheelPosition>angleToRightStop) currentTransition.walkStopAngle = leftStop; - //else currentTransition.walkStopAngle = rightStop; currentTransition.walkStopAngle = rightStop; - - //currentTransition.walkStopAngle = rightStop; - //if( rightStop > 270 && walkWheelPosition < 90 ) currentTransition.walkWheelIncrement = -stepIncrement; - //else if( walkWheelPosition > 270 && rightStop < 90 ) currentTransition.walkWheelIncrement = stepIncrement; - //else if( walkWheelPosition < rightStop ) currentTransition.walkWheelIncrement = stepIncrement; - //else if( walkWheelPosition >= rightStop ) currentTransition.walkWheelIncrement = -stepIncrement; - //currentTransition.walkWheelIncrement = stepIncrement; } - //print('walkWheelPosition '+walkWheelPosition.toFixed(2)+' leftStop '+leftStop+' rightStop '+rightStop+' angleToLeftStop '+angleToLeftStop.toFixed(2)+' angleToRightStop '+angleToRightStop.toFixed(2)+' stop angle '+currentTransition.walkStopAngle) - } else { - // just freeze wheel for sidestepping + // freeze wheel for sidestepping transitions currentTransition.walkWheelIncrement = 0; } } @@ -500,25 +404,13 @@ function animateAvatar(deltaTime, velocity, principleDirection) { if( INTERNAL_STATE !== SIDE_STEPPING ) { // if at a stop angle, hold the walk wheel position for remainder of transition - var tolerance = 10; // must be greater than the walkWheel increment + var tolerance = 7; // must be greater than the walkWheel increment if(( walkWheelPosition > (currentTransition.walkStopAngle - tolerance )) && ( walkWheelPosition < (currentTransition.walkStopAngle + tolerance ))) { - //print('stop now? walkWheelAdvance '+currentTransition.walkWheelAdvance); - - //if( currentTransition.walkWheelAdvance < 45 ) { - - // currentTransition.walkStopAngle += 180; // not enough of a transition - keep moving... - // if( currentTransition.walkStopAngle > 360 ) currentTransition.walkStopAngle %= 360; - - // print('walkStopAngle incremented '); - //} - //else currentTransition.walkWheelIncrement = 0; } // keep turning walk wheel until both feet are below the avi - - //print('walkWheelAdvance '+currentTransition.walkWheelAdvance); walkWheelPosition += currentTransition.walkWheelIncrement; currentTransition.walkWheelAdvance += currentTransition.walkWheelIncrement; } @@ -540,8 +432,8 @@ function animateAvatar(deltaTime, velocity, principleDirection) { // if the timing's right, take a snapshot of the stride max and recalibrate var tolerance = 1.0; // higher the number, the higher the chance of a calibration taking place, but is traded off with lower accuracy - var strideOne = 40; // 130 - var strideTwo = 220; // 300 + var strideOne = 40; + var strideTwo = 220; if( principleDirection === DIRECTION_BACKWARDS ) { strideOne = 130; @@ -556,20 +448,19 @@ function animateAvatar(deltaTime, velocity, principleDirection) { var footLPos = localToGlobal(MyAvatar.getJointPosition("LeftFoot")); var footOffsetZ = Math.abs(footRPos.z - footLPos.z); if(footOffsetZ>1) strideLength = 2 * footOffsetZ + aviFootSize.z; // sometimes getting very low value here - just ignore for now - //if(statsOn) print('Stride length calibrated to '+strideLength.toFixed(4)+' metres at '+walkWheelPosition.toFixed(1)+' degrees'); + if(statsOn) print('Stride length calibrated to '+strideLength.toFixed(4)+' metres at '+walkWheelPosition.toFixed(1)+' degrees'); if(principleDirection===DIRECTION_FORWARDS) { currentAnimation.calibration.strideLengthForwards = strideLength; } else if (principleDirection===DIRECTION_BACKWARDS) { currentAnimation.calibration.strideLengthBackwards = strideLength; } - } - else { - if(principleDirection===DIRECTION_FORWARDS) { + } else { + + if(principleDirection===DIRECTION_FORWARDS) strideLength = currentAnimation.calibration.strideLengthForwards; - } else if (principleDirection===DIRECTION_BACKWARDS) { + else if (principleDirection===DIRECTION_BACKWARDS) strideLength = currentAnimation.calibration.strideLengthBackwards; - } } } else if(( INTERNAL_STATE===SIDE_STEPPING || @@ -588,8 +479,7 @@ function animateAvatar(deltaTime, velocity, principleDirection) { var footLPos = localToGlobal(MyAvatar.getJointPosition("LeftFoot")); var footOffsetX = Math.abs(footRPos.x - footLPos.x); strideLength = footOffsetX; - //if(statsOn) print('Stride width calibrated to '+strideLength.toFixed(4)+ ' metres at '+walkWheelPosition.toFixed(1)+' degrees'); - //print('Stride width calibrated to '+strideLength.toFixed(4)+ ' metres at '+walkWheelPosition.toFixed(1)+' degrees. footRPos '+footRPos.x.toFixed(3)+' footLPos '+footLPos.x.toFixed(3)+' footOffsetX '+footOffsetX.toFixed(3)); + if(statsOn) print('Stride width calibrated to '+strideLength.toFixed(4)+ ' metres at '+walkWheelPosition.toFixed(1)+' degrees'); currentAnimation.calibration.strideLengthLeft = strideLength; } else { @@ -606,8 +496,7 @@ function animateAvatar(deltaTime, velocity, principleDirection) { var footLPos = localToGlobal(MyAvatar.getJointPosition("LeftFoot")); var footOffsetX = Math.abs(footRPos.x - footLPos.x); strideLength = footOffsetX; - //if(statsOn) print('Stride width calibrated to '+strideLength.toFixed(4)+ ' metres at '+walkWheelPosition.toFixed(1)+' degrees'); - //print('Stride width calibrated to '+strideLength.toFixed(4)+ ' metres at '+walkWheelPosition.toFixed(1)+' degrees. footRPos '+footRPos.x.toFixed(3)+' footLPos '+footLPos.x.toFixed(3)+' footOffsetX '+footOffsetX.toFixed(3)); + if(statsOn) print('Stride width calibrated to '+strideLength.toFixed(4)+ ' metres at '+walkWheelPosition.toFixed(1)+' degrees'); currentAnimation.calibration.strideLengthRight = strideLength; } else { @@ -715,7 +604,6 @@ function animateAvatar(deltaTime, velocity, principleDirection) { var yawOffsetLast = 0; var rollOffsetLast = 0; - // calcualte any hips translation // Note: can only apply hips translations whilst in a config (edit) mode at present, not whilst under locomotion if( INTERNAL_STATE===CONFIG_WALK_STYLES || @@ -727,12 +615,12 @@ function animateAvatar(deltaTime, velocity, principleDirection) { INTERNAL_STATE===CONFIG_FLYING_UP || INTERNAL_STATE===CONFIG_FLYING_DOWN ) { - // calculate hips translation TODO: get this working in normal motion! + // calculate hips translation var motorOscillation = Math.sin(degToRad((cycle * adjustedFrequency * 2) + currentAnimation.joints[0].thrustPhase)) + currentAnimation.joints[0].thrustOffset; var swayOscillation = Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[0].swayPhase)) + currentAnimation.joints[0].swayOffset; var bobOscillation = Math.sin(degToRad((cycle * adjustedFrequency * 2) + currentAnimation.joints[0].bobPhase)) + currentAnimation.joints[0].bobOffset; - // apply hips translation TODO: get this working! + // apply hips translation translateHips({x:swayOscillation*currentAnimation.joints[0].sway, y:motorOscillation*currentAnimation.joints[0].thrust, z:bobOscillation*currentAnimation.joints[0].bob}); } @@ -760,7 +648,7 @@ function animateAvatar(deltaTime, velocity, principleDirection) { rollOscillationLast = (currentTransition.lastAnimation.joints[0].roll * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[0].rollPhase)) + currentTransition.lastAnimation.joints[0].rollOffset); - } else {//if( currentTransition.walkingAtEnd ) { + } else { pitchOscillation = currentAnimation.joints[0].pitch * Math.sin(degToRad((cycle * adjustedFrequency * 2) + currentAnimation.joints[0].pitchPhase)) + currentAnimation.joints[0].pitchOffset; @@ -786,8 +674,6 @@ function animateAvatar(deltaTime, velocity, principleDirection) { yawOscillation = (transitionProgress * yawOscillation) + ((1-transitionProgress) * yawOscillationLast); rollOscillation = (transitionProgress * rollOscillation) + ((1-transitionProgress) * rollOscillationLast); - //print('Hips: '+pitchOscillation+' '+yawOscillation+' '+rollOscillation); - } else { pitchOscillation = currentAnimation.joints[0].pitch * Math.sin(degToRad((cycle * adjustedFrequency * 2) @@ -1014,7 +900,7 @@ function animateAvatar(deltaTime, velocity, principleDirection) { yawOffsetLast = currentTransition.lastAnimation.joints[3].yawOffset; rollOffsetLast = currentTransition.lastAnimation.joints[3].rollOffset; - } else { //if( currentTransition.walkingAtEnd ) { + } else { pitchOscillation = currentAnimation.joints[3].pitch * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[3].pitchPhase)); yawOscillation = currentAnimation.joints[3].yaw * Math.sin(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[3].yawPhase)); @@ -1064,9 +950,7 @@ function animateAvatar(deltaTime, velocity, principleDirection) { MyAvatar.setJointData("RightFoot", Quat.fromPitchYawRollDegrees( pitchOscillation + pitchOffset, yawOscillation + yawOffset, rollOscillation + rollOffset )); MyAvatar.setJointData("LeftFoot", Quat.fromPitchYawRollDegrees( -pitchOscillation + pitchOffset, yawOscillation - yawOffset, rollOscillation - rollOffset )); - - // play footfall sound yet? To determine this, we take the differential of - // the foot's pitch curve to decide when the foot hits the ground. + // play footfall sound yet? To determine this, we take the differential of the foot's pitch curve to decide when the foot hits the ground. if( INTERNAL_STATE===WALKING || INTERNAL_STATE===SIDE_STEPPING || INTERNAL_STATE===CONFIG_WALK_STYLES || @@ -1075,8 +959,7 @@ function animateAvatar(deltaTime, velocity, principleDirection) { INTERNAL_STATE===CONFIG_SIDESTEP_LEFT || INTERNAL_STATE===CONFIG_SIDESTEP_RIGHT ) { - // As luck would have it, we're using sine waves, so finding dy/dx is as - // simple as determining the cosine wave for the foot's pitch function. + // finding dy/dx is as simple as determining the cosine wave for the foot's pitch function. var feetPitchDifferential = Math.cos(degToRad((cycle * adjustedFrequency ) + currentAnimation.joints[3].pitchPhase)); var threshHold = 0.9; // sets the audio trigger point. with accuracy. if(feetPitchDifferential<-threshHold && @@ -1114,7 +997,7 @@ function animateAvatar(deltaTime, velocity, principleDirection) { pitchOffsetLast = currentTransition.lastAnimation.joints[4].pitchOffset; - } else { //if( currentTransition.walkingAtEnd ) { + } else { pitchOscillation = currentAnimation.joints[4].pitch * Math.sin(degToRad((cycle * adjustedFrequency) + currentAnimation.joints[4].pitchPhase)); yawOscillation = currentAnimation.joints[4].yaw * Math.sin(degToRad((cycle * adjustedFrequency) + currentAnimation.joints[4].yawPhase)) + currentAnimation.joints[4].yawOffset; @@ -1156,7 +1039,6 @@ function animateAvatar(deltaTime, velocity, principleDirection) { MyAvatar.setJointData("RightToeBase", Quat.fromPitchYawRollDegrees(-pitchOscillation + pitchOffset, yawOscillation, rollOscillation)); MyAvatar.setJointData("LeftToeBase", Quat.fromPitchYawRollDegrees( pitchOscillation + pitchOffset, yawOscillation, rollOscillation)); - // spine if( currentTransition !== null ) { @@ -1176,8 +1058,7 @@ function animateAvatar(deltaTime, velocity, principleDirection) { rollOscillationLast = currentTransition.lastAnimation.joints[5].roll * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[5].rollPhase)) + currentTransition.lastAnimation.joints[5].rollOffset; - - } else { //if( currentTransition.walkingAtEnd ) { + } else { pitchOscillation = currentAnimation.joints[5].pitch * Math.sin( degToRad(( cycle * adjustedFrequency * 2) + currentAnimation.joints[5].pitchPhase)) + currentAnimation.joints[5].pitchOffset; @@ -1218,7 +1099,6 @@ function animateAvatar(deltaTime, velocity, principleDirection) { // apply spine joint rotations MyAvatar.setJointData("Spine", Quat.fromPitchYawRollDegrees( pitchOscillation, yawOscillation, rollOscillation )); - // spine 1 if(currentTransition!==null) { @@ -1238,7 +1118,7 @@ function animateAvatar(deltaTime, velocity, principleDirection) { * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[6].rollPhase)) + currentTransition.lastAnimation.joints[6].rollOffset; - } else { //if( currentTransition.walkingAtEnd ) { + } else { pitchOscillation = currentAnimation.joints[6].pitch * Math.sin( degToRad(( cycle * adjustedFrequency * 2) + currentAnimation.joints[6].pitchPhase)) + currentAnimation.joints[6].pitchOffset; @@ -1298,7 +1178,7 @@ function animateAvatar(deltaTime, velocity, principleDirection) { * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[7].rollPhase)) + currentTransition.lastAnimation.joints[7].rollOffset; - } else { //if( currentTransition.walkingAtEnd ) { + } else { pitchOscillation = currentAnimation.joints[7].pitch * Math.sin( degToRad(( cycle * adjustedFrequency * 2) @@ -1380,7 +1260,7 @@ function animateAvatar(deltaTime, velocity, principleDirection) { yawOffsetLast = currentTransition.lastAnimation.joints[8].yawOffset; - } else { //if( currentTransition.walkingAtEnd ) { + } else { pitchOscillation = currentAnimation.joints[8].pitch * Math.sin( degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[8].pitchPhase)) + currentAnimation.joints[8].pitchOffset; @@ -1458,7 +1338,7 @@ function animateAvatar(deltaTime, velocity, principleDirection) { pitchOffsetLast = currentTransition.lastAnimation.joints[9].pitchOffset; yawOffsetLast = currentTransition.lastAnimation.joints[9].yawOffset; - } else { //if( currentTransition.walkingAtEnd ) { + } else { pitchOscillation = currentAnimation.joints[9].pitch * Math.sin( degToRad(( cycle * adjustedFrequency ) @@ -1559,7 +1439,7 @@ function animateAvatar(deltaTime, velocity, principleDirection) { yawOffsetLast = currentTransition.lastAnimation.joints[10].yawOffset; rollOffsetLast = currentTransition.lastAnimation.joints[10].rollOffset; - } else { //if( currentTransition.walkingAtEnd ) { + } else { pitchOscillation = currentAnimation.joints[10].pitch * Math.sin( degToRad(( cycle * adjustedFrequency ) @@ -1621,9 +1501,6 @@ function animateAvatar(deltaTime, velocity, principleDirection) { rollOffset = currentAnimation.joints[10].rollOffset; } - // transitionProgress pitchOscillation yawOscillation rollOscillation - //print(transitionProgress+' '+pitchOscillation+' '+yawOscillation+' '+rollOscillation); - // apply forearms rotations MyAvatar.setJointData("RightForeArm", Quat.fromPitchYawRollDegrees( pitchOscillation, yawOscillation + yawOffset, rollOscillation + rollOffset )); MyAvatar.setJointData("LeftForeArm", Quat.fromPitchYawRollDegrees( pitchOscillation, yawOscillation - yawOffset, rollOscillation - rollOffset )); @@ -1632,7 +1509,7 @@ function animateAvatar(deltaTime, velocity, principleDirection) { var sideStepSign = 1; if(INTERNAL_STATE===SIDE_STEPPING) { sideStepSign = 1; - } // TODO: check status of hand rotations + } if(currentTransition!==null) { if(currentTransition.walkingAtStart) { @@ -1655,7 +1532,7 @@ function animateAvatar(deltaTime, velocity, principleDirection) { rollOffset = currentAnimation.joints[11].rollOffset; rollOffsetLast = currentTransition.lastAnimation.joints[11].rollOffset; - } else { //if( currentTransition.walkingAtEnd ) { + } else { pitchOscillation = currentAnimation.joints[11].pitch * Math.sin( degToRad(( cycle * adjustedFrequency ) @@ -1712,7 +1589,7 @@ function animateAvatar(deltaTime, velocity, principleDirection) { } // end if(!armsFree) - // head (includes neck joint) - currently zeroed out in STANDING by request + // head (includes neck joint) - currently zeroed out in STANDING animation files by request if( currentTransition !== null ) { if(currentTransition.walkingAtStart) { @@ -1738,7 +1615,7 @@ function animateAvatar(deltaTime, velocity, principleDirection) { * Math.sin(degToRad(( walkWheelPosition ) + currentTransition.lastAnimation.joints[12].rollPhase)) + currentTransition.lastAnimation.joints[12].rollOffset; - } else { //if( currentTransition.walkingAtEnd ) { + } else { pitchOscillation = 0.5 * currentAnimation.joints[12].pitch * Math.sin(degToRad(( cycle * adjustedFrequency * 2) + currentAnimation.joints[12].pitchPhase)) + currentAnimation.joints[12].pitchOffset; yawOscillation = 0.5 * currentAnimation.joints[12].yaw * Math.sin(degToRad(( cycle * adjustedFrequency ) + currentAnimation.joints[12].yawPhase)) + currentAnimation.joints[12].yawOffset; @@ -1760,7 +1637,6 @@ function animateAvatar(deltaTime, velocity, principleDirection) { + currentTransition.lastAnimation.joints[12].rollOffset; } - // TODO: see if can animate separate heads in any way... pitchOscillation = (transitionProgress * pitchOscillation) + ((1-transitionProgress) * pitchOscillationLast); yawOscillation = (transitionProgress * yawOscillation) + ((1-transitionProgress) * yawOscillationLast); rollOscillation = (transitionProgress * rollOscillation) + ((1-transitionProgress) * rollOscillationLast); @@ -1778,7 +1654,7 @@ function animateAvatar(deltaTime, velocity, principleDirection) { -// getBezier - src: Dan Pupius (www.pupius.net) http://13thparallel.com/archive/bezier-curves/ +// Bezier function for applying to transitions - src: Dan Pupius (www.pupius.net) http://13thparallel.com/archive/bezier-curves/ Coord = function (x,y) { if(!x) var x=0; if(!y) var y=0; @@ -1801,10 +1677,8 @@ function getBezier(percent,C1,C2,C3,C4) { var NZEROS = 8; var NPOLES = 8; var GAIN = 17.40692157; -var xv = [0,0,0,0,0,0,0,0,0]; -//xv.length = NZEROS+1; -var yv = [0,0,0,0,0,0,0,0,0]; -//yv.length = NPOLES+1; +var xv = [0,0,0,0,0,0,0,0,0]; //xv.length = NZEROS+1; +var yv = [0,0,0,0,0,0,0,0,0]; //yv.length = NPOLES+1; function filterButterworth(nextInputValue) { @@ -1820,46 +1694,17 @@ function filterButterworth(nextInputValue) return yv[8]; } - // the faster we go, the further we lean forward. the angle is calcualted here var leanAngles = []; // smooth out and add damping with simple averaging filter. leanAngles.length = 15; function getLeanPitch(velocity) { -/* - // lean backwards when decelerating a lot. skid to a halt. working, but I don't like the effect - will use a reach pose later instead - var accelerationResponse = recentMotions[0].acceleration.z; - var accelerationResponseMax = 45; // max degrees hip pitch - - if(velocityaccelerationResponseMax) - accelerationResponse = accelerationResponseMax; - else if(accelerationResponse<-accelerationResponseMax) - accelerationResponse = -accelerationResponseMax; - // apply yet another averaging filter... - accelerationResponseAngles.push(accelerationResponse); - accelerationResponseAngles.shift(); - var finalAccelerationResponse = 0; - for(ea in accelerationResponseAngles) finalAccelerationResponse += accelerationResponseAngles[ea]; - finalAccelerationResponse /= accelerationResponseAngles.length; - - // calculate any skid for this frame and apply it - var skidDistance = -0.01 * hipsToFeetDistance * Math.sin(degToRad(finalAccelerationResponse)); - if(Math.abs(skidDistance)>0.001 && INTERNAL_STATE===STANDING) { // show skids when stopping - var skidVector = localToGlobal({ x:0, y:0, z:skidDistance }); - print('skidDistance '+skidDistance+' metres'); - MyAvatar.position = Vec3.sum(MyAvatar.position, skidVector); - } - if(Math.abs(accelerationResponse)>0) print('accelerationResponse '+accelerationResponse.toFixed(3)+' recent acceleration '+recentMotions[0].acceleration.z.toFixed(3)); -*/ if(velocity>TERMINAL_VELOCITY) velocity=TERMINAL_VELOCITY; var leanProgress = velocity / TERMINAL_VELOCITY; var responseSharpness = 1.8; if(principleDirection==DIRECTION_BACKWARDS) responseSharpness = 3.6; // lean back a bit extra when walking backwards var leanProgressBezier = getBezier((1-leanProgress),{x:0,y:0},{x:0,y:responseSharpness},{x:0,y:1},{x:1,y:1}).y; - //var leanProgressButterworth = filterButterworth(leanProgressBezier); // simple averaging filter seems to give best results leanAngles.push(leanProgressBezier); @@ -1926,27 +1771,22 @@ function getLeanRoll(deltaTime, velocity) { // set up the interface components, update the internal state and kick off any transitions function setInternalState(newInternalState) { - var debugShowStateChanges = false; - - switch(newInternalState) { + switch(newInternalState) { case WALKING: - if(debugShowStateChanges) print('WALKING'); if(!minimised) doStandardMenu(); INTERNAL_STATE = WALKING; return; case FLYING: - if(debugShowStateChanges) print('FLYING'); if(!minimised) doStandardMenu(); INTERNAL_STATE = FLYING; return; case SIDE_STEPPING: - if(debugShowStateChanges) print('SIDE_STEPPING'); if(!minimised) doStandardMenu(); INTERNAL_STATE = SIDE_STEPPING; return; @@ -2118,7 +1958,6 @@ function setInternalState(newInternalState) { case STANDING: default: - if(debugShowStateChanges) print('STANDING'); INTERNAL_STATE = STANDING; if(!minimised) doStandardMenu(); @@ -2138,9 +1977,8 @@ function setInternalState(newInternalState) { // 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 +// stabilising vars - most state changes are preceded by a couple of hints that they are about to happen rather than +// momentarilly switching between states (causes flicker), we count the number of hints in a row before actually changing state var standHints = 0; var walkHints = 0; var flyHints = 0; @@ -2303,7 +2141,6 @@ Script.update.connect(function(deltaTime) { // NB: this section will change significantly once we are ground plane aware // it will change even more once we have uneven surfaces to deal with - // but for now, we have to deal with states like 'standing in the air' // maybe at walking speed, but sideways? if( actionToTake === WALKING && @@ -2361,9 +2198,9 @@ Script.update.connect(function(deltaTime) { switch(currentAnimation) { case selectedWalk: + // Walking to Standing var timeWalking = new Date().getTime() - framesHistory.lastWalkStartTime; - //print('You were walking for '+timeWalking+' mS'); var bezierCoeffsOne = {x:0.0, y:1.0}; var bezierCoeffsTwo = {x:0.0, y:1.0}; @@ -2382,7 +2219,6 @@ Script.update.connect(function(deltaTime) { case selectedSideStepLeft: case selectedSideStepRight: - //currentTransition = new Transition(currentAnimation, selectedWalk, [], 0.3, {x:0.5,y:0.08}, {x:0.05,y:0.75}); break; default: @@ -2430,6 +2266,7 @@ Script.update.connect(function(deltaTime) { switch(currentAnimation) { case selectedStand: + // Standing to Walking currentTransition = new Transition(currentAnimation, selectedWalk, [], 0.25, {x:0.5,y:0.08}, {x:0.05,y:0.75}); break; @@ -2464,22 +2301,20 @@ Script.update.connect(function(deltaTime) { if( principleDirection === DIRECTION_LEFT ) { - walkWheelPosition = sideStepCycleStartLeft;//selectedSideStep.calibration.sideStepCycleStartLeft; + walkWheelPosition = sideStepCycleStartLeft; } else { - walkWheelPosition = sideStepCycleStartRight;//selectedSideStep.calibration.sideStepCycleStartRight; + walkWheelPosition = sideStepCycleStartRight; } switch(currentAnimation) { case selectedStand: - //currentTransition = new Transition(currentAnimation, selectedSideStep, [], 0.8, {x:0.5,y:0.08}, {x:0.28,y:1}); break; default: - //currentTransition = new Transition(currentAnimation, selectedSideStep, [], 0.8, {x:0.5,y:0.08}, {x:0.28,y:1}); break; } setInternalState(SIDE_STEPPING); @@ -2607,13 +2442,6 @@ Script.update.connect(function(deltaTime) { // before we go, populate the stats overlay if( statsOn ) { - // quick test for the frame execution time measurement - // lots of console logging messes up execution times pretty well! - //for(var doh = 0 ; doh < 10 ; doh++) { - // //var fake = doh * doh * doh; - // print('faking bad coding...'+doh); - //} - var cumulativeTimeMS = Math.floor(cumulativeTime*1000); var deltaTimeMS = deltaTime * 1000; var frameExecutionTime = new Date().getTime() - frameStartTime; @@ -2682,8 +2510,6 @@ var jointsControlOverlays = []; var bigButtonOverlays = []; -// take a deep breath and... - // load UI backgrounds var controlsBackground = Overlays.addOverlay("image", { bounds: { x: backgroundX, y: backgroundY, width: backgroundWidth, height: backgroundHeight }, @@ -2730,9 +2556,6 @@ var controlsBackgroundFlyingEdit = Overlays.addOverlay("image", { }); backgroundOverlays.push(controlsBackgroundFlyingEdit); - - - // minimised tab - not put in array, as is a one off var controlsMinimisedTab = Overlays.addOverlay("image", { x: Window.innerWidth-58, y: Window.innerHeight -145, width: 50, height: 50, @@ -2742,8 +2565,6 @@ var controlsMinimisedTab = Overlays.addOverlay("image", { alpha: 0.9 }); - - // load character joint selection control images var hipsJointControl = Overlays.addOverlay("image", { bounds: { x: jointsControlX, y: jointsControlY, width: 200, height: 300}, @@ -3088,8 +2909,6 @@ var configWalkTweaksButtonSelected = Overlays.addOverlay("image", { }); buttonOverlays.push(configWalkTweaksButtonSelected); - - var configSideStepLeftButton = Overlays.addOverlay("image", { bounds: { x: backgroundX+83, y: backgroundY+buttonsY, width: 60, height: 47 }, imageURL: pathToOverlays+"ddao-edit-sidestep-left-button.png", @@ -3254,158 +3073,6 @@ var strutWalkBigButtonSelected = Overlays.addOverlay("image", { }); bigButtonOverlays.push(strutWalkBigButtonSelected); -bigButtonYOffset += 60 -var sexyWalkBigButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, - imageURL: pathToOverlays+"ddao-walk-select-button-sexy.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(sexyWalkBigButton); - -var sexyWalkBigButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, - imageURL: pathToOverlays+"ddao-walk-select-button-sexy-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(sexyWalkBigButtonSelected); - -bigButtonYOffset += 60; -var powerWalkBigButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, - imageURL: pathToOverlays+"ddao-walk-select-button-power-walk.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(powerWalkBigButton); - -var powerWalkBigButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, - imageURL: pathToOverlays+"ddao-walk-select-button-power-walk-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(powerWalkBigButtonSelected); - -bigButtonYOffset += 60; -var shuffleBigButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, - imageURL: pathToOverlays+"ddao-walk-select-button-shuffle.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(shuffleBigButton); - -var shuffleBigButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, - imageURL: pathToOverlays+"ddao-walk-select-button-shuffle-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(shuffleBigButtonSelected); - -bigButtonYOffset += 60; -var runBigButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, - imageURL: pathToOverlays+"ddao-walk-select-button-run.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(runBigButton); - -var runBigButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, - imageURL: pathToOverlays+"ddao-walk-select-button-run-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(runBigButtonSelected); - -bigButtonYOffset += 60; -var randomWalkBigButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, - imageURL: pathToOverlays+"ddao-walk-select-button-random.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(randomWalkBigButton); - -var randomWalkBigButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, - imageURL: pathToOverlays+"ddao-walk-select-button-random-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(randomWalkBigButtonSelected); - -bigButtonYOffset += 60; -var toughWalkBigButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, - imageURL: pathToOverlays+"ddao-walk-select-button-tough.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(toughWalkBigButton); - -var toughWalkBigButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, - imageURL: pathToOverlays+"ddao-walk-select-button-tough-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(toughWalkBigButtonSelected); - -bigButtonYOffset += 60; -var coolWalkBigButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, - imageURL: pathToOverlays+"ddao-walk-select-button-cool.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(coolWalkBigButton); - -var coolWalkBigButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, - imageURL: pathToOverlays+"ddao-walk-select-button-cool-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(coolWalkBigButtonSelected); - -bigButtonYOffset += 60; -var elderlyWalkBigButton = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, - imageURL: pathToOverlays+"ddao-walk-select-button-elderly.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(elderlyWalkBigButton); - -var elderlyWalkBigButtonSelected = Overlays.addOverlay("image", { - bounds: { x: backgroundX + backgroundWidth/2 - 115, y: backgroundY + bigButtonYOffset, width: 230, height: 36 }, - imageURL: pathToOverlays+"ddao-walk-select-button-elderly-selected.png", - color: { red: 255, green: 255, blue: 255}, - alpha: 1, - visible: false - }); -bigButtonOverlays.push(elderlyWalkBigButtonSelected); - // overlays to show the walk wheel stats var walkWheelZLine = Overlays.addOverlay("line3d", { position: { x: 0, y: 0, z:hipsToFeetDistance }, @@ -3675,42 +3342,10 @@ function showWalkStyleButtons(showButtons) { } // set the currently selected one - if(selectedWalk === femaleSexyWalk || selectedWalk === maleSexyWalk) { - Overlays.editOverlay(sexyWalkBigButtonSelected, { visible: showButtons }); - Overlays.editOverlay(sexyWalkBigButton, {visible: false}); - } - else if(selectedWalk === femaleStrutWalk || selectedWalk === maleStrutWalk) { + if(selectedWalk === femaleStrutWalk || selectedWalk === maleStrutWalk) { Overlays.editOverlay(strutWalkBigButtonSelected, { visible: showButtons }); Overlays.editOverlay(strutWalkBigButton, {visible: false}); } - else if(selectedWalk === femalePowerWalk || selectedWalk === malePowerWalk) { - Overlays.editOverlay(powerWalkBigButtonSelected, { visible: showButtons }); - Overlays.editOverlay(powerWalkBigButton, {visible: false}); - } - else if(selectedWalk === femaleShuffle || selectedWalk === maleShuffle) { - Overlays.editOverlay(shuffleBigButtonSelected, { visible: showButtons }); - Overlays.editOverlay(shuffleBigButton, {visible: false}); - } - else if(selectedWalk === femaleRun || selectedWalk === maleRun) { - Overlays.editOverlay(runBigButtonSelected, { visible: showButtons }); - Overlays.editOverlay(runBigButton, {visible: false}); - } - else if(selectedWalk === femaleRandomWalk || selectedWalk === maleRandomWalk) { - Overlays.editOverlay(randomWalkBigButtonSelected, { visible: showButtons }); - Overlays.editOverlay(randomWalkBigButton, {visible: false}); - } - else if(selectedWalk === femaleToughWalk || selectedWalk === maleToughWalk) { - Overlays.editOverlay(toughWalkBigButtonSelected, { visible: showButtons }); - Overlays.editOverlay(toughWalkBigButton, {visible: false}); - } - else if(selectedWalk === femaleCoolWalk || selectedWalk === maleCoolWalk) { - Overlays.editOverlay(coolWalkBigButtonSelected, { visible: showButtons }); - Overlays.editOverlay(coolWalkBigButton, {visible: false}); - } - else if(selectedWalk === femaleElderlyWalk || selectedWalk === maleElderlyWalk) { - Overlays.editOverlay(elderlyWalkBigButtonSelected, { visible: showButtons }); - Overlays.editOverlay(elderlyWalkBigButton, {visible: false}); - } } // mouse event handlers @@ -3809,70 +3444,6 @@ function mousePressEvent(event) { showWalkStyleButtons(true); return; -/* case sexyWalkBigButton: - if(avatarGender===FEMALE) selectedWalk = femaleSexyWalk; - else selectedWalk = maleSexyWalk; - currentAnimation = selectedWalk; - showWalkStyleButtons(true); - return; - - case powerWalkBigButton: - if(avatarGender===FEMALE) selectedWalk = femalePowerWalk; - else selectedWalk = malePowerWalk; - currentAnimation = selectedWalk; - showWalkStyleButtons(true); - return; - - case shuffleBigButton: - if(avatarGender===FEMALE) selectedWalk = femaleShuffle; - else selectedWalk = maleShuffle; - currentAnimation = selectedWalk; - showWalkStyleButtons(true); - return; - - case runBigButton: - if(avatarGender===FEMALE) selectedWalk = femaleRun; - else selectedWalk = maleRun; - currentAnimation = selectedWalk; - showWalkStyleButtons(true); - return; - - case randomWalkBigButton: - if(avatarGender===FEMALE) selectedWalk = femaleRandomWalk; - else selectedWalk = maleRandomWalk; - currentAnimation = selectedWalk; - showWalkStyleButtons(true); - return; - - case toughWalkBigButton: - if(avatarGender===FEMALE) selectedWalk = femaleToughWalk; - else selectedWalk = maleToughWalk; - currentAnimation = selectedWalk; - showWalkStyleButtons(true); - return; - - case coolWalkBigButton: - if(avatarGender===FEMALE) selectedWalk = femaleCoolWalk; - else selectedWalk = maleCoolWalk; - currentAnimation = selectedWalk; - showWalkStyleButtons(true); - return; - - case elderlyWalkBigButton: - if(avatarGender===FEMALE) selectedWalk = femaleElderlyWalk; - else selectedWalk = maleElderlyWalk; - currentAnimation = selectedWalk; - showWalkStyleButtons(true); - return; - - case sexyWalkBigButtonSelected: - case elderlyWalkBigButtonSelected: - case powerWalkBigButtonSelected: - case shuffleBigButtonSelected: - case runBigButtonSelected: - case randomWalkBigButtonSelected: - case toughWalkBigButtonSelected: - case coolWalkBigButtonSelected:*/ case strutWalkBigButtonSelected: // toggle forwards / backwards walk display @@ -4249,33 +3820,11 @@ var sideStep = 0.002; // i.e. 2mm increments whilst sidestepping - JS movement k function keyPressEvent(event) { if (event.text == "q") { - // export currentAnimation as json string when q key is pressed. - // reformat result at http://www.freeformatter.com/json-formatter.html + // 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'); - } - // advanced editing - else if (event.text == "r") { - // zero out everything - //for(var i= 0 ; i < currentAnimation.joints.length ; i++) { - // currentAnimation.joints[i].pitch = 0; - // currentAnimation.joints[i].yaw = 0; - // currentAnimation.joints[i].roll = 0; - // currentAnimation.joints[i].pitchPhase = 0; - // currentAnimation.joints[i].yawPhase = 0; - // currentAnimation.joints[i].rollPhase = 0; - // currentAnimation.joints[i].pitchOffset = 0; - // currentAnimation.joints[i].yawOffset = 0; - // currentAnimation.joints[i].rollOffset = 0; - // if(i===0) { - // currentAnimation.joints[i].thrust = 0; - // currentAnimation.joints[i].sway = 0; - // currentAnimation.joints[i].bob = 0; - // } - print('...'); - //} } else if (event.text == "t") { statsOn = !statsOn; @@ -4285,50 +3834,18 @@ function keyPressEvent(event) { Overlays.editOverlay(walkWheelYLine, {visible: statsOn}); Overlays.editOverlay(walkWheelZLine, {visible: statsOn}); } - // this is a dev tool for tweaking individual values. edit and use freely - else if (event.text == "[") { - var jointNum = 0; - var anim = currentAnimation; - var frequency = currentAnimation.settings.baseFrequency; - frequency-=5; - currentAnimation.settings.baseFrequency = frequency; - //print(anim.name+' thrustPhase is now '+anim.joints[jointNum].thrustPhase+' for the '+anim.joints[jointNum].name+' joint'); - } - else if (event.text == "]") { - var jointNum = 0; - var anim = currentAnimation; - var frequency = currentAnimation.settings.baseFrequency; - frequency+=5; - currentAnimation.settings.baseFrequency = frequency; - //print(anim.name+' bobPhase is now '+anim.joints[jointNum].thrustPhase+' for the '+anim.joints[jointNum].name+' joint'); - } } Controller.keyPressEvent.connect(keyPressEvent); - - - - -// debug and other info - -// TODO: implement joint mapping using reg expressions to cover a wide range of avi bone structures +// get the list of joint names 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]); } // used to position the visual representation of the walkwheel only var hipsToFeetDistance = MyAvatar.getJointPosition("Hips").y - MyAvatar.getJointPosition("RightFoot").y; -print('\nwalk.js: Hips to feet: '+hipsToFeetDistance); - -// This script is designed around the Finite State Machine (FSM) -// model, so to start things up we just select the STANDING state. +// This script is designed around the Finite State Machine (FSM) model, so to start things up we just select the STANDING state. setInternalState(STANDING); \ No newline at end of file From 2486a24c90a82b06091f3f82b9bdb22a00c928b9 Mon Sep 17 00:00:00 2001 From: stojce Date: Mon, 29 Sep 2014 18:26:25 +0200 Subject: [PATCH 004/179] possible fix for Windows login and address-bar modal dialog --- interface/src/ui/AddressBarDialog.cpp | 3 +-- interface/src/ui/LoginDialog.cpp | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/interface/src/ui/AddressBarDialog.cpp b/interface/src/ui/AddressBarDialog.cpp index 4043d5acb3..4925a43827 100644 --- a/interface/src/ui/AddressBarDialog.cpp +++ b/interface/src/ui/AddressBarDialog.cpp @@ -48,8 +48,7 @@ void AddressBarDialog::setupUI() { const int DIALOG_INITIAL_WIDTH = 560; setModal(true); - setWindowModality(Qt::WindowModal); - setHideOnBlur(false); + setWindowModality(Qt::ApplicationModal); QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); setSizePolicy(sizePolicy); diff --git a/interface/src/ui/LoginDialog.cpp b/interface/src/ui/LoginDialog.cpp index 57e02689c1..599ff28f35 100644 --- a/interface/src/ui/LoginDialog.cpp +++ b/interface/src/ui/LoginDialog.cpp @@ -36,8 +36,7 @@ LoginDialog::LoginDialog(QWidget* parent) : _ui->errorLabel->setVisible(false); setModal(true); - setWindowModality(Qt::WindowModal); - setHideOnBlur(false); + setWindowModality(Qt::ApplicationModal); connect(&AccountManager::getInstance(), &AccountManager::loginComplete, this, &LoginDialog::handleLoginCompleted); From 9c926d9e67d1db0a35cdcecc9b8ae988c8ad98be Mon Sep 17 00:00:00 2001 From: stojce Date: Thu, 2 Oct 2014 00:17:57 +0200 Subject: [PATCH 005/179] Layout changes --- interface/src/ui/AddressBarDialog.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/interface/src/ui/AddressBarDialog.cpp b/interface/src/ui/AddressBarDialog.cpp index 4925a43827..a1fd8b1b50 100644 --- a/interface/src/ui/AddressBarDialog.cpp +++ b/interface/src/ui/AddressBarDialog.cpp @@ -33,18 +33,18 @@ void AddressBarDialog::setupUI() { const int ADDRESSBAR_MIN_WIDTH = 200; const int ADDRESSBAR_MAX_WIDTH = 615; - const int ADDRESSBAR_HEIGHT = 54; + const int ADDRESSBAR_HEIGHT = 42; const int ADDRESSBAR_STRETCH = 60; - const int BUTTON_SPACER_SIZE = 10; + const int BUTTON_SPACER_SIZE = 5; const int DEFAULT_SPACER_SIZE = 20; const int ADDRESS_LAYOUT_RIGHT_MARGIN = 10; - const int GO_BUTTON_SIZE = 55; + const int GO_BUTTON_SIZE = 42; const int CLOSE_BUTTON_SIZE = 16; const QString CLOSE_BUTTON_ICON = "styles/close.svg"; - const int DIALOG_HEIGHT = 100; + const int DIALOG_HEIGHT = 62; const int DIALOG_INITIAL_WIDTH = 560; setModal(true); @@ -53,9 +53,11 @@ void AddressBarDialog::setupUI() { QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); setSizePolicy(sizePolicy); setMinimumSize(QSize(DIALOG_INITIAL_WIDTH, DIALOG_HEIGHT)); + setMaximumHeight(DIALOG_HEIGHT); setStyleSheet(DIALOG_STYLESHEET); _verticalLayout = new QVBoxLayout(this); + _verticalLayout->setContentsMargins(0, 0, 0, 0); _addressLayout = new QHBoxLayout(); _addressLayout->setContentsMargins(0, 0, ADDRESS_LAYOUT_RIGHT_MARGIN, 0); @@ -68,6 +70,7 @@ void AddressBarDialog::setupUI() { _addressLayout->addItem(_leftSpacer); _addressLineEdit = new QLineEdit(this); + _addressLineEdit->setAttribute(Qt::WA_MacShowFocusRect, 0); _addressLineEdit->setPlaceholderText(ADDRESSBAR_PLACEHOLDER); QSizePolicy sizePolicyLineEdit(QSizePolicy::Preferred, QSizePolicy::Fixed); sizePolicyLineEdit.setHorizontalStretch(ADDRESSBAR_STRETCH); @@ -117,6 +120,7 @@ void AddressBarDialog::setupUI() { void AddressBarDialog::showEvent(QShowEvent* event) { _goButton->setIcon(QIcon(Application::resourcesPath() + ADDRESSBAR_GO_BUTTON_ICON)); _addressLineEdit->setText(QString()); + _addressLineEdit->setFocus(); FramelessDialog::showEvent(event); } From 0634d15abb45942ed882b4e09e6891ac3eb488a7 Mon Sep 17 00:00:00 2001 From: stojce Date: Thu, 2 Oct 2014 00:49:20 +0200 Subject: [PATCH 006/179] Fix update dialog layout on WIn --- interface/ui/updateDialog.ui | 71 +++++++++++++++++------------------- 1 file changed, 34 insertions(+), 37 deletions(-) diff --git a/interface/ui/updateDialog.ui b/interface/ui/updateDialog.ui index b0f1e63cb9..0e0eb57e56 100644 --- a/interface/ui/updateDialog.ui +++ b/interface/ui/updateDialog.ui @@ -60,10 +60,7 @@ - Arial - 36 - PreferAntialias - false + 20 @@ -77,10 +74,10 @@ - 100 - 110 - 561 - 61 + 50 + 90 + 641 + 141 @@ -103,8 +100,8 @@ 360 240 - 364 - 40 + 374 + 42 @@ -115,15 +112,15 @@ background-color: #333333; - border-width: 0; - border-radius: 9px; - border-radius: 9px; - font-family: Arial; - font-size: 18px; - font-weight: 100; - color: #b7b7b7; - width: 120px; - height: 40px; +border-width: 0; +border-radius: 9px; +border-radius: 9px; +font-family: Arial; +font-size: 18px; +font-weight: 100; +color: #b7b7b7; +width: 120px; +height: 40px; Download @@ -137,15 +134,15 @@ background-color: #333333; - border-width: 0; - border-radius: 9px; - border-radius: 9px; - font-family: Arial; - font-size: 18px; - font-weight: 100; - color: #b7b7b7; - width: 120px; - height: 40px; +border-width: 0; +border-radius: 9px; +border-radius: 9px; +font-family: Arial; +font-size: 18px; +font-weight: 100; +color: #b7b7b7; +width: 120px; +height: 40px; Skip Version @@ -159,15 +156,15 @@ background-color: #333333; - border-width: 0; - border-radius: 9px; - border-radius: 9px; - font-family: Arial; - font-size: 18px; - font-weight: 100; - color: #b7b7b7; - width: 120px; - height: 40px; +border-width: 0; +border-radius: 9px; +border-radius: 9px; +font-family: Arial; +font-size: 18px; +font-weight: 100; +color: #b7b7b7; +width: 120px; +height: 40px; Close From b2229a9a9fd0929d5128d7f0bacc2abfbcaf9eaa Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 2 Oct 2014 12:05:20 -0700 Subject: [PATCH 007/179] Update editModels.js to automatically resize new models to their naturalDimensions --- examples/editModels.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/examples/editModels.js b/examples/editModels.js index 5c426c9fb3..0532d1bc85 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -1211,19 +1211,42 @@ var toolBar = (function () { Overlays.editOverlay(loadFileMenuItem, { visible: active }); } + var RESIZE_INTERVAL = 50; + var RESIZE_TIMEOUT = 20000; + var RESIZE_MAX_CHECKS = RESIZE_TIMEOUT / RESIZE_INTERVAL; function addModel(url) { var position; position = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), SPAWN_DISTANCE)); if (position.x > 0 && position.y > 0 && position.z > 0) { - Entities.addEntity({ + var entityId = Entities.addEntity({ type: "Model", position: position, dimensions: { x: DEFAULT_DIMENSION, y: DEFAULT_DIMENSION, z: DEFAULT_DIMENSION }, modelURL: url }); print("Model added: " + url); + + var checkCount = 0; + function resize() { + var entityProperties = Entities.getEntityProperties(entityId); + var naturalDimensions = entityProperties.naturalDimensions; + + if (naturalDimensions.x == 0 && naturalDimensions.y == 0 && naturalDimensions.z == 0) { + if (checkCount < RESIZE_TIMEOUT / RESIZE_INTERVAL) { + Script.setTimeout(resize, RESIZE_INTERVAL); + } else { + print("Resize failed: timed out waiting for model (" + url + ") to load"); + } + } else { + entityProperties.dimensions = naturalDimensions; + Entities.editEntity(entityId, entityProperties); + } + } + + Script.setTimeout(resize, 50); + } else { print("Can't add model: Model would be out of bounds."); } From d7f383f74a3bf3ff17ce2868b14a2a9ec4f7412a Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 2 Oct 2014 12:10:20 -0700 Subject: [PATCH 008/179] Fix failure case when resizing a new model --- examples/editModels.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/editModels.js b/examples/editModels.js index 0532d1bc85..503e3a6dad 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -1233,6 +1233,8 @@ var toolBar = (function () { var entityProperties = Entities.getEntityProperties(entityId); var naturalDimensions = entityProperties.naturalDimensions; + checkCount++; + if (naturalDimensions.x == 0 && naturalDimensions.y == 0 && naturalDimensions.z == 0) { if (checkCount < RESIZE_TIMEOUT / RESIZE_INTERVAL) { Script.setTimeout(resize, RESIZE_INTERVAL); From 61e38f545e0c2203b18e642102e8f9a3ec266ecf Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 2 Oct 2014 15:38:36 -0700 Subject: [PATCH 009/179] new table type --- domain-server/resources/web/js/settings.js | 82 ++++++++++++++++++++-- 1 file changed, 78 insertions(+), 4 deletions(-) diff --git a/domain-server/resources/web/js/settings.js b/domain-server/resources/web/js/settings.js index 48b3b15e8f..4471efdc66 100644 --- a/domain-server/resources/web/js/settings.js +++ b/domain-server/resources/web/js/settings.js @@ -22,13 +22,77 @@ var viewHelpers = { } if (setting.type === 'checkbox') { - form_group += "" + if (setting.label !== null && typeof(setting.label) !== 'undefined' && setting.label !== "") { + form_group += "" + } form_group += "
" form_group += ""; form_group += "
" + } else if (setting.type === 'table') { + form_group += "
" + form_group += "
" + setting.label + "
" + form_group += "
" + form_group += "

" + setting.help + "

" + form_group += "
" + + form_group += "" + // Column names + form_group += "" + if (setting.number === true) { + form_group += "" + } + form_group += "" + _.each(setting.columns, function(col) { + form_group += "" + }) + if (setting.can_delete === true || setting.can_add === true) { + form_group += "" + } + form_group += "" + + // Rows + var row_num = 1 + _.each(setting_value, function(row, name) { + form_group += "" + if (setting.number === true) { + form_group += "" + } + form_group += "" + _.each(setting.columns, function(col) { + form_group += "" + }) + if (setting.can_delete === true) { + form_group += "" + } else if (setting.can_add === true) { + form_group += "" + } + form_group += "" + row_num++ + }) + + // Entries + if (setting.can_add === true) { + form_group += "" + if (setting.number === true) { + form_group += "" + } + form_group += "" + _.each(setting.columns, function(col) { + form_group += "" + }) + form_group += "" + form_group += "" + } + + form_group += "
#" + setting.key.label + "" + col.label + "
" + row_num + "" + name + "" + if (row.hasOwnProperty(col.name)) { + form_group += row[col.name] + } + form_group += "
" + form_group += "
" } else { input_type = _.has(setting, 'type') ? setting.type : "text" @@ -46,7 +110,7 @@ var viewHelpers = { form_group += "" } else { - form_group += "" } @@ -79,8 +143,18 @@ $(document).ready(function(){ resizeFn(); $(window).resize(resizeFn); }) + + + $('#settings-form').on('click', '.add-row', function(){ + console.log("add-row " + $(this)) + }) - $('#settings-form').on('change', 'input', function(){ + $('#settings-form').on('click', '.del-row', function(){ + console.log("del-row " + $(this)) + }) + + + $('#settings-form').on('change', '.setting-input', function(){ // this input was changed, add the changed data attribute to it $(this).attr('data-changed', true) From a5108375b88dde5238935ac9177e218f7923d3d7 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 2 Oct 2014 15:39:02 -0700 Subject: [PATCH 010/179] Table JSON data --- .../resources/describe-settings.json | 86 +++++++++++++------ 1 file changed, 59 insertions(+), 27 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 24e9a5b63b..fb0989d91f 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -3,45 +3,77 @@ "name": "metaverse", "label": "Metaverse Registration", "settings": [ - { - "name": "access_token", - "label": "Access Token", - "help": "This is an access token generated on the My Tokens page of your High Fidelity account.
Generate a token with the 'domains' scope and paste it here.
This is required to associate this domain-server with a domain in your account." - }, - { - "name": "id", - "label": "Domain ID", - "help": "This is your High Fidelity domain ID. If you do not want your domain to be registered in the High Fidelity metaverse you can leave this blank." - } + ] }, { "name": "security", "label": "Security", "settings": [ - { - "name": "http_username", - "label": "HTTP Username", - "help": "Username used for basic HTTP authentication." - }, - { - "name": "http_password", - "label": "HTTP Password", - "type": "password", - "help": "Password used for basic HTTP authentication. Leave this blank if you do not want to change it.", - "value-hidden": true - } + ] }, { - "name": "audio", - "label": "Audio", - "assignment-types": [0], - "settings": [ + "name": "audio", + "label": "Audio", + "assignment-types": [0], + "settings": [ + { + "name": "zones", + "type": "table", + "label": "Zones", + "help": "In this table you can define a set of zones in which you can specify various audio properties.", + "number": true, + "can_add": true, + "can_delete": true, + "key": { + "label": "Name", + "placeholder": "Zone name" + }, + "columns": [ + { + "name": "x-range", + "label": "X range", + "can_set": true, + "placeholder": "0-16384" + }, + { + "name": "y-range", + "label": "Y range", + "can_set": true, + "placeholder": "0-16384" + }, + { + "name": "z-range", + "label": "Z range", + "can_set": true, + "placeholder": "0-16384" + } + ], + "default": { + "Zone 1": + { + "x-range": "10-82", + "y-range": "36-94", + "z-range": "38-84" + }, + "Zone 2": + { + "x-range": "12-163", + "y-range": "64-134", + "z-range": "27-184" + }, + "Zone 3": + { + "x-range": "463-632", + "y-range": "264-384", + "z-range": "843-937" + } + } + }, { "name": "enable_filter", "type": "checkbox", - "label": "Enable Positional Filter", "help": "positional audio stream uses lowpass filter", "default": true }, From e1581852966e3d0e6ef68540171a09f835ef4267 Mon Sep 17 00:00:00 2001 From: stojce Date: Fri, 3 Oct 2014 13:20:02 +0200 Subject: [PATCH 011/179] layout changes on update dialog --- interface/ui/updateDialog.ui | 56 ++---------------------------------- 1 file changed, 3 insertions(+), 53 deletions(-) diff --git a/interface/ui/updateDialog.ui b/interface/ui/updateDialog.ui index 0e0eb57e56..25d9936b36 100644 --- a/interface/ui/updateDialog.ui +++ b/interface/ui/updateDialog.ui @@ -10,7 +10,7 @@ 0 0 750 - 300 + 243
@@ -22,67 +22,17 @@ background-color: rgb(255, 255, 255); - - - - 0 - 0 - 751 - 71 - - - - Qt::LeftToRight - - - false - - - background-color: rgb(236, 236, 236); - - - QFrame::StyledPanel - - - QFrame::Plain - - - 0 - - - - - 240 - 10 - 271 - 41 - - - - - 20 - - - - color: rgb(51, 51, 51); - - - Update Required - - - 50 - 90 + 20 641 141 - Arial 18 50 false @@ -99,7 +49,7 @@ 360 - 240 + 190 374 42 From f2095dacbd4021c648730ee150e43163c633384d Mon Sep 17 00:00:00 2001 From: stojce Date: Fri, 3 Oct 2014 13:45:26 +0200 Subject: [PATCH 012/179] more dialog fixes --- interface/src/ui/UpdateDialog.cpp | 4 ++-- interface/ui/updateDialog.ui | 15 +++++++++------ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/interface/src/ui/UpdateDialog.cpp b/interface/src/ui/UpdateDialog.cpp index ace022b683..33024586be 100644 --- a/interface/src/ui/UpdateDialog.cpp +++ b/interface/src/ui/UpdateDialog.cpp @@ -23,8 +23,8 @@ UpdateDialog::UpdateDialog(QWidget *parent, const QString& releaseNotes, const Q Ui::Dialog dialogUI; dialogUI.setupUi(this); - QString updateRequired = QString("You are currently running build %1, the latest build released is %2. \ - Please download and install the most recent release to access the latest features and bug fixes.") + QString updateRequired = QString("You are currently running build %1, the latest build released is %2." + "\n\nPlease download and install the most recent release to access the latest features and bug fixes.") .arg(Application::getInstance()->applicationVersion(), latestVersion); setAttribute(Qt::WA_DeleteOnClose); diff --git a/interface/ui/updateDialog.ui b/interface/ui/updateDialog.ui index 25d9936b36..fc375e17c2 100644 --- a/interface/ui/updateDialog.ui +++ b/interface/ui/updateDialog.ui @@ -10,7 +10,7 @@ 0 0 750 - 243 + 213 @@ -28,16 +28,19 @@ 50 20 641 - 141 + 111 - 18 - 50 - false + Arial + -1 + + font-family: Arial; +font-size: 20px; + @@ -49,7 +52,7 @@ 360 - 190 + 160 374 42 From 420326b2128942cecef2cb907d91cb61ac346369 Mon Sep 17 00:00:00 2001 From: stojce Date: Fri, 3 Oct 2014 14:21:05 +0200 Subject: [PATCH 013/179] Layout changes --- interface/src/ui/AddressBarDialog.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/interface/src/ui/AddressBarDialog.cpp b/interface/src/ui/AddressBarDialog.cpp index a1fd8b1b50..e42f92d663 100644 --- a/interface/src/ui/AddressBarDialog.cpp +++ b/interface/src/ui/AddressBarDialog.cpp @@ -27,9 +27,7 @@ void AddressBarDialog::setupUI() { const QString DIALOG_STYLESHEET = "font-family: Helvetica, Arial, sans-serif;"; const QString ADDRESSBAR_PLACEHOLDER = "Go to: domain, @user, #location"; - const QString ADDRESSBAR_STYLESHEET = "padding: 0 10px;"; - const QString ADDRESSBAR_FONT_FAMILY = "Helvetica,Arial,sans-serif"; - const int ADDRESSBAR_FONT_SIZE = 20; + const QString ADDRESSBAR_STYLESHEET = "padding: 10px; font-size: 20px;"; const int ADDRESSBAR_MIN_WIDTH = 200; const int ADDRESSBAR_MAX_WIDTH = 615; @@ -48,7 +46,11 @@ void AddressBarDialog::setupUI() { const int DIALOG_INITIAL_WIDTH = 560; setModal(true); +#ifndef Q_OS_MAC setWindowModality(Qt::ApplicationModal); +#else + setWindowModality(Qt::WindowModal); +#endif QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); setSizePolicy(sizePolicy); @@ -77,8 +79,6 @@ void AddressBarDialog::setupUI() { _addressLineEdit->setSizePolicy(sizePolicyLineEdit); _addressLineEdit->setMinimumSize(QSize(ADDRESSBAR_MIN_WIDTH, ADDRESSBAR_HEIGHT)); _addressLineEdit->setMaximumSize(QSize(ADDRESSBAR_MAX_WIDTH, ADDRESSBAR_HEIGHT)); - QFont font(ADDRESSBAR_FONT_FAMILY, ADDRESSBAR_FONT_SIZE); - _addressLineEdit->setFont(font); _addressLineEdit->setStyleSheet(ADDRESSBAR_STYLESHEET); _addressLayout->addWidget(_addressLineEdit); From 429ddd71159a7392ca3d708578dd142a2699c1d1 Mon Sep 17 00:00:00 2001 From: stojce Date: Fri, 3 Oct 2014 14:30:03 +0200 Subject: [PATCH 014/179] address bar style fix --- interface/src/ui/AddressBarDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/AddressBarDialog.cpp b/interface/src/ui/AddressBarDialog.cpp index e42f92d663..d537872fcd 100644 --- a/interface/src/ui/AddressBarDialog.cpp +++ b/interface/src/ui/AddressBarDialog.cpp @@ -27,7 +27,7 @@ void AddressBarDialog::setupUI() { const QString DIALOG_STYLESHEET = "font-family: Helvetica, Arial, sans-serif;"; const QString ADDRESSBAR_PLACEHOLDER = "Go to: domain, @user, #location"; - const QString ADDRESSBAR_STYLESHEET = "padding: 10px; font-size: 20px;"; + const QString ADDRESSBAR_STYLESHEET = "padding: 5px 10px; font-size: 20px;"; const int ADDRESSBAR_MIN_WIDTH = 200; const int ADDRESSBAR_MAX_WIDTH = 615; From a1d3e3289c9e913b70029a3118a353608f6fc402 Mon Sep 17 00:00:00 2001 From: stojce Date: Fri, 3 Oct 2014 14:51:29 +0200 Subject: [PATCH 015/179] close icon size fix --- interface/src/ui/AddressBarDialog.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/ui/AddressBarDialog.cpp b/interface/src/ui/AddressBarDialog.cpp index d537872fcd..26505af0be 100644 --- a/interface/src/ui/AddressBarDialog.cpp +++ b/interface/src/ui/AddressBarDialog.cpp @@ -108,6 +108,7 @@ void AddressBarDialog::setupUI() { _closeButton->setMaximumSize(QSize(CLOSE_BUTTON_SIZE, CLOSE_BUTTON_SIZE)); QIcon icon(Application::resourcesPath() + CLOSE_BUTTON_ICON); _closeButton->setIcon(icon); + _closeButton->setIconSize(QSize(CLOSE_BUTTON_SIZE, CLOSE_BUTTON_SIZE)); _closeButton->setFlat(true); _addressLayout->addWidget(_closeButton, 0, Qt::AlignRight); From f2d0e539a01beff87b13fc6043e2589e6681bcde Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 3 Oct 2014 11:23:08 -0700 Subject: [PATCH 016/179] remove files for gh-pages that are no longer in use --- images/bg_hr.png | Bin 943 -> 0 bytes images/blacktocat.png | Bin 1428 -> 0 bytes images/body-bg.png | Bin 8859 -> 0 bytes images/highlight-bg.jpg | Bin 34222 -> 0 bytes images/hr.png | Bin 1037 -> 0 bytes images/icon_download.png | Bin 1162 -> 0 bytes images/octocat-icon.png | Bin 1651 -> 0 bytes images/sprite_download.png | Bin 16799 -> 0 bytes images/tar-gz-icon.png | Bin 1671 -> 0 bytes images/zip-icon.png | Bin 1661 -> 0 bytes index.html | 52 ------------------------------------- javascripts/main.js | 1 - javascripts/scale.fix.js | 17 ------------ params.json | 1 - 14 files changed, 71 deletions(-) delete mode 100644 images/bg_hr.png delete mode 100644 images/blacktocat.png delete mode 100644 images/body-bg.png delete mode 100644 images/highlight-bg.jpg delete mode 100644 images/hr.png delete mode 100644 images/icon_download.png delete mode 100644 images/octocat-icon.png delete mode 100644 images/sprite_download.png delete mode 100644 images/tar-gz-icon.png delete mode 100644 images/zip-icon.png delete mode 100644 index.html delete mode 100644 javascripts/main.js delete mode 100644 javascripts/scale.fix.js delete mode 100644 params.json diff --git a/images/bg_hr.png b/images/bg_hr.png deleted file mode 100644 index 7973bd69888c7e10ccad1111d555ceabb7cd99b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 943 zcmaJ=%We}f6tz@@P(=|NB#MM&xrh~+SDxc$lBSsnjl`5{8i{O>>dZLFsP%a8xMW&( zu;L&1hW-Ex*zyZ35P!e|Hi)7kr%B3!;FW!K&bjA4{C02m@!IOWRRF+RcgGC?0M`Hj zcWzt<0FYNtw*Ua^((B88K9mz8C}>4|Kw+1W5e+DbPF{SXbpTdS-0RD}{{)AeX+&YP zoTWgWdNWT+ct|B2&{3Q?=-c}b2*#0vo|S#WPup}H@0<#{f4bWXPY**oLd^!O=Qw96 zqmsa!9VHpg9W>R&NrqKeM{o*}hYq?l)%W*cn+podno$UiiUBL8W)@4;YV{Gc4AamJ zOE;~8S;a*Q8wQ*m)PQvn4RPRhX1PQ(bkJDJ6zlqAGSMbQjf;_P+P1AUEUO@*VIez7 zB*_a&wlP<5X%>n&l`&7CQX~U@EFFaAC9rfMn`E;#g`DX*Np({*R7sb$veftg4`pnD z&SXHZ{Qgro>z$-j4`{}ZMMwiW+)$}f+!mBbE_$3F&AYfa=8|V)p2GHi8TurQ6ZM|r zeIIv|Op+v|UDrW5OSL$TaH(1;m$to*XIlx@v}7DF_u?+qn{lJ1UOaCpS8u?&t_J(ppy#2$?WpTw zZ5!}v@o5q{NT6op{)5dk0Ki7qZT0fcgY%1v=8APN*jjnh`Fj5I`$g;S!;iJ--L2aP YVExC*E}?St2U03%T&bpQYW diff --git a/images/blacktocat.png b/images/blacktocat.png deleted file mode 100644 index 6e264fe57a2e35a2855405ac7d4102c3f6ddcdae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1428 zcmaJ>eNYr-99}%48<0k&n3Tp@mPo+3-M!-uSndwb`;ePBK8_PHgkiZ|V1>Qib{AME z1mhz!%0Y(|CYq)ZqH#FGus{mP8OA^xa3}*!QpCvoVxXERqh|T+59~Md&b;qC&-1*` z?_=IKlM;6MdT;Rt0KnH8XR-qTuvJ=eF8}~y5ch`w0Bjb_X+jEbOpc~o2}N2Zh}IGm;V&S(OP)q`3Q6KR$v1soLV0vC^oI%q)`bMcsT4MX4p zM99}ci>A_SNuZJ8NKman!kvf)0X3)sRYgQbM!pCt5fp(DC5$S=(MU|C#1I5r3P=xX zIU)zMn=DIjaYT*|$`b?@gW=-hVnwk^!Em`S8XX-iX(*N99FY^wm$(F640rKC%L*ov zcXAXfP>c(d6!C1PP|!ipatbuNBJ1Lp%H(8dSj1TvRUlGIi@DOQ&G!FLnqEQkf}LFT zyQVPjC}Bz1PV!74=Opc9PLT8ziy1i*7Z}dLFa^t1Ov+;fhRaL7L~>LSNmw|B1{YGss5QJq7)?=@2(zT8T-(bcmsrEg64&@x zF02Q&u+-T9GtAkIv2pz;hv3hx*a1j93$*m@XL%e!v&vm*AS+7qh zgM*05oT`AEnmo+FcxtjdEguB10c@m40T3{Jk{jOk{Zr*-t-(J1f%DlH+M5a*TSj_= zd!whiW`3|K)$hMFRMgxvNj&J9*2Z58DVR9p`Ch0WK6N%%HgS3O`s@gw_#BXV=VII6 zGmq-XvChG4Zo8d5oqkhqym0VauQ})w;N^RVo-|g}olm|U#v%@Pj8Db%j@rB12VRx$3yGb+`>E!h|z_Yj=e5*dtW#gt ziqkPyykp!&na%#Z_LNL9err>ee^_m`aISfCYt{a$XJ1&C9@v~Q7PW2f#}(hTH-tkzF3VG60%er@;UF~Z_DlqG=H-t>x>ZR(4iZ|-pRC*l!Ns(Lv8n!d`SH$^=?PqJ06LH;_$hV=9>A> z*zz~3TgD%hS}T70+&4Vw%U=)2^*rBkpy6=m#uj5{dE99)-#^kTJOICWbA9_!&@KIw NR&#>My)*0ee*yf36t@5X diff --git a/images/body-bg.png b/images/body-bg.png deleted file mode 100644 index d0618fe749178e814554f19fd158dea90020252d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8859 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 diff --git a/images/octocat-icon.png b/images/octocat-icon.png deleted file mode 100644 index f0ba137d268da4921d9f4b5905bed9e724c45770..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1651 zcmaJ?Yfuwc6y8>)DuuD-ArvUfQbDF>A9*2b5`=_6tU(M>FtlnO8(3ho>+V7Vilt~P zR!5YgpjJc$#^>`CZDOFjaz97HVZkhi(&v_DdJs>*_uc2poPdL9ZKlV@m2^V zZAvIZrbqRRn#dtjidiDPIMrw^&a=kZpm-IiaN#bBp$Og#x~O~yhr5)}5HIfFa3PF9 z;7|&mr-c3ym8nky)ig_hGFT$Aq8J9srEIP>fK}CG*5FmGy|&B<=|9I0;5Cb zp%PREQ?L}14SOj;P#G@9a1_N+GzJ8x>djWtAz)*M$n|<$=iqp=!%FBhO2|bqFiG0* z1c^*6ixsw7ieX7uq9#F-lq41IGMQAX9>Hp8YXL<#_z|q_1y(*PR+t;XJ6uDsWFcYG zvNQz_`Gb?AYmtn~H;lE7u0=X37Eyr;M3{nqO~pvapwSA)=QFMXU%V2+VN*gZ6tB7w z{k9wcUOuMNBp6-2_4D7!@tf;^QlcCCO?Z_>|FmajUW0f1uE2L|dOkc1Ys$*|61!&2 zVxYq7Ea&1 zdEnyHi|t!W`;XO?1&3Yk2(pB<^^m&kO8eU5cY~mH$yo`BAF149E!w`Z_ME0U3^%KM zQyuWWRQCitG@*56)Wa;lou%b7Zv{qdkBa{wqInVIqh8CY>?zHSwuG?dwaEuRJIZHH z8W)y-#aEg9AYow3#!2FnvcS++&Rj1kyL~U>i0tm{PG6|L9}P_-<`#i10bbqFFYUYl zVBU+nyv|l|llqycgMxCv{&)qsELfI33b>{9p&20x_ z)|WH{ZSrrfiJtAyj9h<_ISMCcvA6WG2lntiuYt_e1Tr15{pIf)1 zBkPX)r03aSpB32Ujy41<>H~_9Trq*|KApR8*@{r2;*hp_Z|>lwf~ggU+e8;*Q!g+5 zZSaQfGZl?MN{-kB_fveRz0!M&$wDj)T4Y zgcYhealNOUk%gVD2eld>OECG9f6JGYzbDiav}AirgK04O6tH=KE%eoGNEW^UT~exM JZ{p&zzX3M5X(|8! diff --git a/images/sprite_download.png b/images/sprite_download.png deleted file mode 100644 index f2babd575dc1cbd6e9342cc58ca795377d35afdb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16799 zcmaL9RZtvJw1$fX4Q>Gj*Wm8%5;V95w_r0kgS!WJhu{!`+u#=5gUjFqw;|ZA9K8?s z-2K$OYps7TtM0D)sybRjO#u^~6deu@4pT`{RtpXet_cnfE)EqL4i0W{FZ3D?4vxfK zPT&2ri;cUNInWwT%F4yUno7yZ+}2vl+T6;=ZOmE}4i1sVUR&Q?U-gr)rHd20`9B+W zZzor{e@j%t+tu9C(b}EL!rIo}S&ZhQvxkPt-b#!{k583T)m6sY&R)?MX#Lq&P21Af z(Nf5YMnarQ)LYow$<@i)-JHtX>8mqH*jtR|KXiqiLBjvGIcTW zl5qiAQ}MBLvRQKSb5ikhv2*e83J3_WQgL%~adL2Sb8vC9aR~_Xa0_#CQvKJW5vLLb zTGhu*RuZKc>h0zLE1j9)*M>aAQumyrL~r|4eh_9T!m$T*5>Xm zKy4S7um4>|4LcWi7m%HcE0xS=J}OmnOMB;k_y1w9sw%AH401PjwzO7~6{GQXa%H!- zw-V;&=9cA=6XfRSmF4E*lH(GR;gOQ(krm*Sk&~0<;*|YwUs)GR4<~D9_y6{_`d?q3 z|I_#1DEupju&g!E-qYGj9_Zpk^&cq<+yCFOaQ>fq|K)4-f5*c0fBJHWQ;Bl?YwZ84 z(f_@rB`g2$@_)uwoa%oE-`d$qj0Q*}AufpT2M-4)j;|yurR}}?$KO5`pqF+KJ33LN zRoTSR(uJnPzV`dQ^Gar!K|)gEmGnT6d9P)MeFW%t=gRs`sCk6_mk#^PP_FUYA9=?% zJVuE8h%G`qs+29mWWRZ#I?2{6@z!VQ^g7lyRD(xJ~q zhJkZWqQfQnMTuajpS5fKx>epfFVUXs+d5rjXOBq>*4E)cCGhKuo7Hz+5#xEf>$VYv zTM9RF&fLkOjrByAgAtLyWOE&cX2@Vyppg|RMhPC*q2#E&7NSLUpPwLRP+s3*HtnWp zVu&n2m=#wcA@ha+SHU7ez`&tcI9Jo=1X@Y|$B_0W^sM)AP;4tQ=hM(H>S~V^Kc-XZeOxipcN3I0cZ+sH;8%b)-Ph&%iG_6e8w3hfssO+$AtAoQ zittTaRHy8O8{%vv=sjo9^d0FGP-P+UsX|CvULO7r9Gw~2>RF~*vHL9t(b!|Uxs%d zujQ#u7Bx-a8S#s7q#YgX2;Z@J_r~JauSEH$6(bI*-dzY3ZZ5s z;6M}TZ7j206B*X4?b{y~P5^(e_p~KKkS297X%0~DEVMbkks)#&u9W($=wxI=3mz#x zbS!$p@$^>A|HQ*X&W#o7sdeqdj8_ko|{1D)pXJSP5Sw+azI$%({A8@kVciKYcS>| zd-aZNXb)@4<#h~2_31}LOU!Ath+DFlW&%8;UN;9*EMPP5xX3?qViXo_v@M2IzU)-gtp`T6UsZs@%&!H8r} z!~UE%kE7s{sCjb&QS6k*9n-I8kozJP-PgUPsI6Bgt&zHeDUxk6fglkDs10z)qH%8z zV-i+;r$D~NW9l3KcqXxq=wzFo&Zs9VxjvF0Qm(X=x0$b$v~VP|ey7}>)kTt*emG$; zQ1!v5rI*#LXMN$M+*@rQPWlIFinTND$6+7h8TQdtK2J{4*okY8Q@B6m>2`C2$9_w| zTO?~?1T(D`d9x*W3$>BpSk@nhXtwHzZRHiaLesu|P~%WFgtS+VdeGm^HUs~^pzT1f-{Nvy zQP7&RwnmAU`DyIc*L=^*`HABqv<@OEOoV1u=ThD25eS~9h{cjlVh9f{*N9~8EM1eB zwc5IOw*99Xu@l&EGgsqD(_x>4OY7Y9$tekU{GUuWyXs%m5WeL{Q566_Vhydzx>Ru; ziVkKqemR_H`GFuv7`}jU$73${Iv0QP?+pi{t6o~$yMo7TaYhvQc5LFD(wsRj=Sv5h z<9Sny{Kty```5b`lUxtQ|~mk);8tEl2RKgu4N+qDS%w;EHl!1#pcBF5)i~urTGr)C-%hI#jV@hoAIZg;sL>U5Q|TjuXoYwe;^M* z_7rx)PiUM|y-|uObaoe2NE`Y%p}0gjrP0j8A3h99PUI=wba{Q{9g%K=PrBWlvaIWa~?b)uI>0J zX!afHo9%^?Da)*yF?18_V&%g)n}Q?dDq6&1?SU<2&#dVErR61mZ}ZVj2~8lE_4Jk6)0CxUUK*h=6>SMz6-tPl(OXg zvFCCg*C&Kkz&Huo0=M`KSBs-L3>&J@mCl=&UxNIL*FK(5QGQcvd?NGJe}yytG>2Gr zcJAkp5vb79ck#pjj|^&VO-Zc%GesbFa;rD;G5xk|&_kc&Bi!!ONWg;+Xp)ff-Lnn+ zABLk~$py^qIm;|1n?^jTjP@HOS3$Z1&}7!z{rnfJ#LLA?vCA3aiDk0~+}=M_oW%w| zP7Q551DVl;*^j5{KuLT^Y*OV@jpo-}jXNO{;aIh7lV6>GD4M9AI3eMfaM=FX<43B= zJtNg$4N@}EdQEs$co@DoS}-=x4HA@^_4qtu;++4OeU|_YVJ0?s&MlQ;*m*x#!HMMb zZSew2bTYGv1~xbjPkX!5-v$?rc{KnQO&DG{3jqz3P2^81X64m z=-Vsk3|PIExxDZuTh9x#z0thgFaE$9D)%7&?a`%%k8{UH;5G4F29Z(jySr07hv#N! zm170l`5N14EoS4jw!#dNKwNgV;SO7J6$O@}_QPKgFY-g+D(V(GnD%HQ=B~VBv=Wnh zF$SEW%z*;5&8XJ|&GxN_o81u9c(>6W*efOt^vQNd2HA-%`QuEM4F<0H|5$H7WfsIj zP@y`E;hL&X3!{?D8^-i5I3m1IvdEKV#0(-FFI;ZMUSu_=)hs7}zg*7Wf9!rdifp1G zt5)lYhl9c}JrZ2lC$BUYe7T?7=3fz4Pq2TRk8iw#h0L#1$R{JsnJT zl~rk+Y5-X^t-L8%J1=I*nOU16%waV>Xj3URBV(Inpa9-%Ry2iMAr_IXwEO_ufECv2#>+_2%KKq zhXDaT5*266;49%S4&?Z6ne*uw+I$SbTvkCBQwDZ{{qll075kExkYft0GwJoDcii?u z=W+5o2KC@S*O#^cD1{$f>ZR0kr@xQ>lr5f*Ntf8U>%;Uhp+NjW( z=F!@=0ENbaQ#W@?m0Qbh---k1{@K-ox7jmhOXzZ~sDFyku|c3qz;(k#R+j&$sql9S zubKtm1WofgiCa^h#t+r}$83*-tom0_@53%G#Q#$4eBx$O>5v+-#U1I%zmq-46IqiZ zAZctlOFEJ@k7YC8M=-|l^?J4}@J6!{7KU+F_&f4G!g}c#!eQgPfN}DhZhl;JWIJFc z3fyb3(rRxDT6JnwY_8jxxN}Mpgt7}xQ!BRarN2#>T9%<<(zK_>N^aPu33u?f3i|whyR#J?lqO`W!d-h2JmEi4mja#RXm2@ zf4>Kit|B$$jh!|Y8fgF3FGL8$3#ffh3>r5DB2}U|=!(FzvbhsX=C$BfO}81e?|`e* z&Dk682&@|(03<34?QZRRnK}Xudn>fy$U(26zp7J$vT1DbZL7w5S{VN9Jfw`7Pyk!|6E&Yh%&vHgzU&_Rt~po)i+zt5W( z=_gCV-;t?2GiL}D@-+$U%k93%=F2VBMp}klxWX)exsyGuUk0B8bRK8yo`c23=8@?A ztBwdx_ylu?zyBgn?p0>d=Yf-14yUm!LrQPh)No}&mtRk;u~kD&{!m)Lw|BVjq?C}^ zV$*#a>v!Ee8&wxSTb2LeGM9WugbtEtGharsm!z&A>x)MEGMyQx4J&`)u6hsR7Wpi9 zIHoaUD=QWvM$4!!JfeFieZfo8jd*r)QiGWr$;|{8b{w?m3oMLOiFt)u; z_cBPCM9T2p+#jE)O{Rob=J+HHx*9W)qO7WB9ln8TEtaR~?EvElGC9zu#C)Y z)n+HIjZTu1uOg2h(BiL#Vk{i`iPk0lG7ldj&M0=CZo&CNG$u@5Z+~*Pxx!)VcGP%K zht{6O>rBP=!mI)NavjHq>3ys_2V`g}&C>{Q``G)9S4FEX*YF$h32MwFE(Fx)wZ!qW zLPN-R!^;`j>MR{S-F?FjB6sF%-|qNDWlB0g`Qy^4*GGI{)S3>766x~xt4@~m*jir{ z30ruwfum1$HkPlDD3^i-2|kh6N3J+rh|F$|5cuU+dd+-_cy{BSN4!j{O0PrVF9YTj zy}cmq+UOFE@-8CEZ<47&S6ed=FatyrsPNno>TwBo+^2_+)^YUFN=B3C=w%F%EVSUr0b=cK-Ek#Bo~Vox1xAOo+-K^mUg%{ui{f7%zL5@N3IcBKws*$Oa819W zl0w;|Wq~Y8cDZY*f|~h)t#iGO00kIUyi2)34Lu>A2BTfqX#06kXm4C$Boy0de=uV` z3_FuoxO9ynW?aRSH!pFp#8|8-+{s$FgaN%dcm_GMzHM9ZQo|#^yim7^)zfp57CJ?L z^`X63*uImm-%Al}^5xxG;#W9w!==JYc06|Bs+zA^XJzf_rFM(%q8*ge*xQ<{=#s81 zd5pgl1@wCzmu>-2Gk};9!~7 zoXx}who6Aev~jTAe90-Uin@rB`d71Yr|%2>QpmKoms$#?Pxg=S*{BQP`s^pg#_xP@ zOo#HBdQ?NjpK{zo^D>uq4C3%3FwcMc2x??d?1->JoO0N4CYCGQQ;J8!kiBhPiLOMA zgrH9CRW^EG$JDN)KHKGy5*Gof>AiTABp4>`ls>FFSlfH3Tm&t=@zRu>t^ra|Wp}^M zpU!lbB(8UyhEnW^5QEn!%=YHmMni^rPgyZoy?EeypYIKfV81Ela?ufjHkoWfc z2wj_Z1DN-m>Vtf^{sAyxsuWe`>8SESpKwf;mPOISs@y(Iiq zpLWQIfX7M{%gqc;@)fb%vNz^!vD7_P( zIm+=+j3TMo>p+=de6iD?&E!0dJ;#?A1R}CiPQ;ZoDATqIFs$H<>+=(RD}UcqjmF+KIaIF3g8N-GYL4i|z4 zo3P8}!nNF4#yS?WS~ZQs_(^s|kRWa)i2TZibPRXDH@ZRe|q>l=oXgH+-49Vn4y(%LCWQ*(UFE1D?KDTm<8tF`EoDLL@XEa5T zF}7HIxuN?J6Mi2y)?KxOfS8%X+3zI?W=ZHcVQdEUgO03P?1wCBbz2IX39+(A7k~s- z^p8@K_1sKN8kGbd)Wn|y6EqH@44JLRu*ZK}6FBC)-)~vPCeK@%K;0_3nlyF@J}v?7 zZFcXqyk6_VSUb{$9j<-SW;Nf@wVPWh@}}aEaNCqdEsDP5HeyQ^ndf-O;agwNApWDjaZdjQqH1>(wx;8oh z@t27XFv2mK7hKpjEdZ!GzZ14YyQ+&vI!a2hLCB7$JHz85VJka!bDB(%@c3D0Ab*-a)!lbR4 z5~14zfS*nLI5&9KYw5_(mDHjFfBmI2i9?ZYP-6_umV}a5LSNt z>XWm&ksK!)f?~6bYrDM@w?ZAwVpdVJA3NYCQ-N|C-g!HRJB}Ud$fwn?6`72@^cb_b zMtt$Bc#b{@zHjIyj()6CJ)d)VWfkdwT`SQP>|AZ10<9xB(Q6e&7q|?P(`>NJ3?wZo zo2sbhm!sW&SZ_4VAUaeFG&$UhuCX=|C{ph^iQFUDn(l1AIoniTf7#D|I}$2?xL6>CJnocE;SUF zcH6Mqw>JiHXyF{6;=)$XL?&^7;jC&WKF2`V%&%T_j?oAjf*bK_ zu=;9M1yi~Le0=QfeWpqP9PD>U%L(kT*Fk05r`(%>wJx%Le`l$UV(LCQmkFon?}14r z-~G}0p_3JOmlF z@IeCXk@FZEcoJZGQ&d~1u;pla+I}DTN>cauOZTRq!~LoOkfVe|r@Xh$v|q}&cSg3s zx4iz&>21IJK&FRDLa54<1D4Ij(J`DS=yTL&9f<~w-7IXHud?{?lJUjhFp!Z&IoCmi z-VN??N;$LwOXuydDy*fId@D)GCP+hMo%jNa6_$j|q>gUXr4v*@UE^9{v>DRg6ZdJp?0`C*yKLiDTC#lDGXcua+Mhn!b zPg?jqIa>PNqr%{5=4Y4`lc6W;0DrK!uMvik@R5qZob*No-7Y2DyOg z$;N-p59joF^AOqODbQrj=_2qM>>>fy|b?zEzPZ|B} zNh3&##g3*Geu>pt{nqTIggwdhF?2&}*(5OpN7+90js|`7MSLN39G4})?s0>wxAivn z)h9iV*XbPmc~T9$P*5w}=Z2<=bZ!VuB+2?^eB>n>XizlXbA=28c_*4ml*V#=U-R@$ z?$!<&eyJE2uo_mWU1^kh@03xk^F4L;qXC}+w5>=oW{y?>v35wpII zrH$Dvq-K3$5$p8RY3tV>0-_d=WnYi3LJHLm&jn!ySPXP}%8i)>I8JQp?tfbGOiZU6Sp!$ z65d%iwA4Mw(fv~jrb)&co5>vl<7nC!{hoW{qF9+udL1b7)14No7;LqhI&va%i8j(n zXWg*_uwndH<;h8lR^{{9I{dDoerkpILCad&1EF&Vl(-}61Njj~_j8Y@hfvdxYSh(7 zO96s)^2Icx);~-5;Q)%Pjg;>>>x*01XFN6sXtRE3lq44`9KKr`fM*3f>RERCj(-}l+Jcn2*%D}Hj3|H zYJU_q$gFVt;`(Eh$HK(qOA+yARQ|-z1wSEV_Jt$7MJ`vqX;{F^d7XJAzUMx|LzgVL z0_zK0n6blY1~a#DhpO1aTXmrD7fhGkUcKiFZit&)wEt5NGkAW`N2r4&1~HwBsikv> z(pKpsfMuv8y|7;@1MSdQZx3;JLw6P3(okz!Pdvq2t~g@LrRUJI@c?l{tA4G;U6NQk z+4}c{+0737a<+JLwP|6@wO-+tD&o!WE@%*sA#Z}-ZDV@&ih^yHVNxZZ&@aH?KI4P{ z#ILo33ilzq2|KH?&eUlsuW1`bW&$MTY z3$D6@^&TMv-uNu zmL2;%eY^RfhfUTv709D(R$JM9*2~|aJjAHC*JabuJ&?72>G(V&YpJj0CPlv6SXd|* z#qMu(sLQFwGBN9CEtEmxJ4i!*f38Lsxe_obrcMy^Xc5@&K z8IyBWZ?HzU!=7v1vj`njFeynJ`+~BQBpuaui zN_j~c!{}#&gL1V5okd{BEZfO$^junDn;%=|$Vl<;gBLIxKBr(V@BVT*^p(!oprr+) z^a`ln8zqv-zemv(a)_UBYNN3Blpl1n2zc7anQ*h+#Oj!nZ_`|#M?1dFK<}AwOK;4E zFgh28x3ufi;6^EN#3rz~+)klcEELk0CXyleMadmfiqx6;k?M8Vmk)Cc1RIxV&=nL+%2(BZs_xjEL>MSKDm7oS93 z5NwOoZL3VH!f0?Up5``2RWiegEbY*gZfkxguIf8qZFKHGeLxF(h%QrY&F9>XG;P7s zE0+yl#q|jpmWxh&wkcS-TI=DfRtx<29Dwjj**H(Zl(!>M5?u}rC`lg38n7`^Ph*Jv+qN!Rfs$lLdEi9k$5;%JO&B7MJ=Fe0FPsS3A+;&QT^6N}@UE&OS|bWQ%e zd7(mF4_sE1^Yk*uHRPGo{s>xL>|-R>HK-3 zShP3SEFUxQjt2i_KEdeFXA<9Ko&IDig?9HN{N|uMB94bJ*h4lR*}PnKg1hjiIX>`s z!VNM(ut}#E^}{ABOy?;9x8y?&@MQM;zB2$RT37&!lDDg&30XN(8LQUqm>1rkJ)Gyk zb_5r6jwYngJb>?R4BfSGmZcba#LqQPt)@2UPY`o6DgZfT!7m z1RS8yREa?%qYf2+>&TfT2)g-UBme!=$l8h=v*EX@-10g&A=KPC)p_;jz9)%OBatF_ z;nN-GpH4-40r!HLs-v2mc$*H~@$orRu z&c|_gOkP0XfEv8Ul zTgFcV4b=_Hq?S|)yW4Rg&>WP^p_GFP?6D$RWcPu$d{fJ%P2)Btc0peFydTRIGezqj zxPEzwv>59wdLIUjqeG(FcBZ-H7p`!9brU%LLJeP=2l8nHt8km>&h_E_)(bHEYMarx zP)Ek!Nwtbmw}M5;-+t+QdxXnB*ZhnsgC{Aj(4T+=iDHSkBJwVF2AGGOdw0j+Za_L3~B{Mm!=udZbqf zwRI;bwRhN>zk4-=>1~EVBPd@lBLgwdrkKL=C=nNFmjOQVW@X9K!JH2HL5v)2+aVeC z#_iY2PzNS}CYbgxyAfs@_;N@2Y2D)PQ-!}eor{XNUP$^NfMrk=ex#UQCEXaV*O?0L zDoxa=*>KYDzM}vQjFA7D_%`legYc%XJ#Z)og+hsIjatvias*s9nQviVDdMxf!DplC zgq;@7;vnL3rA-14-(e83MnL-;8XE3yf-d+THoUgP;G;pT2{j0(%AZbUjwU@A(1}@1 zI^2bVfat-WB>UkA3d-~nJ3(k)5ezzqv4?5eh}j3$cb?|%0m3?Q1CKN(#+r%T-$M^# zAbHqdkodc@xzHvo__l%9v%|!%tsl;tDImV14_xO*~ zyhEzEFxMYbO^Jc)DaaENv@`B_6+ZdZ%a6-f`{NlBD4Ux*PrL`whQPzG`I6~_xttaW znMH&cQ{=n8xjgEBLFkuawWjs;VyiG|Kg%Ev-O)Ca?HqC$>8bEeeskeKdd+1P?RZ5f zz&qcyAB`~|d_9%{&r~hgy3JDnp~azR?7Qe@*F(s4m)d2$G(^O@PUe{sgl33%{_%#Z zQ@5Oe8~j7w6EHo>n!btQ5FK&m#JRBQ8H-k$ zpoPrIN1<-5Id`5R_Y$j^PI3!aVrL`}B=ia0Wa{xS2sp2M-yfG3yebid!f=rCP4H0C z1q?SPWM&7*XJZ&b!zj{McZ!oKQ0r-Djs##a54-ZX&7o(Olt%%#Mjh#=#dzLd@$;*_ zk*DqikKEZ>M%D)3$c5dHZX{rR*y1PfF5D&(7~a@XBI@22;tva-)n9mT&BN*wE{Nf_ z5__kyxQo^3rAFXGIW4BZ<8n)NCQs$ADa~M;8#3j8uzsC6!S}ncqi0QfRZNOSU~bAvtlqtkcLtYQb* zq;^NbAZ_qrC>*_WKT0mLERg5CyzKS5FKIVff)R@qlSv#O6At>F&3luyQDn4PaS#yw zMdc$6YL7ZfUk1p6Gu`(R6E}7txF8JHA_jr7b{M2kBzEjpouavMgjr7Ki%Eo&ZD3=r zy%l-0C>KhLQB_N(#2r2{7Lr?{ZZeoATF2j{a zOo+e(a>H^5sP;I&kZgw_iG)U?be%PvF&WENfuL{~#T%VoZvepq#2NMo#j7W#y?2F& zvTCP8Ze{mgVE7)z=tg_^1Oi() zMFbCt*|A|$i;$ZNGzLTjR;Nh^@l1}4ua&%hD+()UAg_0E-s<$a*xCZ$Ol~1stWCck zltn@wRTX&W`(RL>=eb&d2q8|qJd3>ujk;iKUB70dIv2aV8JH+Zy|E%=dqlPEhdmw^ zyv@qR5}8DO)ioX3vnPqlUr74k!I*>i=`1fWC}uW1`S2PXV^Xc~`k3}0^F zoJP`aq9E#<*hUI|GLiYf={F<0b6$rO%zMEPk%t)3#3-fahzoJHiI?P9W}H|8TrOH4 zO-jswT9~BvGx4wi*Xs08c`B6=Unb*mTOmqLusTg_XOZ9t^#hg|?=%zi#k#IJA7Zzj z*g2l60lt!`?ELA+&bdDbW(%^;LVmXS`j0{M3sJ8ZBks!>)gk=-j89rn94Y0GZj0Xm zZtM95F4CH?TbJ@omMFDJtrSYnw^WRT000z=G$Z0JGCa!7VASJ(uzHKjHQit*6pJhF zKPfc;5~Mzll>TfVV3(g6=4*mMnnj~2xx^7jl_g4RqCnk>NnDSF9>_G+UW#APDu>PC zA(5qAx$kaw{&B^H-L&jMh8A_OCWHr+GxU!io4F@N0Gnl)6{gl*oa!WYRFnKh$&@(T zGn4ALD=)%Bei*n$s23PrhF|M=A@ zi9CfCOH)?@O(3!JdMb~?IPSM}ZsKt1N{(>F{lak5b`AqmO1v^)gkG7ha%*~aZuM<& zs|;WQ(V1BnY!z2%_z!8c8l-J+xn!y4?7q%LeWQtkJ6NjQ>~G4XPo2Kgf6yGO8Ah^4L?SC zY~{Nf>c<3LoHp;|h=e_90{%2K;ni;5*0gkl%6)x}o;L4$q?sE1vi@a>16uH5*u@`C z7G33P!4`b$%4-tpv zsU8b`i-R)Um%@n84`}v8{=p+2^_gL&Q>9b?bQFV<@M+~^<+lW=bVr02Qi0HV&|egr z3V*D=aP4Nzo%9JQ`LPzr$K9H|e_|!14?c)67Bh^gmY&#Pw?>QMuu>-zbPRPhW>cMH!}Mr|J26;d|LVO)VK&e4qZlEP8AX8Gm1tI4{`E&Hm%L96T}!FQBu`b_ z`LHcVv<4d*Lu!tsN<^vY$2(Ch?&W!_gRBL%<|c&>igt{B3cs|Hv2-(?jx%|fxHC93 z;K&#^spU0G`=HtS*!#2c;LLp|h=To};5I9Nd1Y+z~}bTr3Riq7=o> zl*l=pIs1lQ4)|BCRz%p;%6Ra2oMD%yGSeZp>UxOLG8heec>|XGSVc#qT55k@rQu3V zFucDW8f(awS{-g*W~!_baVZPH0tkKs2)kDp6iH+(B;Z11pljmZmtS}WIsbN?1@Sa7 zamj%&aEXg@VxrW>$Onnt9oo^eDV8|?%9&fnBZiA28t$qwWtXuX?V*WvsUiWQgoMB_ zSCC}J2I|(%)fucgyh?dlKr1RhYa7|~qxdn`DuOcPPvk#VEW+S$qb+xA^ggX6xsLpp zeJ*Gzd6UoVW3&uf?!n32d(!xuokn&uNEcK^Pe(_NZ9&8?&@=2p1J=@jeECD(e5wn; z)@HAu618(qSjUm1xCe-+adhq)-Ip?4N@Er8x8)MZE&ZJ=g^(4@Kx zFbZ_$=tibN@ex^6C1%>epi3@)X+kQ%D8OrdGxeV66SVA9YP-iL5&Vbm2CYUfON*NPzvMYlcTWz&p(2YiaGlA zA0#^>j9?UHO8OBAn?w(AaDQO|4;{0W9MxnivrLI$vrpDw-Ek(jn=uqXji_LRRr-$B zsv--&;OBEyefa=1C*fZrLL}i#e`gTXt>ewviAoir+pfg%Ev5P8tU!q>-8vn7B~i3I zg=T4h0OFFNF3oa}$4IV4G*H zCbUoR^g2xDBI*EhSieWz&Y7m~>#-uZj!d(zDt(gUL28;{hWNx!obTpF1f}}?Tm|}P zUDnka%$xFklX2W@d&{Wjzam3#p2R@`9$5x+;N7s8Jt{xFMvyrRI>3I3o=7cGVFh2z z$Wx~~o>{#{SIB7J<+<~*|APGlId_eoh;=z<8*>%u6fR$b=y7!oVA&ptZ+@43D3grh zS7=Wgh}fbth&3%h*#n}+Z@jC3JSjn*8z9{X`c~CoF>ScZsFjUmso_f+)^s+ZPy>g}lUvCbIA}N@|3x~qS^(UhOBD)VR zcLr_}IK(MO_QWoH68)D7UT@3q{lEv!jvGYLe)oSGwn_{`&WwHb)9#;)T)G!)OuJW2 zpAH0i+GU^ho38Ha1G}9tRQ}M^xl43mb0_F^pXe|%^}OEIPfiEiH!_2(m1S?uKBM-2 zk@lGKGDuz{3F~h%ewbV50@{olI%*j^n47g1erC7sAIvM4csV|i(JFHN+w&Y38WS2i zQl(QpVYGQobo2Vq)3bp6OXYsL*DHmb?ng))4P*tp8+(GRrX_sobJ1~Hw@Y%>_H^EP zX4{3u*n5ArcIHLOKlcNCS8Zm3!)Y4YQ|{P+38o~)f0nQ{2ACz9jA;Kk+tk~a><#v7 z+6MyLUqa=hfRql$G3W-JK%7UQccsj=G@W4>x)1^u@(VJ`dw992;4SF(uc!|w53y#? z#Xe&yrWSXq0ApU7S=R+w`twrw! zEs;X9_Go;4_q}0f+UTO*ztHf+$fKx%&Z)*gyza|z4%Q!Ue{3Zj+1vM$rBBQyzR6g2 zE~pP?paMo@*J4NB_z86?Bd}|{RYX%B-+|reQBrkv?b?xmKmO_fGkgh%hkp7d>KeZ@ z!*vzCA_d6q5|};y(u-TeEBhJ*L_{5;Y`ID)crN8Ebp4W4SQa}*OekA32d|y*9391h zN3}}O>3R0^!4Lv&C*>MMjD8$9dj%#^j|g2jwQlI*@Z<8DCax6hsrH{93rPH(O^msa zffZ+Q$6?i)9+7>#U)?q$zdS>$pf#kYQcDdbIK^6&!_fJGO&@_zO~uHdfoq4<{wqEV z#i@Y`&CDo99e{LdkBxILegJcT$6Cm^@?L7px1JKcnV@J6dTLKnQl!=LHAR&OV7ox9 z@~-#WIE}d<_16#PsIuW<(CGg{l@_{A4>YF_lr*5#XBZuwq;4j~`bmZUAQu@^IZFTZ zbDgDiVpfs*Tat)gnU3=AVt*(1Q+ydZT~SvijvFNlSg2^%Huu(!s+d3qLB=wn8oemG zmoZaUQcHF40WZb<(Xp-_S+C?)+bB(*`qR1^Vfr09R&rwkpUjizH^tPk17p5#xzfn0 zP41&r7F)?V*J-m_NKl{SvJ4_!kxJ4c0HRM~6`wbl^QF-S;*d-dRDlWQt$iHU6Pclv z9ejp7bWgVopk*&_&G2t5WFk7TQTxx?#ZpP7R0ZG1d;%uJijlM(fT@?Y*u_wDU^2m3 zu6LW@LKVzz$H>&c6fbRo-kO{@U!`}5$Ka9|b?f!MRmE9wAzE`0^(=$2M&+(wMo)Rf2zo?Sb*B4@s>Jr;5LcwnVV+&XMsxu{XeSQ`+w$DEs4$?$G7!-Z*J z2;Xa-&9tj+Z%FVk7gWQMm7pGQosx#6`l`QsKDu(zbu*QmFw%;9A53Ua(NJJ+2i3cY z=a85oj1Fr99ZvNt%Ft$>&KUmvNElgk`fYqyY~~By+uNb|Lpuc-(v@rml`73Aq3wp? z)A}CqFc)TYzI)DufU@2g3nnY~%R4J=SlE3EG#_P3Rd9LRmt*T(@;fImkektvP9I(R zvY&-Oai*$A?}Me7b&a4Vw0HYUlI@<~)>Hn*QSwD18-uuy5Hj0>zSa7q0L1P?N<#!v z1Tv{O2QFn5;*lwB&t(iD%Yt3;AohjVhQ~6Yyuc<@#q4i#wmI=!ZS|$KDb^wzvp_>p z?N5!C?InW`_WDSdC znLJS4BjNFjgHgm-E)uCL-L_ZvsmZ_u$=Xkah~OI8)PAk6)J1eEFh?ix}|nd%@Dq>Ozn0R z)<;Z_^BA%}oFBRyTPLVZ{|$|*{J{J^#|6^rzYQ7)-a z5yR-aByh%OA@&r~Z#2^=fC@R(3HQ!{kuQBM>=v@K)k4ajW3bi|CLS<^)bB+ZCe&-K zvE}9EIXO5O5kiBMZd3ao9L=7xedcpEtOmehay>73Vlq#YH|@{#(>TkDhxA&tpMhoSn6vp$W5NE|G*PG?&>#w0WBe(EJVo4 zkKnX8Oy!eS3YDU(>`$3j9jary4E_nHMsqVe>p{J{osw6zU8VHX-S6G6X*Q5}QRH}V zlw`G<)hkOPl;4d4(3d=sX>!~Tq&_RovaJR%@5W99-~OQub3unO46yg@VhHgRG>U|Z zOHxFXVd7fHnHetfK3xhgOyk%g#6wEN#7kXtNZ$e77#BsLSyn%RqRZIL`;R(8kkz_c zSzf@`@8zCg{tp5O)iHd#eB`|km#AC8m#QR?syw_H0z58g;%r&dJh2SP;f@Z)STZ}w zF0!a((29|$vGOnRXqhY>hSQR<@B-tnZj?2wfT;{>w~*QNo$(2-fbI$8y_En+_sjds z3GIt8xet~hZ?v@FCn!e2!xO#!F(gpr=+ zyUyH@pVH^9vc)wRJX0Z39ma z7d=y*Ny0H$wUuPvCQp#3^G^HYxiYU_&@=olhLij%Lpt}(Hw9$AJnaMB8>iK_^NFjn z2X8iC@0obUEBa>njRZ zG#AnKUw;Wyf&Qj5666tqi^Ir-u-X1CMw;ReFZl@5n915W9#s_ppP>uPj0lP~X8Eh9 zFs{}^R7&nHRf&HnP(PQH`b`|Z{xKN@?^|^=U9_*C)SCho5&o4@pdyR^Q(f9YnyyWj zwU^TE8+XG2dhi3SO|;K5!RO@!Wc*{J-orNxPB_9m?%$^KM>79@nV=-6CR-={CFK7B D;4+a2 diff --git a/images/tar-gz-icon.png b/images/tar-gz-icon.png deleted file mode 100644 index d50f34f6de9f468bc2c832ca126273ae53332976..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1671 zcmaJ?X;2eq7+#?TwWW%vD5biybi9!45jMz5NOM7AO{4)a#Zk$zK)^lRED+FXE2s>E zRutr{qV0H<%L~woP!CX4L>OBwSgBQ{B8~;A2Z(fnp#7nJe|_`K^E~hKKJ$L_rH5#P zUB-Ki2LQlDty1U!0GJ5?fcsb{0015jW`_X)Fr8QG`A{Z`Pc(2OAT={a5>!)$Xi`TS z%t>n+$N&IvTw)2+^LouHVQ7mAu0Evw?nBqttG?LL4S`0lpSqp&{vlv>2 zYY+`9Cu1zCWR46?)`ppq<4pc$ND>GJ*a#cNQY3ExZPaSoO4!8Eur5Jc3Hvn+fx{3! zP7J*=rPqXja)u*8Tp;u@At(xpL;}U}WNXF$9f{K(Vi7Y3oQ#CWeA-1{OvIh<&72vr?=^^Z!tadX2X7I`WO* zw+dUsl2{Vfkya+2Gm$zn%FEu0CFC4w;2AEAVOEc(7!t$qj5UT~L3yYMoP!Dl$Z&Xw z5WxkMz!$|wvJ}DyPGBg3AOwQU1;IHQgULeMxpRlbH5x)qTX_R*BGn2pWTRMt#bPF; zLL9^WFw_r|`=Y24l_{h`rP3Go!{j*b8zdj)Di~8dMbi8z*ZhWyy_0L-8+&$yg5)d- zq&bLVC~!C*!txd`B4h!M$QLO6Fq!P_US4s{@AiVc(+eC32Eg_$_|I01Ug;D;_T%dv z4+P)55|TEHAr6uR#wX-o1ptRDYK1h+)>;zYxWw&?iA7IugfDWLoQ{IZvuP7uQ@I|8 zNfq0?$GvpqGTEo8S;=R%p7Tm~rnyOXPG_O$0q2g-s%>Mkw#RIqH6AamTwZnZ&gBPm zX&>cI&Cb8vmUOhXy)ggjtupn?eA_*ccX^{7p9z?pO<9m;97T^u`h26HEu`R+WKpP zp=;Xg^>>wYrmBM+bnnSnrXR~yk-00sE>`n{AA9P*at@kRzN?C^{(Fnqsd+jkoH^sz zU;89k+T07DbQRw@+9tMm89z0C5Sx?GQYXoG&fe*#53b+fa81*C>cLWCV+wO`@wx<~ zgNP}Q?F>d%c$B9{ty)DkWi%`b)K*S-ZiDvRJ5t~sH(7WHELhYezq-4mv#_q@$*EqK z>ygVEZn{Y_XSCkv>`C*GOj$eB`@5U#G~WI0+ABL(Y#SKpOgDdI-J7R|qS^u1Xve^V zKXyxlHM!5@q2uW%TArzX>)B-;{2Yon)%~6S%iw!E6$v|3zc{DVuiV`E_(eqTx}NS0 zOPd_A^S{nQLM7fWoTYOLy^A+@w%v!b;Fe<(RbJmNe-cah76Psr4($xyHM_-9QN3_n zPw$z%aX;wyx1~yF-m3kl>!Q$8-WS|ad;UiM)S6WhdF_tz*^Q45NjEXMe1)>NNOrE` md+p82SbS+7)->?`;M7QfaY|^cnNoD${xztTT1A;GGUZ=slZcG~ diff --git a/images/zip-icon.png b/images/zip-icon.png deleted file mode 100644 index 162c425b432d8a80f54372594bbbb5ffba52b7b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1661 zcmaJ?X;2eq7+#e_smdT;;K90%2xyYsT#$u8bAUt%azqG4k&xZMikpp_g#@8mVbpqo zj*16r(W-z4h(Hw_r7BRVXdUW-5zt~QXf4IIrUgx>69ny#()ZUl-#pLrKJPQ{H{X`1 z$VC%eJY4_)n4k!k#{dA}1pvUbu}%O0{BGN$0sz2+2~{((l#VfJXdIAWR0<9%NKGmp zgKMy?HO+Vs0E}5msML&F8G&jklC800*k;lI*efW+Y|v=aaRyAmQwhBo`t?#h1QM7S ziWewhr9p>6Ayi^g;;W0s!Lm|1$`++hVd zZq(9*fgvb8XjjyvP#KIEf`&&R4ew?3#-W(B6v;7b3><_F+edmgD``+F{~t<{@6kpk z2LIsqKZT8|ECbGo!HrY~t;J(--CTPs11h6&4MWi?idsFKVpJN%P{uUM0Lo&8pbx@h z!-L_$JXpXc*?dGWlqHV?3s5eC!Y~TMz98tM)MyF4o$EU&u2iB5y^+!AwYWkqhRmda zO%NC=gaZVyEI{VZl}ZsL6p_j$ywFg-z@IA<2>4;LVXmCgW{|j^8RlXixbhLX_Pw!Z zhstr9$i%TQnj*o$d{AO!FOm`UhPc?sUZf*(Il*8M$G!#s+KS<;7ukp|Yw_%cZTsTFC2o!+ROWq2pSiNTBO;|Pu;{F} zYfuaJtfTvYDfs&R@-%QwRG+8Mxwz89@ij|biSHykvU4Ao()vb+khH1y7tBod%g|Z7 zHXLn^?Jd5QlhpsJxwckeO04X&c9c9=+Svva%mJ1c&OtU+VrX{6l*tn}i^p%2E|#={ ztk&_uk`}kt%Vn=t`xN%XI)*}St_0w>(}~#So%~rXYqY~6_q^*w^}?RJhxp;!_`d)~ zrM2LX)JU)Xvon$pdV?vuzaj&5etT}>$=gSDxBG6Xo_W0H^^51>cdFBA<^Z;e-#9(q zDPgOJ@7~1*CPjK!Z1Fu>^f0gX>FxBotG8Ay^HBLr4kGKyWhd0Cifq1Lp?g+wR>zEh zt@ZNiBVKiaqQyx!h{yzX_eT4{Bc`x2XjDdMRj0#}dnVr@D;#O7LiAQ;I zFY(2ybvBR4IRmF#>%aN2Nw`kEBFW;sqT#-4+vL#PBeu-E - - - - - Hifi by highfidelity - - - - - - - -
-
-

Hifi

-

Open, decentralized virtual worlds using sensors to control avatars and dynamically assigned devices as servers. San Francisco based startup, we are hiring: http://highfidelity.io/jobs You can also contribute by doing jobs listed at http://worklist.net -

- -

View the Project on GitHub highfidelity/hifi

- - - -
-
-

-Avatar Documentation

- - -
- -
- - - - \ No newline at end of file diff --git a/javascripts/main.js b/javascripts/main.js deleted file mode 100644 index d8135d37b1..0000000000 --- a/javascripts/main.js +++ /dev/null @@ -1 +0,0 @@ -console.log('This would be the main JS file.'); diff --git a/javascripts/scale.fix.js b/javascripts/scale.fix.js deleted file mode 100644 index 87a40ca716..0000000000 --- a/javascripts/scale.fix.js +++ /dev/null @@ -1,17 +0,0 @@ -var metas = document.getElementsByTagName('meta'); -var i; -if (navigator.userAgent.match(/iPhone/i)) { - for (i=0; i Date: Fri, 3 Oct 2014 11:23:51 -0700 Subject: [PATCH 017/179] remove stylesheets for gh-pages --- stylesheets/print.css | 226 ------------------- stylesheets/pygment_trac.css | 69 ------ stylesheets/styles.css | 255 --------------------- stylesheets/stylesheet.css | 423 ----------------------------------- 4 files changed, 973 deletions(-) delete mode 100644 stylesheets/print.css delete mode 100644 stylesheets/pygment_trac.css delete mode 100644 stylesheets/styles.css delete mode 100644 stylesheets/stylesheet.css diff --git a/stylesheets/print.css b/stylesheets/print.css deleted file mode 100644 index 541695bfd6..0000000000 --- a/stylesheets/print.css +++ /dev/null @@ -1,226 +0,0 @@ -html, body, div, span, applet, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, img, ins, kbd, q, s, samp, -small, strike, strong, sub, sup, tt, var, -b, u, i, center, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, embed, -figure, figcaption, footer, header, hgroup, -menu, nav, output, ruby, section, summary, -time, mark, audio, video { - margin: 0; - padding: 0; - border: 0; - font-size: 100%; - font: inherit; - vertical-align: baseline; -} -/* HTML5 display-role reset for older browsers */ -article, aside, details, figcaption, figure, -footer, header, hgroup, menu, nav, section { - display: block; -} -body { - line-height: 1; -} -ol, ul { - list-style: none; -} -blockquote, q { - quotes: none; -} -blockquote:before, blockquote:after, -q:before, q:after { - content: ''; - content: none; -} -table { - border-collapse: collapse; - border-spacing: 0; -} -body { - font-size: 13px; - line-height: 1.5; - font-family: 'Helvetica Neue', Helvetica, Arial, serif; - color: #000; -} - -a { - color: #d5000d; - font-weight: bold; -} - -header { - padding-top: 35px; - padding-bottom: 10px; -} - -header h1 { - font-weight: bold; - letter-spacing: -1px; - font-size: 48px; - color: #303030; - line-height: 1.2; -} - -header h2 { - letter-spacing: -1px; - font-size: 24px; - color: #aaa; - font-weight: normal; - line-height: 1.3; -} -#downloads { - display: none; -} -#main_content { - padding-top: 20px; -} - -code, pre { - font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal; - color: #222; - margin-bottom: 30px; - font-size: 12px; -} - -code { - padding: 0 3px; -} - -pre { - border: solid 1px #ddd; - padding: 20px; - overflow: auto; -} -pre code { - padding: 0; -} - -ul, ol, dl { - margin-bottom: 20px; -} - - -/* COMMON STYLES */ - -table { - width: 100%; - border: 1px solid #ebebeb; -} - -th { - font-weight: 500; -} - -td { - border: 1px solid #ebebeb; - text-align: center; - font-weight: 300; -} - -form { - background: #f2f2f2; - padding: 20px; - -} - - -/* GENERAL ELEMENT TYPE STYLES */ - -h1 { - font-size: 2.8em; -} - -h2 { - font-size: 22px; - font-weight: bold; - color: #303030; - margin-bottom: 8px; -} - -h3 { - color: #d5000d; - font-size: 18px; - font-weight: bold; - margin-bottom: 8px; -} - -h4 { - font-size: 16px; - color: #303030; - font-weight: bold; -} - -h5 { - font-size: 1em; - color: #303030; -} - -h6 { - font-size: .8em; - color: #303030; -} - -p { - font-weight: 300; - margin-bottom: 20px; -} - -a { - text-decoration: none; -} - -p a { - font-weight: 400; -} - -blockquote { - font-size: 1.6em; - border-left: 10px solid #e9e9e9; - margin-bottom: 20px; - padding: 0 0 0 30px; -} - -ul li { - list-style: disc inside; - padding-left: 20px; -} - -ol li { - list-style: decimal inside; - padding-left: 3px; -} - -dl dd { - font-style: italic; - font-weight: 100; -} - -footer { - margin-top: 40px; - padding-top: 20px; - padding-bottom: 30px; - font-size: 13px; - color: #aaa; -} - -footer a { - color: #666; -} - -/* MISC */ -.clearfix:after { - clear: both; - content: '.'; - display: block; - visibility: hidden; - height: 0; -} - -.clearfix {display: inline-block;} -* html .clearfix {height: 1%;} -.clearfix {display: block;} \ No newline at end of file diff --git a/stylesheets/pygment_trac.css b/stylesheets/pygment_trac.css deleted file mode 100644 index c6a6452d24..0000000000 --- a/stylesheets/pygment_trac.css +++ /dev/null @@ -1,69 +0,0 @@ -.highlight { background: #ffffff; } -.highlight .c { color: #999988; font-style: italic } /* Comment */ -.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ -.highlight .k { font-weight: bold } /* Keyword */ -.highlight .o { font-weight: bold } /* Operator */ -.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ -.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ -.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ -.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ -.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ -.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */ -.highlight .ge { font-style: italic } /* Generic.Emph */ -.highlight .gr { color: #aa0000 } /* Generic.Error */ -.highlight .gh { color: #999999 } /* Generic.Heading */ -.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ -.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */ -.highlight .go { color: #888888 } /* Generic.Output */ -.highlight .gp { color: #555555 } /* Generic.Prompt */ -.highlight .gs { font-weight: bold } /* Generic.Strong */ -.highlight .gu { color: #800080; font-weight: bold; } /* Generic.Subheading */ -.highlight .gt { color: #aa0000 } /* Generic.Traceback */ -.highlight .kc { font-weight: bold } /* Keyword.Constant */ -.highlight .kd { font-weight: bold } /* Keyword.Declaration */ -.highlight .kn { font-weight: bold } /* Keyword.Namespace */ -.highlight .kp { font-weight: bold } /* Keyword.Pseudo */ -.highlight .kr { font-weight: bold } /* Keyword.Reserved */ -.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ -.highlight .m { color: #009999 } /* Literal.Number */ -.highlight .s { color: #d14 } /* Literal.String */ -.highlight .na { color: #008080 } /* Name.Attribute */ -.highlight .nb { color: #0086B3 } /* Name.Builtin */ -.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ -.highlight .no { color: #008080 } /* Name.Constant */ -.highlight .ni { color: #800080 } /* Name.Entity */ -.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ -.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ -.highlight .nn { color: #555555 } /* Name.Namespace */ -.highlight .nt { color: #000080 } /* Name.Tag */ -.highlight .nv { color: #008080 } /* Name.Variable */ -.highlight .ow { font-weight: bold } /* Operator.Word */ -.highlight .w { color: #bbbbbb } /* Text.Whitespace */ -.highlight .mf { color: #009999 } /* Literal.Number.Float */ -.highlight .mh { color: #009999 } /* Literal.Number.Hex */ -.highlight .mi { color: #009999 } /* Literal.Number.Integer */ -.highlight .mo { color: #009999 } /* Literal.Number.Oct */ -.highlight .sb { color: #d14 } /* Literal.String.Backtick */ -.highlight .sc { color: #d14 } /* Literal.String.Char */ -.highlight .sd { color: #d14 } /* Literal.String.Doc */ -.highlight .s2 { color: #d14 } /* Literal.String.Double */ -.highlight .se { color: #d14 } /* Literal.String.Escape */ -.highlight .sh { color: #d14 } /* Literal.String.Heredoc */ -.highlight .si { color: #d14 } /* Literal.String.Interpol */ -.highlight .sx { color: #d14 } /* Literal.String.Other */ -.highlight .sr { color: #009926 } /* Literal.String.Regex */ -.highlight .s1 { color: #d14 } /* Literal.String.Single */ -.highlight .ss { color: #990073 } /* Literal.String.Symbol */ -.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ -.highlight .vc { color: #008080 } /* Name.Variable.Class */ -.highlight .vg { color: #008080 } /* Name.Variable.Global */ -.highlight .vi { color: #008080 } /* Name.Variable.Instance */ -.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ - -.type-csharp .highlight .k { color: #0000FF } -.type-csharp .highlight .kt { color: #0000FF } -.type-csharp .highlight .nf { color: #000000; font-weight: normal } -.type-csharp .highlight .nc { color: #2B91AF } -.type-csharp .highlight .nn { color: #000000 } -.type-csharp .highlight .s { color: #A31515 } -.type-csharp .highlight .sc { color: #A31515 } diff --git a/stylesheets/styles.css b/stylesheets/styles.css deleted file mode 100644 index dacf2e1861..0000000000 --- a/stylesheets/styles.css +++ /dev/null @@ -1,255 +0,0 @@ -@import url(https://fonts.googleapis.com/css?family=Lato:300italic,700italic,300,700); - -body { - padding:50px; - font:14px/1.5 Lato, "Helvetica Neue", Helvetica, Arial, sans-serif; - color:#777; - font-weight:300; -} - -h1, h2, h3, h4, h5, h6 { - color:#222; - margin:0 0 20px; -} - -p, ul, ol, table, pre, dl { - margin:0 0 20px; -} - -h1, h2, h3 { - line-height:1.1; -} - -h1 { - font-size:28px; -} - -h2 { - color:#393939; -} - -h3, h4, h5, h6 { - color:#494949; -} - -a { - color:#39c; - font-weight:400; - text-decoration:none; -} - -a small { - font-size:11px; - color:#777; - margin-top:-0.6em; - display:block; -} - -.wrapper { - width:860px; - margin:0 auto; -} - -blockquote { - border-left:1px solid #e5e5e5; - margin:0; - padding:0 0 0 20px; - font-style:italic; -} - -code, pre { - font-family:Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal; - color:#333; - font-size:12px; -} - -pre { - padding:8px 15px; - background: #f8f8f8; - border-radius:5px; - border:1px solid #e5e5e5; - overflow-x: auto; -} - -table { - width:100%; - border-collapse:collapse; -} - -th, td { - text-align:left; - padding:5px 10px; - border-bottom:1px solid #e5e5e5; -} - -dt { - color:#444; - font-weight:700; -} - -th { - color:#444; -} - -img { - max-width:100%; -} - -header { - width:270px; - float:left; - position:fixed; -} - -header ul { - list-style:none; - height:40px; - - padding:0; - - background: #eee; - background: -moz-linear-gradient(top, #f8f8f8 0%, #dddddd 100%); - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd)); - background: -webkit-linear-gradient(top, #f8f8f8 0%,#dddddd 100%); - background: -o-linear-gradient(top, #f8f8f8 0%,#dddddd 100%); - background: -ms-linear-gradient(top, #f8f8f8 0%,#dddddd 100%); - background: linear-gradient(top, #f8f8f8 0%,#dddddd 100%); - - border-radius:5px; - border:1px solid #d2d2d2; - box-shadow:inset #fff 0 1px 0, inset rgba(0,0,0,0.03) 0 -1px 0; - width:270px; -} - -header li { - width:89px; - float:left; - border-right:1px solid #d2d2d2; - height:40px; -} - -header ul a { - line-height:1; - font-size:11px; - color:#999; - display:block; - text-align:center; - padding-top:6px; - height:40px; -} - -strong { - color:#222; - font-weight:700; -} - -header ul li + li { - width:88px; - border-left:1px solid #fff; -} - -header ul li + li + li { - border-right:none; - width:89px; -} - -header ul a strong { - font-size:14px; - display:block; - color:#222; -} - -section { - width:500px; - float:right; - padding-bottom:50px; -} - -small { - font-size:11px; -} - -hr { - border:0; - background:#e5e5e5; - height:1px; - margin:0 0 20px; -} - -footer { - width:270px; - float:left; - position:fixed; - bottom:50px; -} - -@media print, screen and (max-width: 960px) { - - div.wrapper { - width:auto; - margin:0; - } - - header, section, footer { - float:none; - position:static; - width:auto; - } - - header { - padding-right:320px; - } - - section { - border:1px solid #e5e5e5; - border-width:1px 0; - padding:20px 0; - margin:0 0 20px; - } - - header a small { - display:inline; - } - - header ul { - position:absolute; - right:50px; - top:52px; - } -} - -@media print, screen and (max-width: 720px) { - body { - word-wrap:break-word; - } - - header { - padding:0; - } - - header ul, header p.view { - position:static; - } - - pre, code { - word-wrap:normal; - } -} - -@media print, screen and (max-width: 480px) { - body { - padding:15px; - } - - header ul { - display:none; - } -} - -@media print { - body { - padding:0.4in; - font-size:12pt; - color:#444; - } -} diff --git a/stylesheets/stylesheet.css b/stylesheets/stylesheet.css deleted file mode 100644 index 7a08b019b1..0000000000 --- a/stylesheets/stylesheet.css +++ /dev/null @@ -1,423 +0,0 @@ -/******************************************************************************* -Slate Theme for GitHub Pages -by Jason Costello, @jsncostello -*******************************************************************************/ - -@import url(pygment_trac.css); - -/******************************************************************************* -MeyerWeb Reset -*******************************************************************************/ - -html, body, div, span, applet, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, img, ins, kbd, q, s, samp, -small, strike, strong, sub, sup, tt, var, -b, u, i, center, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, embed, -figure, figcaption, footer, header, hgroup, -menu, nav, output, ruby, section, summary, -time, mark, audio, video { - margin: 0; - padding: 0; - border: 0; - font: inherit; - vertical-align: baseline; -} - -/* HTML5 display-role reset for older browsers */ -article, aside, details, figcaption, figure, -footer, header, hgroup, menu, nav, section { - display: block; -} - -ol, ul { - list-style: none; -} - -table { - border-collapse: collapse; - border-spacing: 0; -} - -/******************************************************************************* -Theme Styles -*******************************************************************************/ - -body { - box-sizing: border-box; - color:#373737; - background: #212121; - font-size: 16px; - font-family: 'Myriad Pro', Calibri, Helvetica, Arial, sans-serif; - line-height: 1.5; - -webkit-font-smoothing: antialiased; -} - -h1, h2, h3, h4, h5, h6 { - margin: 10px 0; - font-weight: 700; - color:#222222; - font-family: 'Lucida Grande', 'Calibri', Helvetica, Arial, sans-serif; - letter-spacing: -1px; -} - -h1 { - font-size: 36px; - font-weight: 700; -} - -h2 { - padding-bottom: 10px; - font-size: 32px; - background: url('../images/bg_hr.png') repeat-x bottom; -} - -h3 { - font-size: 24px; -} - -h4 { - font-size: 21px; -} - -h5 { - font-size: 18px; -} - -h6 { - font-size: 16px; -} - -p { - margin: 10px 0 15px 0; -} - -footer p { - color: #f2f2f2; -} - -a { - text-decoration: none; - color: #007edf; - text-shadow: none; - - transition: color 0.5s ease; - transition: text-shadow 0.5s ease; - -webkit-transition: color 0.5s ease; - -webkit-transition: text-shadow 0.5s ease; - -moz-transition: color 0.5s ease; - -moz-transition: text-shadow 0.5s ease; - -o-transition: color 0.5s ease; - -o-transition: text-shadow 0.5s ease; - -ms-transition: color 0.5s ease; - -ms-transition: text-shadow 0.5s ease; -} - -a:hover, a:focus {text-decoration: underline;} - -footer a { - color: #F2F2F2; - text-decoration: underline; -} - -em { - font-style: italic; -} - -strong { - font-weight: bold; -} - -img { - position: relative; - margin: 0 auto; - max-width: 739px; - padding: 5px; - margin: 10px 0 10px 0; - border: 1px solid #ebebeb; - - box-shadow: 0 0 5px #ebebeb; - -webkit-box-shadow: 0 0 5px #ebebeb; - -moz-box-shadow: 0 0 5px #ebebeb; - -o-box-shadow: 0 0 5px #ebebeb; - -ms-box-shadow: 0 0 5px #ebebeb; -} - -p img { - display: inline; - margin: 0; - padding: 0; - vertical-align: middle; - text-align: center; - border: none; -} - -pre, code { - width: 100%; - color: #222; - background-color: #fff; - - font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; - font-size: 14px; - - border-radius: 2px; - -moz-border-radius: 2px; - -webkit-border-radius: 2px; -} - -pre { - width: 100%; - padding: 10px; - box-shadow: 0 0 10px rgba(0,0,0,.1); - overflow: auto; -} - -code { - padding: 3px; - margin: 0 3px; - box-shadow: 0 0 10px rgba(0,0,0,.1); -} - -pre code { - display: block; - box-shadow: none; -} - -blockquote { - color: #666; - margin-bottom: 20px; - padding: 0 0 0 20px; - border-left: 3px solid #bbb; -} - - -ul, ol, dl { - margin-bottom: 15px -} - -ul { - list-style: inside; - padding-left: 20px; -} - -ol { - list-style: decimal inside; - padding-left: 20px; -} - -dl dt { - font-weight: bold; -} - -dl dd { - padding-left: 20px; - font-style: italic; -} - -dl p { - padding-left: 20px; - font-style: italic; -} - -hr { - height: 1px; - margin-bottom: 5px; - border: none; - background: url('../images/bg_hr.png') repeat-x center; -} - -table { - border: 1px solid #373737; - margin-bottom: 20px; - text-align: left; - } - -th { - font-family: 'Lucida Grande', 'Helvetica Neue', Helvetica, Arial, sans-serif; - padding: 10px; - background: #373737; - color: #fff; - } - -td { - padding: 10px; - border: 1px solid #373737; - } - -form { - background: #f2f2f2; - padding: 20px; -} - -/******************************************************************************* -Full-Width Styles -*******************************************************************************/ - -.outer { - width: 100%; -} - -.inner { - position: relative; - max-width: 640px; - padding: 20px 10px; - margin: 0 auto; -} - -#forkme_banner { - display: block; - position: absolute; - top:0; - right: 10px; - z-index: 10; - padding: 10px 50px 10px 10px; - color: #fff; - background: url('../images/blacktocat.png') #0090ff no-repeat 95% 50%; - font-weight: 700; - box-shadow: 0 0 10px rgba(0,0,0,.5); - border-bottom-left-radius: 2px; - border-bottom-right-radius: 2px; -} - -#header_wrap { - background: #212121; - background: -moz-linear-gradient(top, #373737, #212121); - background: -webkit-linear-gradient(top, #373737, #212121); - background: -ms-linear-gradient(top, #373737, #212121); - background: -o-linear-gradient(top, #373737, #212121); - background: linear-gradient(top, #373737, #212121); -} - -#header_wrap .inner { - padding: 50px 10px 30px 10px; -} - -#project_title { - margin: 0; - color: #fff; - font-size: 42px; - font-weight: 700; - text-shadow: #111 0px 0px 10px; -} - -#project_tagline { - color: #fff; - font-size: 24px; - font-weight: 300; - background: none; - text-shadow: #111 0px 0px 10px; -} - -#downloads { - position: absolute; - width: 210px; - z-index: 10; - bottom: -40px; - right: 0; - height: 70px; - background: url('../images/icon_download.png') no-repeat 0% 90%; -} - -.zip_download_link { - display: block; - float: right; - width: 90px; - height:70px; - text-indent: -5000px; - overflow: hidden; - background: url(../images/sprite_download.png) no-repeat bottom left; -} - -.tar_download_link { - display: block; - float: right; - width: 90px; - height:70px; - text-indent: -5000px; - overflow: hidden; - background: url(../images/sprite_download.png) no-repeat bottom right; - margin-left: 10px; -} - -.zip_download_link:hover { - background: url(../images/sprite_download.png) no-repeat top left; -} - -.tar_download_link:hover { - background: url(../images/sprite_download.png) no-repeat top right; -} - -#main_content_wrap { - background: #f2f2f2; - border-top: 1px solid #111; - border-bottom: 1px solid #111; -} - -#main_content { - padding-top: 40px; -} - -#footer_wrap { - background: #212121; -} - - - -/******************************************************************************* -Small Device Styles -*******************************************************************************/ - -@media screen and (max-width: 480px) { - body { - font-size:14px; - } - - #downloads { - display: none; - } - - .inner { - min-width: 320px; - max-width: 480px; - } - - #project_title { - font-size: 32px; - } - - h1 { - font-size: 28px; - } - - h2 { - font-size: 24px; - } - - h3 { - font-size: 21px; - } - - h4 { - font-size: 18px; - } - - h5 { - font-size: 14px; - } - - h6 { - font-size: 12px; - } - - code, pre { - min-width: 320px; - max-width: 480px; - font-size: 11px; - } - -} From 78825f0c4d92266ef2f3f3e5b480f4b2a64772d5 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 3 Oct 2014 13:52:50 -0700 Subject: [PATCH 018/179] Fix for normalization crash. --- interface/src/MetavoxelSystem.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index 1e235b6116..f82fba98a0 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -1551,6 +1551,11 @@ public: AxisIndex(int x = -1, int y = -1, int z = -1) : x(x), y(y), z(z) { } }; +static glm::vec3 safeNormalize(const glm::vec3& vector) { + float length = glm::length(vector); + return (length > 0.0f) ? (vector / length) : vector; +} + int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { if (!info.isLeaf) { return DEFAULT_ORDER; @@ -1879,7 +1884,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { } } } - glm::vec3 normal = glm::normalize(axisNormals[0] + axisNormals[1] + axisNormals[2]); + glm::vec3 normal = safeNormalize(axisNormals[0] + axisNormals[1] + axisNormals[2]); center /= crossingCount; // use a sequence of Givens rotations to perform a QR decomposition @@ -1967,12 +1972,12 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { vertices.append(point); } else { - axisNormals[0] = glm::normalize(axisNormals[0]); - axisNormals[1] = glm::normalize(axisNormals[1]); - axisNormals[2] = glm::normalize(axisNormals[2]); - glm::vec3 normalXY(glm::normalize(axisNormals[0] + axisNormals[1])); - glm::vec3 normalXZ(glm::normalize(axisNormals[0] + axisNormals[2])); - glm::vec3 normalYZ(glm::normalize(axisNormals[1] + axisNormals[2])); + axisNormals[0] = safeNormalize(axisNormals[0]); + axisNormals[1] = safeNormalize(axisNormals[1]); + axisNormals[2] = safeNormalize(axisNormals[2]); + glm::vec3 normalXY(safeNormalize(axisNormals[0] + axisNormals[1])); + glm::vec3 normalXZ(safeNormalize(axisNormals[0] + axisNormals[2])); + glm::vec3 normalYZ(safeNormalize(axisNormals[1] + axisNormals[2])); if (glm::dot(axisNormals[0], normalXY) > CREASE_COS_NORMAL && glm::dot(axisNormals[1], normalXY) > CREASE_COS_NORMAL) { point.setNormal(normalXY); From 1aab86884d25a7085904b899f9a7eeaf1d6bfd89 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 3 Oct 2014 14:25:36 -0700 Subject: [PATCH 019/179] Move table view code + wire row delete --- .../resources/describe-settings.json | 20 +-- domain-server/resources/web/js/settings.js | 155 ++++++++++-------- 2 files changed, 90 insertions(+), 85 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index fb0989d91f..d07d73b74c 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -1,18 +1,4 @@ [ - { - "name": "metaverse", - "label": "Metaverse Registration", - "settings": [ - - ] - }, - { - "name": "security", - "label": "Security", - "settings": [ - - ] - }, { "name": "audio", "label": "Audio", @@ -51,19 +37,19 @@ } ], "default": { - "Zone 1": + "Zone_1": { "x-range": "10-82", "y-range": "36-94", "z-range": "38-84" }, - "Zone 2": + "Zone_2": { "x-range": "12-163", "y-range": "64-134", "z-range": "27-184" }, - "Zone 3": + "Zone_3": { "x-range": "463-632", "y-range": "264-384", diff --git a/domain-server/resources/web/js/settings.js b/domain-server/resources/web/js/settings.js index 4471efdc66..660fac7081 100644 --- a/domain-server/resources/web/js/settings.js +++ b/domain-server/resources/web/js/settings.js @@ -32,67 +32,7 @@ var viewHelpers = { form_group += " " + setting.help + ""; form_group += "" } else if (setting.type === 'table') { - form_group += "
" - form_group += "
" + setting.label + "
" - form_group += "
" - form_group += "

" + setting.help + "

" - form_group += "
" - - form_group += "" - // Column names - form_group += "" - if (setting.number === true) { - form_group += "" - } - form_group += "" - _.each(setting.columns, function(col) { - form_group += "" - }) - if (setting.can_delete === true || setting.can_add === true) { - form_group += "" - } - form_group += "" - - // Rows - var row_num = 1 - _.each(setting_value, function(row, name) { - form_group += "" - if (setting.number === true) { - form_group += "" - } - form_group += "" - _.each(setting.columns, function(col) { - form_group += "" - }) - if (setting.can_delete === true) { - form_group += "" - } else if (setting.can_add === true) { - form_group += "" - } - form_group += "" - row_num++ - }) - - // Entries - if (setting.can_add === true) { - form_group += "" - if (setting.number === true) { - form_group += "" - } - form_group += "" - _.each(setting.columns, function(col) { - form_group += "" - }) - form_group += "" - form_group += "" - } - - form_group += "
#" + setting.key.label + "" + col.label + "
" + row_num + "" + name + "" - if (row.hasOwnProperty(col.name)) { - form_group += row[col.name] - } - form_group += "
" - form_group += "
" + form_group += makeTable(setting, setting_name, setting_value); } else { input_type = _.has(setting, 'type') ? setting.type : "text" @@ -145,13 +85,20 @@ $(document).ready(function(){ }) - $('#settings-form').on('click', '.add-row', function(){ - console.log("add-row " + $(this)) - }) - - $('#settings-form').on('click', '.del-row', function(){ - console.log("del-row " + $(this)) - }) + $('#settings-form').on('click', '.add-row', function(){ + console.log("add-row " + $(this)) + + var row = $(this).parents("tr") + + }) + + $('#settings-form').on('click', '.del-row', function(){ + console.log("del-row " + $(this)) + + var row = $(this).parents("tr") + row.empty() + row.html(""); + }) $('#settings-form').on('change', '.setting-input', function(){ @@ -262,6 +209,78 @@ $('body').on('click', '.save-button', function(e){ return false; }); +function makeTable(setting, setting_name, setting_value) { + var html = "
" + html += "
" + setting.label + "
" + html += "
" + html += "

" + setting.help + "

" + html += "
" + html += "" + + // Column names + html += "" + if (setting.number === true) { + html += "" // Row number + } + html += "" // Key + _.each(setting.columns, function(col) { + html += "" // Data + }) + if (setting.can_delete === true || setting.can_add === true) { + html += "" // Buttons + } + html += "" + + // Rows + var row_num = 1 + _.each(setting_value, function(row, name) { + html += "" + if (setting.number === true) { + html += "" + } + html += "" + _.each(setting.columns, function(col) { + html += "" + }) + if (setting.can_delete === true) { + html += "" + } else if (setting.can_add === true) { + html += "" + } + html += "" + row_num++ + }) + + // Inputs + if (setting.can_add === true) { + html += makeTableInputs(setting) + } + + html += "
#" + setting.key.label + "" + col.label + "
" + row_num + "" + name + "" + if (row.hasOwnProperty(col.name)) { + html += row[col.name] + } + html += "
" + html += "
" + + return html; +} + +function makeTableInputs(setting) { + var html = "" + if (setting.number === true) { + html += "" + } + html += "" + _.each(setting.columns, function(col) { + html += "" + }) + html += "" + html += "" + + return html +} + function badgeSidebarForDifferences(changedInput) { // figure out which group this input is in var panelParentID = changedInput.closest('.panel').attr('id') From f673ab316a4b0d765e3483248fa74740b7ecb073 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 3 Oct 2014 15:06:27 -0700 Subject: [PATCH 020/179] tell the data-server about auto networking change to full --- domain-server/src/DomainServer.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index c950d2f8b6..2a7c818125 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -359,6 +359,9 @@ void DomainServer::setupAutomaticNetworking() { // call our sendHeartbeaToIceServer immediately anytime a public address changes connect(nodeList, &LimitedNodeList::publicSockAddrChanged, this, &DomainServer::sendHearbeatToIceServer); + + // tell the data server which type of automatic networking we are using + updateNetworkingInfoWithDataServer(automaticNetworkValue); } // attempt to update our sockets now From 1d3754551135bcdefff203413dc81d2238dda324 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 3 Oct 2014 15:25:03 -0700 Subject: [PATCH 021/179] Moved attenuation setting to non advanced --- domain-server/resources/describe-settings.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 24e9a5b63b..1ee52fdf28 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -53,11 +53,11 @@ }, { "name": "attenuation_per_doubling_in_distance", - "label": "Attenuattion per doubling in distance", + "label": "Attenuation per doubling in distance", "help": "Factor between 0.0 and 1.0 (0.0: No attenuation, 1.0: extreme attenuation)", "placeholder": "0.18", "default": "0.18", - "advanced": true + "advanced": false }, { "name": "dynamic_jitter_buffer", From 4e0bb94cdd69f703d38d3ddfc5639042aef9a1b1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 3 Oct 2014 15:25:47 -0700 Subject: [PATCH 022/179] fix for double ICE connect attempts from domain-server --- domain-server/src/DomainServer.cpp | 12 +++++++----- libraries/networking/src/NetworkPeer.cpp | 2 ++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 2a7c818125..452d9d35b7 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1027,7 +1027,7 @@ void DomainServer::sendICEPingPackets() { } else { // send ping packets to this peer's interfaces qDebug() << "Sending ping packets to establish connectivity with ICE peer with ID" - << peer->getUUID(); + << peer->getUUID(); // send the ping packet to the local and public sockets for this node QByteArray localPingPacket = nodeList->constructPingPacket(PingType::Local, false); @@ -1055,11 +1055,13 @@ void DomainServer::processICEHeartbeatResponse(const QByteArray& packet) { while (!iceResponseStream.atEnd()) { iceResponseStream >> receivedPeer; - if (!_connectingICEPeers.contains(receivedPeer.getUUID()) && !_connectedICEPeers.contains(receivedPeer.getUUID())) { - qDebug() << "New peer requesting connection being added to hash -" << receivedPeer; + if (!_connectedICEPeers.contains(receivedPeer.getUUID())) { + if (!_connectingICEPeers.contains(receivedPeer.getUUID())) { + qDebug() << "New peer requesting connection being added to hash -" << receivedPeer; + } + + _connectingICEPeers[receivedPeer.getUUID()] = receivedPeer; } - - _connectingICEPeers[receivedPeer.getUUID()] = receivedPeer; } } diff --git a/libraries/networking/src/NetworkPeer.cpp b/libraries/networking/src/NetworkPeer.cpp index d458f579c1..eaaf57471c 100644 --- a/libraries/networking/src/NetworkPeer.cpp +++ b/libraries/networking/src/NetworkPeer.cpp @@ -46,6 +46,7 @@ NetworkPeer::NetworkPeer(const NetworkPeer& otherPeer) { _wakeTimestamp = otherPeer._wakeTimestamp; _lastHeardMicrostamp = otherPeer._lastHeardMicrostamp; + _connectionAttempts = otherPeer._connectionAttempts; } NetworkPeer& NetworkPeer::operator=(const NetworkPeer& otherPeer) { @@ -62,6 +63,7 @@ void NetworkPeer::swap(NetworkPeer& otherPeer) { swap(_localSocket, otherPeer._localSocket); swap(_wakeTimestamp, otherPeer._wakeTimestamp); swap(_lastHeardMicrostamp, otherPeer._lastHeardMicrostamp); + swap(_connectionAttempts, otherPeer._connectionAttempts); } QByteArray NetworkPeer::toByteArray() const { From 8ce474d3e14aa36b1508c2926cdc5b732202e5cd Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 3 Oct 2014 15:29:16 -0700 Subject: [PATCH 023/179] make the ice server const scoped to remove warning --- domain-server/src/DomainServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 452d9d35b7..61310cad75 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1002,7 +1002,6 @@ void DomainServer::updateNetworkingInfoWithDataServer(const QString& newSetting, } // todo: have data-web respond with ice-server hostname to use -const HifiSockAddr ICE_SERVER_SOCK_ADDR = HifiSockAddr("ice.highfidelity.io", ICE_SERVER_DEFAULT_PORT); void DomainServer::performICEUpdates() { sendHearbeatToIceServer(); @@ -1010,6 +1009,7 @@ void DomainServer::performICEUpdates() { } void DomainServer::sendHearbeatToIceServer() { + const HifiSockAddr ICE_SERVER_SOCK_ADDR = HifiSockAddr("ice.highfidelity.io", ICE_SERVER_DEFAULT_PORT); LimitedNodeList::getInstance()->sendHeartbeatToIceServer(ICE_SERVER_SOCK_ADDR); } From 2ce2c9e9536624ec6f842d4e72190b73334a822f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 3 Oct 2014 15:33:51 -0700 Subject: [PATCH 024/179] add a missing slash in path for release hydra support --- interface/src/devices/SixenseManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index f5d838f95b..48ea85214a 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -101,7 +101,7 @@ void SixenseManager::initialize() { _sixenseLibrary = new QLibrary(SIXENSE_LIB_FILENAME); #else const QString SIXENSE_LIBRARY_NAME = "libsixense_x64"; - QString frameworkSixenseLibrary = QCoreApplication::applicationDirPath() + "../Frameworks/" + QString frameworkSixenseLibrary = QCoreApplication::applicationDirPath() + "/../Frameworks/" + SIXENSE_LIBRARY_NAME; _sixenseLibrary = new QLibrary(frameworkSixenseLibrary); From 738369e21f04adb8e265345a4890e686db935c67 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 3 Oct 2014 16:55:58 -0700 Subject: [PATCH 025/179] Replacing glutSolidSphere by a cached Geometry Instead of calling glutSolidSphere, just call Application::getInstance()->getGeometryCache()->renderSphere(...) - replaced all the instances of "glutSolidSphere" - Changed the atmosphere shaders so instead of drawing a sphere of the size of the atmosphere, we draw a unit sphere, the vertices get scaled at the right radius in th vertex shader using fOuterRadius --- CMakeLists.txt | 2 +- .../resources/web/assignment/js/ace/ace.js | 0 .../web/assignment/js/ace/mode-javascript.js | 0 .../assignment/js/ace/snippets/javascript.js | 0 .../web/assignment/js/ace/theme-twilight.js | 0 .../assignment/js/ace/worker-javascript.js | 0 domain-server/resources/web/js/form2js.min.js | 0 examples/move.js | 0 .../resources/shaders/SkyFromAtmosphere.vert | 6 +- interface/resources/shaders/SkyFromSpace.vert | 6 +- interface/src/Application.cpp | 14 ++- interface/src/BuckyBalls.cpp | 3 +- interface/src/Environment.cpp | 2 +- interface/src/Menu.cpp | 2 +- interface/src/MetavoxelSystem.cpp | 2 +- interface/src/Stars.cpp | 0 interface/src/Stars.h | 0 interface/src/Util.cpp | 15 +-- interface/src/avatar/Avatar.cpp | 7 +- interface/src/avatar/Avatar.h | 0 interface/src/avatar/Hand.cpp | 4 +- interface/src/avatar/Hand.h | 0 interface/src/avatar/MyAvatar.cpp | 4 +- interface/src/avatar/SkeletonModel.cpp | 18 +-- .../src/renderer/DeferredLightingEffect.cpp | 2 +- interface/src/renderer/GeometryCache.cpp | 105 ++++++++++++++++++ interface/src/renderer/GeometryCache.h | 2 + interface/src/starfield/Config.h | 0 interface/src/starfield/Controller.cpp | 0 interface/src/starfield/Controller.h | 0 interface/src/starfield/data/GpuVertex.cpp | 0 interface/src/starfield/data/GpuVertex.h | 0 interface/src/starfield/data/InputVertex.cpp | 0 interface/src/starfield/data/InputVertex.h | 0 interface/src/starfield/data/Tile.h | 0 interface/src/starfield/renderer/Renderer.cpp | 0 interface/src/starfield/renderer/Renderer.h | 0 interface/src/starfield/renderer/Tiling.h | 0 .../src/starfield/renderer/VertexOrder.cpp | 0 .../src/starfield/renderer/VertexOrder.h | 0 interface/src/ui/MetavoxelEditor.cpp | 2 +- interface/src/ui/overlays/Sphere3DOverlay.cpp | 3 +- libraries/avatars/src/AvatarData.h | 0 libraries/avatars/src/HandData.h | 0 .../embedded-webserver/src/HTTPConnection.cpp | 0 .../embedded-webserver/src/HTTPManager.cpp | 0 .../embedded-webserver/src/HTTPManager.h | 0 libraries/octree/src/Plane.cpp | 0 libraries/octree/src/Plane.h | 0 tools/samples/cube1.hio | Bin tools/samples/oneRedVoxel.hio | Bin tools/samples/single.hio | Bin 52 files changed, 158 insertions(+), 41 deletions(-) mode change 100755 => 100644 domain-server/resources/web/assignment/js/ace/ace.js mode change 100755 => 100644 domain-server/resources/web/assignment/js/ace/mode-javascript.js mode change 100755 => 100644 domain-server/resources/web/assignment/js/ace/snippets/javascript.js mode change 100755 => 100644 domain-server/resources/web/assignment/js/ace/theme-twilight.js mode change 100755 => 100644 domain-server/resources/web/assignment/js/ace/worker-javascript.js mode change 100755 => 100644 domain-server/resources/web/js/form2js.min.js mode change 100755 => 100644 examples/move.js mode change 100755 => 100644 interface/src/Stars.cpp mode change 100755 => 100644 interface/src/Stars.h mode change 100755 => 100644 interface/src/avatar/Avatar.h mode change 100755 => 100644 interface/src/avatar/Hand.h mode change 100755 => 100644 interface/src/starfield/Config.h mode change 100755 => 100644 interface/src/starfield/Controller.cpp mode change 100755 => 100644 interface/src/starfield/Controller.h mode change 100755 => 100644 interface/src/starfield/data/GpuVertex.cpp mode change 100755 => 100644 interface/src/starfield/data/GpuVertex.h mode change 100755 => 100644 interface/src/starfield/data/InputVertex.cpp mode change 100755 => 100644 interface/src/starfield/data/InputVertex.h mode change 100755 => 100644 interface/src/starfield/data/Tile.h mode change 100755 => 100644 interface/src/starfield/renderer/Renderer.cpp mode change 100755 => 100644 interface/src/starfield/renderer/Renderer.h mode change 100755 => 100644 interface/src/starfield/renderer/Tiling.h mode change 100755 => 100644 interface/src/starfield/renderer/VertexOrder.cpp mode change 100755 => 100644 interface/src/starfield/renderer/VertexOrder.h mode change 100755 => 100644 libraries/avatars/src/AvatarData.h mode change 100755 => 100644 libraries/avatars/src/HandData.h mode change 100755 => 100644 libraries/embedded-webserver/src/HTTPConnection.cpp mode change 100755 => 100644 libraries/embedded-webserver/src/HTTPManager.cpp mode change 100755 => 100644 libraries/embedded-webserver/src/HTTPManager.h mode change 100755 => 100644 libraries/octree/src/Plane.cpp mode change 100755 => 100644 libraries/octree/src/Plane.h mode change 100755 => 100644 tools/samples/cube1.hio mode change 100755 => 100644 tools/samples/oneRedVoxel.hio mode change 100755 => 100644 tools/samples/single.hio diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c0bfb0892..5f245884fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ if (WIN32) # set path for Microsoft SDKs # if get build error about missing 'glu32' this path is likely wrong # Uncomment the line with 8.1 if running Windows 8.1 - #set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "C:\\Program Files (x86)\\Windows Kits\\8.1\\Lib\\winv6.3\\um\\x86") + set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "C:\\Program Files (x86)\\Windows Kits\\8.1\\Lib\\winv6.3\\um\\x86") set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1 ") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") elseif (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) diff --git a/domain-server/resources/web/assignment/js/ace/ace.js b/domain-server/resources/web/assignment/js/ace/ace.js old mode 100755 new mode 100644 diff --git a/domain-server/resources/web/assignment/js/ace/mode-javascript.js b/domain-server/resources/web/assignment/js/ace/mode-javascript.js old mode 100755 new mode 100644 diff --git a/domain-server/resources/web/assignment/js/ace/snippets/javascript.js b/domain-server/resources/web/assignment/js/ace/snippets/javascript.js old mode 100755 new mode 100644 diff --git a/domain-server/resources/web/assignment/js/ace/theme-twilight.js b/domain-server/resources/web/assignment/js/ace/theme-twilight.js old mode 100755 new mode 100644 diff --git a/domain-server/resources/web/assignment/js/ace/worker-javascript.js b/domain-server/resources/web/assignment/js/ace/worker-javascript.js old mode 100755 new mode 100644 diff --git a/domain-server/resources/web/js/form2js.min.js b/domain-server/resources/web/js/form2js.min.js old mode 100755 new mode 100644 diff --git a/examples/move.js b/examples/move.js old mode 100755 new mode 100644 diff --git a/interface/resources/shaders/SkyFromAtmosphere.vert b/interface/resources/shaders/SkyFromAtmosphere.vert index 31c1ea958a..e04868de1d 100644 --- a/interface/resources/shaders/SkyFromAtmosphere.vert +++ b/interface/resources/shaders/SkyFromAtmosphere.vert @@ -35,6 +35,7 @@ uniform vec3 v3CameraPos; // The camera's current position uniform vec3 v3LightPos; // The direction vector to the light source uniform vec3 v3InvWavelength; // 1 / pow(wavelength, 4) for the red, green, and blue channels +uniform float fOuterRadius; // The outer (atmosphere) radius uniform float fInnerRadius; // The inner (planetary) radius uniform float fKrESun; // Kr * ESun uniform float fKmESun; // Km * ESun @@ -44,6 +45,7 @@ uniform float fScale; // 1 / (fOuterRadius - fInnerRadius) uniform float fScaleDepth; // The scale depth (i.e. the altitude at which the atmosphere's average density is found) uniform float fScaleOverScaleDepth; // fScale / fScaleDepth + const int nSamples = 2; const float fSamples = 2.0; @@ -59,7 +61,7 @@ float scale(float fCos) void main(void) { // Get the ray from the camera to the vertex, and its length (which is the far point of the ray passing through the atmosphere) - position = gl_Vertex.xyz; + position = gl_Vertex.xyz * fOuterRadius; - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + gl_Position = gl_ModelViewProjectionMatrix * vec4(position, 1.0); } diff --git a/interface/resources/shaders/SkyFromSpace.vert b/interface/resources/shaders/SkyFromSpace.vert index 0c06c90cf8..6740d1909e 100644 --- a/interface/resources/shaders/SkyFromSpace.vert +++ b/interface/resources/shaders/SkyFromSpace.vert @@ -32,10 +32,12 @@ // Copyright (c) 2004 Sean O'Neil // +uniform float fOuterRadius; // The outer (atmosphere) radius + varying vec3 position; void main(void) { - position = gl_Vertex.xyz; - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + position = gl_Vertex.xyz * fOuterRadius; + gl_Position = gl_ModelViewProjectionMatrix * vec4(position, 1.0); } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ec40056299..d5cf14f8ce 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -876,8 +876,12 @@ void Application::keyPressEvent(QKeyEvent* event) { break; case Qt::Key_W: - _myAvatar->setDriveKeys(FWD, 1.f); - break; + if (isOption && !isShifted && !isMeta) { + Menu::getInstance()->triggerOption(MenuOption::Wireframe); + } else { + _myAvatar->setDriveKeys(FWD, 1.f); + } + break; case Qt::Key_S: if (isShifted && isMeta && !isOption) { @@ -2886,10 +2890,8 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { // draw a red sphere float originSphereRadius = 0.05f; glColor3f(1,0,0); - glPushMatrix(); - glutSolidSphere(originSphereRadius, 15, 15); - glPopMatrix(); - + _geometryCache.renderSphere(originSphereRadius, 15, 15); + // draw the audio reflector overlay { PerformanceTimer perfTimer("audio"); diff --git a/interface/src/BuckyBalls.cpp b/interface/src/BuckyBalls.cpp index 1bc093283a..893e74f083 100644 --- a/interface/src/BuckyBalls.cpp +++ b/interface/src/BuckyBalls.cpp @@ -11,6 +11,7 @@ #include "BuckyBalls.h" +#include "Application.h" #include "Util.h" #include "world.h" #include "devices/SixenseManager.h" @@ -171,7 +172,7 @@ void BuckyBalls::render() { } glPushMatrix(); glTranslatef(_bballPosition[i].x, _bballPosition[i].y, _bballPosition[i].z); - glutSolidSphere(_bballRadius[i], 15, 15); + Application::getInstance()->getGeometryCache()->renderSphere(_bballRadius[i], 15, 15); glPopMatrix(); } } diff --git a/interface/src/Environment.cpp b/interface/src/Environment.cpp index 67337f963c..6eae464957 100644 --- a/interface/src/Environment.cpp +++ b/interface/src/Environment.cpp @@ -261,7 +261,7 @@ void Environment::renderAtmosphere(Camera& camera, const EnvironmentData& data) glDepthMask(GL_FALSE); glDisable(GL_DEPTH_TEST); - glutSolidSphere(data.getAtmosphereOuterRadius(), 100, 50); + Application::getInstance()->getGeometryCache()->renderSphere(1.f, 100, 50); //Draw a unit sphere glDepthMask(GL_TRUE); program->release(); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 94af1ad80a..d24c837f73 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -385,7 +385,7 @@ Menu::Menu() : 0, appInstance->getGlowEffect(), SLOT(cycleRenderMode())); - addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Wireframe, 0, false); + addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Wireframe, Qt::ALT | Qt::Key_W, false); addActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::LodTools, Qt::SHIFT | Qt::Key_L, this, SLOT(lodTools())); QMenu* avatarDebugMenu = developerMenu->addMenu("Avatar"); diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index ae82e57017..4662fdafa6 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -2339,7 +2339,7 @@ void SphereRenderer::renderUnclipped(float alpha, Mode mode) { glm::vec3 axis = glm::axis(rotation); glRotatef(glm::angle(rotation), axis.x, axis.y, axis.z); - glutSolidSphere(sphere->getScale(), 10, 10); + Application::getInstance()->getGeometryCache()->renderSphere(sphere->getScale(), 10, 10); glPopMatrix(); } diff --git a/interface/src/Stars.cpp b/interface/src/Stars.cpp old mode 100755 new mode 100644 diff --git a/interface/src/Stars.h b/interface/src/Stars.h old mode 100755 new mode 100644 diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index b219509ccd..9d7f5518d0 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -27,6 +27,7 @@ #include "ui/TextRenderer.h" #include "VoxelConstants.h" #include "world.h" +#include "Application.h" #include "Util.h" @@ -112,13 +113,13 @@ void drawVector(glm::vec3 * vector) { glPushMatrix(); glColor3f(1,0,0); glTranslatef(vector->x, 0, 0); - glutSolidSphere(0.02, 10, 10); + Application::getInstance()->getGeometryCache()->renderSphere(0.02f, 10, 10); glColor3f(0,1,0); glTranslatef(-vector->x, vector->y, 0); - glutSolidSphere(0.02, 10, 10); + Application::getInstance()->getGeometryCache()->renderSphere(0.02f, 10, 10); glColor3f(0,0,1); glTranslatef(0, -vector->y, vector->z); - glutSolidSphere(0.02, 10, 10); + Application::getInstance()->getGeometryCache()->renderSphere(0.02f, 10, 10); glPopMatrix(); } @@ -155,22 +156,22 @@ void renderWorldBox() { glPushMatrix(); glTranslatef(MARKER_DISTANCE, 0, 0); glColor3fv(red); - glutSolidSphere(MARKER_RADIUS, 10, 10); + Application::getInstance()->getGeometryCache()->renderSphere(MARKER_RADIUS, 10, 10); glPopMatrix(); glPushMatrix(); glTranslatef(0, MARKER_DISTANCE, 0); glColor3fv(green); - glutSolidSphere(MARKER_RADIUS, 10, 10); + Application::getInstance()->getGeometryCache()->renderSphere(MARKER_RADIUS, 10, 10); glPopMatrix(); glPushMatrix(); glTranslatef(0, 0, MARKER_DISTANCE); glColor3fv(blue); - glutSolidSphere(MARKER_RADIUS, 10, 10); + Application::getInstance()->getGeometryCache()->renderSphere(MARKER_RADIUS, 10, 10); glPopMatrix(); glPushMatrix(); glColor3fv(gray); glTranslatef(MARKER_DISTANCE, 0, MARKER_DISTANCE); - glutSolidSphere(MARKER_RADIUS, 10, 10); + Application::getInstance()->getGeometryCache()->renderSphere(MARKER_RADIUS, 10, 10); glPopMatrix(); } diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 2b72fe2c23..cd76550b59 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -399,8 +399,8 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool } else { glTranslatef(_position.x, getDisplayNamePosition().y + LOOK_AT_INDICATOR_OFFSET, _position.z); } - glutSolidSphere(LOOK_AT_INDICATOR_RADIUS, 15, 15); - glPopMatrix(); + Application::getInstance()->getGeometryCache()->renderSphere(LOOK_AT_INDICATOR_RADIUS, 15, 15); + glPopMatrix(); } } @@ -427,7 +427,8 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool glPushMatrix(); glTranslatef(_position.x, _position.y, _position.z); glScalef(height, height, height); - glutSolidSphere(sphereRadius, 15, 15); + Application::getInstance()->getGeometryCache()->renderSphere(sphereRadius, 15, 15); + glPopMatrix(); } } diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h old mode 100755 new mode 100644 diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 5ef1fbafea..9bddcd1730 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -114,7 +114,7 @@ void Hand::render(bool isMine, Model::RenderMode renderMode) { glPushMatrix(); glTranslatef(position.x, position.y, position.z); glColor3f(0.0f, 1.0f, 0.0f); - glutSolidSphere(PALM_COLLISION_RADIUS * _owningAvatar->getScale(), 10, 10); + Application::getInstance()->getGeometryCache()->renderSphere(PALM_COLLISION_RADIUS * _owningAvatar->getScale(), 10, 10); glPopMatrix(); } } @@ -179,7 +179,7 @@ void Hand::renderHandTargets(bool isMine) { Avatar::renderJointConnectingCone(root, offsetFromPalm, PALM_DISK_RADIUS, 0.0f); glPushMatrix(); glTranslatef(root.x, root.y, root.z); - glutSolidSphere(PALM_BALL_RADIUS, 20.0f, 20.0f); + Application::getInstance()->getGeometryCache()->renderSphere(PALM_BALL_RADIUS, 20.0f, 20.0f); glPopMatrix(); } } diff --git a/interface/src/avatar/Hand.h b/interface/src/avatar/Hand.h old mode 100755 new mode 100644 diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index f7aa8a2bd6..83ff284887 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -399,7 +399,7 @@ void MyAvatar::renderDebugBodyPoints() { glPushMatrix(); glColor4f(0, 1, 0, .5f); glTranslatef(position.x, position.y, position.z); - glutSolidSphere(0.2, 10, 10); + Application::getInstance()->getGeometryCache()->renderSphere(0.2, 10, 10); glPopMatrix(); // Head Sphere @@ -407,7 +407,7 @@ void MyAvatar::renderDebugBodyPoints() { glPushMatrix(); glColor4f(0, 1, 0, .5f); glTranslatef(position.x, position.y, position.z); - glutSolidSphere(0.15, 10, 10); + Application::getInstance()->getGeometryCache()->renderSphere(0.15, 10, 10); glPopMatrix(); } diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index a1fccf1a10..61bee4b4c5 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -554,9 +554,9 @@ void SkeletonModel::renderRagdoll() { glTranslatef(position.x, position.y, position.z); // draw each point as a yellow hexagon with black border glColor4f(0.0f, 0.0f, 0.0f, alpha); - glutSolidSphere(radius2, BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); + Application::getInstance()->getGeometryCache()->renderSphere(radius2, BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); glColor4f(1.0f, 1.0f, 0.0f, alpha); - glutSolidSphere(radius1, BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); + Application::getInstance()->getGeometryCache()->renderSphere(radius1, BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); glPopMatrix(); } glPopMatrix(); @@ -847,7 +847,7 @@ void SkeletonModel::renderBoundingCollisionShapes(float alpha) { endPoint = endPoint - _translation; glTranslatef(endPoint.x, endPoint.y, endPoint.z); glColor4f(0.6f, 0.6f, 0.8f, alpha); - glutSolidSphere(_boundingShape.getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); + Application::getInstance()->getGeometryCache()->renderSphere(_boundingShape.getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); // draw a yellow sphere at the capsule startpoint glm::vec3 startPoint; @@ -856,7 +856,7 @@ void SkeletonModel::renderBoundingCollisionShapes(float alpha) { glm::vec3 axis = endPoint - startPoint; glTranslatef(-axis.x, -axis.y, -axis.z); glColor4f(0.8f, 0.8f, 0.6f, alpha); - glutSolidSphere(_boundingShape.getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); + Application::getInstance()->getGeometryCache()->renderSphere(_boundingShape.getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); // draw a green cylinder between the two points glm::vec3 origin(0.0f); @@ -889,7 +889,7 @@ void SkeletonModel::renderJointCollisionShapes(float alpha) { glTranslatef(position.x, position.y, position.z); // draw a grey sphere at shape position glColor4f(0.75f, 0.75f, 0.75f, alpha); - glutSolidSphere(shape->getBoundingRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); + Application::getInstance()->getGeometryCache()->renderSphere(shape->getBoundingRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); } else if (shape->getType() == CAPSULE_SHAPE) { CapsuleShape* capsule = static_cast(shape); @@ -898,8 +898,8 @@ void SkeletonModel::renderJointCollisionShapes(float alpha) { capsule->getEndPoint(endPoint); endPoint = endPoint - simulationTranslation; glTranslatef(endPoint.x, endPoint.y, endPoint.z); - glColor4f(0.6f, 0.6f, 0.8f, alpha); - glutSolidSphere(capsule->getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); + glColor4f(0.6f, 0.6f, 0.8f, alpha); + Application::getInstance()->getGeometryCache()->renderSphere(capsule->getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); // draw a yellow sphere at the capsule startpoint glm::vec3 startPoint; @@ -907,8 +907,8 @@ void SkeletonModel::renderJointCollisionShapes(float alpha) { startPoint = startPoint - simulationTranslation; glm::vec3 axis = endPoint - startPoint; glTranslatef(-axis.x, -axis.y, -axis.z); - glColor4f(0.8f, 0.8f, 0.6f, alpha); - glutSolidSphere(capsule->getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); + glColor4f(0.8f, 0.8f, 0.6f, alpha); + Application::getInstance()->getGeometryCache()->renderSphere(capsule->getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); // draw a green cylinder between the two points glm::vec3 origin(0.0f); diff --git a/interface/src/renderer/DeferredLightingEffect.cpp b/interface/src/renderer/DeferredLightingEffect.cpp index 585fa9b31c..46fb889c75 100644 --- a/interface/src/renderer/DeferredLightingEffect.cpp +++ b/interface/src/renderer/DeferredLightingEffect.cpp @@ -51,7 +51,7 @@ void DeferredLightingEffect::releaseSimpleProgram() { void DeferredLightingEffect::renderSolidSphere(float radius, int slices, int stacks) { bindSimpleProgram(); - glutSolidSphere(radius, slices, stacks); + Application::getInstance()->getGeometryCache()->renderSphere(radius, slices, stacks); releaseSimpleProgram(); } diff --git a/interface/src/renderer/GeometryCache.cpp b/interface/src/renderer/GeometryCache.cpp index 7c3c2dc1ca..1eecebcea2 100644 --- a/interface/src/renderer/GeometryCache.cpp +++ b/interface/src/renderer/GeometryCache.cpp @@ -110,6 +110,111 @@ void GeometryCache::renderHemisphere(int slices, int stacks) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } + +void GeometryCache::renderSphere(float radius, int slices, int stacks) { + VerticesIndices& vbo = _sphereVBOs[IntPair(slices, stacks)]; + int vertices = slices * (stacks - 1) + 2; + int indices = slices * 2 * 3 * (stacks - 1) + slices * 2 * 3; + if (vbo.first == 0) { + GLfloat* vertexData = new GLfloat[vertices * 3]; + GLfloat* vertex = vertexData; + + // south pole + *(vertex++) = 0.0f; + *(vertex++) = 0.0f; + *(vertex++) = -1.0f; + + //add stacks vertices climbing up Y axis + for (int i = 1; i < stacks; i++) { + float phi = PI * (float)i / (float)(stacks) - PI_OVER_TWO; + float z = sinf(phi), radius = cosf(phi); + + for (int j = 0; j < slices; j++) { + float theta = TWO_PI * (float)j / (float)slices; + + *(vertex++) = sinf(theta) * radius; + *(vertex++) = cosf(theta) * radius; + *(vertex++) = z; + } + } + + // north pole + *(vertex++) = 0.0f; + *(vertex++) = 0.0f; + *(vertex++) = 1.0f; + + glGenBuffers(1, &vbo.first); + glBindBuffer(GL_ARRAY_BUFFER, vbo.first); + const int BYTES_PER_VERTEX = 3 * sizeof(GLfloat); + glBufferData(GL_ARRAY_BUFFER, vertices * BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW); + delete[] vertexData; + + GLushort* indexData = new GLushort[indices]; + GLushort* index = indexData; + + // South cap + GLushort bottom = 0; + GLushort top = 1; + for (int i = 0; i < slices; i++) { + *(index++) = bottom; + *(index++) = top + i; + *(index++) = top + (i + 1) % slices; + } + + // (stacks - 2) ribbons + for (int i = 0; i < stacks - 2; i++) { + bottom = i * slices + 1; + top = bottom + slices; + for (int j = 0; j < slices; j++) { + int next = (j + 1) % slices; + + *(index++) = bottom + j; + *(index++) = top + next; + *(index++) = top + j; + + *(index++) = bottom + j; + *(index++) = bottom + next; + *(index++) = top + next; + } + } + + // north cap + bottom = (stacks - 2) * slices + 1; + top = bottom + slices; + for (int i = 0; i < slices; i++) { + *(index++) = bottom + i; + *(index++) = bottom + (i + 1) % slices; + *(index++) = top; + } + + glGenBuffers(1, &vbo.second); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second); + const int BYTES_PER_INDEX = sizeof(GLushort); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices * BYTES_PER_INDEX, indexData, GL_STATIC_DRAW); + delete[] indexData; + + } else { + glBindBuffer(GL_ARRAY_BUFFER, vbo.first); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo.second); + } + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + + glVertexPointer(3, GL_FLOAT, 0, 0); + glNormalPointer(GL_FLOAT, 0, 0); + + glPushMatrix(); + glScalef(radius, radius, radius); + glDrawRangeElementsEXT(GL_TRIANGLES, 0, vertices - 1, indices, GL_UNSIGNED_SHORT, 0); + glPopMatrix(); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +} + void GeometryCache::renderSquare(int xDivisions, int yDivisions) { VerticesIndices& vbo = _squareVBOs[IntPair(xDivisions, yDivisions)]; int xVertices = xDivisions + 1; diff --git a/interface/src/renderer/GeometryCache.h b/interface/src/renderer/GeometryCache.h index 647e0592fd..e0ada10e5b 100644 --- a/interface/src/renderer/GeometryCache.h +++ b/interface/src/renderer/GeometryCache.h @@ -39,6 +39,7 @@ public: virtual ~GeometryCache(); void renderHemisphere(int slices, int stacks); + void renderSphere(float radius, int slices, int stacks); void renderSquare(int xDivisions, int yDivisions); void renderHalfCylinder(int slices, int stacks); void renderGrid(int xDivisions, int yDivisions); @@ -67,6 +68,7 @@ private: typedef QPair VerticesIndices; QHash _hemisphereVBOs; + QHash _sphereVBOs; QHash _squareVBOs; QHash _halfCylinderVBOs; QHash _gridBuffers; diff --git a/interface/src/starfield/Config.h b/interface/src/starfield/Config.h old mode 100755 new mode 100644 diff --git a/interface/src/starfield/Controller.cpp b/interface/src/starfield/Controller.cpp old mode 100755 new mode 100644 diff --git a/interface/src/starfield/Controller.h b/interface/src/starfield/Controller.h old mode 100755 new mode 100644 diff --git a/interface/src/starfield/data/GpuVertex.cpp b/interface/src/starfield/data/GpuVertex.cpp old mode 100755 new mode 100644 diff --git a/interface/src/starfield/data/GpuVertex.h b/interface/src/starfield/data/GpuVertex.h old mode 100755 new mode 100644 diff --git a/interface/src/starfield/data/InputVertex.cpp b/interface/src/starfield/data/InputVertex.cpp old mode 100755 new mode 100644 diff --git a/interface/src/starfield/data/InputVertex.h b/interface/src/starfield/data/InputVertex.h old mode 100755 new mode 100644 diff --git a/interface/src/starfield/data/Tile.h b/interface/src/starfield/data/Tile.h old mode 100755 new mode 100644 diff --git a/interface/src/starfield/renderer/Renderer.cpp b/interface/src/starfield/renderer/Renderer.cpp old mode 100755 new mode 100644 diff --git a/interface/src/starfield/renderer/Renderer.h b/interface/src/starfield/renderer/Renderer.h old mode 100755 new mode 100644 diff --git a/interface/src/starfield/renderer/Tiling.h b/interface/src/starfield/renderer/Tiling.h old mode 100755 new mode 100644 diff --git a/interface/src/starfield/renderer/VertexOrder.cpp b/interface/src/starfield/renderer/VertexOrder.cpp old mode 100755 new mode 100644 diff --git a/interface/src/starfield/renderer/VertexOrder.h b/interface/src/starfield/renderer/VertexOrder.h old mode 100755 new mode 100644 diff --git a/interface/src/ui/MetavoxelEditor.cpp b/interface/src/ui/MetavoxelEditor.cpp index bb62bee9a1..7cd34ae333 100644 --- a/interface/src/ui/MetavoxelEditor.cpp +++ b/interface/src/ui/MetavoxelEditor.cpp @@ -1415,7 +1415,7 @@ void SphereTool::render() { glEnable(GL_CULL_FACE); - glutSolidSphere(_radius->value(), 10, 10); + Application::getInstance()->getGeometryCache()->renderSphere(_radius->value(), 10, 10); glDisable(GL_CULL_FACE); diff --git a/interface/src/ui/overlays/Sphere3DOverlay.cpp b/interface/src/ui/overlays/Sphere3DOverlay.cpp index c2ac92f45c..40be8007ad 100644 --- a/interface/src/ui/overlays/Sphere3DOverlay.cpp +++ b/interface/src/ui/overlays/Sphere3DOverlay.cpp @@ -15,6 +15,7 @@ #include #include "Sphere3DOverlay.h" +#include "Application.h" Sphere3DOverlay::Sphere3DOverlay() { } @@ -39,7 +40,7 @@ void Sphere3DOverlay::render() { glLineWidth(_lineWidth); const int slices = 15; if (_isSolid) { - glutSolidSphere(_size, slices, slices); + Application::getInstance()->getGeometryCache()->renderSphere(_size, slices, slices); } else { glutWireSphere(_size, slices, slices); } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h old mode 100755 new mode 100644 diff --git a/libraries/avatars/src/HandData.h b/libraries/avatars/src/HandData.h old mode 100755 new mode 100644 diff --git a/libraries/embedded-webserver/src/HTTPConnection.cpp b/libraries/embedded-webserver/src/HTTPConnection.cpp old mode 100755 new mode 100644 diff --git a/libraries/embedded-webserver/src/HTTPManager.cpp b/libraries/embedded-webserver/src/HTTPManager.cpp old mode 100755 new mode 100644 diff --git a/libraries/embedded-webserver/src/HTTPManager.h b/libraries/embedded-webserver/src/HTTPManager.h old mode 100755 new mode 100644 diff --git a/libraries/octree/src/Plane.cpp b/libraries/octree/src/Plane.cpp old mode 100755 new mode 100644 diff --git a/libraries/octree/src/Plane.h b/libraries/octree/src/Plane.h old mode 100755 new mode 100644 diff --git a/tools/samples/cube1.hio b/tools/samples/cube1.hio old mode 100755 new mode 100644 diff --git a/tools/samples/oneRedVoxel.hio b/tools/samples/oneRedVoxel.hio old mode 100755 new mode 100644 diff --git a/tools/samples/single.hio b/tools/samples/single.hio old mode 100755 new mode 100644 From 5203113b416070f308759d6627f4a6107b9fb130 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 3 Oct 2014 17:01:33 -0700 Subject: [PATCH 026/179] separate ICE ID and domain ID for reconnections to moved domains --- interface/src/Application.cpp | 6 +++--- libraries/networking/src/DomainHandler.cpp | 12 +++++++++--- libraries/networking/src/DomainHandler.h | 3 +++ libraries/networking/src/NodeList.cpp | 4 ++-- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d41b50a232..0551886abb 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3462,9 +3462,9 @@ void Application::updateWindowTitle(){ void Application::updateLocationInServer() { AccountManager& accountManager = AccountManager::getInstance(); - const QUuid& domainUUID = NodeList::getInstance()->getDomainHandler().getUUID(); + DomainHandler& domainHandler = NodeList::getInstance()->getDomainHandler(); - if (accountManager.isLoggedIn() && !domainUUID.isNull()) { + if (accountManager.isLoggedIn() && domainHandler.isConnected() && !domainHandler.getUUID().isNull()) { // construct a QJsonObject given the user's current address information QJsonObject rootObject; @@ -3478,7 +3478,7 @@ void Application::updateLocationInServer() { const QString DOMAIN_ID_KEY_IN_LOCATION = "domain_id"; locationObject.insert(PATH_KEY_IN_LOCATION, pathString); - locationObject.insert(DOMAIN_ID_KEY_IN_LOCATION, domainUUID.toString()); + locationObject.insert(DOMAIN_ID_KEY_IN_LOCATION, domainHandler.getUUID().toString()); rootObject.insert(LOCATION_KEY_IN_ROOT, locationObject); diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index fecbd1457f..5714e6923d 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -25,6 +25,7 @@ DomainHandler::DomainHandler(QObject* parent) : _uuid(), _sockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)), _assignmentUUID(), + _iceDomainID(), _iceClientID(), _iceServerSockAddr(), _icePeer(), @@ -39,9 +40,13 @@ DomainHandler::DomainHandler(QObject* parent) : void DomainHandler::clearConnectionInfo() { _uuid = QUuid(); - _iceServerSockAddr = HifiSockAddr(); _icePeer = NetworkPeer(); + if (requiresICE()) { + // if we connected to this domain with ICE, re-set the socket so we reconnect through the ice-server + _sockAddr.setAddress(QHostAddress::Null); + } + _isConnected = false; emit disconnectedFromDomain(); @@ -65,6 +70,7 @@ void DomainHandler::softReset() { void DomainHandler::hardReset() { softReset(); + _iceDomainID = QUuid(); _hostname = QString(); _sockAddr.setAddress(QHostAddress::Null); } @@ -136,7 +142,7 @@ void DomainHandler::setIceServerHostnameAndID(const QString& iceServerHostname, // re-set the domain info to connect to new domain hardReset(); - setUUID(id); + _iceDomainID = id; _iceServerSockAddr = HifiSockAddr(iceServerHostname, ICE_SERVER_DEFAULT_PORT); // refresh our ICE client UUID to something new @@ -265,7 +271,7 @@ void DomainHandler::processICEResponsePacket(const QByteArray& icePacket) { NetworkPeer packetPeer; iceResponseStream >> packetPeer; - if (packetPeer.getUUID() != _uuid) { + if (packetPeer.getUUID() != _iceDomainID) { qDebug() << "Received a network peer with ID that does not match current domain. Will not attempt connection."; } else { qDebug() << "Received network peer object for domain -" << packetPeer; diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index e9d7fb1725..86c6e6bc57 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -55,6 +55,8 @@ public: const QUuid& getAssignmentUUID() const { return _assignmentUUID; } void setAssignmentUUID(const QUuid& assignmentUUID) { _assignmentUUID = assignmentUUID; } + const QUuid& getICEDomainID() const { return _iceDomainID; } + const QUuid& getICEClientID() const { return _iceClientID; } bool requiresICE() const { return !_iceServerSockAddr.isNull(); } @@ -97,6 +99,7 @@ private: QString _hostname; HifiSockAddr _sockAddr; QUuid _assignmentUUID; + QUuid _iceDomainID; QUuid _iceClientID; HifiSockAddr _iceServerSockAddr; NetworkPeer _icePeer; diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 50539e1196..905fc06eeb 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -342,10 +342,10 @@ void NodeList::handleICEConnectionToDomainServer() { LimitedNodeList::sendHeartbeatToIceServer(_domainHandler.getICEServerSockAddr(), _domainHandler.getICEClientID(), - _domainHandler.getUUID()); + _domainHandler.getICEDomainID()); } else { qDebug() << "Sending ping packets to establish connectivity with domain-server with ID" - << uuidStringWithoutCurlyBraces(_domainHandler.getUUID()); + << uuidStringWithoutCurlyBraces(_domainHandler.getICEDomainID()); // send the ping packet to the local and public sockets for this nodfe QByteArray localPingPacket = constructPingPacket(PingType::Local, false, _domainHandler.getICEClientID()); From 3d8846356907da635d148a4532ea3453de153c25 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 3 Oct 2014 17:05:14 -0700 Subject: [PATCH 027/179] Blend between cube face textures. --- .../shaders/metavoxel_voxel_splat.frag | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/interface/resources/shaders/metavoxel_voxel_splat.frag b/interface/resources/shaders/metavoxel_voxel_splat.frag index d0d0661164..368f6fa52b 100644 --- a/interface/resources/shaders/metavoxel_voxel_splat.frag +++ b/interface/resources/shaders/metavoxel_voxel_splat.frag @@ -26,12 +26,20 @@ varying vec4 alphaValues; void main(void) { // determine the cube face to use for texture coordinate generation vec3 absNormal = abs(normal); - vec3 steps = step(absNormal.zzy, absNormal.xyx); - vec2 parameters = mix(vec2(0.0, steps.y), vec2(steps.x, steps.x), steps.z); + vec3 steps = smoothstep(absNormal.zzy - vec3(0.25, 0.25, 0.25), absNormal.zzy + vec3(0.25, 0.25, 0.25), absNormal.xyx); // blend the splat textures - gl_FragColor = (texture2D(diffuseMaps[0], mix(gl_TexCoord[0].xy, gl_TexCoord[0].zw, parameters)) * alphaValues.x + - texture2D(diffuseMaps[1], mix(gl_TexCoord[1].xy, gl_TexCoord[1].zw, parameters)) * alphaValues.y + - texture2D(diffuseMaps[2], mix(gl_TexCoord[2].xy, gl_TexCoord[2].zw, parameters)) * alphaValues.z + - texture2D(diffuseMaps[3], mix(gl_TexCoord[3].xy, gl_TexCoord[3].zw, parameters)) * alphaValues.w); + vec4 base0 = texture2D(diffuseMaps[0], gl_TexCoord[0].xy); + vec4 base1 = texture2D(diffuseMaps[1], gl_TexCoord[1].xy); + vec4 base2 = texture2D(diffuseMaps[2], gl_TexCoord[2].xy); + vec4 base3 = texture2D(diffuseMaps[3], gl_TexCoord[3].xy); + gl_FragColor = + mix(mix(base0, texture2D(diffuseMaps[0], gl_TexCoord[0].xw), steps.y), + mix(base0, texture2D(diffuseMaps[0], gl_TexCoord[0].zw), steps.x), steps.z) * alphaValues.x + + mix(mix(base1, texture2D(diffuseMaps[1], gl_TexCoord[1].xw), steps.y), + mix(base1, texture2D(diffuseMaps[1], gl_TexCoord[1].zw), steps.x), steps.z) * alphaValues.y + + mix(mix(base2, texture2D(diffuseMaps[2], gl_TexCoord[2].xw), steps.y), + mix(base2, texture2D(diffuseMaps[2], gl_TexCoord[2].zw), steps.x), steps.z) * alphaValues.z + + mix(mix(base3, texture2D(diffuseMaps[3], gl_TexCoord[3].xw), steps.y), + mix(base3, texture2D(diffuseMaps[3], gl_TexCoord[3].zw), steps.x), steps.z) * alphaValues.w; } From aa15ef7f85c71774ac2db891148c332180e2cc9a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 3 Oct 2014 17:10:56 -0700 Subject: [PATCH 028/179] only have the ice-server respond if there was a matching conectee --- ice-server/src/IceServer.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ice-server/src/IceServer.cpp b/ice-server/src/IceServer.cpp index e3db679009..c06bb0fc88 100644 --- a/ice-server/src/IceServer.cpp +++ b/ice-server/src/IceServer.cpp @@ -102,7 +102,7 @@ void IceServer::processDatagrams() { if (requestingConnections.size() > 0) { // send a heartbeart response based on the set of connections qDebug() << "Sending a heartbeat response to" << senderUUID << "who has" << requestingConnections.size() - << "potential connections"; + << "potential connections"; sendHeartbeatResponse(sendingSockAddr, requestingConnections); } } @@ -114,6 +114,7 @@ void IceServer::sendHeartbeatResponse(const HifiSockAddr& destinationSockAddr, Q QByteArray outgoingPacket(MAX_PACKET_SIZE, 0); int currentPacketSize = populatePacketHeader(outgoingPacket, PacketTypeIceServerHeartbeatResponse, _id); + int numHeaderBytes = currentPacketSize; // go through the connections, sending packets containing connection information for those nodes while (peerID != connections.end()) { @@ -142,9 +143,11 @@ void IceServer::sendHeartbeatResponse(const HifiSockAddr& destinationSockAddr, Q } } - // write the last packet - _serverSocket.writeDatagram(outgoingPacket.data(), currentPacketSize, - destinationSockAddr.getAddress(), destinationSockAddr.getPort()); + if (currentPacketSize > numHeaderBytes) { + // write the last packet, if there is data in it + _serverSocket.writeDatagram(outgoingPacket.data(), currentPacketSize, + destinationSockAddr.getAddress(), destinationSockAddr.getPort()); + } } void IceServer::clearInactivePeers() { From 91942e6188b6e50bd54e0ccd62affa5c64f01b34 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 3 Oct 2014 17:17:22 -0700 Subject: [PATCH 029/179] Reduce the size of the smoothing step. --- interface/resources/shaders/metavoxel_voxel_splat.frag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/shaders/metavoxel_voxel_splat.frag b/interface/resources/shaders/metavoxel_voxel_splat.frag index 368f6fa52b..e7a33618cb 100644 --- a/interface/resources/shaders/metavoxel_voxel_splat.frag +++ b/interface/resources/shaders/metavoxel_voxel_splat.frag @@ -26,7 +26,7 @@ varying vec4 alphaValues; void main(void) { // determine the cube face to use for texture coordinate generation vec3 absNormal = abs(normal); - vec3 steps = smoothstep(absNormal.zzy - vec3(0.25, 0.25, 0.25), absNormal.zzy + vec3(0.25, 0.25, 0.25), absNormal.xyx); + vec3 steps = smoothstep(absNormal.zzy - vec3(0.05, 0.05, 0.05), absNormal.zzy + vec3(0.05, 0.05, 0.05), absNormal.xyx); // blend the splat textures vec4 base0 = texture2D(diffuseMaps[0], gl_TexCoord[0].xy); From b7165cb3539c331e16cf04571b34a34967d919a1 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Sun, 5 Oct 2014 21:11:42 +0200 Subject: [PATCH 030/179] store the last selected audio device --- examples/selectAudioDevice.js | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/examples/selectAudioDevice.js b/examples/selectAudioDevice.js index 23606f774c..a90f3da4cf 100644 --- a/examples/selectAudioDevice.js +++ b/examples/selectAudioDevice.js @@ -41,6 +41,9 @@ if (typeof String.prototype.trimEndsWith != 'function') { }; } +const INPUT_DEVICE_SETTING = "audio_input_device"; +const OUTPUT_DEVICE_SETTING = "audio_output_device"; + var selectedInputMenu = ""; var selectedOutputMenu = ""; @@ -48,9 +51,14 @@ function setupAudioMenus() { Menu.addMenu("Tools > Audio"); Menu.addSeparator("Tools > Audio","Output Audio Device"); + var outputDeviceSetting = Settings.getValue(OUTPUT_DEVICE_SETTING); var outputDevices = AudioDevice.getOutputDevices(); var selectedOutputDevice = AudioDevice.getOutputDevice(); - + if (outputDevices.indexOf(outputDeviceSetting) != -1 && selectedOutputDevice != outputDeviceSetting) { + if (AudioDevice.setOutputDevice(outputDeviceSetting)) { + selectedOutputDevice = outputDeviceSetting; + } + } for(var i = 0; i < outputDevices.length; i++) { var thisDeviceSelected = (outputDevices[i] == selectedOutputDevice); var menuItem = "Use " + outputDevices[i] + " for Output"; @@ -67,9 +75,14 @@ function setupAudioMenus() { Menu.addSeparator("Tools > Audio","Input Audio Device"); + var inputDeviceSetting = Settings.getValue(INPUT_DEVICE_SETTING); var inputDevices = AudioDevice.getInputDevices(); var selectedInputDevice = AudioDevice.getInputDevice(); - + if (inputDevices.indexOf(inputDeviceSetting) != -1 && selectedInputDevice != inputDeviceSetting) { + if (AudioDevice.setInputDevice(inputDeviceSetting)) { + selectedInputDevice = inputDeviceSetting; + } + } for(var i = 0; i < inputDevices.length; i++) { var thisDeviceSelected = (inputDevices[i] == selectedInputDevice); var menuItem = "Use " + inputDevices[i] + " for Input"; @@ -85,7 +98,8 @@ function setupAudioMenus() { } } -setupAudioMenus(); +// Have a small delay before the menu's get setup and the audio devices can switch to the last selected ones +Script.setTimeout(function() { setupAudioMenus(); }, 5000); function scriptEnding() { Menu.removeMenu("Tools > Audio"); @@ -101,15 +115,18 @@ function menuItemEvent(menuItem) { Menu.setIsOptionChecked(selectedOutputMenu, false); selectedOutputMenu = menuItem; Menu.setIsOptionChecked(selectedOutputMenu, true); - AudioDevice.setOutputDevice(selectedDevice); - + if (AudioDevice.setOutputDevice(selectedDevice)) { + Settings.setValue(OUTPUT_DEVICE_SETTING, selectedDevice); + } } else if (menuItem.endsWith(" for Input")) { var selectedDevice = menuItem.trimStartsWith("Use ").trimEndsWith(" for Input"); print("input audio selection..." + selectedDevice); Menu.setIsOptionChecked(selectedInputMenu, false); selectedInputMenu = menuItem; Menu.setIsOptionChecked(selectedInputMenu, true); - AudioDevice.setInputDevice(selectedDevice); + if (AudioDevice.setInputDevice(selectedDevice)) { + Settings.setValue(INPUT_DEVICE_SETTING, selectedDevice); + } } } } From e70c57cb95a6af326c3fd8cf73934f6757aab2d5 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 6 Oct 2014 08:37:07 -0700 Subject: [PATCH 031/179] Replace magic numbers wiht const values --- examples/editModels.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/editModels.js b/examples/editModels.js index 503e3a6dad..820fe613c8 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -1236,7 +1236,7 @@ var toolBar = (function () { checkCount++; if (naturalDimensions.x == 0 && naturalDimensions.y == 0 && naturalDimensions.z == 0) { - if (checkCount < RESIZE_TIMEOUT / RESIZE_INTERVAL) { + if (checkCount < RESIZE_MAX_CHECKS) { Script.setTimeout(resize, RESIZE_INTERVAL); } else { print("Resize failed: timed out waiting for model (" + url + ") to load"); @@ -1247,7 +1247,7 @@ var toolBar = (function () { } } - Script.setTimeout(resize, 50); + Script.setTimeout(resize, RESIZE_INTERVAL); } else { print("Can't add model: Model would be out of bounds."); From f89b225da2d8c11017ec405d72328813224723ce Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 6 Oct 2014 09:17:25 -0700 Subject: [PATCH 032/179] handle local socket changes by monitoring every so often --- assignment-client/src/octree/OctreeServer.cpp | 2 +- interface/src/FileLogger.cpp | 2 +- libraries/networking/src/HifiSockAddr.cpp | 41 +++++++++---------- libraries/networking/src/HifiSockAddr.h | 2 +- libraries/networking/src/LimitedNodeList.cpp | 29 ++++++++++++- libraries/networking/src/LimitedNodeList.h | 5 +++ libraries/networking/src/NodeList.cpp | 4 +- 7 files changed, 56 insertions(+), 29 deletions(-) diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 5833d8a764..42af8ff1b9 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -940,7 +940,7 @@ void OctreeServer::run() { qDebug("--statusHost=%s", statusHost); _statusHost = statusHost; } else { - _statusHost = QHostAddress(getHostOrderLocalAddress()).toString(); + _statusHost = getLocalAddress().toString(); } qDebug("statusHost=%s", qPrintable(_statusHost)); diff --git a/interface/src/FileLogger.cpp b/interface/src/FileLogger.cpp index cb3d43925d..4808842036 100644 --- a/interface/src/FileLogger.cpp +++ b/interface/src/FileLogger.cpp @@ -28,7 +28,7 @@ FileLogger::FileLogger(QObject* parent) : setExtraDebugging(false); _fileName = FileUtils::standardPath(LOGS_DIRECTORY); - QHostAddress clientAddress = QHostAddress(getHostOrderLocalAddress()); + QHostAddress clientAddress = getLocalAddress(); QDateTime now = QDateTime::currentDateTime(); _fileName.append(QString(FILENAME_FORMAT).arg(clientAddress.toString(), now.toString(DATETIME_FORMAT))); } diff --git a/libraries/networking/src/HifiSockAddr.cpp b/libraries/networking/src/HifiSockAddr.cpp index d30f7944d7..97e9721356 100644 --- a/libraries/networking/src/HifiSockAddr.cpp +++ b/libraries/networking/src/HifiSockAddr.cpp @@ -90,32 +90,29 @@ QDataStream& operator>>(QDataStream& dataStream, HifiSockAddr& sockAddr) { return dataStream; } -quint32 getHostOrderLocalAddress() { +QHostAddress getLocalAddress() { - static int localAddress = 0; + QHostAddress localAddress; - if (localAddress == 0) { - foreach(const QNetworkInterface &networkInterface, QNetworkInterface::allInterfaces()) { - if (networkInterface.flags() & QNetworkInterface::IsUp - && networkInterface.flags() & QNetworkInterface::IsRunning - && networkInterface.flags() & ~QNetworkInterface::IsLoopBack) { - // we've decided that this is the active NIC - // enumerate it's addresses to grab the IPv4 address - foreach(const QNetworkAddressEntry &entry, networkInterface.addressEntries()) { - // make sure it's an IPv4 address that isn't the loopback - if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol && !entry.ip().isLoopback()) { - qDebug("Node's local address is %s", entry.ip().toString().toLocal8Bit().constData()); - - // set our localAddress and break out - localAddress = entry.ip().toIPv4Address(); - break; - } + foreach(const QNetworkInterface &networkInterface, QNetworkInterface::allInterfaces()) { + if (networkInterface.flags() & QNetworkInterface::IsUp + && networkInterface.flags() & QNetworkInterface::IsRunning + && networkInterface.flags() & ~QNetworkInterface::IsLoopBack) { + // we've decided that this is the active NIC + // enumerate it's addresses to grab the IPv4 address + foreach(const QNetworkAddressEntry &entry, networkInterface.addressEntries()) { + // make sure it's an IPv4 address that isn't the loopback + if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol && !entry.ip().isLoopback()) { + + // set our localAddress and break out + localAddress = entry.ip(); + break; } } - - if (localAddress != 0) { - break; - } + } + + if (!localAddress.isNull()) { + break; } } diff --git a/libraries/networking/src/HifiSockAddr.h b/libraries/networking/src/HifiSockAddr.h index 8a591a60b8..42f815390a 100644 --- a/libraries/networking/src/HifiSockAddr.h +++ b/libraries/networking/src/HifiSockAddr.h @@ -58,7 +58,7 @@ private: uint qHash(const HifiSockAddr& key, uint seed); -quint32 getHostOrderLocalAddress(); +QHostAddress getLocalAddress(); Q_DECLARE_METATYPE(HifiSockAddr) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 507788009a..a428f1f495 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -70,6 +70,7 @@ LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short _nodeHashMutex(QMutex::Recursive), _nodeSocket(this), _dtlsSocket(NULL), + _localSockAddr(), _publicSockAddr(), _numCollectedPackets(0), _numCollectedBytes(0), @@ -89,6 +90,15 @@ LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short const int LARGER_BUFFER_SIZE = 1048576; changeSocketBufferSizes(LARGER_BUFFER_SIZE); + // check for local socket updates every so often + const int LOCAL_SOCKET_UPDATE_INTERVAL_MSECS = 5 * 1000; + QTimer* localSocketUpdate = new QTimer(this); + connect(localSocketUpdate, &QTimer::timeout, this, &LimitedNodeList::updateLocalSockAddr); + localSocketUpdate->start(LOCAL_SOCKET_UPDATE_INTERVAL_MSECS); + + // check the local socket right now + updateLocalSockAddr(); + _packetStatTimer.start(); } @@ -652,6 +662,23 @@ bool LimitedNodeList::processSTUNResponse(const QByteArray& packet) { return false; } +void LimitedNodeList::updateLocalSockAddr() { + HifiSockAddr newSockAddr(getLocalAddress(), _nodeSocket.localPort()); + if (newSockAddr != _localSockAddr) { + + if (_localSockAddr.isNull()) { + qDebug() << "Local socket is" << newSockAddr; + } else { + qDebug() << "Local socket has changed from" << _localSockAddr << "to" << newSockAddr; + } + + + _localSockAddr = newSockAddr; + + emit localSockAddrChanged(_localSockAddr); + } +} + void LimitedNodeList::sendHeartbeatToIceServer(const HifiSockAddr& iceServerSockAddr, QUuid headerID, const QUuid& connectionRequestID) { @@ -662,7 +689,7 @@ void LimitedNodeList::sendHeartbeatToIceServer(const HifiSockAddr& iceServerSock QByteArray iceRequestByteArray = byteArrayWithPopulatedHeader(PacketTypeIceServerHeartbeat, headerID); QDataStream iceDataStream(&iceRequestByteArray, QIODevice::Append); - iceDataStream << _publicSockAddr << HifiSockAddr(QHostAddress(getHostOrderLocalAddress()), _nodeSocket.localPort()); + iceDataStream << _publicSockAddr << _localSockAddr; if (!connectionRequestID.isNull()) { iceDataStream << connectionRequestID; diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index a7ffc7ec28..1b30375fad 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -127,11 +127,15 @@ public slots: void removeSilentNodes(); + void updateLocalSockAddr(); + void killNodeWithUUID(const QUuid& nodeUUID); signals: void uuidChanged(const QUuid& ownerUUID, const QUuid& oldUUID); void nodeAdded(SharedNodePointer); void nodeKilled(SharedNodePointer); + + void localSockAddrChanged(const HifiSockAddr& localSockAddr); void publicSockAddrChanged(const HifiSockAddr& publicSockAddr); protected: static std::auto_ptr _sharedInstance; @@ -153,6 +157,7 @@ protected: QMutex _nodeHashMutex; QUdpSocket _nodeSocket; QUdpSocket* _dtlsSocket; + HifiSockAddr _localSockAddr; HifiSockAddr _publicSockAddr; int _numCollectedPackets; int _numCollectedBytes; diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 905fc06eeb..cac4071fb2 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -302,9 +302,7 @@ void NodeList::sendDomainServerCheckIn() { QDataStream packetStream(&domainServerPacket, QIODevice::Append); // pack our data to send to the domain-server - packetStream << _ownerType << _publicSockAddr - << HifiSockAddr(QHostAddress(getHostOrderLocalAddress()), _nodeSocket.localPort()) - << (quint8) _nodeTypesOfInterest.size(); + packetStream << _ownerType << _publicSockAddr << _localSockAddr << (quint8) _nodeTypesOfInterest.size(); // copy over the bytes for node types of interest, if required foreach (NodeType_t nodeTypeOfInterest, _nodeTypesOfInterest) { From b61e659382001fa474b9c1efd88b1a4c66fc147e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 6 Oct 2014 09:18:50 -0700 Subject: [PATCH 033/179] send an ICE heartbeat anytime the domain-server local socket changes --- domain-server/src/DomainServer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 61310cad75..cceb55ab62 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -357,7 +357,8 @@ void DomainServer::setupAutomaticNetworking() { connect(iceHeartbeatTimer, &QTimer::timeout, this, &DomainServer::performICEUpdates); iceHeartbeatTimer->start(ICE_HEARBEAT_INTERVAL_MSECS); - // call our sendHeartbeaToIceServer immediately anytime a public address changes + // call our sendHeartbeaToIceServer immediately anytime a local or public socket changes + connect(nodeList, &LimitedNodeList::localSockAddrChanged, this &DomainServer::sendHearbeatToIceServer); connect(nodeList, &LimitedNodeList::publicSockAddrChanged, this, &DomainServer::sendHearbeatToIceServer); // tell the data server which type of automatic networking we are using From 0459254e3f705f1449b1e90a4c142411e879c2bc Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 6 Oct 2014 09:24:48 -0700 Subject: [PATCH 034/179] fix connection to slot for local addr update, refresh AcctManager after restart --- domain-server/src/DomainServer.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index cceb55ab62..232348e05a 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -57,6 +57,11 @@ DomainServer::DomainServer(int argc, char* argv[]) : setApplicationName("domain-server"); QSettings::setDefaultFormat(QSettings::IniFormat); + + // make sure we have a fresh AccountManager instance + // (need this since domain-server can restart itself and maintain static variables) + AccountManager::getInstance(true); + _settingsManager.setupConfigMap(arguments()); installNativeEventFilter(&_shutdownEventListener); @@ -82,10 +87,6 @@ DomainServer::DomainServer(int argc, char* argv[]) : void DomainServer::restart() { qDebug() << "domain-server is restarting."; - // make sure all static instances are reset - LimitedNodeList::getInstance()->reset(); - AccountManager::getInstance(true); - exit(DomainServer::EXIT_CODE_REBOOT); } @@ -358,7 +359,7 @@ void DomainServer::setupAutomaticNetworking() { iceHeartbeatTimer->start(ICE_HEARBEAT_INTERVAL_MSECS); // call our sendHeartbeaToIceServer immediately anytime a local or public socket changes - connect(nodeList, &LimitedNodeList::localSockAddrChanged, this &DomainServer::sendHearbeatToIceServer); + connect(nodeList, &LimitedNodeList::localSockAddrChanged, this, &DomainServer::sendHearbeatToIceServer); connect(nodeList, &LimitedNodeList::publicSockAddrChanged, this, &DomainServer::sendHearbeatToIceServer); // tell the data server which type of automatic networking we are using From 89cc7c7b0d4593c13715b15b8a5e22e6c1f4d7a8 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 6 Oct 2014 09:35:44 -0700 Subject: [PATCH 035/179] add an optional forced reset of NetworkAccessManager --- domain-server/src/DomainServer.cpp | 2 ++ libraries/networking/src/NetworkAccessManager.cpp | 5 +++-- libraries/networking/src/NetworkAccessManager.h | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 232348e05a..5a8f8fb40e 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -57,6 +57,8 @@ DomainServer::DomainServer(int argc, char* argv[]) : setApplicationName("domain-server"); QSettings::setDefaultFormat(QSettings::IniFormat); + // force a refresh of the NetworkAccessManager instance for this thread + NetworkAccessManager::getInstance(true); // make sure we have a fresh AccountManager instance // (need this since domain-server can restart itself and maintain static variables) diff --git a/libraries/networking/src/NetworkAccessManager.cpp b/libraries/networking/src/NetworkAccessManager.cpp index e92760d303..6e2580f51e 100644 --- a/libraries/networking/src/NetworkAccessManager.cpp +++ b/libraries/networking/src/NetworkAccessManager.cpp @@ -15,8 +15,8 @@ QThreadStorage networkAccessManagers; -NetworkAccessManager& NetworkAccessManager::getInstance() { - if (!networkAccessManagers.hasLocalData()) { +NetworkAccessManager& NetworkAccessManager::getInstance(bool forceReset) { + if (!networkAccessManagers.hasLocalData() || forceReset) { networkAccessManagers.setLocalData(new NetworkAccessManager()); } @@ -24,4 +24,5 @@ NetworkAccessManager& NetworkAccessManager::getInstance() { } NetworkAccessManager::NetworkAccessManager() { + } diff --git a/libraries/networking/src/NetworkAccessManager.h b/libraries/networking/src/NetworkAccessManager.h index 9594170518..6636a0eae6 100644 --- a/libraries/networking/src/NetworkAccessManager.h +++ b/libraries/networking/src/NetworkAccessManager.h @@ -18,7 +18,7 @@ class NetworkAccessManager : public QNetworkAccessManager { Q_OBJECT public: - static NetworkAccessManager& getInstance(); + static NetworkAccessManager& getInstance(bool forceReset = false); private: NetworkAccessManager(); From a441c5fb166ed3902dd17080b073204a9db59d83 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 6 Oct 2014 09:42:47 -0700 Subject: [PATCH 036/179] don't use an unecessary subclass of QNetworkAccessManager --- libraries/networking/src/NetworkAccessManager.cpp | 10 +++------- libraries/networking/src/NetworkAccessManager.h | 7 ++----- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/libraries/networking/src/NetworkAccessManager.cpp b/libraries/networking/src/NetworkAccessManager.cpp index 6e2580f51e..161170a87d 100644 --- a/libraries/networking/src/NetworkAccessManager.cpp +++ b/libraries/networking/src/NetworkAccessManager.cpp @@ -13,16 +13,12 @@ #include "NetworkAccessManager.h" -QThreadStorage networkAccessManagers; +QThreadStorage networkAccessManagers; -NetworkAccessManager& NetworkAccessManager::getInstance(bool forceReset) { +QNetworkAccessManager& NetworkAccessManager::getInstance(bool forceReset) { if (!networkAccessManagers.hasLocalData() || forceReset) { - networkAccessManagers.setLocalData(new NetworkAccessManager()); + networkAccessManagers.setLocalData(new QNetworkAccessManager()); } return *networkAccessManagers.localData(); } - -NetworkAccessManager::NetworkAccessManager() { - -} diff --git a/libraries/networking/src/NetworkAccessManager.h b/libraries/networking/src/NetworkAccessManager.h index 6636a0eae6..3a236f7041 100644 --- a/libraries/networking/src/NetworkAccessManager.h +++ b/libraries/networking/src/NetworkAccessManager.h @@ -15,13 +15,10 @@ #include /// Wrapper around QNetworkAccessManager to restrict at one instance by thread -class NetworkAccessManager : public QNetworkAccessManager { +class NetworkAccessManager : public QObject { Q_OBJECT public: - static NetworkAccessManager& getInstance(bool forceReset = false); - -private: - NetworkAccessManager(); + static QNetworkAccessManager& getInstance(bool forceReset = false); }; #endif // hifi_NetworkAccessManager_h \ No newline at end of file From 78f8aba504b9f9eca90509a75a604c4897c32c0f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 6 Oct 2014 09:44:47 -0700 Subject: [PATCH 037/179] fix for NetworkAccessManager getInstance return --- libraries/networking/src/AccountManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp index 7d924d02de..bb471442ea 100644 --- a/libraries/networking/src/AccountManager.cpp +++ b/libraries/networking/src/AccountManager.cpp @@ -187,7 +187,7 @@ void AccountManager::invokedRequest(const QString& path, const JSONCallbackParameters& callbackParams, const QByteArray& dataByteArray, QHttpMultiPart* dataMultiPart) { - NetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkRequest networkRequest; @@ -359,7 +359,7 @@ void AccountManager::setAccessTokenForCurrentAuthURL(const QString& accessToken) void AccountManager::requestAccessToken(const QString& login, const QString& password) { - NetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkRequest request; @@ -431,7 +431,7 @@ void AccountManager::requestAccessTokenError(QNetworkReply::NetworkError error) } void AccountManager::requestProfile() { - NetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QUrl profileURL = _authURL; profileURL.setPath("/api/v1/users/profile"); From 484c0d30cb92d9794d9bac6837fe2d33b52a8282 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 6 Oct 2014 09:54:52 -0700 Subject: [PATCH 038/179] don't require refresh of NetworkAccessManager, should handle restarts --- domain-server/src/DomainServer.cpp | 3 --- libraries/networking/src/NetworkAccessManager.cpp | 6 +++--- libraries/networking/src/NetworkAccessManager.h | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 5a8f8fb40e..7352729fa4 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -57,9 +57,6 @@ DomainServer::DomainServer(int argc, char* argv[]) : setApplicationName("domain-server"); QSettings::setDefaultFormat(QSettings::IniFormat); - // force a refresh of the NetworkAccessManager instance for this thread - NetworkAccessManager::getInstance(true); - // make sure we have a fresh AccountManager instance // (need this since domain-server can restart itself and maintain static variables) AccountManager::getInstance(true); diff --git a/libraries/networking/src/NetworkAccessManager.cpp b/libraries/networking/src/NetworkAccessManager.cpp index 161170a87d..841b7491c7 100644 --- a/libraries/networking/src/NetworkAccessManager.cpp +++ b/libraries/networking/src/NetworkAccessManager.cpp @@ -15,9 +15,9 @@ QThreadStorage networkAccessManagers; -QNetworkAccessManager& NetworkAccessManager::getInstance(bool forceReset) { - if (!networkAccessManagers.hasLocalData() || forceReset) { - networkAccessManagers.setLocalData(new QNetworkAccessManager()); +QNetworkAccessManager& NetworkAccessManager::getInstance() { + if (!networkAccessManagers.hasLocalData()) { + networkAccessManagers.setLocalData(new QNetworkAccessManager()); } return *networkAccessManagers.localData(); diff --git a/libraries/networking/src/NetworkAccessManager.h b/libraries/networking/src/NetworkAccessManager.h index 3a236f7041..d911d935dc 100644 --- a/libraries/networking/src/NetworkAccessManager.h +++ b/libraries/networking/src/NetworkAccessManager.h @@ -18,7 +18,7 @@ class NetworkAccessManager : public QObject { Q_OBJECT public: - static QNetworkAccessManager& getInstance(bool forceReset = false); + static QNetworkAccessManager& getInstance(); }; #endif // hifi_NetworkAccessManager_h \ No newline at end of file From f0852ba283d1f340e82bc7d73c30705dfa1b2d3c Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Mon, 6 Oct 2014 11:21:35 -0600 Subject: [PATCH 039/179] Using new variable in all references to S3 bucket --- examples/ControlACs.js | 4 +- examples/ControlledAC.js | 4 +- examples/Recorder.js | 3 +- examples/airGuitar.js | 28 ++++---- examples/audioBall.js | 4 +- examples/audioReflectorTools.js | 45 ++++++------- examples/avatarCollision.js | 46 ++++++------- examples/bot.js | 10 +-- examples/botProceduralWayPoints.js | 13 ++-- examples/bot_procedural.js | 13 ++-- examples/bot_randomExpression.js | 8 ++- examples/clap.js | 24 +++---- examples/drumStick.js | 6 +- examples/editModelExample.js | 14 ++-- examples/editModels.js | 22 ++++--- examples/editVoxels.js | 78 ++++++++++++----------- examples/fallingSand.js | 4 +- examples/frisbee.js | 4 +- examples/grenadeLauncher.js | 14 ++-- examples/growTrees.js | 4 +- examples/gun.js | 14 ++-- examples/inWorldTestTone.js | 4 +- examples/libraries/entitySelectionTool.js | 4 +- examples/libraries/globals.js | 11 ++++ examples/locationsMenu.js | 4 +- examples/myBalance.js | 4 +- examples/newEditEntities.js | 21 +++--- examples/overlaysExample.js | 9 +-- examples/particleBirds.js | 12 ++-- examples/particleModelExample.js | 6 +- examples/playSound.js | 4 +- examples/playSoundLoop.js | 7 +- examples/playSoundOrbit.js | 4 +- examples/playSoundWave.js | 4 +- examples/radio.js | 5 +- examples/spaceInvadersExample.js | 32 +++++----- examples/squeezeHands.js | 6 +- examples/toyball.js | 4 +- 38 files changed, 290 insertions(+), 213 deletions(-) create mode 100644 examples/libraries/globals.js diff --git a/examples/ControlACs.js b/examples/ControlACs.js index 4ccf5cff59..bbdb1cc4ef 100644 --- a/examples/ControlACs.js +++ b/examples/ControlACs.js @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); + // Set the following variables to the right value var NUM_AC = 3; // This is the number of AC. Their ID need to be unique and between 0 (included) and NUM_AC (excluded) var NAMES = new Array("Craig", "Clement", "Jeff"); // ACs names ordered by IDs (Default name is "ACx", x = ID + 1)) @@ -37,7 +39,7 @@ COLORS[HIDE] = { red: HIDE, green: 0, blue: 0 }; var windowDimensions = Controller.getViewportDimensions(); -var TOOL_ICON_URL = "http://s3-us-west-1.amazonaws.com/highfidelity-public/images/tools/"; +var TOOL_ICON_URL = HIFI_PUBLIC_BUCKET + "images/tools/"; var ALPHA_ON = 1.0; var ALPHA_OFF = 0.7; var COLOR_TOOL_BAR = { red: 0, green: 0, blue: 0 }; diff --git a/examples/ControlledAC.js b/examples/ControlledAC.js index 33fa629ff8..b19d27946a 100644 --- a/examples/ControlledAC.js +++ b/examples/ControlledAC.js @@ -9,8 +9,10 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); + // Set the following variables to the values needed -var filename = "http://s3-us-west-1.amazonaws.com/highfidelity-public/ozan/bartender.rec"; +var filename = HIFI_PUBLIC_BUCKET + "ozan/bartender.rec"; var playFromCurrentLocation = true; var useDisplayName = true; var useAttachments = true; diff --git a/examples/Recorder.js b/examples/Recorder.js index 533f9f7fab..8c784bcea2 100644 --- a/examples/Recorder.js +++ b/examples/Recorder.js @@ -9,6 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); Script.include("libraries/toolBars.js"); var recordingFile = "recording.rec"; @@ -22,7 +23,7 @@ function setPlayerOptions() { } var windowDimensions = Controller.getViewportDimensions(); -var TOOL_ICON_URL = "http://s3-us-west-1.amazonaws.com/highfidelity-public/images/tools/"; +var TOOL_ICON_URL = HIFI_PUBLIC_BUCKET + "images/tools/"; var ALPHA_ON = 1.0; var ALPHA_OFF = 0.7; var COLOR_ON = { red: 128, green: 0, blue: 0 }; diff --git a/examples/airGuitar.js b/examples/airGuitar.js index 78c16be7bc..c0e06add30 100644 --- a/examples/airGuitar.js +++ b/examples/airGuitar.js @@ -10,6 +10,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); + function length(v) { return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z); } @@ -26,28 +28,28 @@ function vMinus(a, b) { } // The model file to be used for the guitar -var guitarModel = "https://s3-us-west-1.amazonaws.com/highfidelity-public/models/attachments/guitar.fst"; +var guitarModel = HIFI_PUBLIC_BUCKET + "models/attachments/guitar.fst"; // Load sounds that will be played var chords = new Array(); // Nylon string guitar -chords[1] = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Guitars/Guitar+-+Nylon+A.raw"); -chords[2] = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Guitars/Guitar+-+Nylon+B.raw"); -chords[3] = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Guitars/Guitar+-+Nylon+E.raw"); -chords[4] = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Guitars/Guitar+-+Nylon+G.raw"); +chords[1] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Nylon+A.raw"); +chords[2] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Nylon+B.raw"); +chords[3] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Nylon+E.raw"); +chords[4] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Nylon+G.raw"); // Electric guitar -chords[5] = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Guitars/Guitar+-+Metal+A+short.raw"); -chords[6] = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Guitars/Guitar+-+Metal+B+short.raw"); -chords[7] = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Guitars/Guitar+-+Metal+E+short.raw"); -chords[8] = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Guitars/Guitar+-+Metal+G+short.raw"); +chords[5] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Metal+A+short.raw"); +chords[6] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Metal+B+short.raw"); +chords[7] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Metal+E+short.raw"); +chords[8] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Metal+G+short.raw"); // Steel Guitar -chords[9] = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Guitars/Guitar+-+Steel+A.raw"); -chords[10] = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Guitars/Guitar+-+Steel+B.raw"); -chords[11] = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Guitars/Guitar+-+Steel+E.raw"); -chords[12] = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Guitars/Guitar+-+Steel+G.raw"); +chords[9] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Steel+A.raw"); +chords[10] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Steel+B.raw"); +chords[11] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Steel+E.raw"); +chords[12] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Steel+G.raw"); var NUM_CHORDS = 4; var NUM_GUITARS = 3; diff --git a/examples/audioBall.js b/examples/audioBall.js index 2a77a0999f..76f9aabec8 100644 --- a/examples/audioBall.js +++ b/examples/audioBall.js @@ -13,7 +13,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var sound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Animals/mexicanWhipoorwill.raw"); +Script.include("libraries/globals.js"); + +var sound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Animals/mexicanWhipoorwill.raw"); var CHANCE_OF_PLAYING_SOUND = 0.01; var FACTOR = 0.75; diff --git a/examples/audioReflectorTools.js b/examples/audioReflectorTools.js index f299407e54..c5a88edd57 100644 --- a/examples/audioReflectorTools.js +++ b/examples/audioReflectorTools.js @@ -11,6 +11,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); var delayScale = 100.0; var fanoutScale = 10.0; @@ -94,7 +95,7 @@ var delaySlider = Overlays.addOverlay("image", { // alternate form of expressing bounds bounds: { x: 100, y: delayY, width: 150, height: sliderHeight}, subImage: { x: 46, y: 0, width: 200, height: 71 }, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/slider.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/slider.png", color: { red: 255, green: 255, blue: 255}, alpha: 1 }); @@ -108,7 +109,7 @@ var delayThumb = Overlays.addOverlay("image", { y: delayY + 9, width: 18, height: 17, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/thumb.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/thumb.png", color: { red: 255, green: 0, blue: 0}, alpha: 1 }); @@ -132,7 +133,7 @@ var fanoutSlider = Overlays.addOverlay("image", { // alternate form of expressing bounds bounds: { x: 100, y: fanoutY, width: 150, height: sliderHeight}, subImage: { x: 46, y: 0, width: 200, height: 71 }, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/slider.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/slider.png", color: { red: 255, green: 255, blue: 255}, alpha: 1 }); @@ -146,7 +147,7 @@ var fanoutThumb = Overlays.addOverlay("image", { y: fanoutY + 9, width: 18, height: 17, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/thumb.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/thumb.png", color: { red: 255, green: 255, blue: 0}, alpha: 1 }); @@ -171,7 +172,7 @@ var speedSlider = Overlays.addOverlay("image", { // alternate form of expressing bounds bounds: { x: 100, y: speedY, width: 150, height: sliderHeight}, subImage: { x: 46, y: 0, width: 200, height: 71 }, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/slider.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/slider.png", color: { red: 255, green: 255, blue: 255}, alpha: 1 }); @@ -185,7 +186,7 @@ var speedThumb = Overlays.addOverlay("image", { y: speedY+9, width: 18, height: 17, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/thumb.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/thumb.png", color: { red: 0, green: 255, blue: 0}, alpha: 1 }); @@ -210,7 +211,7 @@ var factorSlider = Overlays.addOverlay("image", { // alternate form of expressing bounds bounds: { x: 100, y: factorY, width: 150, height: sliderHeight}, subImage: { x: 46, y: 0, width: 200, height: 71 }, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/slider.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/slider.png", color: { red: 255, green: 255, blue: 255}, alpha: 1 }); @@ -224,7 +225,7 @@ var factorThumb = Overlays.addOverlay("image", { y: factorY+9, width: 18, height: 17, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/thumb.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/thumb.png", color: { red: 0, green: 0, blue: 255}, alpha: 1 }); @@ -249,7 +250,7 @@ var localFactorSlider = Overlays.addOverlay("image", { // alternate form of expressing bounds bounds: { x: 100, y: localFactorY, width: 150, height: sliderHeight}, subImage: { x: 46, y: 0, width: 200, height: 71 }, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/slider.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/slider.png", color: { red: 255, green: 255, blue: 255}, alpha: 1 }); @@ -263,7 +264,7 @@ var localFactorThumb = Overlays.addOverlay("image", { y: localFactorY+9, width: 18, height: 17, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/thumb.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/thumb.png", color: { red: 0, green: 128, blue: 128}, alpha: 1 }); @@ -288,7 +289,7 @@ var combFilterSlider = Overlays.addOverlay("image", { // alternate form of expressing bounds bounds: { x: 100, y: combFilterY, width: 150, height: sliderHeight}, subImage: { x: 46, y: 0, width: 200, height: 71 }, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/slider.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/slider.png", color: { red: 255, green: 255, blue: 255}, alpha: 1 }); @@ -302,7 +303,7 @@ var combFilterThumb = Overlays.addOverlay("image", { y: combFilterY+9, width: 18, height: 17, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/thumb.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/thumb.png", color: { red: 128, green: 128, blue: 0}, alpha: 1 }); @@ -328,7 +329,7 @@ var reflectiveSlider = Overlays.addOverlay("image", { // alternate form of expressing bounds bounds: { x: 100, y: reflectiveY, width: 150, height: sliderHeight}, subImage: { x: 46, y: 0, width: 200, height: 71 }, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/slider.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/slider.png", color: { red: 255, green: 255, blue: 255}, alpha: 1 }); @@ -342,7 +343,7 @@ var reflectiveThumb = Overlays.addOverlay("image", { y: reflectiveY+9, width: 18, height: 17, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/thumb.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/thumb.png", color: { red: 255, green: 255, blue: 255}, alpha: 1 }); @@ -367,7 +368,7 @@ var diffusionSlider = Overlays.addOverlay("image", { // alternate form of expressing bounds bounds: { x: 100, y: diffusionY, width: 150, height: sliderHeight}, subImage: { x: 46, y: 0, width: 200, height: 71 }, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/slider.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/slider.png", color: { red: 255, green: 255, blue: 255}, alpha: 1 }); @@ -381,7 +382,7 @@ var diffusionThumb = Overlays.addOverlay("image", { y: diffusionY+9, width: 18, height: 17, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/thumb.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/thumb.png", color: { red: 0, green: 255, blue: 255}, alpha: 1 }); @@ -406,7 +407,7 @@ var absorptionSlider = Overlays.addOverlay("image", { // alternate form of expressing bounds bounds: { x: 100, y: absorptionY, width: 150, height: sliderHeight}, subImage: { x: 46, y: 0, width: 200, height: 71 }, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/slider.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/slider.png", color: { red: 255, green: 255, blue: 255}, alpha: 1 }); @@ -420,7 +421,7 @@ var absorptionThumb = Overlays.addOverlay("image", { y: absorptionY+9, width: 18, height: 17, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/thumb.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/thumb.png", color: { red: 255, green: 0, blue: 255}, alpha: 1 }); @@ -445,7 +446,7 @@ var originalSlider = Overlays.addOverlay("image", { // alternate form of expressing bounds bounds: { x: 100, y: originalY, width: 150, height: sliderHeight}, subImage: { x: 46, y: 0, width: 200, height: 71 }, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/slider.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/slider.png", color: { red: 255, green: 255, blue: 255}, alpha: 1 }); @@ -459,7 +460,7 @@ var originalThumb = Overlays.addOverlay("image", { y: originalY+9, width: 18, height: 17, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/thumb.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/thumb.png", color: { red: 128, green: 128, blue: 0}, alpha: 1 }); @@ -484,7 +485,7 @@ var echoesSlider = Overlays.addOverlay("image", { // alternate form of expressing bounds bounds: { x: 100, y: echoesY, width: 150, height: sliderHeight}, subImage: { x: 46, y: 0, width: 200, height: 71 }, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/slider.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/slider.png", color: { red: 255, green: 255, blue: 255}, alpha: 1 }); @@ -498,7 +499,7 @@ var echoesThumb = Overlays.addOverlay("image", { y: echoesY+9, width: 18, height: 17, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/thumb.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/thumb.png", color: { red: 128, green: 128, blue: 0}, alpha: 1 }); diff --git a/examples/avatarCollision.js b/examples/avatarCollision.js index 5ade894365..6c0886464c 100644 --- a/examples/avatarCollision.js +++ b/examples/avatarCollision.js @@ -11,6 +11,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); + var SOUND_TRIGGER_CLEAR = 1000; // milliseconds var SOUND_TRIGGER_DELAY = 200; // milliseconds var soundExpiry = 0; @@ -20,28 +22,28 @@ audioOptions.volume = 0.5; audioOptions.position = { x: 0, y: 0, z: 0 }; var hitSounds = new Array(); -hitSounds[0] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit1.raw"); -hitSounds[1] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit2.raw"); -hitSounds[2] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit3.raw"); -hitSounds[3] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit4.raw"); -hitSounds[4] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit5.raw"); -hitSounds[5] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit6.raw"); -hitSounds[6] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit7.raw"); -hitSounds[7] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit8.raw"); -hitSounds[8] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit9.raw"); -hitSounds[9] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit10.raw"); -hitSounds[10] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit11.raw"); -hitSounds[11] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit12.raw"); -hitSounds[12] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit13.raw"); -hitSounds[13] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit14.raw"); -hitSounds[14] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit15.raw"); -hitSounds[15] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit16.raw"); -hitSounds[16] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit17.raw"); -hitSounds[17] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit18.raw"); -hitSounds[18] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit19.raw"); -hitSounds[19] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit20.raw"); -hitSounds[20] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit21.raw"); -hitSounds[21] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Collisions-hitsandslaps/Hit22.raw"); +hitSounds[0] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit1.raw"); +hitSounds[1] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit2.raw"); +hitSounds[2] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit3.raw"); +hitSounds[3] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit4.raw"); +hitSounds[4] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit5.raw"); +hitSounds[5] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit6.raw"); +hitSounds[6] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit7.raw"); +hitSounds[7] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit8.raw"); +hitSounds[8] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit9.raw"); +hitSounds[9] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit10.raw"); +hitSounds[10] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit11.raw"); +hitSounds[11] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit12.raw"); +hitSounds[12] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit13.raw"); +hitSounds[13] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit14.raw"); +hitSounds[14] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit15.raw"); +hitSounds[15] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit16.raw"); +hitSounds[16] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit17.raw"); +hitSounds[17] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit18.raw"); +hitSounds[18] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit19.raw"); +hitSounds[19] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit20.raw"); +hitSounds[20] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit21.raw"); +hitSounds[21] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Collisions-hitsandslaps/Hit22.raw"); function playHitSound(mySessionID, theirSessionID, collision) { var now = new Date(); diff --git a/examples/bot.js b/examples/bot.js index e42d234abf..09c9a51cdd 100644 --- a/examples/bot.js +++ b/examples/bot.js @@ -12,6 +12,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); + function getRandomFloat(min, max) { return Math.random() * (max - min) + min; } @@ -110,9 +112,9 @@ if (botNumber <= 20) { // set the face model fst using the bot number // there is no need to change the body model - we're using the default -Avatar.faceModelURL = "https://s3-us-west-1.amazonaws.com/highfidelity-public/meshes/" + newFaceFilePrefix + ".fst"; -Avatar.skeletonModelURL = "https://s3-us-west-1.amazonaws.com/highfidelity-public/meshes/" + newBodyFilePrefix + ".fst"; -Avatar.billboardURL = "https://s3-us-west-1.amazonaws.com/highfidelity-public/meshes/billboards/bot" + botNumber + ".png"; +Avatar.faceModelURL = HIFI_PUBLIC_BUCKET + "meshes/" + newFaceFilePrefix + ".fst"; +Avatar.skeletonModelURL = HIFI_PUBLIC_BUCKET + "meshes/" + newBodyFilePrefix + ".fst"; +Avatar.billboardURL = HIFI_PUBLIC_BUCKET + "meshes/billboards/bot" + botNumber + ".png"; Agent.isAvatar = true; Agent.isListeningToAudioStream = true; @@ -223,7 +225,7 @@ function loadSounds() { "Walken1.raw", "Walken2.raw", "Z1.raw", "Z2.raw" ]; - var SOUND_BASE_URL = "https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Cocktail+Party+Snippets/Raws/"; + var SOUND_BASE_URL = HIFI_PUBLIC_BUCKET + "sounds/Cocktail+Party+Snippets/Raws/"; for (var i = 0; i < sound_filenames.length; i++) { sounds.push(new Sound(SOUND_BASE_URL + sound_filenames[i])); diff --git a/examples/botProceduralWayPoints.js b/examples/botProceduralWayPoints.js index 9f46177587..fc9c0dda74 100644 --- a/examples/botProceduralWayPoints.js +++ b/examples/botProceduralWayPoints.js @@ -20,7 +20,8 @@ // //For procedural walk animation -Script.include("http://s3-us-west-1.amazonaws.com/highfidelity-public/scripts/proceduralAnimationAPI.js"); +Script.include("libraries/globals.js"); +Script.include(HIFI_PUBLIC_BUCKET + "scripts/proceduralAnimationAPI.js"); var procAnimAPI = new ProcAnimAPI(); @@ -120,9 +121,9 @@ var newBodyFilePrefix = "bot" + botNumber; // set the face model fst using the bot number // there is no need to change the body model - we're using the default -Avatar.faceModelURL = "https://s3-us-west-1.amazonaws.com/highfidelity-public/meshes/" + newFaceFilePrefix + ".fst"; -Avatar.skeletonModelURL = "https://s3-us-west-1.amazonaws.com/highfidelity-public/meshes/" + newBodyFilePrefix + "_a.fst"; -Avatar.billboardURL = "https://s3-us-west-1.amazonaws.com/highfidelity-public/meshes/billboards/bot" + botNumber + ".png"; +Avatar.faceModelURL = HIFI_PUBLIC_BUCKET + "meshes/" + newFaceFilePrefix + ".fst"; +Avatar.skeletonModelURL = HIFI_PUBLIC_BUCKET + "meshes/" + newBodyFilePrefix + "_a.fst"; +Avatar.billboardURL = HIFI_PUBLIC_BUCKET + "meshes/billboards/bot" + botNumber + ".png"; Agent.isAvatar = true; Agent.isListeningToAudioStream = true; @@ -145,9 +146,9 @@ function loadSounds() { var footstep_filenames = ["FootstepW2Left-12db.wav", "FootstepW2Right-12db.wav", "FootstepW3Left-12db.wav", "FootstepW3Right-12db.wav", "FootstepW5Left-12db.wav", "FootstepW5Right-12db.wav"]; - var SOUND_BASE_URL = "https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Cocktail+Party+Snippets/Raws/"; + var SOUND_BASE_URL = HIFI_PUBLIC_BUCKET + "sounds/Cocktail+Party+Snippets/Raws/"; - var FOOTSTEP_BASE_URL = "http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Footsteps/"; + var FOOTSTEP_BASE_URL = HIFI_PUBLIC_BUCKET + "sounds/Footsteps/"; for (var i = 0; i < sound_filenames.length; i++) { sounds.push(new Sound(SOUND_BASE_URL + sound_filenames[i])); diff --git a/examples/bot_procedural.js b/examples/bot_procedural.js index 265b887e0a..f445162038 100644 --- a/examples/bot_procedural.js +++ b/examples/bot_procedural.js @@ -11,7 +11,8 @@ // //For procedural walk animation -Script.include("http://s3-us-west-1.amazonaws.com/highfidelity-public/scripts/proceduralAnimationAPI.js"); +Script.include("libraries/globals.js"); +Script.include(HIFI_PUBLIC_BUCKET + "scripts/proceduralAnimationAPI.js"); var procAnimAPI = new ProcAnimAPI(); @@ -82,9 +83,9 @@ var newBodyFilePrefix = "bot" + botNumber; // set the face model fst using the bot number // there is no need to change the body model - we're using the default -Avatar.faceModelURL = "https://s3-us-west-1.amazonaws.com/highfidelity-public/meshes/" + newFaceFilePrefix + ".fst"; -Avatar.skeletonModelURL = "https://s3-us-west-1.amazonaws.com/highfidelity-public/meshes/" + newBodyFilePrefix + "_a.fst"; -Avatar.billboardURL = "https://s3-us-west-1.amazonaws.com/highfidelity-public/meshes/billboards/bot" + botNumber + ".png"; +Avatar.faceModelURL = HIFI_PUBLIC_BUCKET + "meshes/" + newFaceFilePrefix + ".fst"; +Avatar.skeletonModelURL = HIFI_PUBLIC_BUCKET + "meshes/" + newBodyFilePrefix + "_a.fst"; +Avatar.billboardURL = HIFI_PUBLIC_BUCKET + "meshes/billboards/bot" + botNumber + ".png"; Agent.isAvatar = true; Agent.isListeningToAudioStream = true; @@ -107,9 +108,9 @@ function loadSounds() { var footstep_filenames = ["FootstepW2Left-12db.wav", "FootstepW2Right-12db.wav", "FootstepW3Left-12db.wav", "FootstepW3Right-12db.wav", "FootstepW5Left-12db.wav", "FootstepW5Right-12db.wav"]; - var SOUND_BASE_URL = "https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Cocktail+Party+Snippets/Raws/"; + var SOUND_BASE_URL = HIFI_PUBLIC_BUCKET + "sounds/Cocktail+Party+Snippets/Raws/"; - var FOOTSTEP_BASE_URL = "http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Footsteps/"; + var FOOTSTEP_BASE_URL = HIFI_PUBLIC_BUCKET + "sounds/Footsteps/"; for (var i = 0; i < sound_filenames.length; i++) { sounds.push(new Sound(SOUND_BASE_URL + sound_filenames[i])); diff --git a/examples/bot_randomExpression.js b/examples/bot_randomExpression.js index 2d2653e6d5..44d546e763 100644 --- a/examples/bot_randomExpression.js +++ b/examples/bot_randomExpression.js @@ -12,6 +12,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); + function getRandomFloat(min, max) { return Math.random() * (max - min) + min; } @@ -42,9 +44,9 @@ newBodyFilePrefix = "bot" + botNumber; // set the face model fst using the bot number // there is no need to change the body model - we're using the default -Avatar.faceModelURL = "https://s3-us-west-1.amazonaws.com/highfidelity-public/meshes/" + newFaceFilePrefix + ".fst"; -Avatar.skeletonModelURL = "https://s3-us-west-1.amazonaws.com/highfidelity-public/meshes/" + newBodyFilePrefix + ".fst"; -Avatar.billboardURL = "https://s3-us-west-1.amazonaws.com/highfidelity-public/meshes/billboards/bot" + botNumber + ".png"; +Avatar.faceModelURL = HIFI_PUBLIC_BUCKET + "meshes/" + newFaceFilePrefix + ".fst"; +Avatar.skeletonModelURL = HIFI_PUBLIC_BUCKET + "meshes/" + newBodyFilePrefix + ".fst"; +Avatar.billboardURL = HIFI_PUBLIC_BUCKET + "meshes/billboards/bot" + botNumber + ".png"; Agent.isAvatar = true; Agent.isListeningToAudioStream = true; diff --git a/examples/clap.js b/examples/clap.js index 6e70979c2e..9cc79a1c92 100644 --- a/examples/clap.js +++ b/examples/clap.js @@ -12,7 +12,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var clapAnimation = "https://s3-us-west-1.amazonaws.com/highfidelity-public/animations/ClapAnimations/ClapHands_Standing.fbx"; +Script.include("libraries/globals.js"); + +var clapAnimation = HIFI_PUBLIC_BUCKET + "animations/ClapAnimations/ClapHands_Standing.fbx"; var ANIMATION_FRAMES_PER_CLAP = 10.0; var startEndFrames = []; startEndFrames.push({ start: 0, end: 10}); @@ -26,16 +28,16 @@ var lastClapFrame = 0; var lastAnimFrame = 0; var claps = []; -claps.push(new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/claps/BClap1Rvb.wav")); -claps.push(new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/claps/BClap2Rvb.wav")); -claps.push(new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/claps/BClap3Rvb.wav")); -claps.push(new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/claps/BClap4Rvb.wav")); -claps.push(new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/claps/BClap5Rvb.wav")); -claps.push(new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/claps/BClap6Rvb.wav")); -claps.push(new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/claps/BClap7Rvb.wav")); -claps.push(new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/claps/BClap8Rvb.wav")); -claps.push(new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/claps/BClap9Rvb.wav")); -claps.push(new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/claps/BClap10Rvb.wav")); +claps.push(new Sound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap1Rvb.wav")); +claps.push(new Sound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap2Rvb.wav")); +claps.push(new Sound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap3Rvb.wav")); +claps.push(new Sound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap4Rvb.wav")); +claps.push(new Sound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap5Rvb.wav")); +claps.push(new Sound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap6Rvb.wav")); +claps.push(new Sound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap7Rvb.wav")); +claps.push(new Sound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap8Rvb.wav")); +claps.push(new Sound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap9Rvb.wav")); +claps.push(new Sound(HIFI_PUBLIC_BUCKET + "sounds/claps/BClap10Rvb.wav")); var numberOfSounds = claps.length; var clappingNow = false; diff --git a/examples/drumStick.js b/examples/drumStick.js index 188661b000..d0560057c0 100644 --- a/examples/drumStick.js +++ b/examples/drumStick.js @@ -10,6 +10,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); + function length(v) { return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z); } @@ -26,8 +28,8 @@ function vMinus(a, b) { // First, load two percussion sounds to be used on the sticks -var drum1 = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Drums/RackTomHi.raw"); -var drum2 = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Drums/RackTomLo.raw"); +var drum1 = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Drums/RackTomHi.raw"); +var drum2 = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Drums/RackTomLo.raw"); // State Machine: // 0 = not triggered diff --git a/examples/editModelExample.js b/examples/editModelExample.js index 1a17697db3..5a4efc0746 100644 --- a/examples/editModelExample.js +++ b/examples/editModelExample.js @@ -11,6 +11,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); + var count = 0; var moveUntil = 2000; var stopAfter = moveUntil + 100; @@ -31,12 +33,12 @@ var originalProperties = { green: 255, blue: 0 }, - modelURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/Feisar_Ship.FBX", - //modelURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/birarda/birarda_head.fbx", - //modelURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/pug.fbx", - //modelURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/newInvader16x16-large-purple.svo", - //modelURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/minotaur/mino_full.fbx", - //modelURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/Combat_tank_V01.FBX", + modelURL: HIFI_PUBLIC_BUCKET + "meshes/Feisar_Ship.FBX", + //modelURL: HIFI_PUBLIC_BUCKET + "meshes/birarda/birarda_head.fbx", + //modelURL: HIFI_PUBLIC_BUCKET + "meshes/pug.fbx", + //modelURL: HIFI_PUBLIC_BUCKET + "meshes/newInvader16x16-large-purple.svo", + //modelURL: HIFI_PUBLIC_BUCKET + "meshes/minotaur/mino_full.fbx", + //modelURL: HIFI_PUBLIC_BUCKET + "meshes/Combat_tank_V01.FBX", rotation: rotation }; diff --git a/examples/editModels.js b/examples/editModels.js index 1aa12529ce..9cdba8098f 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -22,9 +22,11 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); Script.include("libraries/toolBars.js"); + var windowDimensions = Controller.getViewportDimensions(); -var toolIconUrl = "http://highfidelity-public.s3-us-west-1.amazonaws.com/images/tools/"; +var toolIconUrl = HIFI_PUBLIC_BUCKET + "images/tools/"; var toolHeight = 50; var toolWidth = 50; @@ -45,14 +47,14 @@ var SPAWN_DISTANCE = 1; var DEFAULT_DIMENSION = 0.20; var modelURLs = [ - "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/Feisar_Ship.FBX", - "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/birarda/birarda_head.fbx", - "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/pug.fbx", - "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/newInvader16x16-large-purple.svo", - "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/minotaur/mino_full.fbx", - "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/Combat_tank_V01.FBX", - "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/orc.fbx", - "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/slimer.fbx" + HIFI_PUBLIC_BUCKET + "meshes/Feisar_Ship.FBX", + HIFI_PUBLIC_BUCKET + "meshes/birarda/birarda_head.fbx", + HIFI_PUBLIC_BUCKET + "meshes/pug.fbx", + HIFI_PUBLIC_BUCKET + "meshes/newInvader16x16-large-purple.svo", + HIFI_PUBLIC_BUCKET + "meshes/minotaur/mino_full.fbx", + HIFI_PUBLIC_BUCKET + "meshes/Combat_tank_V01.FBX", + HIFI_PUBLIC_BUCKET + "meshes/orc.fbx", + HIFI_PUBLIC_BUCKET + "meshes/slimer.fbx" ]; var jointList = MyAvatar.getJointNames(); @@ -1766,7 +1768,7 @@ var modelImporter = new ModelImporter(); function isLocked(properties) { // special case to lock the ground plane model in hq. if (location.hostname == "hq.highfidelity.io" && - properties.modelURL == "https://s3-us-west-1.amazonaws.com/highfidelity-public/ozan/Terrain_Reduce_forAlpha.fbx") { + properties.modelURL == HIFI_PUBLIC_BUCKET + "ozan/Terrain_Reduce_forAlpha.fbx") { return true; } return false; diff --git a/examples/editVoxels.js b/examples/editVoxels.js index 3543f062e7..e450f2d1d4 100644 --- a/examples/editVoxels.js +++ b/examples/editVoxels.js @@ -19,6 +19,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); + var editToolsOn = true; // starts out off var windowDimensions = Controller.getViewportDimensions(); @@ -94,61 +96,61 @@ function SoundArray() { } var addVoxelSound = new SoundArray(); -addVoxelSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Voxel+Add/VA+1.raw"); -addVoxelSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Voxel+Add/VA+2.raw"); -addVoxelSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Voxel+Add/VA+3.raw"); -addVoxelSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Voxel+Add/VA+4.raw"); -addVoxelSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Voxel+Add/VA+5.raw"); -addVoxelSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Voxel+Add/VA+6.raw"); +addVoxelSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Voxel+Add/VA+1.raw"); +addVoxelSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Voxel+Add/VA+2.raw"); +addVoxelSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Voxel+Add/VA+3.raw"); +addVoxelSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Voxel+Add/VA+4.raw"); +addVoxelSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Voxel+Add/VA+5.raw"); +addVoxelSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Voxel+Add/VA+6.raw"); var delVoxelSound = new SoundArray(); -delVoxelSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Voxel+Del/VD+A1.raw"); -delVoxelSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Voxel+Del/VD+A2.raw"); -delVoxelSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Voxel+Del/VD+A3.raw"); -delVoxelSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Voxel+Del/VD+B1.raw"); -delVoxelSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Voxel+Del/VD+B2.raw"); -delVoxelSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Voxel+Del/VD+B3.raw"); +delVoxelSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Voxel+Del/VD+A1.raw"); +delVoxelSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Voxel+Del/VD+A2.raw"); +delVoxelSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Voxel+Del/VD+A3.raw"); +delVoxelSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Voxel+Del/VD+B1.raw"); +delVoxelSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Voxel+Del/VD+B2.raw"); +delVoxelSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Voxel+Del/VD+B3.raw"); var resizeVoxelSound = new SoundArray(); -resizeVoxelSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Voxel+Size/V+Size+Minus.raw"); -resizeVoxelSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Voxel+Size/V+Size+Plus.raw"); +resizeVoxelSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Voxel+Size/V+Size+Minus.raw"); +resizeVoxelSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Voxel+Size/V+Size+Plus.raw"); var voxelSizeMinus = 0; var voxelSizePlus = 1; var swatchesSound = new SoundArray(); -swatchesSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Swatches/Swatch+1.raw"); -swatchesSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Swatches/Swatch+2.raw"); -swatchesSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Swatches/Swatch+3.raw"); -swatchesSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Swatches/Swatch+4.raw"); -swatchesSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Swatches/Swatch+5.raw"); -swatchesSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Swatches/Swatch+6.raw"); -swatchesSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Swatches/Swatch+7.raw"); -swatchesSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Swatches/Swatch+8.raw"); -swatchesSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Swatches/Swatch+9.raw"); +swatchesSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Swatches/Swatch+1.raw"); +swatchesSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Swatches/Swatch+2.raw"); +swatchesSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Swatches/Swatch+3.raw"); +swatchesSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Swatches/Swatch+4.raw"); +swatchesSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Swatches/Swatch+5.raw"); +swatchesSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Swatches/Swatch+6.raw"); +swatchesSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Swatches/Swatch+7.raw"); +swatchesSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Swatches/Swatch+8.raw"); +swatchesSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Swatches/Swatch+9.raw"); var undoSound = new SoundArray(); -undoSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Undo/Undo+1.raw"); -undoSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Undo/Undo+2.raw"); -undoSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Undo/Undo+3.raw"); +undoSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Undo/Undo+1.raw"); +undoSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Undo/Undo+2.raw"); +undoSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Undo/Undo+3.raw"); var scriptInitSound = new SoundArray(); -scriptInitSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Script+Init/Script+Init+A.raw"); -scriptInitSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Script+Init/Script+Init+B.raw"); -scriptInitSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Script+Init/Script+Init+C.raw"); -scriptInitSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Script+Init/Script+Init+D.raw"); +scriptInitSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Script+Init/Script+Init+A.raw"); +scriptInitSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Script+Init/Script+Init+B.raw"); +scriptInitSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Script+Init/Script+Init+C.raw"); +scriptInitSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Script+Init/Script+Init+D.raw"); var modeSwitchSound = new SoundArray(); -modeSwitchSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Mode+Switch/Mode+1.raw"); -modeSwitchSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Mode+Switch/Mode+2.raw"); -modeSwitchSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Mode+Switch/Mode+3.raw"); +modeSwitchSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Mode+Switch/Mode+1.raw"); +modeSwitchSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Mode+Switch/Mode+2.raw"); +modeSwitchSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Mode+Switch/Mode+3.raw"); var initialVoxelSound = new SoundArray(); -initialVoxelSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Initial+Voxel/Initial+V.raw"); +initialVoxelSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Initial+Voxel/Initial+V.raw"); var colorInheritSound = new SoundArray(); -colorInheritSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Color+Inherit/Inherit+A.raw"); -colorInheritSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Color+Inherit/Inherit+B.raw"); -colorInheritSound.addSound("https://highfidelity-public.s3.amazonaws.com/sounds/Voxel+Editing/Color+Inherit/Inherit+C.raw"); +colorInheritSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Color+Inherit/Inherit+A.raw"); +colorInheritSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Color+Inherit/Inherit+B.raw"); +colorInheritSound.addSound(HIFI_PUBLIC_BUCKET + "sounds/Voxel+Editing/Color+Inherit/Inherit+C.raw"); // previewAsVoxel - by default, we will preview adds/deletes/recolors as just 4 lines on the intersecting face. But if you // the preview to show a full voxel then set this to true and the voxel will be displayed for voxel editing @@ -213,7 +215,7 @@ var swatchesWidth = swatchWidth * numColors + numColors + swatchExtraPadding * 2 var swatchesX = (windowDimensions.x - (swatchesWidth + scaleSelectorWidth)) / 2; var swatchesY = windowDimensions.y - swatchHeight + 1; -var toolIconUrl = "http://highfidelity-public.s3-us-west-1.amazonaws.com/images/tools/"; +var toolIconUrl = HIFI_PUBLIC_BUCKET + "images/tools/"; // create the overlays, position them in a row, set their colors, and for the selected one, use a different source image // location so that it displays the "selected" marker diff --git a/examples/fallingSand.js b/examples/fallingSand.js index 4eccccdc5a..5018aeb9ca 100644 --- a/examples/fallingSand.js +++ b/examples/fallingSand.js @@ -12,12 +12,14 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); + var zFightingSizeAdjust = 0.002; // used to adjust preview voxels to prevent z fighting var previewLineWidth = 2.0; var voxelSize = 1; var windowDimensions = Controller.getViewportDimensions(); -var toolIconUrl = "http://highfidelity-public.s3-us-west-1.amazonaws.com/images/tools/"; +var toolIconUrl = HIFI_PUBLIC_BUCKET + "images/tools/"; var MAX_VOXEL_SCALE_POWER = 5; var MIN_VOXEL_SCALE_POWER = -8; diff --git a/examples/frisbee.js b/examples/frisbee.js index c069d03275..653a1d4b57 100644 --- a/examples/frisbee.js +++ b/examples/frisbee.js @@ -14,6 +14,8 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // + +Script.include("libraries/globals.js"); Script.include("libraries/toolBars.js"); const LEFT_PALM = 0; @@ -160,7 +162,7 @@ var currentMouseControl = false; var newSound = new Sound("https://dl.dropboxusercontent.com/u/1864924/hifi-sounds/throw.raw"); var catchSound = new Sound("https://dl.dropboxusercontent.com/u/1864924/hifi-sounds/catch.raw"); -var throwSound = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Switches%20and%20sliders/slider%20-%20whoosh1.raw"); +var throwSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Switches%20and%20sliders/slider%20-%20whoosh1.raw"); var simulatedFrisbees = []; diff --git a/examples/grenadeLauncher.js b/examples/grenadeLauncher.js index 0cac55baa7..dc25282448 100644 --- a/examples/grenadeLauncher.js +++ b/examples/grenadeLauncher.js @@ -14,6 +14,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); + function getRandomFloat(min, max) { return Math.random() * (max - min) + min; } @@ -34,11 +36,11 @@ var RELOAD_INTERVAL = 5; var showScore = false; // Load some sound to use for loading and firing -var fireSound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Guns/GUN-SHOT2.raw"); -var loadSound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Guns/Gun_Reload_Weapon22.raw"); -var impactSound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Guns/BulletImpact2.raw"); -var targetHitSound = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Space%20Invaders/hit.raw"); -var targetLaunchSound = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Space%20Invaders/shoot.raw"); +var fireSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guns/GUN-SHOT2.raw"); +var loadSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guns/Gun_Reload_Weapon22.raw"); +var impactSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guns/BulletImpact2.raw"); +var targetHitSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/hit.raw"); +var targetLaunchSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/shoot.raw"); var gunModel = "http://public.highfidelity.io/models/attachments/HaloGun.fst"; @@ -67,7 +69,7 @@ var reticle = Overlays.addOverlay("image", { y: screenSize.y / 2 - 16, width: 32, height: 32, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/reticle.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/reticle.png", color: { red: 255, green: 255, blue: 255}, alpha: 1 }); diff --git a/examples/growTrees.js b/examples/growTrees.js index 142c72300a..13d6cdc587 100644 --- a/examples/growTrees.js +++ b/examples/growTrees.js @@ -11,12 +11,14 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); + var zFightingSizeAdjust = 0.002; // used to adjust preview voxels to prevent z fighting var previewLineWidth = 2.0; var voxelSize = 1; var windowDimensions = Controller.getViewportDimensions(); -var toolIconUrl = "http://highfidelity-public.s3-us-west-1.amazonaws.com/images/tools/"; +var toolIconUrl = HIFI_PUBLIC_BUCKET + "images/tools/"; var MAX_VOXEL_SCALE_POWER = 5; var MIN_VOXEL_SCALE_POWER = -8; diff --git a/examples/gun.js b/examples/gun.js index a5c0ee83e0..6f1371e5d9 100644 --- a/examples/gun.js +++ b/examples/gun.js @@ -14,6 +14,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); + function getRandomFloat(min, max) { return Math.random() * (max - min) + min; } @@ -33,11 +35,11 @@ var RELOAD_INTERVAL = 5; var showScore = false; // Load some sound to use for loading and firing -var fireSound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Guns/GUN-SHOT2.raw"); -var loadSound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Guns/Gun_Reload_Weapon22.raw"); -var impactSound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Guns/BulletImpact2.raw"); -var targetHitSound = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Space%20Invaders/hit.raw"); -var targetLaunchSound = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Space%20Invaders/shoot.raw"); +var fireSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guns/GUN-SHOT2.raw"); +var loadSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guns/Gun_Reload_Weapon22.raw"); +var impactSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guns/BulletImpact2.raw"); +var targetHitSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/hit.raw"); +var targetLaunchSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/shoot.raw"); var gunModel = "http://public.highfidelity.io/models/attachments/HaloGun.fst"; @@ -66,7 +68,7 @@ var reticle = Overlays.addOverlay("image", { y: screenSize.y / 2 - 16, width: 32, height: 32, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/reticle.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/reticle.png", color: { red: 255, green: 255, blue: 255}, alpha: 1 }); diff --git a/examples/inWorldTestTone.js b/examples/inWorldTestTone.js index e4f34d87cd..590bb6c342 100644 --- a/examples/inWorldTestTone.js +++ b/examples/inWorldTestTone.js @@ -11,7 +11,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var sound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/220Sine.wav"); +Script.include("libraries/globals.js"); + +var sound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/220Sine.wav"); var soundPlaying = false; diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index 5a0164ad1f..e07fb752e5 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -11,6 +11,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); + SelectionDisplay = (function () { var that = {}; @@ -100,7 +102,7 @@ SelectionDisplay = (function () { }); var grabberMoveUp = Overlays.addOverlay("billboard", { - url: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/up-arrow.png", + url: HIFI_PUBLIC_BUCKET + "images/up-arrow.png", position: { x:0, y: 0, z: 0}, color: { red: 0, green: 0, blue: 0 }, alpha: 1.0, diff --git a/examples/libraries/globals.js b/examples/libraries/globals.js new file mode 100644 index 0000000000..211e0d56b6 --- /dev/null +++ b/examples/libraries/globals.js @@ -0,0 +1,11 @@ +// +// globals.js +// examples/libraries +// +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +var HIFI_PUBLIC_BUCKET = "https://s3.amazonaws.com/hifi-public/"; \ No newline at end of file diff --git a/examples/locationsMenu.js b/examples/locationsMenu.js index 24b0dabf46..30fa377a6f 100644 --- a/examples/locationsMenu.js +++ b/examples/locationsMenu.js @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); + var scriptUrl = "https://script.google.com/macros/s/AKfycbwIo4lmF-qUwX1Z-9eA_P-g2gse9oFhNcjVyyksGukyDDEFXgU/exec?action=listOwners&domain=alpha.highfidelity.io"; var LocationMenu = function(opts) { @@ -24,7 +26,7 @@ var LocationMenu = function(opts) { var disabledColor = { red: 64, green: 64, blue: 64}; var position = { x: 0, y: 0 }; - var locationIconUrl = "http://highfidelity-public.s3-us-west-1.amazonaws.com/images/tools/location.svg"; + var locationIconUrl = HIFI_PUBLIC_BUCKET + "images/tools/location.svg"; var toolHeight = 50; var toolWidth = 50; var visible = false; diff --git a/examples/myBalance.js b/examples/myBalance.js index bd48e8fd21..43f1f40eae 100644 --- a/examples/myBalance.js +++ b/examples/myBalance.js @@ -11,6 +11,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); + var Controller = Controller || {}; var Overlays = Overlays || {}; var Script = Script || {}; @@ -18,7 +20,7 @@ var Account = Account || {}; (function () { "use strict"; - var iconUrl = 'http://highfidelity-public.s3-us-west-1.amazonaws.com/images/tools/', + var iconUrl = HIFI_PUBLIC_BUCKET + 'images/tools/', overlayWidth = 150, overlayHeight = 50, overlayTopOffset = 15, diff --git a/examples/newEditEntities.js b/examples/newEditEntities.js index de39121e35..a223813347 100644 --- a/examples/newEditEntities.js +++ b/examples/newEditEntities.js @@ -11,6 +11,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); Script.include("libraries/stringHelpers.js"); Script.include("libraries/dataviewHelpers.js"); Script.include("libraries/httpMultiPart.js"); @@ -31,7 +32,7 @@ Script.include("libraries/entityPropertyDialogBox.js"); var entityPropertyDialogBox = EntityPropertyDialogBox; var windowDimensions = Controller.getViewportDimensions(); -var toolIconUrl = "http://highfidelity-public.s3-us-west-1.amazonaws.com/images/tools/"; +var toolIconUrl = HIFI_PUBLIC_BUCKET + "images/tools/"; var toolHeight = 50; var toolWidth = 50; @@ -45,14 +46,14 @@ var SPAWN_DISTANCE = 1; var DEFAULT_DIMENSION = 0.20; var modelURLs = [ - "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/Feisar_Ship.FBX", - "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/birarda/birarda_head.fbx", - "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/pug.fbx", - "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/newInvader16x16-large-purple.svo", - "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/minotaur/mino_full.fbx", - "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/Combat_tank_V01.FBX", - "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/orc.fbx", - "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/slimer.fbx" + HIFI_PUBLIC_BUCKET + "meshes/Feisar_Ship.FBX", + HIFI_PUBLIC_BUCKET + "meshes/birarda/birarda_head.fbx", + HIFI_PUBLIC_BUCKET + "meshes/pug.fbx", + HIFI_PUBLIC_BUCKET + "meshes/newInvader16x16-large-purple.svo", + HIFI_PUBLIC_BUCKET + "meshes/minotaur/mino_full.fbx", + HIFI_PUBLIC_BUCKET + "meshes/Combat_tank_V01.FBX", + HIFI_PUBLIC_BUCKET + "meshes/orc.fbx", + HIFI_PUBLIC_BUCKET + "meshes/slimer.fbx" ]; var mode = 0; @@ -310,7 +311,7 @@ var exportMenu = null; function isLocked(properties) { // special case to lock the ground plane model in hq. if (location.hostname == "hq.highfidelity.io" && - properties.modelURL == "https://s3-us-west-1.amazonaws.com/highfidelity-public/ozan/Terrain_Reduce_forAlpha.fbx") { + properties.modelURL == HIFI_PUBLIC_BUCKET + "ozan/Terrain_Reduce_forAlpha.fbx") { return true; } return false; diff --git a/examples/overlaysExample.js b/examples/overlaysExample.js index d0b3870803..2161b1c903 100644 --- a/examples/overlaysExample.js +++ b/examples/overlaysExample.js @@ -11,6 +11,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); // The "Swatches" example of this script will create 9 different image overlays, that use the color feature to // display different colors as color swatches. The overlays can be clicked on, to change the "selectedSwatch" variable @@ -51,7 +52,7 @@ for (s = 0; s < numberOfSwatches; s++) { width: 31, height: 54, subImage: { x: imageFromX, y: imageFromY, width: 30, height: 54 }, - imageURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/images/testing-swatches.svg", + imageURL: HIFI_PUBLIC_BUCKET + "images/testing-swatches.svg", color: swatchColors[s], alpha: 1 }); @@ -77,7 +78,7 @@ var toolA = Overlays.addOverlay("image", { width: 62, height: 40, subImage: { x: 0, y: 0, width: 62, height: 40 }, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/hifi-interface-tools.svg", + imageURL: HIFI_PUBLIC_BUCKET + "images/hifi-interface-tools.svg", color: { red: 255, green: 255, blue: 255}, visible: false }); @@ -87,7 +88,7 @@ var toolA = Overlays.addOverlay("image", { var slider = Overlays.addOverlay("image", { // alternate form of expressing bounds bounds: { x: 100, y: 300, width: 158, height: 35}, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/slider.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/slider.png", color: { red: 255, green: 255, blue: 255}, alpha: 1 }); @@ -101,7 +102,7 @@ var thumb = Overlays.addOverlay("image", { y: 309, width: 18, height: 17, - imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/thumb.png", + imageURL: HIFI_PUBLIC_BUCKET + "images/thumb.png", color: { red: 255, green: 255, blue: 255}, alpha: 1 }); diff --git a/examples/particleBirds.js b/examples/particleBirds.js index 9492a321ce..6ed37aefe1 100644 --- a/examples/particleBirds.js +++ b/examples/particleBirds.js @@ -11,6 +11,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); + // Multiply vector by scalar function vScalarMult(v, s) { var rval = { x: v.x * s, y: v.y * s, z: v.z * s }; @@ -68,23 +70,23 @@ function addBird() var size; var which = Math.random(); if (which < 0.2) { - tweet = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Animals/bushtit_1.raw"); + tweet = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Animals/bushtit_1.raw"); color = { red: 100, green: 50, blue: 120 }; size = 0.08; } else if (which < 0.4) { - tweet = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Animals/rosyfacedlovebird.raw"); + tweet = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Animals/rosyfacedlovebird.raw"); color = { red: 100, green: 150, blue: 75 }; size = 0.09; } else if (which < 0.6) { - tweet = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Animals/saysphoebe.raw"); + tweet = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Animals/saysphoebe.raw"); color = { red: 84, green: 121, blue: 36 }; size = 0.05; } else if (which < 0.8) { - tweet = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Animals/mexicanWhipoorwill.raw"); + tweet = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Animals/mexicanWhipoorwill.raw"); color = { red: 23, green: 197, blue: 230 }; size = 0.12; } else { - tweet = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Animals/westernscreechowl.raw"); + tweet = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Animals/westernscreechowl.raw"); color = { red: 50, green: 67, blue: 144 }; size = 0.15; } diff --git a/examples/particleModelExample.js b/examples/particleModelExample.js index b489e704c9..d589e6bb31 100644 --- a/examples/particleModelExample.js +++ b/examples/particleModelExample.js @@ -11,6 +11,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); + var count = 0; var stopAfter = 100; @@ -20,7 +22,7 @@ var modelPropertiesA = { gravity: { x: 0, y: 0, z: 0 }, damping: 0, radius : 0.25, - modelURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/Feisar_Ship.FBX", + modelURL: HIFI_PUBLICK_BUCKET + "meshes/Feisar_Ship.FBX", lifetime: 20 }; @@ -30,7 +32,7 @@ var modelPropertiesB = { gravity: { x: 0, y: 0, z: 0 }, damping: 0, radius : 0.25, - modelURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/meshes/newInvader16x16.svo", + modelURL: HIFI_PUBLIC_BUCKET + "meshes/newInvader16x16.svo", modelScale: 450, modelTranslation: { x: -1.3, y: -1.3, z: -1.3 }, lifetime: 20 diff --git a/examples/playSound.js b/examples/playSound.js index 189c24e86f..4130db5b16 100644 --- a/examples/playSound.js +++ b/examples/playSound.js @@ -8,8 +8,10 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +Script.include("libraries/globals.js"); + // First, load a sample sound from a URL -var bird = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Animals/bushtit_1.raw"); +var bird = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Animals/bushtit_1.raw"); function maybePlaySound(deltaTime) { if (Math.random() < 0.01) { diff --git a/examples/playSoundLoop.js b/examples/playSoundLoop.js index 30f8762248..3122f13f37 100644 --- a/examples/playSoundLoop.js +++ b/examples/playSoundLoop.js @@ -11,12 +11,13 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); // A few sample files you may want to try: -var sound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Guitars/Guitar+-+Nylon+A.raw"); -//var sound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/220Sine.wav"); -//var sound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Cocktail+Party+Snippets/Bandcamp.wav"); +var sound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Guitars/Guitar+-+Nylon+A.raw"); +//var sound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/220Sine.wav"); +//var sound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Cocktail+Party+Snippets/Bandcamp.wav"); var soundPlaying = false; var options = new AudioInjectionOptions(); diff --git a/examples/playSoundOrbit.js b/examples/playSoundOrbit.js index da7c746e8e..2c44a4535a 100644 --- a/examples/playSoundOrbit.js +++ b/examples/playSoundOrbit.js @@ -9,7 +9,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var soundClip = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Voxels/voxel create 3.raw"); +Script.include("libraries/globals.js"); + +var soundClip = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Voxels/voxel create 3.raw"); var currentTime = 1.570079; // pi/2 var deltaTime = 0.05; diff --git a/examples/playSoundWave.js b/examples/playSoundWave.js index 419fd80cd2..f152effb47 100644 --- a/examples/playSoundWave.js +++ b/examples/playSoundWave.js @@ -9,7 +9,9 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var soundClip = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Cocktail%20Party%20Snippets/Walken1.wav"); +Script.include("libraries/globals.js"); + +var soundClip = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Cocktail%20Party%20Snippets/Walken1.wav"); function playSound() { var options = new AudioInjectionOptions(); diff --git a/examples/radio.js b/examples/radio.js index 575d9d70c8..293867398a 100644 --- a/examples/radio.js +++ b/examples/radio.js @@ -9,9 +9,10 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); -var modelURL = "https://s3-us-west-1.amazonaws.com/highfidelity-public/models/entities/radio/Speakers.fbx"; -var soundURL = "https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/FamilyStereo.raw"; +var modelURL = HIFI_PUBLIC_BUCKET + "models/entities/radio/Speakers.fbx"; +var soundURL = HIFI_PUBLIC_BUCKET + "sounds/FamilyStereo.raw"; var AudioRotationOffset = Quat.fromPitchYawRollDegrees(0, -90, 0); var audioOptions = new AudioInjectionOptions(); diff --git a/examples/spaceInvadersExample.js b/examples/spaceInvadersExample.js index 5d62102d71..862d731f90 100644 --- a/examples/spaceInvadersExample.js +++ b/examples/spaceInvadersExample.js @@ -11,6 +11,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); + var iteration = 0; var gameOver = false; @@ -82,13 +84,13 @@ var missileFired = false; var myMissile; // sounds -var hitSound = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Space%20Invaders/hit.raw"); -var shootSound = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Space%20Invaders/shoot.raw"); +var hitSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/hit.raw"); +var shootSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/shoot.raw"); var moveSounds = new Array(); -moveSounds[0] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Space%20Invaders/Lo1.raw"); -moveSounds[1] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Space%20Invaders/Lo2.raw"); -moveSounds[2] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Space%20Invaders/Lo3.raw"); -moveSounds[3] = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Space%20Invaders/Lo4.raw"); +moveSounds[0] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/Lo1.raw"); +moveSounds[1] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/Lo2.raw"); +moveSounds[2] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/Lo3.raw"); +moveSounds[3] = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Space%20Invaders/Lo4.raw"); var currentMoveSound = 0; var numberOfSounds = 4; var stepsPerSound = invaderStepsPerCycle / numberOfSounds; @@ -99,36 +101,36 @@ var soundInMyHead = true; // models... var invaderModels = new Array(); invaderModels[0] = { - modelURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/meshes/newInvader16x16-large-purple.svo", + modelURL: HIFI_PUBLIC_BUCKET + "meshes/newInvader16x16-large-purple.svo", modelScale: 450, modelTranslation: { x: -1.3, y: -1.3, z: -1.3 }, }; invaderModels[1] = { - modelURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/meshes/newInvader16x16-large-cyan.svo", + modelURL: HIFI_PUBLIC_BUCKET + "meshes/newInvader16x16-large-cyan.svo", modelScale: 450, modelTranslation: { x: -1.3, y: -1.3, z: -1.3 }, }; invaderModels[2] = { - modelURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/meshes/newInvader16x16-medium-cyan.svo", + modelURL: HIFI_PUBLIC_BUCKET + "meshes/newInvader16x16-medium-cyan.svo", modelScale: 450, modelTranslation: { x: -1.3, y: -1.3, z: -1.3 }, }; invaderModels[3] = { - modelURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/meshes/newInvader16x16-medium-green.svo", + modelURL: HIFI_PUBLIC_BUCKET + "meshes/newInvader16x16-medium-green.svo", modelScale: 450, modelTranslation: { x: -1.3, y: -1.3, z: -1.3 }, }; invaderModels[4] = { - modelURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/meshes/newInvader16x16-small-green.svo", + modelURL: HIFI_PUBLIC_BUCKET + "meshes/newInvader16x16-small-green.svo", modelScale: 450, modelTranslation: { x: -1.3, y: -1.3, z: -1.3 }, }; -//modelURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/Feisar_Ship.FBX", -//modelURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/meshes/invader.svo", -// "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/spaceInvader3.fbx" +//modelURL: HIFI_PUBLIC_BUCKET + "meshes/Feisar_Ship.FBX", +//modelURL: HIFI_PUBLIC_BUCKET + "meshes/invader.svo", +// HIFI_PUBLIC_BUCKET + "meshes/spaceInvader3.fbx" function initializeMyShip() { myShipProperties = { @@ -138,7 +140,7 @@ function initializeMyShip() { damping: 0, radius: shipSize, color: { red: 0, green: 255, blue: 0 }, - modelURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/meshes/myCannon16x16.svo", + modelURL: HIFI_PUBLIC_BUCKET + "meshes/myCannon16x16.svo", modelScale: 450, modelTranslation: { x: -1.3, y: -1.3, z: -1.3 }, lifetime: itemLifetimes diff --git a/examples/squeezeHands.js b/examples/squeezeHands.js index f920692a3b..21da7f9c25 100644 --- a/examples/squeezeHands.js +++ b/examples/squeezeHands.js @@ -9,8 +9,10 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var rightHandAnimation = "https://s3-us-west-1.amazonaws.com/highfidelity-public/animations/RightHandAnimPhilip.fbx"; -var leftHandAnimation = "https://s3-us-west-1.amazonaws.com/highfidelity-public/animations/LeftHandAnimPhilip.fbx"; +Script.include("libraries/globals.js"); + +var rightHandAnimation = HIFI_PUBLIC_BUCKET + "animations/RightHandAnimPhilip.fbx"; +var leftHandAnimation = HIFI_PUBLIC_BUCKET + "animations/LeftHandAnimPhilip.fbx"; var LEFT = 0; var RIGHT = 1; diff --git a/examples/toyball.js b/examples/toyball.js index e03fd67a5d..f79f3cb1f4 100644 --- a/examples/toyball.js +++ b/examples/toyball.js @@ -15,6 +15,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/globals.js"); + // maybe we should make these constants... var LEFT_PALM = 0; var LEFT_TIP = 1; @@ -39,7 +41,7 @@ var rightHandParticle; var newSound = new Sound("https://dl.dropboxusercontent.com/u/1864924/hifi-sounds/throw.raw"); var catchSound = new Sound("https://dl.dropboxusercontent.com/u/1864924/hifi-sounds/catch.raw"); -var throwSound = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Switches%20and%20sliders/slider%20-%20whoosh1.raw"); +var throwSound = new Sound(HIFI_PUBLIC_BUCKET + "sounds/Switches%20and%20sliders/slider%20-%20whoosh1.raw"); var targetRadius = 1.0; From 0b7ff189705f64eda78203e652f82efaf0408a50 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Mon, 6 Oct 2014 11:24:10 -0600 Subject: [PATCH 040/179] Changes in non-Js code --- interface/src/ScriptsModel.cpp | 2 +- tests/octree/src/ModelTests.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/ScriptsModel.cpp b/interface/src/ScriptsModel.cpp index 9c206fe9f6..8bea122338 100644 --- a/interface/src/ScriptsModel.cpp +++ b/interface/src/ScriptsModel.cpp @@ -21,7 +21,7 @@ #include "ScriptsModel.h" -static const QString S3_URL = "http://highfidelity-public.s3-us-west-1.amazonaws.com"; +static const QString S3_URL = "https://s3.amazonaws.com/hifi-public"; static const QString PUBLIC_URL = "http://public.highfidelity.io"; static const QString MODELS_LOCATION = "scripts/"; diff --git a/tests/octree/src/ModelTests.cpp b/tests/octree/src/ModelTests.cpp index 405b4a95d3..f6bef3e533 100644 --- a/tests/octree/src/ModelTests.cpp +++ b/tests/octree/src/ModelTests.cpp @@ -62,7 +62,7 @@ void EntityTests::entityTreeTests(bool verbose) { properties.setPosition(positionAtCenterInMeters); // TODO: Fix these unit tests. //properties.setRadius(halfMeter); - //properties.setModelURL("https://s3-us-west-1.amazonaws.com/highfidelity-public/ozan/theater.fbx"); + //properties.setModelURL("https://s3.amazonaws.com/hifi-public/ozan/theater.fbx"); tree.addEntity(entityID, properties); @@ -269,7 +269,7 @@ void EntityTests::entityTreeTests(bool verbose) { // TODO: fix these unit tests //properties.setRadius(halfMeter); - //properties.setModelURL("https://s3-us-west-1.amazonaws.com/highfidelity-public/ozan/theater.fbx"); + //properties.setModelURL("https://s3.amazonaws.com/hifi-public/ozan/theater.fbx"); if (extraVerbose) { qDebug() << "iteration:" << i From 4f26c9e0fad6248fcf1bdaa702291e4c68892a8f Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 6 Oct 2014 11:06:23 -0700 Subject: [PATCH 041/179] fix formatting and syntax issues --- interface/src/Application.cpp | 10 ++-- interface/src/BuckyBalls.cpp | 2 +- interface/src/Environment.cpp | 2 +- interface/src/avatar/Hand.cpp | 2 +- interface/src/avatar/SkeletonModel.cpp | 4 +- .../src/renderer/DeferredLightingEffect.cpp | 2 +- interface/src/renderer/GeometryCache.cpp | 47 ++++++++++--------- 7 files changed, 36 insertions(+), 33 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0c892e68f0..215848b355 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -884,11 +884,11 @@ void Application::keyPressEvent(QKeyEvent* event) { case Qt::Key_W: if (isOption && !isShifted && !isMeta) { - Menu::getInstance()->triggerOption(MenuOption::Wireframe); + Menu::getInstance()->triggerOption(MenuOption::Wireframe); } else { - _myAvatar->setDriveKeys(FWD, 1.f); - } - break; + _myAvatar->setDriveKeys(FWD, 1.f); + } + break; case Qt::Key_S: if (isShifted && isMeta && !isOption) { @@ -2906,7 +2906,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { // draw a red sphere float originSphereRadius = 0.05f; glColor3f(1,0,0); - _geometryCache.renderSphere(originSphereRadius, 15, 15); + _geometryCache.renderSphere(originSphereRadius, 15, 15); // draw the audio reflector overlay { diff --git a/interface/src/BuckyBalls.cpp b/interface/src/BuckyBalls.cpp index 893e74f083..0ea73556c5 100644 --- a/interface/src/BuckyBalls.cpp +++ b/interface/src/BuckyBalls.cpp @@ -172,7 +172,7 @@ void BuckyBalls::render() { } glPushMatrix(); glTranslatef(_bballPosition[i].x, _bballPosition[i].y, _bballPosition[i].z); - Application::getInstance()->getGeometryCache()->renderSphere(_bballRadius[i], 15, 15); + Application::getInstance()->getGeometryCache()->renderSphere(_bballRadius[i], 15, 15); glPopMatrix(); } } diff --git a/interface/src/Environment.cpp b/interface/src/Environment.cpp index 6eae464957..631e3da1cf 100644 --- a/interface/src/Environment.cpp +++ b/interface/src/Environment.cpp @@ -266,5 +266,5 @@ void Environment::renderAtmosphere(Camera& camera, const EnvironmentData& data) program->release(); - glPopMatrix(); + glPopMatrix(); } diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 9bddcd1730..d29e7312ff 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -114,7 +114,7 @@ void Hand::render(bool isMine, Model::RenderMode renderMode) { glPushMatrix(); glTranslatef(position.x, position.y, position.z); glColor3f(0.0f, 1.0f, 0.0f); - Application::getInstance()->getGeometryCache()->renderSphere(PALM_COLLISION_RADIUS * _owningAvatar->getScale(), 10, 10); + Application::getInstance()->getGeometryCache()->renderSphere(PALM_COLLISION_RADIUS * _owningAvatar->getScale(), 10, 10); glPopMatrix(); } } diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 61bee4b4c5..a791d01d53 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -899,7 +899,7 @@ void SkeletonModel::renderJointCollisionShapes(float alpha) { endPoint = endPoint - simulationTranslation; glTranslatef(endPoint.x, endPoint.y, endPoint.z); glColor4f(0.6f, 0.6f, 0.8f, alpha); - Application::getInstance()->getGeometryCache()->renderSphere(capsule->getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); + Application::getInstance()->getGeometryCache()->renderSphere(capsule->getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); // draw a yellow sphere at the capsule startpoint glm::vec3 startPoint; @@ -908,7 +908,7 @@ void SkeletonModel::renderJointCollisionShapes(float alpha) { glm::vec3 axis = endPoint - startPoint; glTranslatef(-axis.x, -axis.y, -axis.z); glColor4f(0.8f, 0.8f, 0.6f, alpha); - Application::getInstance()->getGeometryCache()->renderSphere(capsule->getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); + Application::getInstance()->getGeometryCache()->renderSphere(capsule->getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); // draw a green cylinder between the two points glm::vec3 origin(0.0f); diff --git a/interface/src/renderer/DeferredLightingEffect.cpp b/interface/src/renderer/DeferredLightingEffect.cpp index 46fb889c75..f1668629da 100644 --- a/interface/src/renderer/DeferredLightingEffect.cpp +++ b/interface/src/renderer/DeferredLightingEffect.cpp @@ -51,7 +51,7 @@ void DeferredLightingEffect::releaseSimpleProgram() { void DeferredLightingEffect::renderSolidSphere(float radius, int slices, int stacks) { bindSimpleProgram(); - Application::getInstance()->getGeometryCache()->renderSphere(radius, slices, stacks); + Application::getInstance()->getGeometryCache()->renderSphere(radius, slices, stacks); releaseSimpleProgram(); } diff --git a/interface/src/renderer/GeometryCache.cpp b/interface/src/renderer/GeometryCache.cpp index 1eecebcea2..54e4afb70a 100644 --- a/interface/src/renderer/GeometryCache.cpp +++ b/interface/src/renderer/GeometryCache.cpp @@ -114,17 +114,20 @@ void GeometryCache::renderHemisphere(int slices, int stacks) { void GeometryCache::renderSphere(float radius, int slices, int stacks) { VerticesIndices& vbo = _sphereVBOs[IntPair(slices, stacks)]; int vertices = slices * (stacks - 1) + 2; - int indices = slices * 2 * 3 * (stacks - 1) + slices * 2 * 3; - if (vbo.first == 0) { - GLfloat* vertexData = new GLfloat[vertices * 3]; + int numVerticesPerTriangle = 3; + int numTrianglesPerQuad = 2; + int indices = slices * numTrianglesPerQuad * numVerticesPerTriangle * (stacks - 1) + slices * numTrianglesPerQuad * numVerticesPerTriangle; + if (vbo.first == 0) { + int numCoordinatesPerVertex = 3; + GLfloat* vertexData = new GLfloat[vertices * numCoordinatesPerVertex]; GLfloat* vertex = vertexData; - - // south pole - *(vertex++) = 0.0f; + + // south pole + *(vertex++) = 0.0f; *(vertex++) = 0.0f; *(vertex++) = -1.0f; - //add stacks vertices climbing up Y axis + //add stacks vertices climbing up Y axis for (int i = 1; i < stacks; i++) { float phi = PI * (float)i / (float)(stacks) - PI_OVER_TWO; float z = sinf(phi), radius = cosf(phi); @@ -138,31 +141,31 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks) { } } - // north pole - *(vertex++) = 0.0f; + // north pole + *(vertex++) = 0.0f; *(vertex++) = 0.0f; *(vertex++) = 1.0f; glGenBuffers(1, &vbo.first); glBindBuffer(GL_ARRAY_BUFFER, vbo.first); - const int BYTES_PER_VERTEX = 3 * sizeof(GLfloat); + const int BYTES_PER_VERTEX = numCoordinatesPerVertex * sizeof(GLfloat); glBufferData(GL_ARRAY_BUFFER, vertices * BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW); delete[] vertexData; GLushort* indexData = new GLushort[indices]; GLushort* index = indexData; - - // South cap - GLushort bottom = 0; + + // South cap + GLushort bottom = 0; GLushort top = 1; for (int i = 0; i < slices; i++) { *(index++) = bottom; *(index++) = top + i; *(index++) = top + (i + 1) % slices; } - - // (stacks - 2) ribbons - for (int i = 0; i < stacks - 2; i++) { + + // (stacks - 2) ribbons + for (int i = 0; i < stacks - 2; i++) { bottom = i * slices + 1; top = bottom + slices; for (int j = 0; j < slices; j++) { @@ -178,8 +181,8 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks) { } } - // north cap - bottom = (stacks - 2) * slices + 1; + // north cap + bottom = (stacks - 2) * slices + 1; top = bottom + slices; for (int i = 0; i < slices; i++) { *(index++) = bottom + i; @@ -199,12 +202,12 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks) { } glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); - + glVertexPointer(3, GL_FLOAT, 0, 0); glNormalPointer(GL_FLOAT, 0, 0); - - glPushMatrix(); - glScalef(radius, radius, radius); + + glPushMatrix(); + glScalef(radius, radius, radius); glDrawRangeElementsEXT(GL_TRIANGLES, 0, vertices - 1, indices, GL_UNSIGNED_SHORT, 0); glPopMatrix(); From ba2d072a657e091739db39422e3ec4fe8555daa7 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 6 Oct 2014 12:15:36 -0700 Subject: [PATCH 042/179] fix syntax issues for constant names and the CmakeLists.txt useless change --- CMakeLists.txt | 2 +- interface/src/avatar/Avatar.cpp | 6 +++--- interface/src/renderer/GeometryCache.cpp | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ba713d35da..62cdc925f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ if (WIN32) # set path for Microsoft SDKs # if get build error about missing 'glu32' this path is likely wrong # Uncomment the line with 8.1 if running Windows 8.1 - set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "C:\\Program Files (x86)\\Windows Kits\\8.1\\Lib\\winv6.3\\um\\x86") + #set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "C:\\Program Files (x86)\\Windows Kits\\8.1\\Lib\\winv6.3\\um\\x86") set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1 ") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") elseif (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index cd76550b59..0477f6e04e 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -399,8 +399,8 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool } else { glTranslatef(_position.x, getDisplayNamePosition().y + LOOK_AT_INDICATOR_OFFSET, _position.z); } - Application::getInstance()->getGeometryCache()->renderSphere(LOOK_AT_INDICATOR_RADIUS, 15, 15); - glPopMatrix(); + Application::getInstance()->getGeometryCache()->renderSphere(LOOK_AT_INDICATOR_RADIUS, 15, 15); + glPopMatrix(); } } @@ -427,7 +427,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool glPushMatrix(); glTranslatef(_position.x, _position.y, _position.z); glScalef(height, height, height); - Application::getInstance()->getGeometryCache()->renderSphere(sphereRadius, 15, 15); + Application::getInstance()->getGeometryCache()->renderSphere(sphereRadius, 15, 15); glPopMatrix(); } diff --git a/interface/src/renderer/GeometryCache.cpp b/interface/src/renderer/GeometryCache.cpp index 54e4afb70a..107dac62f5 100644 --- a/interface/src/renderer/GeometryCache.cpp +++ b/interface/src/renderer/GeometryCache.cpp @@ -114,12 +114,12 @@ void GeometryCache::renderHemisphere(int slices, int stacks) { void GeometryCache::renderSphere(float radius, int slices, int stacks) { VerticesIndices& vbo = _sphereVBOs[IntPair(slices, stacks)]; int vertices = slices * (stacks - 1) + 2; - int numVerticesPerTriangle = 3; - int numTrianglesPerQuad = 2; - int indices = slices * numTrianglesPerQuad * numVerticesPerTriangle * (stacks - 1) + slices * numTrianglesPerQuad * numVerticesPerTriangle; + const int NUM_VERTICES_PER_TRIANGLE = 3; + const int NUM_TRIANGLES_PER_QUAD = 2; + int indices = slices * NUM_TRIANGLES_PER_QUAD * NUM_VERTICES_PER_TRIANGLE * (stacks - 1) + slices * NUM_TRIANGLES_PER_QUAD * NUM_VERTICES_PER_TRIANGLE; if (vbo.first == 0) { - int numCoordinatesPerVertex = 3; - GLfloat* vertexData = new GLfloat[vertices * numCoordinatesPerVertex]; + const int NUM_COORDS_PER_VERTEX = 3; + GLfloat* vertexData = new GLfloat[vertices * NUM_COORDS_PER_VERTEX]; GLfloat* vertex = vertexData; // south pole @@ -148,7 +148,7 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks) { glGenBuffers(1, &vbo.first); glBindBuffer(GL_ARRAY_BUFFER, vbo.first); - const int BYTES_PER_VERTEX = numCoordinatesPerVertex * sizeof(GLfloat); + const int BYTES_PER_VERTEX = NUM_COORDS_PER_VERTEX * sizeof(GLfloat); glBufferData(GL_ARRAY_BUFFER, vertices * BYTES_PER_VERTEX, vertexData, GL_STATIC_DRAW); delete[] vertexData; From 253fe53571d67df7fd00b208c7c02528a47dd14c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 6 Oct 2014 10:40:56 -0700 Subject: [PATCH 043/179] cleanup a couple of debug lines --- domain-server/src/DomainServer.cpp | 1 + libraries/networking/src/DomainHandler.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 7352729fa4..b95756f5f0 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -957,6 +957,7 @@ void DomainServer::transactionJSONCallback(const QJsonObject& data) { } void DomainServer::requestCurrentPublicSocketViaSTUN() { + qDebug() << "Sending STUN request to retrieve public socket information."; LimitedNodeList::getInstance()->sendSTUNRequest(); } diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index 5714e6923d..760c9f4c04 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -90,7 +90,7 @@ void DomainHandler::setSockAddr(const HifiSockAddr& sockAddr, const QString& hos void DomainHandler::setUUID(const QUuid& uuid) { if (uuid != _uuid) { _uuid = uuid; - qDebug() << "Domain uuid changed to" << uuidStringWithoutCurlyBraces(_uuid); + qDebug() << "Domain ID changed to" << uuidStringWithoutCurlyBraces(_uuid); } } From 319cf34b837e9fc88202ed1be5387e7faa9bdcb1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 6 Oct 2014 12:23:49 -0700 Subject: [PATCH 044/179] use an ephemeral port when using auto-networking for domain-server --- domain-server/src/DomainServer.cpp | 18 +++++++++++------- libraries/networking/src/LimitedNodeList.cpp | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index b95756f5f0..ce2a3b0052 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -189,6 +189,11 @@ bool DomainServer::optionallySetupOAuth() { const QString DOMAIN_CONFIG_ID_KEY = "id"; +const QString METAVERSE_AUTOMATIC_NETWORKING_KEY_PATH = "metaverse.automatic_networking"; +const QString FULL_AUTOMATIC_NETWORKING_VALUE = "full"; +const QString IP_ONLY_AUTOMATIC_NETWORKING_VALUE = "ip"; +const QString DISABLED_AUTOMATIC_NETWORKING_VALUE = "disabled"; + void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) { const QString CUSTOM_PORT_OPTION = "port"; @@ -196,7 +201,12 @@ void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) { QVariantMap& settingsMap = _settingsManager.getSettingsMap(); - if (settingsMap.contains(CUSTOM_PORT_OPTION)) { + QVariant autoNetworkingValue = _settingsManager.valueOrDefaultValueForKeyPath(METAVERSE_AUTOMATIC_NETWORKING_KEY_PATH); + + if (!autoNetworkingValue.isNull() && autoNetworkingValue.toString() == FULL_AUTOMATIC_NETWORKING_VALUE) { + // when using full networking use an ephemeral port + domainServerPort = 0; + } else if (settingsMap.contains(CUSTOM_PORT_OPTION)) { domainServerPort = (unsigned short) settingsMap.value(CUSTOM_PORT_OPTION).toUInt(); } @@ -310,12 +320,7 @@ bool DomainServer::optionallySetupAssignmentPayment() { return true; } -const QString FULL_AUTOMATIC_NETWORKING_VALUE = "full"; -const QString IP_ONLY_AUTOMATIC_NETWORKING_VALUE = "ip"; -const QString DISABLED_AUTOMATIC_NETWORKING_VALUE = "disabled"; - void DomainServer::setupAutomaticNetworking() { - const QString METAVERSE_AUTOMATIC_NETWORKING_KEY_PATH = "metaverse.automatic_networking"; if (!didSetupAccountManagerWithAccessToken()) { qDebug() << "Cannot setup domain-server automatic networking without an access token."; @@ -957,7 +962,6 @@ void DomainServer::transactionJSONCallback(const QJsonObject& data) { } void DomainServer::requestCurrentPublicSocketViaSTUN() { - qDebug() << "Sending STUN request to retrieve public socket information."; LimitedNodeList::getInstance()->sendSTUNRequest(); } diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index a428f1f495..d7c8f4bd12 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -580,7 +580,7 @@ void LimitedNodeList::sendSTUNRequest() { memcpy(stunRequestPacket + packetIndex, randomUUID.toRfc4122().data(), NUM_TRANSACTION_ID_BYTES); // lookup the IP for the STUN server - static HifiSockAddr stunSockAddr(STUN_SERVER_HOSTNAME, STUN_SERVER_PORT); + HifiSockAddr stunSockAddr(STUN_SERVER_HOSTNAME, STUN_SERVER_PORT); _nodeSocket.writeDatagram((char*) stunRequestPacket, sizeof(stunRequestPacket), stunSockAddr.getAddress(), stunSockAddr.getPort()); From 3cd71a33c921c8d409ad7dfcd4fb1e2511460d09 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 6 Oct 2014 12:28:44 -0700 Subject: [PATCH 045/179] disable ephemeral port for DS until ACs can discover --- domain-server/src/DomainServer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index ce2a3b0052..6b2faffe01 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -204,8 +204,8 @@ void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) { QVariant autoNetworkingValue = _settingsManager.valueOrDefaultValueForKeyPath(METAVERSE_AUTOMATIC_NETWORKING_KEY_PATH); if (!autoNetworkingValue.isNull() && autoNetworkingValue.toString() == FULL_AUTOMATIC_NETWORKING_VALUE) { - // when using full networking use an ephemeral port - domainServerPort = 0; + // when using full networking use an ephemeral port - disabled until nodes can find us this way + // domainServerPort = 0; } else if (settingsMap.contains(CUSTOM_PORT_OPTION)) { domainServerPort = (unsigned short) settingsMap.value(CUSTOM_PORT_OPTION).toUInt(); } From 0fd7ec34fc5323180fb7437b22d337d17d2764e1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 6 Oct 2014 12:34:12 -0700 Subject: [PATCH 046/179] remove an unused const --- assignment-client/src/audio/AudioMixer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 681cc58cb3..37d89f3790 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -364,7 +364,6 @@ int AudioMixer::addStreamToMixForListeningNodeWithStream(AudioMixerClientData* l const float ZERO_DB = 1.0f; const float NEGATIVE_ONE_DB = 0.891f; const float NEGATIVE_THREE_DB = 0.708f; - const float NEGATIVE_SIX_DB = 0.501f; const float FILTER_GAIN_AT_0 = ZERO_DB; // source is in front const float FILTER_GAIN_AT_90 = NEGATIVE_ONE_DB; // source is incident to left or right ear From 1de473a01324ca47354c309105f67c231eedca7f Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Mon, 6 Oct 2014 14:27:25 -0600 Subject: [PATCH 047/179] Fixing globals var scopt --- examples/libraries/globals.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/libraries/globals.js b/examples/libraries/globals.js index 211e0d56b6..1bd851af77 100644 --- a/examples/libraries/globals.js +++ b/examples/libraries/globals.js @@ -8,4 +8,4 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var HIFI_PUBLIC_BUCKET = "https://s3.amazonaws.com/hifi-public/"; \ No newline at end of file +HIFI_PUBLIC_BUCKET = "https://s3.amazonaws.com/hifi-public/"; From 499e748d54b062f20ef6b893c00aa645db9a316f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 6 Oct 2014 13:45:11 -0700 Subject: [PATCH 048/179] rebind the node socket when switching to ThreadedAssignment --- libraries/networking/src/LimitedNodeList.cpp | 7 +++++++ libraries/networking/src/LimitedNodeList.h | 2 ++ libraries/networking/src/ThreadedAssignment.cpp | 3 +++ 3 files changed, 12 insertions(+) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 507788009a..0279c9b697 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -576,6 +576,13 @@ void LimitedNodeList::sendSTUNRequest() { stunSockAddr.getAddress(), stunSockAddr.getPort()); } +void LimitedNodeList::rebindNodeSocket() { + quint16 oldPort = _nodeSocket.localPort(); + + _nodeSocket.close(); + _nodeSocket.bind(QHostAddress::AnyIPv4, oldPort); +} + bool LimitedNodeList::processSTUNResponse(const QByteArray& packet) { // check the cookie to make sure this is actually a STUN response // and read the first attribute and make sure it is a XOR_MAPPED_ADDRESS diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index a7ffc7ec28..406b851d0e 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -69,6 +69,8 @@ public: const QUuid& getSessionUUID() const { return _sessionUUID; } void setSessionUUID(const QUuid& sessionUUID); + + void rebindNodeSocket(); QUdpSocket& getNodeSocket() { return _nodeSocket; } QUdpSocket& getDTLSSocket(); diff --git a/libraries/networking/src/ThreadedAssignment.cpp b/libraries/networking/src/ThreadedAssignment.cpp index cd80c441c1..6d2e366499 100644 --- a/libraries/networking/src/ThreadedAssignment.cpp +++ b/libraries/networking/src/ThreadedAssignment.cpp @@ -59,6 +59,9 @@ void ThreadedAssignment::commonInit(const QString& targetName, NodeType_t nodeTy NodeList* nodeList = NodeList::getInstance(); nodeList->setOwnerType(nodeType); + // this is a temp fix for Qt 5.3 - rebinding the node socket gives us readyRead for the socket on this thread + nodeList->rebindNodeSocket(); + QTimer* domainServerTimer = new QTimer(this); connect(domainServerTimer, SIGNAL(timeout()), this, SLOT(checkInWithDomainServerOrExit())); domainServerTimer->start(DOMAIN_SERVER_CHECK_IN_MSECS); From 08147380c71444950ab2b08c49a49c018dccbb18 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Mon, 6 Oct 2014 14:09:23 -0700 Subject: [PATCH 049/179] Fix property names used for text overlay colors --- examples/overlaysExample.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/overlaysExample.js b/examples/overlaysExample.js index 2161b1c903..fef502c761 100644 --- a/examples/overlaysExample.js +++ b/examples/overlaysExample.js @@ -64,8 +64,8 @@ var text = Overlays.addOverlay("text", { y: 100, width: 150, height: 50, - color: { red: 0, green: 0, blue: 0}, - textColor: { red: 255, green: 0, blue: 0}, + backgroundColor: { red: 255, green: 255, blue: 255}, + color: { red: 255, green: 0, blue: 0}, topMargin: 4, leftMargin: 4, text: "Here is some text.\nAnd a second line." From 12deec928c002c5ec01af00ff65b7de5390fb5b9 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 6 Oct 2014 14:15:22 -0700 Subject: [PATCH 050/179] add tick marks to planar ellipse/circle overlays --- examples/libraries/entitySelectionTool.js | 23 +++- interface/src/ui/overlays/Circle3DOverlay.cpp | 118 +++++++++++++++++- interface/src/ui/overlays/Circle3DOverlay.h | 21 ++++ 3 files changed, 157 insertions(+), 5 deletions(-) diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index e07fb752e5..d9cf2c54fd 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -169,7 +169,14 @@ SelectionDisplay = (function () { alpha: 0.2, solid: true, visible: false, - rotation: yawOverlayRotation + rotation: yawOverlayRotation, + hasTickMarks: true, + majorTickMarksAngle: 12.5, + minorTickMarksAngle: 0, + majorTickMarksLength: -0.25, + minorTickMarksLength: 0, + majorTickMarksColor: { red: 0, green: 0, blue: 0 }, + minorTickMarksColor: { red: 0, green: 0, blue: 0 }, }); var rotateOverlayOuter = Overlays.addOverlay("circle3d", { @@ -179,7 +186,15 @@ SelectionDisplay = (function () { alpha: 0.2, solid: true, visible: false, - rotation: yawOverlayRotation + rotation: yawOverlayRotation, + + hasTickMarks: true, + majorTickMarksAngle: 45.0, + minorTickMarksAngle: 5, + majorTickMarksLength: 0.25, + minorTickMarksLength: 0.1, + majorTickMarksColor: { red: 0, green: 0, blue: 0 }, + minorTickMarksColor: { red: 0, green: 0, blue: 0 }, }); var rotateOverlayCurrent = Overlays.addOverlay("circle3d", { @@ -571,7 +586,7 @@ SelectionDisplay = (function () { innerRadius: 0.9, startAt: 0, endAt: 360, - alpha: outerAlpha + alpha: outerAlpha, }); Overlays.editOverlay(rotateOverlayCurrent, @@ -584,7 +599,7 @@ SelectionDisplay = (function () { size: outerRadius, startAt: 0, endAt: 0, - innerRadius: 0.9 + innerRadius: 0.9, }); // TODO: we have not implemented the rotating handle/controls yet... so for now, these handles are hidden diff --git a/interface/src/ui/overlays/Circle3DOverlay.cpp b/interface/src/ui/overlays/Circle3DOverlay.cpp index cecec29130..6ff256d48e 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.cpp +++ b/interface/src/ui/overlays/Circle3DOverlay.cpp @@ -21,8 +21,15 @@ Circle3DOverlay::Circle3DOverlay() : _startAt(0.0f), _endAt(360.0f), _outerRadius(1.0f), - _innerRadius(0.0f) + _innerRadius(0.0f), + _hasTickMarks(false), + _majorTickMarksAngle(0.0f), + _minorTickMarksAngle(0.0f), + _majorTickMarksLength(0.0f), + _minorTickMarksLength(0.0f) { + _majorTickMarksColor.red = _majorTickMarksColor.green = _majorTickMarksColor.blue = (unsigned char)0; + _minorTickMarksColor.red = _minorTickMarksColor.green = _minorTickMarksColor.blue = (unsigned char)0; } Circle3DOverlay::~Circle3DOverlay() { @@ -142,6 +149,66 @@ void Circle3DOverlay::render() { glVertex2f(lastOuterPoint.x, lastOuterPoint.y); glEnd(); } + + // draw our tick marks + // for our overlay, is solid means we draw a ring between the inner and outer radius of the circle, otherwise + // we just draw a line... + if (getHasTickMarks()) { + glBegin(GL_LINES); + + // draw our major tick marks + if (getMajorTickMarksAngle() > 0.0f && getMajorTickMarksLength() != 0.0f) { + + xColor color = getMajorTickMarksColor(); + glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); + + float angle = startAt; + float angleInRadians = glm::radians(angle); + float tickMarkLength = getMajorTickMarksLength(); + float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius; + float endRadius = startRadius + tickMarkLength; + + while (angle <= endAt) { + angleInRadians = glm::radians(angle); + + glm::vec2 thisPointA(cos(angleInRadians) * startRadius, sin(angleInRadians) * startRadius); + glm::vec2 thisPointB(cos(angleInRadians) * endRadius, sin(angleInRadians) * endRadius); + + glVertex2f(thisPointA.x, thisPointA.y); + glVertex2f(thisPointB.x, thisPointB.y); + + angle += getMajorTickMarksAngle(); + } + } + + // draw our minor tick marks + if (getMinorTickMarksAngle() > 0.0f && getMinorTickMarksLength() != 0.0f) { + + xColor color = getMinorTickMarksColor(); + glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); + + float angle = startAt; + float angleInRadians = glm::radians(angle); + float tickMarkLength = getMinorTickMarksLength(); + float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius; + float endRadius = startRadius + tickMarkLength; + + while (angle <= endAt) { + angleInRadians = glm::radians(angle); + + glm::vec2 thisPointA(cos(angleInRadians) * startRadius, sin(angleInRadians) * startRadius); + glm::vec2 thisPointB(cos(angleInRadians) * endRadius, sin(angleInRadians) * endRadius); + + glVertex2f(thisPointA.x, thisPointA.y); + glVertex2f(thisPointB.x, thisPointB.y); + + angle += getMinorTickMarksAngle(); + } + } + + glEnd(); + } + glPopMatrix(); glPopMatrix(); @@ -173,6 +240,55 @@ void Circle3DOverlay::setProperties(const QScriptValue &properties) { if (innerRadius.isValid()) { setInnerRadius(innerRadius.toVariant().toFloat()); } + + QScriptValue hasTickMarks = properties.property("hasTickMarks"); + if (hasTickMarks.isValid()) { + setHasTickMarks(hasTickMarks.toVariant().toBool()); + } + + QScriptValue majorTickMarksAngle = properties.property("majorTickMarksAngle"); + if (majorTickMarksAngle.isValid()) { + setMajorTickMarksAngle(majorTickMarksAngle.toVariant().toFloat()); + } + + QScriptValue minorTickMarksAngle = properties.property("minorTickMarksAngle"); + if (minorTickMarksAngle.isValid()) { + setMinorTickMarksAngle(minorTickMarksAngle.toVariant().toFloat()); + } + + QScriptValue majorTickMarksLength = properties.property("majorTickMarksLength"); + if (majorTickMarksLength.isValid()) { + setMajorTickMarksLength(majorTickMarksLength.toVariant().toFloat()); + } + + QScriptValue minorTickMarksLength = properties.property("minorTickMarksLength"); + if (minorTickMarksLength.isValid()) { + setMinorTickMarksLength(minorTickMarksLength.toVariant().toFloat()); + } + + QScriptValue majorTickMarksColor = properties.property("majorTickMarksColor"); + if (majorTickMarksColor.isValid()) { + QScriptValue red = majorTickMarksColor.property("red"); + QScriptValue green = majorTickMarksColor.property("green"); + QScriptValue blue = majorTickMarksColor.property("blue"); + if (red.isValid() && green.isValid() && blue.isValid()) { + _majorTickMarksColor.red = red.toVariant().toInt(); + _majorTickMarksColor.green = green.toVariant().toInt(); + _majorTickMarksColor.blue = blue.toVariant().toInt(); + } + } + + QScriptValue minorTickMarksColor = properties.property("minorTickMarksColor"); + if (minorTickMarksColor.isValid()) { + QScriptValue red = minorTickMarksColor.property("red"); + QScriptValue green = minorTickMarksColor.property("green"); + QScriptValue blue = minorTickMarksColor.property("blue"); + if (red.isValid() && green.isValid() && blue.isValid()) { + _minorTickMarksColor.red = red.toVariant().toInt(); + _minorTickMarksColor.green = green.toVariant().toInt(); + _minorTickMarksColor.blue = blue.toVariant().toInt(); + } + } } diff --git a/interface/src/ui/overlays/Circle3DOverlay.h b/interface/src/ui/overlays/Circle3DOverlay.h index cea9db0384..791d951105 100644 --- a/interface/src/ui/overlays/Circle3DOverlay.h +++ b/interface/src/ui/overlays/Circle3DOverlay.h @@ -26,17 +26,38 @@ public: float getEndAt() const { return _endAt; } float getOuterRadius() const { return _outerRadius; } float getInnerRadius() const { return _innerRadius; } + bool getHasTickMarks() const { return _hasTickMarks; } + float getMajorTickMarksAngle() const { return _majorTickMarksAngle; } + float getMinorTickMarksAngle() const { return _minorTickMarksAngle; } + float getMajorTickMarksLength() const { return _majorTickMarksLength; } + float getMinorTickMarksLength() const { return _minorTickMarksLength; } + xColor getMajorTickMarksColor() const { return _majorTickMarksColor; } + xColor getMinorTickMarksColor() const { return _minorTickMarksColor; } void setStartAt(float value) { _startAt = value; } void setEndAt(float value) { _endAt = value; } void setOuterRadius(float value) { _outerRadius = value; } void setInnerRadius(float value) { _innerRadius = value; } + void setHasTickMarks(bool value) { _hasTickMarks = value; } + void setMajorTickMarksAngle(float value) { _majorTickMarksAngle = value; } + void setMinorTickMarksAngle(float value) { _minorTickMarksAngle = value; } + void setMajorTickMarksLength(float value) { _majorTickMarksLength = value; } + void setMinorTickMarksLength(float value) { _minorTickMarksLength = value; } + void setMajorTickMarksColor(const xColor& value) { _majorTickMarksColor = value; } + void setMinorTickMarksColor(const xColor& value) { _minorTickMarksColor = value; } protected: float _startAt; float _endAt; float _outerRadius; float _innerRadius; + bool _hasTickMarks; + float _majorTickMarksAngle; + float _minorTickMarksAngle; + float _majorTickMarksLength; + float _minorTickMarksLength; + xColor _majorTickMarksColor; + xColor _minorTickMarksColor; }; From 65b559ca3d4fdb2877fe5912f35e930ea9faceb2 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Mon, 6 Oct 2014 15:21:51 -0600 Subject: [PATCH 051/179] Missed one --- interface/src/ui/ModelsBrowser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/ModelsBrowser.cpp b/interface/src/ui/ModelsBrowser.cpp index 9ff839256d..0f89c44d23 100644 --- a/interface/src/ui/ModelsBrowser.cpp +++ b/interface/src/ui/ModelsBrowser.cpp @@ -26,7 +26,7 @@ const char* MODEL_TYPE_NAMES[] = { "entities", "heads", "skeletons", "attachments" }; -static const QString S3_URL = "http://highfidelity-public.s3-us-west-1.amazonaws.com"; +static const QString S3_URL = "https://s3.amazonaws.com/hifi-public"; static const QString PUBLIC_URL = "http://public.highfidelity.io"; static const QString MODELS_LOCATION = "models/"; From 6aba2359ed0646d77a2b5cec0320b4de8242d46f Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 6 Oct 2014 14:27:43 -0700 Subject: [PATCH 052/179] Tweak low velocity avatar keyboard control. --- interface/src/avatar/MyAvatar.cpp | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index a31c25b572..469df6066d 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -49,8 +49,8 @@ const float PITCH_SPEED = 100.0f; // degrees/sec const float COLLISION_RADIUS_SCALAR = 1.2f; // pertains to avatar-to-avatar collisions const float COLLISION_RADIUS_SCALE = 0.125f; -const float MIN_KEYBOARD_CONTROL_SPEED = 1.5f; -const float MAX_WALKING_SPEED = 3.0f * MIN_KEYBOARD_CONTROL_SPEED; +const float MIN_KEYBOARD_CONTROL_SPEED = 0.75f; +const float MAX_WALKING_SPEED = 4.5f; // TODO: normalize avatar speed for standard avatar size, then scale all motion logic // to properly follow avatar size. @@ -1262,21 +1262,19 @@ glm::vec3 MyAvatar::applyKeyboardMotor(float deltaTime, const glm::vec3& localVe // Compute the target keyboard velocity (which ramps up slowly, and damps very quickly) // the max magnitude of which depends on what we're doing: - float finalMaxMotorSpeed = hasFloor ? _scale * MAX_WALKING_SPEED : _scale * MAX_KEYBOARD_MOTOR_SPEED; float motorLength = glm::length(_keyboardMotorVelocity); + float finalMaxMotorSpeed = hasFloor ? _scale * MAX_WALKING_SPEED : _scale * MAX_KEYBOARD_MOTOR_SPEED; + float speedGrowthTimescale = 2.0f; + float speedIncreaseFactor = 1.8f; + motorLength *= 1.0f + glm::clamp(deltaTime / speedGrowthTimescale , 0.0f, 1.0f) * speedIncreaseFactor; if (motorLength < _scale * MIN_KEYBOARD_CONTROL_SPEED) { // an active keyboard motor should never be slower than this - _keyboardMotorVelocity = _scale * MIN_KEYBOARD_CONTROL_SPEED * direction; + motorLength = _scale * MIN_KEYBOARD_CONTROL_SPEED; motorEfficiency = 1.0f; - } else { - float KEYBOARD_MOTOR_LENGTH_TIMESCALE = 2.0f; - float INCREASE_FACTOR = 1.8f; - motorLength *= 1.0f + glm::clamp(deltaTime / KEYBOARD_MOTOR_LENGTH_TIMESCALE, 0.0f, 1.0f) * INCREASE_FACTOR; - if (motorLength > finalMaxMotorSpeed) { - motorLength = finalMaxMotorSpeed; - } - _keyboardMotorVelocity = motorLength * direction; + } else if (motorLength > finalMaxMotorSpeed) { + motorLength = finalMaxMotorSpeed; } + _keyboardMotorVelocity = motorLength * direction; _isPushing = true; } } else { From 07832fdd686911df1c4b5a94689f6e02d724c773 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 6 Oct 2014 14:34:19 -0700 Subject: [PATCH 053/179] fix include for https relative urls --- libraries/script-engine/src/ScriptEngine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 47e0ced6bf..f45ae19939 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -681,7 +681,7 @@ void ScriptEngine::include(const QString& includeFile) { QUrl url = resolveInclude(includeFile); QString includeContents; - if (url.scheme() == "http" || url.scheme() == "ftp") { + if (url.scheme() == "http" || url.scheme() == "https" || url.scheme() == "ftp") { NetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkReply* reply = networkAccessManager.get(QNetworkRequest(url)); qDebug() << "Downloading included script at" << includeFile; From 14cd04435905630b41d51d66b02d9b000ec9bfcf Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 6 Oct 2014 14:41:16 -0700 Subject: [PATCH 054/179] handle custom local UDP port for domain-server from webpage --- domain-server/resources/describe-settings.json | 8 ++++++++ domain-server/resources/web/js/settings.js | 5 +++++ domain-server/src/DomainServerSettingsManager.cpp | 3 +++ 3 files changed, 16 insertions(+) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 2fbe33a4e1..cadbc4d2c8 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -33,6 +33,14 @@ "label": "None: use the network information I have entered for this domain at data.highfidelity.io" } ] + }, + { + "name": "port", + "label": "Local UDP Port", + "help": "This is the local port your domain-server binds to for UDP connections.
Depending on your router, this may need to be changed to run multiple full automatic networking domain-servers in the same network.", + "default": "40102", + "type": "int", + "advanced": true } ] }, diff --git a/domain-server/resources/web/js/settings.js b/domain-server/resources/web/js/settings.js index 48b3b15e8f..5c3dfdd6dd 100644 --- a/domain-server/resources/web/js/settings.js +++ b/domain-server/resources/web/js/settings.js @@ -46,6 +46,11 @@ var viewHelpers = { form_group += "" } else { + + if (input_type == 'integer') { + input_type = "text" + } + form_group += "" diff --git a/domain-server/src/DomainServerSettingsManager.cpp b/domain-server/src/DomainServerSettingsManager.cpp index 28b1151f2d..7c92f1cc51 100644 --- a/domain-server/src/DomainServerSettingsManager.cpp +++ b/domain-server/src/DomainServerSettingsManager.cpp @@ -254,11 +254,14 @@ void DomainServerSettingsManager::recurseJSONObjectAndOverwriteSettings(const QJ QString settingType = groupObject[SETTING_DESCRIPTION_TYPE_KEY].toString(); const QString INPUT_DOUBLE_TYPE = "double"; + const QString INPUT_INTEGER_TYPE = "int"; // make sure the resulting json value has the right type if (settingType == INPUT_DOUBLE_TYPE) { settingsVariant[key] = rootValue.toString().toDouble(); + } else if (settingType == INPUT_INTEGER_TYPE) { + settingsVariant[key] = rootValue.toString().toInt(); } else { settingsVariant[key] = rootValue.toString(); } From 78920234bbf51495b211d43c6e052033de785d42 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 6 Oct 2014 14:49:15 -0700 Subject: [PATCH 055/179] handle changed domain-server port on start --- domain-server/resources/describe-settings.json | 2 +- domain-server/src/DomainServer.cpp | 15 ++++----------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index cadbc4d2c8..568931e074 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -35,7 +35,7 @@ ] }, { - "name": "port", + "name": "local_port", "label": "Local UDP Port", "help": "This is the local port your domain-server binds to for UDP connections.
Depending on your router, this may need to be changed to run multiple full automatic networking domain-servers in the same network.", "default": "40102", diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 6b2faffe01..fa7a0fe012 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -196,20 +196,13 @@ const QString DISABLED_AUTOMATIC_NETWORKING_VALUE = "disabled"; void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) { - const QString CUSTOM_PORT_OPTION = "port"; - unsigned short domainServerPort = DEFAULT_DOMAIN_SERVER_PORT; + const QString CUSTOM_LOCAL_PORT_OPTION = "metaverse.local_port"; + + QVariant localPortValue = _settingsManager.valueOrDefaultValueForKeyPath(CUSTOM_LOCAL_PORT_OPTION); + unsigned short domainServerPort = (unsigned short) localPortValue.toUInt(); QVariantMap& settingsMap = _settingsManager.getSettingsMap(); - QVariant autoNetworkingValue = _settingsManager.valueOrDefaultValueForKeyPath(METAVERSE_AUTOMATIC_NETWORKING_KEY_PATH); - - if (!autoNetworkingValue.isNull() && autoNetworkingValue.toString() == FULL_AUTOMATIC_NETWORKING_VALUE) { - // when using full networking use an ephemeral port - disabled until nodes can find us this way - // domainServerPort = 0; - } else if (settingsMap.contains(CUSTOM_PORT_OPTION)) { - domainServerPort = (unsigned short) settingsMap.value(CUSTOM_PORT_OPTION).toUInt(); - } - unsigned short domainServerDTLSPort = 0; if (_isUsingDTLS) { From f19c5c98503f38b24e57372177ea8a135c2a52a3 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 6 Oct 2014 14:57:38 -0700 Subject: [PATCH 056/179] repair NetworkAccessManager returns, handle custom AS port in assignment-client --- assignment-client/src/Agent.cpp | 2 +- assignment-client/src/AssignmentClient.cpp | 21 ++++++++++++++++---- interface/src/Application.cpp | 2 +- interface/src/ScriptsModel.cpp | 2 +- libraries/audio/src/Sound.cpp | 2 +- libraries/avatars/src/AvatarData.cpp | 4 ++-- libraries/avatars/src/Recording.cpp | 2 +- libraries/networking/src/NodeList.cpp | 8 +------- libraries/script-engine/src/ScriptEngine.cpp | 4 ++-- 9 files changed, 27 insertions(+), 20 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index ea49b90852..140742ce88 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -206,7 +206,7 @@ void Agent::run() { scriptURL = QUrl(_payload); } - NetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkReply *reply = networkAccessManager.get(QNetworkRequest(scriptURL)); QNetworkDiskCache* cache = new QNetworkDiskCache(); diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index 24b6127d63..b30cd355d1 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -59,6 +59,7 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : const QString ASSIGNMENT_POOL_OPTION = "pool"; const QString ASSIGNMENT_WALLET_DESTINATION_ID_OPTION = "wallet"; const QString CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION = "a"; + const QString CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION = "p"; Assignment::Type requestAssignmentType = Assignment::AllTypes; @@ -87,17 +88,29 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) : // create a NodeList as an unassigned client NodeList* nodeList = NodeList::createInstance(NodeType::Unassigned); + + unsigned short assignmentServerPort = DEFAULT_DOMAIN_SERVER_PORT; + + // check for an overriden assignment server port + if (argumentVariantMap.contains(CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION)) { + assignmentServerPort = + argumentVariantMap.value(CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION).toString().toUInt(); + } + + HifiSockAddr assignmentServerSocket(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME, assignmentServerPort); // check for an overriden assignment server hostname if (argumentVariantMap.contains(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION)) { _assignmentServerHostname = argumentVariantMap.value(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION).toString(); - // set the custom assignment socket on our NodeList - HifiSockAddr customAssignmentSocket = HifiSockAddr(_assignmentServerHostname, DEFAULT_DOMAIN_SERVER_PORT); - - nodeList->setAssignmentServerSocket(customAssignmentSocket); + // change the hostname for our assignment server + assignmentServerSocket = HifiSockAddr(_assignmentServerHostname, assignmentServerSocket.getPort()); } + + nodeList->setAssignmentServerSocket(assignmentServerSocket); + qDebug() << "Assignment server socket is" << assignmentServerSocket; + // call a timer function every ASSIGNMENT_REQUEST_INTERVAL_MSECS to ask for assignment, if required qDebug() << "Waiting for assignment -" << _requestAssignment; diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 215848b355..a31b148d1b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -350,7 +350,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation); - NetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkDiskCache* cache = new QNetworkDiskCache(); cache->setCacheDirectory(!cachePath.isEmpty() ? cachePath : "interfaceCache"); networkAccessManager.setCache(cache); diff --git a/interface/src/ScriptsModel.cpp b/interface/src/ScriptsModel.cpp index 8bea122338..b95b6ae735 100644 --- a/interface/src/ScriptsModel.cpp +++ b/interface/src/ScriptsModel.cpp @@ -117,7 +117,7 @@ void ScriptsModel::requestRemoteFiles(QString marker) { } url.setQuery(query); - NetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkRequest request(url); QNetworkReply* reply = networkAccessManager.get(request); connect(reply, SIGNAL(finished()), SLOT(downloadFinished())); diff --git a/libraries/audio/src/Sound.cpp b/libraries/audio/src/Sound.cpp index 6fa002a664..2266385425 100644 --- a/libraries/audio/src/Sound.cpp +++ b/libraries/audio/src/Sound.cpp @@ -78,7 +78,7 @@ Sound::Sound(const QUrl& sampleURL, bool isStereo, QObject* parent) : // assume we have a QApplication or QCoreApplication instance and use the // QNetworkAccess manager to grab the raw audio file at the given URL - NetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); qDebug() << "Requesting audio file" << sampleURL.toDisplayString(); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index ef7083e3bf..62cde44909 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -1048,7 +1048,7 @@ void AvatarData::setBillboardFromURL(const QString &billboardURL) { QNetworkRequest billboardRequest; billboardRequest.setUrl(QUrl(billboardURL)); - NetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkReply* networkReply = networkAccessManager.get(billboardRequest); connect(networkReply, SIGNAL(finished()), this, SLOT(setBillboardFromNetworkReply())); } @@ -1113,7 +1113,7 @@ void AvatarData::updateJointMappings() { _jointNames.clear(); if (_skeletonModelURL.fileName().toLower().endsWith(".fst")) { - NetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkReply* networkReply = networkAccessManager.get(QNetworkRequest(_skeletonModelURL)); connect(networkReply, SIGNAL(finished()), this, SLOT(setJointMappingsFromNetworkReply())); } diff --git a/libraries/avatars/src/Recording.cpp b/libraries/avatars/src/Recording.cpp index 7465eb1aac..0d089a2bd2 100644 --- a/libraries/avatars/src/Recording.cpp +++ b/libraries/avatars/src/Recording.cpp @@ -385,7 +385,7 @@ RecordingPointer readRecordingFromFile(RecordingPointer recording, const QString if (url.scheme() == "http" || url.scheme() == "https" || url.scheme() == "ftp") { // Download file if necessary qDebug() << "Downloading recording at" << url; - NetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkReply* reply = networkAccessManager.get(QNetworkRequest(url)); QEventLoop loop; QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index cac4071fb2..25531861ca 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -418,13 +418,7 @@ void NodeList::sendAssignment(Assignment& assignment) { packetStream << assignment; - static HifiSockAddr DEFAULT_ASSIGNMENT_SOCKET(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME, DEFAULT_DOMAIN_SERVER_PORT); - - const HifiSockAddr* assignmentServerSocket = _assignmentServerSocket.isNull() - ? &DEFAULT_ASSIGNMENT_SOCKET - : &_assignmentServerSocket; - - _nodeSocket.writeDatagram(packet, assignmentServerSocket->getAddress(), assignmentServerSocket->getPort()); + _nodeSocket.writeDatagram(packet, _assignmentServerSocket.getAddress(), _assignmentServerSocket.getPort()); } void NodeList::pingPunchForInactiveNode(const SharedNodePointer& node) { diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 47e0ced6bf..26466ddc47 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -157,7 +157,7 @@ ScriptEngine::ScriptEngine(const QUrl& scriptURL, emit errorMessage("ERROR Loading file:" + fileName); } } else { - NetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkReply* reply = networkAccessManager.get(QNetworkRequest(url)); qDebug() << "Downloading script at" << url; QEventLoop loop; @@ -682,7 +682,7 @@ void ScriptEngine::include(const QString& includeFile) { QString includeContents; if (url.scheme() == "http" || url.scheme() == "ftp") { - NetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkReply* reply = networkAccessManager.get(QNetworkRequest(url)); qDebug() << "Downloading included script at" << includeFile; QEventLoop loop; From a358b4e2af55f5e66eeea594479d69a23326d43e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 6 Oct 2014 14:57:54 -0700 Subject: [PATCH 057/179] repair another reference to NetworkAccessManager --- interface/src/ui/ModelsBrowser.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/ModelsBrowser.cpp b/interface/src/ui/ModelsBrowser.cpp index 0f89c44d23..7a76bc2d7d 100644 --- a/interface/src/ui/ModelsBrowser.cpp +++ b/interface/src/ui/ModelsBrowser.cpp @@ -221,7 +221,7 @@ void ModelHandler::update() { } for (int i = 0; i < _model.rowCount(); ++i) { QUrl url(_model.item(i,0)->data(Qt::UserRole).toString()); - NetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkRequest request(url); QNetworkReply* reply = networkAccessManager.head(request); connect(reply, SIGNAL(finished()), SLOT(downloadFinished())); @@ -272,7 +272,7 @@ void ModelHandler::queryNewFiles(QString marker) { // Download url.setQuery(query); - NetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkRequest request(url); QNetworkReply* reply = networkAccessManager.get(request); connect(reply, SIGNAL(finished()), SLOT(downloadFinished())); From b4cfce8ffa36a2b2cfe2089e79ecd9ee2933ab97 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 6 Oct 2014 14:58:23 -0700 Subject: [PATCH 058/179] final NetworkAccessManager return repairs --- interface/src/ui/ScriptEditorWidget.cpp | 2 +- interface/src/ui/overlays/ImageOverlay.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/ScriptEditorWidget.cpp b/interface/src/ui/ScriptEditorWidget.cpp index 1473e4a6a0..b55c753061 100644 --- a/interface/src/ui/ScriptEditorWidget.cpp +++ b/interface/src/ui/ScriptEditorWidget.cpp @@ -150,7 +150,7 @@ void ScriptEditorWidget::loadFile(const QString& scriptPath) { disconnect(_scriptEngine, &ScriptEngine::finished, this, &ScriptEditorWidget::onScriptFinished); } } else { - NetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkReply* reply = networkAccessManager.get(QNetworkRequest(url)); qDebug() << "Downloading included script at" << scriptPath; QEventLoop loop; diff --git a/interface/src/ui/overlays/ImageOverlay.cpp b/interface/src/ui/overlays/ImageOverlay.cpp index 8322b9bea4..2b4e1e2f56 100644 --- a/interface/src/ui/overlays/ImageOverlay.cpp +++ b/interface/src/ui/overlays/ImageOverlay.cpp @@ -37,7 +37,7 @@ ImageOverlay::~ImageOverlay() { // TODO: handle setting image multiple times, how do we manage releasing the bound texture? void ImageOverlay::setImageURL(const QUrl& url) { _isLoaded = false; - NetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkReply* reply = networkAccessManager.get(QNetworkRequest(url)); connect(reply, &QNetworkReply::finished, this, &ImageOverlay::replyFinished); } From 63730a37da0f39ad93c18fd8e17b5718eeabbb6e Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Mon, 6 Oct 2014 15:26:47 -0700 Subject: [PATCH 059/179] Bring initial walk speed down for easier maneuvering around people --- interface/src/avatar/MyAvatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 469df6066d..087d670760 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -49,7 +49,7 @@ const float PITCH_SPEED = 100.0f; // degrees/sec const float COLLISION_RADIUS_SCALAR = 1.2f; // pertains to avatar-to-avatar collisions const float COLLISION_RADIUS_SCALE = 0.125f; -const float MIN_KEYBOARD_CONTROL_SPEED = 0.75f; +const float MIN_KEYBOARD_CONTROL_SPEED = 0.50f; const float MAX_WALKING_SPEED = 4.5f; // TODO: normalize avatar speed for standard avatar size, then scale all motion logic From 9fc0abe2b3c37925fc357a49c9e7d3929e702957 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 6 Oct 2014 17:30:28 -0700 Subject: [PATCH 060/179] Working on metavoxel averaging. Still pretty rough. --- interface/src/MetavoxelSystem.cpp | 58 +++---- interface/src/ui/MetavoxelEditor.cpp | 2 +- .../metavoxels/src/AttributeRegistry.cpp | 153 +++++++++++++++++- 3 files changed, 179 insertions(+), 34 deletions(-) diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index 7faf1a5bf4..cb2673b08d 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -1564,14 +1564,13 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { VoxelColorDataPointer color = info.inputValues.at(0).getInlineValue(); VoxelMaterialDataPointer material = info.inputValues.at(1).getInlineValue(); VoxelHermiteDataPointer hermite = info.inputValues.at(2).getInlineValue(); - if (color && material && hermite) { + if (color && hermite) { QVector vertices; QVector indices; // see http://www.frankpetterson.com/publications/dualcontour/dualcontour.pdf for a description of the // dual contour algorithm for generating meshes from voxel data using Hermite-tagged edges const QVector& colorContents = color->getContents(); - const QByteArray& materialContents = material->getContents(); const QVector& hermiteContents = hermite->getContents(); int size = color->getSize(); int area = size * size; @@ -1589,7 +1588,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { int hermiteStride = hermite->getSize() * VoxelHermiteData::EDGE_COUNT; int hermiteArea = hermiteStride * hermite->getSize(); - const char* materialData = materialContents.constData(); + const char* materialData = material ? material->getContents().constData() : NULL; // as we scan down the cube generating vertices between grid points, we remember the indices of the last // (element, line, section--x, y, z) so that we can connect generated vertices as quads @@ -1667,7 +1666,8 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { int clampedX = qMax(x - 1, 0), clampedY = qMax(y - 1, 0), clampedZ = qMax(z - 1, 0); const QRgb* hermiteBase = hermiteData + clampedZ * hermiteArea + clampedY * hermiteStride + clampedX * VoxelHermiteData::EDGE_COUNT; - const char* materialBase = materialData + clampedZ * area + clampedY * size + clampedX; + const char* materialBase = materialData ? + (materialData + clampedZ * area + clampedY * size + clampedX) : NULL; int crossingCount = 0; if (middleX) { if (alpha0 != alpha1) { @@ -1676,10 +1676,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha0 == 0) { crossing.color = colorX[1]; - crossing.material = materialBase[1]; + crossing.material = materialBase ? materialBase[1] : 0; } else { crossing.color = colorX[0]; - crossing.material = materialBase[0]; + crossing.material = materialBase ? materialBase[0] : 0; } crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 0.0f); crossing.axis = 0; @@ -1691,10 +1691,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha1 == 0) { crossing.color = colorX[offset3]; - crossing.material = materialBase[offset3]; + crossing.material = materialBase ? materialBase[offset3] : 0; } else { crossing.color = colorX[1]; - crossing.material = materialBase[1]; + crossing.material = materialBase ? materialBase[1] : 0; } crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f); crossing.axis = 1; @@ -1705,10 +1705,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha2 == 0) { crossing.color = colorX[offset3]; - crossing.material = materialBase[offset3]; + crossing.material = materialBase ? materialBase[offset3] : 0; } else { crossing.color = colorX[size]; - crossing.material = materialBase[size]; + crossing.material = materialBase ? materialBase[size] : 0; } crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 0.0f); crossing.axis = 0; @@ -1720,10 +1720,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha3 == 0) { crossing.color = colorX[offset7]; - crossing.material = materialBase[offset7]; + crossing.material = materialBase ? materialBase[offset7] : 0; } else { crossing.color = colorX[offset3]; - crossing.material = materialBase[offset3]; + crossing.material = materialBase ? materialBase[offset3] : 0; } crossing.point = glm::vec3(1.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); crossing.axis = 2; @@ -1734,10 +1734,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha5 == 0) { crossing.color = colorX[offset7]; - crossing.material = materialBase[offset7]; + crossing.material = materialBase ? materialBase[offset7] : 0; } else { crossing.color = colorX[offset5]; - crossing.material = materialBase[offset5]; + crossing.material = materialBase ? materialBase[offset5] : 0; } crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f); crossing.axis = 1; @@ -1748,10 +1748,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha6 == 0) { crossing.color = colorX[offset7]; - crossing.material = materialBase[offset7]; + crossing.material = materialBase ? materialBase[offset7] : 0; } else { crossing.color = colorX[offset6]; - crossing.material = materialBase[offset6]; + crossing.material = materialBase ? materialBase[offset6] : 0; } crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 1.0f); crossing.axis = 0; @@ -1765,10 +1765,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha1 == 0) { crossing.color = colorX[offset5]; - crossing.material = materialBase[offset5]; + crossing.material = materialBase ? materialBase[offset5] : 0; } else { crossing.color = colorX[1]; - crossing.material = materialBase[1]; + crossing.material = materialBase ? materialBase[1] : 0; } crossing.point = glm::vec3(1.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); crossing.axis = 2; @@ -1779,10 +1779,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha4 == 0) { crossing.color = colorX[offset5]; - crossing.material = materialBase[offset5]; + crossing.material = materialBase ? materialBase[offset5] : 0; } else { crossing.color = colorX[area]; - crossing.material = materialBase[area]; + crossing.material = materialBase ? materialBase[area] : 0; } crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 1.0f); crossing.axis = 0; @@ -1796,10 +1796,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha0 == 0) { crossing.color = colorX[size]; - crossing.material = materialBase[size]; + crossing.material = materialBase ? materialBase[size] : 0; } else { crossing.color = colorX[0]; - crossing.material = materialBase[0]; + crossing.material = materialBase ? materialBase[0] : 0; } crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f); crossing.axis = 1; @@ -1811,10 +1811,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha2 == 0) { crossing.color = colorX[offset6]; - crossing.material = materialBase[offset6]; + crossing.material = materialBase ? materialBase[offset6] : 0; } else { crossing.color = colorX[size]; - crossing.material = materialBase[size]; + crossing.material = materialBase ? materialBase[size] : 0; } crossing.point = glm::vec3(0.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); crossing.axis = 2; @@ -1825,10 +1825,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha4 == 0) { crossing.color = colorX[offset6]; - crossing.material = materialBase[offset6]; + crossing.material = materialBase ? materialBase[offset6] : 0; } else { crossing.color = colorX[area]; - crossing.material = materialBase[area]; + crossing.material = materialBase ? materialBase[area] : 0; } crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f); crossing.axis = 1; @@ -1841,10 +1841,10 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { crossing.normal = unpackNormal(hermite); if (alpha0 == 0) { crossing.color = colorX[area]; - crossing.material = materialBase[area]; + crossing.material = materialBase ? materialBase[area] : 0; } else { crossing.color = colorX[0]; - crossing.material = materialBase[0]; + crossing.material = materialBase ? materialBase[0] : 0; } crossing.point = glm::vec3(0.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); crossing.axis = 2; @@ -2091,7 +2091,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { } } - buffer = new VoxelBuffer(vertices, indices, material->getMaterials()); + buffer = new VoxelBuffer(vertices, indices, material ? material->getMaterials() : QVector()); } BufferDataPointer pointer(buffer); info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(pointer)); diff --git a/interface/src/ui/MetavoxelEditor.cpp b/interface/src/ui/MetavoxelEditor.cpp index dffc02ee07..45911d9626 100644 --- a/interface/src/ui/MetavoxelEditor.cpp +++ b/interface/src/ui/MetavoxelEditor.cpp @@ -48,7 +48,7 @@ enum GridPlane { const glm::vec2 INVALID_VECTOR(FLT_MAX, FLT_MAX); MetavoxelEditor::MetavoxelEditor() : - QWidget(Application::getInstance()->getGLWidget(), Qt::Tool | Qt::WindowStaysOnTopHint) { + QWidget(Application::getInstance()->getGLWidget(), Qt::Tool) { setWindowTitle("Metavoxel Editor"); setAttribute(Qt::WA_DeleteOnClose); diff --git a/libraries/metavoxels/src/AttributeRegistry.cpp b/libraries/metavoxels/src/AttributeRegistry.cpp index aec9a069be..3ea011c265 100644 --- a/libraries/metavoxels/src/AttributeRegistry.cpp +++ b/libraries/metavoxels/src/AttributeRegistry.cpp @@ -1616,8 +1616,74 @@ bool VoxelColorAttribute::merge(void*& parent, void* children[], bool postRead) maxSize = qMax(maxSize, pointer->getSize()); } } - *(VoxelColorDataPointer*)&parent = VoxelColorDataPointer(); - return maxSize == 0; + if (maxSize == 0) { + *(VoxelColorDataPointer*)&parent = VoxelColorDataPointer(); + return true; + } + int size = maxSize; + int area = size * size; + QVector contents(area * size); + int halfSize = size / 2; + int halfSizeComplement = size - halfSize; + for (int i = 0; i < MERGE_COUNT; i++) { + VoxelColorDataPointer child = decodeInline(children[i]); + if (!child) { + continue; + } + const QVector& childContents = child->getContents(); + int childSize = child->getSize(); + int childArea = childSize * childSize; + const int INDEX_MASK = 1; + int xIndex = i & INDEX_MASK; + const int Y_SHIFT = 1; + int yIndex = (i >> Y_SHIFT) & INDEX_MASK; + int Z_SHIFT = 2; + int zIndex = (i >> Z_SHIFT) & INDEX_MASK; + QRgb* dest = contents.data() + (zIndex * halfSize * area) + (yIndex * halfSize * size) + (xIndex * halfSize); + const QRgb* src = childContents.data(); + + const int MAX_ALPHA = 255; + if (childSize == size) { + // simple case: one destination value for four child values + for (int z = 0; z < halfSizeComplement; z++) { + int offset4 = (z == halfSize) ? 0 : childArea; + for (int y = 0; y < halfSizeComplement; y++) { + int offset2 = (y == halfSize) ? 0 : childSize; + int offset6 = offset4 + offset2; + for (QRgb* end = dest + halfSizeComplement; dest != end; ) { + int offset1 = (dest == end - 1) ? 0 : 1; + QRgb v0 = src[0], v1 = src[offset1], v2 = src[offset2], v3 = src[offset2 + offset1], v4 = src[offset4], + v5 = src[offset4 + offset1], v6 = src[offset6], v7 = src[offset6 + offset1]; + src += (1 + offset1); + int a0 = qAlpha(v0), a1 = qAlpha(v1), a2 = qAlpha(v2), a3 = qAlpha(v3), + a4 = qAlpha(v4), a5 = qAlpha(v5), a6 = qAlpha(v6), a7 = qAlpha(v7); + int alphaTotal = a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7; + if (alphaTotal == 0) { + *dest++ = qRgba(0, 0, 0, 0); + continue; + } + *dest++ = qRgba( + (qRed(v0) * a0 + qRed(v1) * a1 + qRed(v2) * a2 + qRed(v3) * a3 + + qRed(v4) * a4 + qRed(v5) * a5 + qRed(v6) * a6 + qRed(v7) * a7) / alphaTotal, + (qGreen(v0) * a0 + qGreen(v1) * a1 + qGreen(v2) * a2 + qGreen(v3) * a3 + + qGreen(v4) * a4 + qGreen(v5) * a5 + qGreen(v6) * a6 + qGreen(v7) * a7) / alphaTotal, + (qBlue(v0) * a0 + qBlue(v1) * a1 + qBlue(v2) * a2 + qBlue(v3) * a3 + + qBlue(v4) * a4 + qBlue(v5) * a5 + qBlue(v6) * a6 + qBlue(v7) * a7) / alphaTotal, + MAX_ALPHA); + } + dest += halfSize; + src += offset2; + } + dest += halfSize * size; + src += offset4; + } + } else { + // more complex: N destination values for four child values + // ... + } + } + *(VoxelColorDataPointer*)&parent = VoxelColorDataPointer(new VoxelColorData(contents, size)); + return false; } const int VOXEL_MATERIAL_HEADER_SIZE = sizeof(qint32) * 6; @@ -2020,8 +2086,87 @@ bool VoxelHermiteAttribute::merge(void*& parent, void* children[], bool postRead maxSize = qMax(maxSize, pointer->getSize()); } } - *(VoxelHermiteDataPointer*)&parent = VoxelHermiteDataPointer(); - return maxSize == 0; + if (maxSize == 0) { + *(VoxelHermiteDataPointer*)&parent = VoxelHermiteDataPointer(); + return true; + } + int size = maxSize; + int area = size * size; + QVector contents(area * size * VoxelHermiteData::EDGE_COUNT); + int halfSize = size / 2; + int halfSizeComplement = size - halfSize; + for (int i = 0; i < MERGE_COUNT; i++) { + VoxelHermiteDataPointer child = decodeInline(children[i]); + if (!child) { + continue; + } + const QVector& childContents = child->getContents(); + int childSize = child->getSize(); + int childArea = childSize * childSize; + const int INDEX_MASK = 1; + int xIndex = i & INDEX_MASK; + const int Y_SHIFT = 1; + int yIndex = (i >> Y_SHIFT) & INDEX_MASK; + int Z_SHIFT = 2; + int zIndex = (i >> Z_SHIFT) & INDEX_MASK; + QRgb* dest = contents.data() + ((zIndex * halfSize * area) + (yIndex * halfSize * size) + (xIndex * halfSize)) * + VoxelHermiteData::EDGE_COUNT; + const QRgb* src = childContents.data(); + + if (childSize == size) { + // simple case: one destination value for four child values + for (int z = 0; z < halfSizeComplement; z++) { + int offset4 = (z == halfSize) ? 0 : (childArea * VoxelHermiteData::EDGE_COUNT); + for (int y = 0; y < halfSizeComplement; y++) { + int offset2 = (y == halfSize) ? 0 : (childSize * VoxelHermiteData::EDGE_COUNT); + int offset6 = offset4 + offset2; + for (QRgb* end = dest + halfSizeComplement * VoxelHermiteData::EDGE_COUNT; dest != end; + dest += VoxelHermiteData::EDGE_COUNT) { + int offset1 = (dest == end - VoxelHermiteData::EDGE_COUNT) ? 0 : VoxelHermiteData::EDGE_COUNT; + for (int i = 0; i < VoxelHermiteData::EDGE_COUNT; i++) { + QRgb v[] = { src[i], src[offset1 + i], src[offset2 + i], src[offset2 + offset1 + i], + src[offset4 + i], src[offset4 + offset1 + i], src[offset6 + i], src[offset6 + offset1 + i] }; + glm::vec3 n[] = { unpackNormal(v[0]), unpackNormal(v[1]), unpackNormal(v[2]), unpackNormal(v[3]), + unpackNormal(v[4]), unpackNormal(v[5]), unpackNormal(v[6]), unpackNormal(v[7]) }; + float l[] = { glm::length(n[0]), glm::length(n[1]), glm::length(n[2]), glm::length(n[3]), + glm::length(n[4]), glm::length(n[5]), glm::length(n[6]), glm::length(n[7]) }; + float lengthTotal = l[0] + l[1] + l[2] + l[3] + l[4] + l[5] + l[6] + l[7]; + if (lengthTotal == 0.0f) { + dest[i] = qRgba(0, 0, 0, 0); + continue; + } + glm::vec3 combinedNormal = n[0] * l[0] + n[1] * l[1] + n[2] * l[2] + n[3] * l[3] + n[4] * l[4] + + n[5] * l[5] + n[6] * l[6] + n[7] * l[7]; + float combinedLength = glm::length(combinedNormal); + if (combinedLength > 0.0f) { + combinedNormal /= combinedLength; + } + float combinedOffset = 0.0f; + int mask = 1 << i; + for (int j = 0; j < MERGE_COUNT; j++) { + float offset = qAlpha(v[j]) * (0.5f / EIGHT_BIT_MAXIMUM); + if (j & mask) { + offset += 0.5f; + } + combinedOffset += offset * l[j]; + } + dest[i] = packNormal(combinedNormal, EIGHT_BIT_MAXIMUM * combinedOffset / lengthTotal); + } + src += (VoxelHermiteData::EDGE_COUNT + offset1); + } + dest += (halfSize * VoxelHermiteData::EDGE_COUNT); + src += offset2; + } + dest += (halfSize * size * VoxelHermiteData::EDGE_COUNT); + src += offset4; + } + } else { + // more complex: N destination values for four child values + // ... + } + } + *(VoxelHermiteDataPointer*)&parent = VoxelHermiteDataPointer(new VoxelHermiteData(contents, size)); + return false; } SharedObjectAttribute::SharedObjectAttribute(const QString& name, const QMetaObject* metaObject, From 8be5c1841222602dc5623519ceab58decb0e544d Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 6 Oct 2014 17:52:41 -0700 Subject: [PATCH 061/179] Get table data over to DS --- .../resources/describe-settings.json | 6 +- domain-server/resources/web/js/settings.js | 124 ++++++++++++++---- .../src/DomainServerSettingsManager.cpp | 33 ++--- 3 files changed, 118 insertions(+), 45 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 660edcf735..2c0b0cebf4 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -58,10 +58,6 @@ "name": "audio", "label": "Audio", "assignment-types": [0], - "settings": [ - "name": "audio", - "label": "Audio", - "assignment-types": [0], "settings": [ { "name": "zones", @@ -72,6 +68,7 @@ "can_add": true, "can_delete": true, "key": { + "name": "name", "label": "Name", "placeholder": "Zone name" }, @@ -119,6 +116,7 @@ { "name": "enable_filter", "type": "checkbox", + "label": "Positional filter", "help": "positional audio stream uses lowpass filter", "default": true }, diff --git a/domain-server/resources/web/js/settings.js b/domain-server/resources/web/js/settings.js index 660fac7081..4c2da87887 100644 --- a/domain-server/resources/web/js/settings.js +++ b/domain-server/resources/web/js/settings.js @@ -22,9 +22,7 @@ var viewHelpers = { } if (setting.type === 'checkbox') { - if (setting.label !== null && typeof(setting.label) !== 'undefined' && setting.label !== "") { - form_group += "" - } + form_group += "" form_group += "
" form_group += "
" - - return html; + return html; } function makeTableInputs(setting) { - var html = "" - if (setting.number === true) { - html += "" - } - html += "\ - \ - " - _.each(setting.columns, function(col) { - html += "\ - \ - " - }) - html += "" - html += "" + var html = "" + if (setting.number === true) { + html += "" + } + html += "\ + \ + " + _.each(setting.columns, function(col) { + html += "\ + \ + " + }) + html += "" + html += "" - return html + return html } function badgeSidebarForDifferences(changedInput) { @@ -406,7 +406,7 @@ function cleanupFormValues(node) { if (node.type && node.type === 'checkbox') { return { name: node.name, value: node.checked ? true : false }; } else { - return false; + return false; } } @@ -461,7 +461,7 @@ function chooseFromHighFidelityDomains(clickedButton) { } } modal_body = "

You do not have any domains in your High Fidelity account." + - "

Go to your domains page to create a new one. Once your domain is created re-open this dialog to select it.

" + "

Go to your domains page to create a new one. Once your domain is created re-open this dialog to select it.

" } @@ -479,7 +479,7 @@ function chooseFromHighFidelityDomains(clickedButton) { } else { bootbox.alert({ message: "You must have an access token to query your High Fidelity domains.

" + - "Please follow the instructions on the settings page to add an access token.", + "Please follow the instructions on the settings page to add an access token.", title: "Access token required" }) } From 17b9f4a37d23797990dc6f8e1e7421da22ee1dab Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 8 Oct 2014 11:34:45 -0700 Subject: [PATCH 096/179] allow a call to Joysticks.reset to reset SDL while interface is running --- interface/src/devices/Joystick.cpp | 4 + interface/src/devices/Joystick.h | 3 + .../scripting/JoystickScriptingInterface.cpp | 91 ++++++++++++++----- .../scripting/JoystickScriptingInterface.h | 6 ++ 4 files changed, 79 insertions(+), 25 deletions(-) diff --git a/interface/src/devices/Joystick.cpp b/interface/src/devices/Joystick.cpp index d220a827f1..f636e47a42 100644 --- a/interface/src/devices/Joystick.cpp +++ b/interface/src/devices/Joystick.cpp @@ -29,6 +29,10 @@ Joystick::Joystick(const QString& name, SDL_Joystick* sdlJoystick) : #endif Joystick::~Joystick() { + closeJoystick(); +} + +void Joystick::closeJoystick() { #ifdef HAVE_SDL SDL_JoystickClose(_sdlJoystick); #endif diff --git a/interface/src/devices/Joystick.h b/interface/src/devices/Joystick.h index 228e993204..0335bf6af3 100644 --- a/interface/src/devices/Joystick.h +++ b/interface/src/devices/Joystick.h @@ -37,6 +37,9 @@ public: void update(); + void closeJoystick(); + void setSDLJoystick(SDL_Joystick* sdlJoystick) { _sdlJoystick = sdlJoystick; } + const QString& getName() const { return _name; } const QVector& getAxes() const { return _axes; } diff --git a/interface/src/scripting/JoystickScriptingInterface.cpp b/interface/src/scripting/JoystickScriptingInterface.cpp index 1e35c11f61..87f841c494 100644 --- a/interface/src/scripting/JoystickScriptingInterface.cpp +++ b/interface/src/scripting/JoystickScriptingInterface.cpp @@ -27,17 +27,10 @@ JoystickScriptingInterface& JoystickScriptingInterface::getInstance() { JoystickScriptingInterface::JoystickScriptingInterface() : _openJoysticks(), - _availableDeviceNames() + _availableDeviceNames(), + _isInitialized(false) { -#ifdef HAVE_SDL - SDL_Init(SDL_INIT_JOYSTICK); - - int joystickCount = SDL_NumJoysticks(); - - for (int i = 0; i < joystickCount; i++) { - _availableDeviceNames << SDL_JoystickName(i); - } -#endif + reset(); } JoystickScriptingInterface::~JoystickScriptingInterface() { @@ -45,18 +38,53 @@ JoystickScriptingInterface::~JoystickScriptingInterface() { #ifdef HAVE_SDL SDL_Quit(); + _isInitialized = false; +#endif +} + +void JoystickScriptingInterface::reset() { +#ifdef HAVE_SDL + + if (_isInitialized) { + _isInitialized = false; + + // close all the open joysticks before we quit + foreach(Joystick* openJoystick, _openJoysticks) { + openJoystick->closeJoystick(); + } + + SDL_Quit(); + } + + bool initSuccess = (SDL_Init(SDL_INIT_JOYSTICK) == 0); + + if (initSuccess) { + + int joystickCount = SDL_NumJoysticks(); + + for (int i = 0; i < joystickCount; i++) { + _availableDeviceNames << SDL_JoystickName(i); + } + + foreach(const QString& joystickName, _openJoysticks.keys()) { + _openJoysticks[joystickName]->setSDLJoystick(openSDLJoystickWithName(joystickName)); + } + + _isInitialized = true; + } #endif } void JoystickScriptingInterface::update() { #ifdef HAVE_SDL - PerformanceTimer perfTimer("JoystickScriptingInterface::update"); - SDL_JoystickUpdate(); - - foreach(Joystick* joystick, _openJoysticks) { - joystick->update(); + if (_isInitialized) { + PerformanceTimer perfTimer("JoystickScriptingInterface::update"); + SDL_JoystickUpdate(); + + foreach(Joystick* joystick, _openJoysticks) { + joystick->update(); + } } - #endif } @@ -64,17 +92,13 @@ Joystick* JoystickScriptingInterface::joystickWithName(const QString& name) { Joystick* matchingJoystick = _openJoysticks.value(name); #ifdef HAVE_SDL if (!matchingJoystick) { - // we haven't opened a joystick with this name yet - enumerate our SDL devices and see if it exists - int joystickCount = SDL_NumJoysticks(); + SDL_Joystick* openSDLJoystick = openSDLJoystickWithName(name); - for (int i = 0; i < joystickCount; i++) { - if (SDL_JoystickName(i) == name) { - matchingJoystick = _openJoysticks.insert(name, new Joystick(name, SDL_JoystickOpen(i))).value(); - break; - } + if (openSDLJoystick) { + matchingJoystick = _openJoysticks.insert(name, new Joystick(name, openSDLJoystick)).value(); + } else { + qDebug() << "No matching joystick found with name" << name << "- returning NULL pointer."; } - - qDebug() << "No matching joystick found with name" << name << "- returning NULL pointer."; } #endif @@ -82,3 +106,20 @@ Joystick* JoystickScriptingInterface::joystickWithName(const QString& name) { } +#ifdef HAVE_SDL + +SDL_Joystick* JoystickScriptingInterface::openSDLJoystickWithName(const QString &name) { + // we haven't opened a joystick with this name yet - enumerate our SDL devices and see if it exists + int joystickCount = SDL_NumJoysticks(); + + for (int i = 0; i < joystickCount; i++) { + if (SDL_JoystickName(i) == name) { + return SDL_JoystickOpen(i); + break; + } + } + + return NULL; +} + +#endif diff --git a/interface/src/scripting/JoystickScriptingInterface.h b/interface/src/scripting/JoystickScriptingInterface.h index 98e38f5698..02624c70d5 100644 --- a/interface/src/scripting/JoystickScriptingInterface.h +++ b/interface/src/scripting/JoystickScriptingInterface.h @@ -31,13 +31,19 @@ public: public slots: Joystick* joystickWithName(const QString& name); + void reset(); private: +#ifdef HAVE_SDL + SDL_Joystick* openSDLJoystickWithName(const QString& name); +#endif + JoystickScriptingInterface(); ~JoystickScriptingInterface(); QMap _openJoysticks; QStringList _availableDeviceNames; + bool _isInitialized; }; #endif // hifi_JoystickScriptingInterface_h From cd67c9d4563fdd8b0ea9ba6c680e9f4fb9c4ecbc Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 8 Oct 2014 11:40:43 -0700 Subject: [PATCH 097/179] Removed console logs --- domain-server/resources/web/js/settings.js | 13 +++++-------- domain-server/src/DomainServerSettingsManager.cpp | 8 ++------ 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/domain-server/resources/web/js/settings.js b/domain-server/resources/web/js/settings.js index 0bccdacfb0..fc6b664359 100644 --- a/domain-server/resources/web/js/settings.js +++ b/domain-server/resources/web/js/settings.js @@ -84,7 +84,7 @@ $(document).ready(function(){ $('#settings-form').on('click', '.add-row', function(){ var row = $(this).parents("tr") - var row-data = row.parent().children(".row-data") + var data = row.parent().children(".row-data") // Check key spaces var name = row.children(".key").children("input").val() @@ -94,7 +94,7 @@ $(document).ready(function(){ } // Check keys with the same name var equals = false; - _.each(row-data.children(".key"), function(element) { + _.each(data.children(".key"), function(element) { if ($(element).text() === name) { equals = true return @@ -125,7 +125,7 @@ $(document).ready(function(){ _.each(row.children(), function(element) { if ($(element).hasClass("number")) { // Index row - var numbers = row-data.children(".number") + var numbers = data.children(".number") if (numbers.length > 0) { $(element).html(parseInt(numbers.last().text()) + 1) } else { @@ -134,10 +134,7 @@ $(document).ready(function(){ } else if ($(element).hasClass("buttons")) { // Change buttons var prevSpan = $(element).parent().prev().children(".buttons").children("span") var span = $(element).children("span") - console.log(prevSpan.length) - console.log(span.length) if (prevSpan.hasClass("del-row")) { - console.log("Switching icons") span.removeClass("glyphicon-ok add-row") span.addClass("glyphicon-remove del-row") } else { @@ -308,7 +305,7 @@ function makeTable(setting, setting_name, setting_value) { } html += "" + name + "" _.each(setting.columns, function(col) { - html += "" + html += "" if (row.hasOwnProperty(col.name)) { html += row[col.name] } @@ -343,7 +340,7 @@ function makeTableInputs(setting) { \ " _.each(setting.columns, function(col) { - html += "\ + html += "\ \ " }) diff --git a/domain-server/src/DomainServerSettingsManager.cpp b/domain-server/src/DomainServerSettingsManager.cpp index 5fcc7a8f82..c0366157db 100644 --- a/domain-server/src/DomainServerSettingsManager.cpp +++ b/domain-server/src/DomainServerSettingsManager.cpp @@ -279,9 +279,7 @@ void DomainServerSettingsManager::updateSetting(const QString& key, const QJsonV QVariantMap& thisMap = *reinterpret_cast(settingMap[key].data()); foreach(const QString childKey, newValue.toObject().keys()) { - updateSetting(childKey, newValue.toObject()[childKey], - thisMap, - settingDescription.toObject()[key]); + updateSetting(childKey, newValue.toObject()[childKey], thisMap, settingDescription.toObject()[key]); } if (settingMap[key].toMap().isEmpty()) { @@ -310,9 +308,7 @@ void DomainServerSettingsManager::recurseJSONObjectAndOverwriteSettings(const QJ QJsonValue thisDescription; if (settingExists(groupKey, settingKey, descriptionArray, thisDescription)) { QVariantMap& thisMap = *reinterpret_cast(settingsVariant[groupKey].data()); - updateSetting(settingKey, settingValue, - thisMap, - thisDescription); + updateSetting(settingKey, settingValue, thisMap, thisDescription); } } From 8e2d41f37fe79a02382ee858a3979090f8a28349 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 8 Oct 2014 11:41:07 -0700 Subject: [PATCH 098/179] remove deadzone handling from Joystick class --- interface/src/devices/Joystick.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/interface/src/devices/Joystick.cpp b/interface/src/devices/Joystick.cpp index f636e47a42..fe67eaceaa 100644 --- a/interface/src/devices/Joystick.cpp +++ b/interface/src/devices/Joystick.cpp @@ -42,14 +42,12 @@ void Joystick::update() { #ifdef HAVE_SDL // update our current values, emit a signal when there is a change for (int j = 0; j < getNumAxes(); j++) { - float value = glm::round(SDL_JoystickGetAxis(_sdlJoystick, j) + 0.5f) / std::numeric_limits::max(); - const float DEAD_ZONE = 0.1f; - float cleanValue = glm::abs(value) < DEAD_ZONE ? 0.0f : value; - - if (_axes[j] != cleanValue) { + float newValue = glm::round(SDL_JoystickGetAxis(_sdlJoystick, j) + 0.5f) / std::numeric_limits::max(); + + if (_axes[j] != newValue) { float oldValue = _axes[j]; - _axes[j] = cleanValue; - emit axisValueChanged(j, cleanValue, oldValue); + _axes[j] = newValue; + emit axisValueChanged(j, newValue, oldValue); } } for (int j = 0; j < getNumButtons(); j++) { From 48071bbdb39c834d42b2ae5ccc11bec6587b5606 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 8 Oct 2014 11:48:30 -0700 Subject: [PATCH 099/179] don't collide with entities with unknown IDs --- libraries/entities/src/EntityCollisionSystem.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/libraries/entities/src/EntityCollisionSystem.cpp b/libraries/entities/src/EntityCollisionSystem.cpp index 4ec9912b01..7f987db9ed 100644 --- a/libraries/entities/src/EntityCollisionSystem.cpp +++ b/libraries/entities/src/EntityCollisionSystem.cpp @@ -115,6 +115,11 @@ void EntityCollisionSystem::updateCollisionWithEntities(EntityItem* entityA) { return; // bail early if this entity is to be ignored... } + // don't collide entities with unknown IDs, + if (!entityA->isKnownID()) { + return; + } + glm::vec3 penetration; EntityItem* entityB = NULL; @@ -133,6 +138,11 @@ void EntityCollisionSystem::updateCollisionWithEntities(EntityItem* entityA) { penetration = collision->_penetration; entityB = static_cast(collision->_extraData); + // don't collide entities with unknown IDs, + if (!entityB->isKnownID()) { + continue; // skip this loop pass if the entity has an unknown ID + } + // NOTE: 'penetration' is the depth that 'entityA' overlaps 'entityB'. It points from A into B. glm::vec3 penetrationInTreeUnits = penetration / (float)(TREE_SCALE); @@ -267,6 +277,12 @@ void EntityCollisionSystem::updateCollisionWithAvatars(EntityItem* entity) { } void EntityCollisionSystem::applyHardCollision(EntityItem* entity, const CollisionInfo& collisionInfo) { + + // don't collide entities with unknown IDs, + if (!entity->isKnownID()) { + return; + } + // HALTING_* params are determined using expected acceleration of gravity over some timescale. // This is a HACK for entities that bounce in a 1.0 gravitational field and should eventually be made more universal. const float HALTING_ENTITY_PERIOD = 0.0167f; // ~1/60th of a second From ce505c1b0cae9c75c76d39c34169987f100f6b48 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 8 Oct 2014 12:09:40 -0700 Subject: [PATCH 100/179] add a missing HAVE_SDL wrap on setter in Joystick --- interface/src/devices/Joystick.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/src/devices/Joystick.h b/interface/src/devices/Joystick.h index 0335bf6af3..8343c20a04 100644 --- a/interface/src/devices/Joystick.h +++ b/interface/src/devices/Joystick.h @@ -38,7 +38,10 @@ public: void update(); void closeJoystick(); + +#ifdef HAVE_SDL void setSDLJoystick(SDL_Joystick* sdlJoystick) { _sdlJoystick = sdlJoystick; } +#endif const QString& getName() const { return _name; } From 19d103c343824fef71ef66f34bd590ceaa8b3e47 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 8 Oct 2014 13:54:53 -0700 Subject: [PATCH 101/179] Indentation --- domain-server/resources/web/js/settings.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/domain-server/resources/web/js/settings.js b/domain-server/resources/web/js/settings.js index 60d7b7ba35..d6646a87da 100644 --- a/domain-server/resources/web/js/settings.js +++ b/domain-server/resources/web/js/settings.js @@ -26,7 +26,7 @@ var viewHelpers = { form_group += "
" form_group += ""; form_group += "
" } else if (setting.type === 'table') { @@ -463,7 +463,7 @@ function chooseFromHighFidelityDomains(clickedButton) { } } modal_body = "

You do not have any domains in your High Fidelity account." + - "

Go to your domains page to create a new one. Once your domain is created re-open this dialog to select it.

" + "

Go to your domains page to create a new one. Once your domain is created re-open this dialog to select it.

" } @@ -481,7 +481,7 @@ function chooseFromHighFidelityDomains(clickedButton) { } else { bootbox.alert({ message: "You must have an access token to query your High Fidelity domains.

" + - "Please follow the instructions on the settings page to add an access token.", + "Please follow the instructions on the settings page to add an access token.", title: "Access token required" }) } From b5b82ed387c84775f985bd0fe289f1c02719c73b Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 8 Oct 2014 14:05:14 -0700 Subject: [PATCH 102/179] Provide the option to display lower detail metavoxel data as points. --- interface/src/Menu.cpp | 4 +- interface/src/Menu.h | 1 + interface/src/MetavoxelSystem.cpp | 194 ++++++++++-------- interface/src/MetavoxelSystem.h | 10 +- .../metavoxels/src/AttributeRegistry.cpp | 4 +- 5 files changed, 122 insertions(+), 91 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 954f04f47d..5e375dc6be 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -425,7 +425,9 @@ Menu::Menu() : QMenu* metavoxelOptionsMenu = developerMenu->addMenu("Metavoxels"); addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::DisplayHermiteData, 0, false, - Application::getInstance()->getMetavoxels(), SLOT(updateHermiteDisplay())); + Application::getInstance()->getMetavoxels(), SLOT(refreshVoxelData())); + addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::LowerDetailAsPoints, 0, false, + Application::getInstance()->getMetavoxels(), SLOT(refreshVoxelData())); QMenu* handOptionsMenu = developerMenu->addMenu("Hands"); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlignForearmsWithWrists, 0, false); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 67a4163c67..11e1131da4 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -414,6 +414,7 @@ namespace MenuOption { const QString Log = "Log"; const QString Logout = "Logout"; const QString LowVelocityFilter = "Low Velocity Filter"; + const QString LowerDetailAsPoints = "Lower Detail as Points"; const QString MetavoxelEditor = "Metavoxel Editor..."; const QString Metavoxels = "Metavoxels"; const QString Mirror = "Mirror"; diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index 1b8e3094be..2d4e9e7459 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -137,15 +137,13 @@ void MetavoxelSystem::render() { emit rendering(); } -void MetavoxelSystem::updateHermiteDisplay() { - if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData)) { - foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { - if (node->getType() == NodeType::MetavoxelServer) { - QMutexLocker locker(&node->getMutex()); - MetavoxelSystemClient* client = static_cast(node->getLinkedData()); - if (client) { - QMetaObject::invokeMethod(client, "refreshVoxelData"); - } +void MetavoxelSystem::refreshVoxelData() { + foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { + if (node->getType() == NodeType::MetavoxelServer) { + QMutexLocker locker(&node->getMutex()); + MetavoxelSystemClient* client = static_cast(node->getLinkedData()); + if (client) { + QMetaObject::invokeMethod(client, "refreshVoxelData"); } } } @@ -642,8 +640,47 @@ void PointBuffer::render(bool cursor) { _buffer.release(); } -VoxelPointBuffer::VoxelPointBuffer(const BufferPointVector& points) : - PointBuffer(points) { +VoxelPointBuffer::VoxelPointBuffer(const BufferPointVector& points, const QVector& hermite) : + PointBuffer(points), + _hermite(hermite), + _hermiteCount(hermite.size()) { +} + +static void renderHermiteData(QVector& hermite, int hermiteCount, QOpenGLBuffer& hermiteBuffer) { + if (hermiteCount > 0 && Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData)) { + if (!hermiteBuffer.isCreated()) { + hermiteBuffer.create(); + hermiteBuffer.bind(); + hermiteBuffer.allocate(hermite.constData(), hermite.size() * sizeof(glm::vec3)); + hermite.clear(); + + } else { + hermiteBuffer.bind(); + } + + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + + glVertexPointer(3, GL_FLOAT, 0, 0); + + Application::getInstance()->getDeferredLightingEffect()->getSimpleProgram().bind(); + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glNormal3f(0.0f, 1.0f, 0.0f); + + glLineWidth(2.0f); + + glDrawArrays(GL_LINES, 0, hermiteCount); + + glLineWidth(1.0f); + + DefaultMetavoxelRendererImplementation::getBaseVoxelProgram().bind(); + + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + + hermiteBuffer.release(); + } } void VoxelPointBuffer::render(bool cursor) { @@ -656,6 +693,8 @@ void VoxelPointBuffer::render(bool cursor) { glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); DefaultMetavoxelRendererImplementation::getBaseVoxelProgram().bind(); + + renderHermiteData(_hermite, _hermiteCount, _hermiteBuffer); } const int HeightfieldBuffer::HEIGHT_BORDER = 1; @@ -1136,40 +1175,7 @@ void VoxelBuffer::render(bool cursor) { _vertexBuffer.release(); _indexBuffer.release(); - if (_hermiteCount > 0 && Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData)) { - if (!_hermiteBuffer.isCreated()) { - _hermiteBuffer.create(); - _hermiteBuffer.bind(); - _hermiteBuffer.allocate(_hermite.constData(), _hermite.size() * sizeof(glm::vec3)); - _hermite.clear(); - - } else { - _hermiteBuffer.bind(); - } - - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - - glVertexPointer(3, GL_FLOAT, 0, 0); - - Application::getInstance()->getDeferredLightingEffect()->getSimpleProgram().bind(); - - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - glNormal3f(0.0f, 1.0f, 0.0f); - - glLineWidth(2.0f); - - glDrawArrays(GL_LINES, 0, _hermiteCount); - - glLineWidth(1.0f); - - DefaultMetavoxelRendererImplementation::getBaseVoxelProgram().bind(); - - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - - _hermiteBuffer.release(); - } + renderHermiteData(_hermite, _hermiteCount, _hermiteBuffer); } BufferDataAttribute::BufferDataAttribute(const QString& name) : @@ -1638,11 +1644,14 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { if (!info.isLeaf) { return DEFAULT_ORDER; } + const int EDGES_PER_CUBE = 12; + BufferData* buffer = NULL; VoxelColorDataPointer color = info.inputValues.at(0).getInlineValue(); VoxelMaterialDataPointer material = info.inputValues.at(1).getInlineValue(); VoxelHermiteDataPointer hermite = info.inputValues.at(2).getInlineValue(); - if (color && hermite && material) { + + if (color && hermite && (material || !Menu::getInstance()->isOptionChecked(MenuOption::LowerDetailAsPoints))) { QVector vertices; QVector indices; QVector hermiteSegments; @@ -1677,7 +1686,6 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { QVector planeIndices(expanded * expanded); QVector lastPlaneIndices(expanded * expanded); - const int EDGES_PER_CUBE = 12; EdgeCrossing crossings[EDGES_PER_CUBE]; float highest = size - 1.0f; @@ -2182,6 +2190,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { } else if (color && hermite) { BufferPointVector points; + QVector hermiteSegments; const QVector& colorContents = color->getContents(); const QVector& hermiteContents = hermite->getContents(); @@ -2201,6 +2210,9 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { const QRgb* hermiteData = hermiteContents.constData(); int hermiteStride = hermite->getSize() * VoxelHermiteData::EDGE_COUNT; int hermiteArea = hermiteStride * hermite->getSize(); + bool displayHermite = Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData); + + EdgeCrossing crossings[EDGES_PER_CUBE]; for (int z = 0; z < limit; z++) { const QRgb* colorY = colorZ; @@ -2218,80 +2230,90 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { } const QRgb* hermiteBase = hermiteData + z * hermiteArea + y * hermiteStride + x * VoxelHermiteData::EDGE_COUNT; - glm::vec3 normal; - glm::vec3 position; int crossingCount = 0; if (a0 != a1) { QRgb hermite = hermiteBase[0]; - position += glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 0.0f); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 0.0f); + crossing.normal = unpackNormal(hermite); } if (a0 != a2) { QRgb hermite = hermiteBase[1]; - position += glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f); + crossing.normal = unpackNormal(hermite); } if (a0 != a4) { QRgb hermite = hermiteBase[2]; - position += glm::vec3(0.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(0.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); + crossing.normal = unpackNormal(hermite); } if (a1 != a3) { QRgb hermite = hermiteBase[VoxelHermiteData::EDGE_COUNT + 1]; - position += glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f); + crossing.normal = unpackNormal(hermite); } if (a1 != a5) { QRgb hermite = hermiteBase[VoxelHermiteData::EDGE_COUNT + 2]; - position += glm::vec3(1.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(1.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); + crossing.normal = unpackNormal(hermite); } if (a2 != a3) { QRgb hermite = hermiteBase[hermiteStride]; - position += glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 0.0f); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 0.0f); + crossing.normal = unpackNormal(hermite); } if (a2 != a6) { QRgb hermite = hermiteBase[hermiteStride + 2]; - position += glm::vec3(0.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(0.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); + crossing.normal = unpackNormal(hermite); } if (a3 != a7) { QRgb hermite = hermiteBase[hermiteStride + VoxelHermiteData::EDGE_COUNT + 2]; - position += glm::vec3(1.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(1.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); + crossing.normal = unpackNormal(hermite); } if (a4 != a5) { QRgb hermite = hermiteBase[hermiteArea]; - position += glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 1.0f); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 1.0f); + crossing.normal = unpackNormal(hermite); } if (a4 != a6) { QRgb hermite = hermiteBase[hermiteArea + 1]; - position += glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f); + crossing.normal = unpackNormal(hermite); } if (a5 != a7) { QRgb hermite = hermiteBase[hermiteArea + VoxelHermiteData::EDGE_COUNT + 1]; - position += glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f); + crossing.normal = unpackNormal(hermite); } if (a6 != a7) { QRgb hermite = hermiteBase[hermiteArea + hermiteStride]; - position += glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 1.0f); - normal += unpackNormal(hermite); - crossingCount++; + EdgeCrossing& crossing = crossings[crossingCount++]; + crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 1.0f); + crossing.normal = unpackNormal(hermite); + } + glm::vec3 normal; + glm::vec3 position; + for (int i = 0; i < crossingCount; i++) { + const EdgeCrossing& crossing = crossings[i]; + position += crossing.point; + normal += crossing.normal; + if (displayHermite) { + glm::vec3 base = glm::vec3(minimum) + (glm::vec3(x, y, z) + crossing.point) * step; + hermiteSegments.append(base); + hermiteSegments.append(base + crossing.normal * step); + } } normal = safeNormalize(normal); BufferPoint point = { minimum + (glm::vec4(x, y, z, 1.0f) + @@ -2309,7 +2331,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { } colorZ += area; } - buffer = new VoxelPointBuffer(points); + buffer = new VoxelPointBuffer(points, hermiteSegments); } BufferDataPointer pointer(buffer); info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(pointer)); diff --git a/interface/src/MetavoxelSystem.h b/interface/src/MetavoxelSystem.h index e349546bb4..e8987a3f5e 100644 --- a/interface/src/MetavoxelSystem.h +++ b/interface/src/MetavoxelSystem.h @@ -58,7 +58,7 @@ signals: public slots: - void updateHermiteDisplay(); + void refreshVoxelData(); protected: @@ -150,9 +150,15 @@ private: class VoxelPointBuffer : public PointBuffer { public: - VoxelPointBuffer(const BufferPointVector& points); + VoxelPointBuffer(const BufferPointVector& points, const QVector& hermite); virtual void render(bool cursor = false); + +private: + + QVector _hermite; + int _hermiteCount; + QOpenGLBuffer _hermiteBuffer; }; /// Contains the information necessary to render a heightfield block. diff --git a/libraries/metavoxels/src/AttributeRegistry.cpp b/libraries/metavoxels/src/AttributeRegistry.cpp index 3ea011c265..44c333a03f 100644 --- a/libraries/metavoxels/src/AttributeRegistry.cpp +++ b/libraries/metavoxels/src/AttributeRegistry.cpp @@ -1657,11 +1657,11 @@ bool VoxelColorAttribute::merge(void*& parent, void* children[], bool postRead) src += (1 + offset1); int a0 = qAlpha(v0), a1 = qAlpha(v1), a2 = qAlpha(v2), a3 = qAlpha(v3), a4 = qAlpha(v4), a5 = qAlpha(v5), a6 = qAlpha(v6), a7 = qAlpha(v7); - int alphaTotal = a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7; - if (alphaTotal == 0) { + if (a0 == 0) { *dest++ = qRgba(0, 0, 0, 0); continue; } + int alphaTotal = a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7; *dest++ = qRgba( (qRed(v0) * a0 + qRed(v1) * a1 + qRed(v2) * a2 + qRed(v3) * a3 + qRed(v4) * a4 + qRed(v5) * a5 + qRed(v6) * a6 + qRed(v7) * a7) / alphaTotal, From fb8c5c3bf0f6072db711e844121faedb89fe5da8 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 8 Oct 2014 14:52:53 -0700 Subject: [PATCH 103/179] initial styling changes to domain table --- domain-server/resources/describe-settings.json | 13 +++++++++++++ domain-server/resources/web/css/style.css | 4 ++++ domain-server/resources/web/js/settings.js | 16 ++++++---------- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 8b33fede2e..04c8c5bf1f 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -59,6 +59,19 @@ "type": "password", "help": "Password used for basic HTTP authentication. Leave this blank if you do not want to change it.", "value-hidden": true + }, + { + "name": "allowed_users", + "type": "table", + "label": "Allowed Users", + "help": "A list of usernames for the High Fidelity users you want to allow into your domain. Users not found in this list will not be allowed to connect.", + "number": false, + "can_add": true, + "can_delete": true, + "key": { + "name": "username", + "label": "Username" + } } ] }, diff --git a/domain-server/resources/web/css/style.css b/domain-server/resources/web/css/style.css index 60f493593a..46e8b94a3a 100644 --- a/domain-server/resources/web/css/style.css +++ b/domain-server/resources/web/css/style.css @@ -74,3 +74,7 @@ span.port { width: 100%; margin-bottom: 15px; } + +td.buttons { + width: 14px; +} diff --git a/domain-server/resources/web/js/settings.js b/domain-server/resources/web/js/settings.js index d6646a87da..246a9a1705 100644 --- a/domain-server/resources/web/js/settings.js +++ b/domain-server/resources/web/js/settings.js @@ -280,12 +280,9 @@ $('body').on('click', '.save-button', function(e){ }); function makeTable(setting, setting_name, setting_value) { - var html = "
" - html += "
" + setting.label + "
" - html += "
" - html += "

" + setting.help + "

" - html += "
" - html += "" + var html = "" + html += "" + setting.help + "" + html += "
" // Column names html += "" @@ -297,7 +294,7 @@ function makeTable(setting, setting_name, setting_value) { html += "" // Data }) if (setting.can_delete === true || setting.can_add === true) { - html += "" // Buttons + html += "" // Buttons } html += "" @@ -329,9 +326,8 @@ function makeTable(setting, setting_name, setting_value) { if (setting.can_add === true) { html += makeTableInputs(setting) } - + html += "
" + col.label + "+/-
" - html += "
" return html; } @@ -342,7 +338,7 @@ function makeTableInputs(setting) { html += "" } html += "\ - \ + \ " _.each(setting.columns, function(col) { html += "\ From f4eddbc93b5031958d48807be1ec7fa73fac318b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 8 Oct 2014 14:54:41 -0700 Subject: [PATCH 104/179] change number to numbered for domain-server settings --- domain-server/resources/describe-settings.json | 4 ++-- domain-server/resources/web/js/settings.js | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 04c8c5bf1f..30d843c7eb 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -65,7 +65,7 @@ "type": "table", "label": "Allowed Users", "help": "A list of usernames for the High Fidelity users you want to allow into your domain. Users not found in this list will not be allowed to connect.", - "number": false, + "numbered": false, "can_add": true, "can_delete": true, "key": { @@ -85,7 +85,7 @@ "type": "table", "label": "Zones", "help": "In this table you can define a set of zones in which you can specify various audio properties.", - "number": false, + "numbered": false, "can_add": true, "can_delete": true, "key": { diff --git a/domain-server/resources/web/js/settings.js b/domain-server/resources/web/js/settings.js index 246a9a1705..311a25dacd 100644 --- a/domain-server/resources/web/js/settings.js +++ b/domain-server/resources/web/js/settings.js @@ -302,8 +302,8 @@ function makeTable(setting, setting_name, setting_value) { var row_num = 1 _.each(setting_value, function(row, name) { html += "" - if (setting.number === true) { - html += "" + row_num + "" + if (setting.numbered === true) { + html += "" + row_num + "" } html += "" + name + "" _.each(setting.columns, function(col) { @@ -334,8 +334,8 @@ function makeTable(setting, setting_name, setting_value) { function makeTableInputs(setting) { var html = "" - if (setting.number === true) { - html += "" + if (setting.numbered === true) { + html += "" } html += "\ \ From 51afd52ffb4af3a899048994718cf580ae1a1830 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 8 Oct 2014 14:56:09 -0700 Subject: [PATCH 105/179] vertically center the glyphicon for table button --- domain-server/resources/web/css/style.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/domain-server/resources/web/css/style.css b/domain-server/resources/web/css/style.css index 46e8b94a3a..4c365ed110 100644 --- a/domain-server/resources/web/css/style.css +++ b/domain-server/resources/web/css/style.css @@ -78,3 +78,8 @@ span.port { td.buttons { width: 14px; } + +td.buttons .glyphicon { + display: block; + text-align: center; +} From 37eff685bcefad15239fd1b71a5d91e49b235810 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Wed, 8 Oct 2014 15:11:55 -0700 Subject: [PATCH 106/179] Remove the "render lower detail as points" option. It doesn't seem too promising. --- interface/src/Menu.cpp | 2 - interface/src/Menu.h | 1 - interface/src/MetavoxelSystem.cpp | 240 +++++------------------------- interface/src/MetavoxelSystem.h | 15 -- 4 files changed, 34 insertions(+), 224 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 5e375dc6be..77009da18b 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -426,8 +426,6 @@ Menu::Menu() : QMenu* metavoxelOptionsMenu = developerMenu->addMenu("Metavoxels"); addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::DisplayHermiteData, 0, false, Application::getInstance()->getMetavoxels(), SLOT(refreshVoxelData())); - addCheckableActionToQMenuAndActionHash(metavoxelOptionsMenu, MenuOption::LowerDetailAsPoints, 0, false, - Application::getInstance()->getMetavoxels(), SLOT(refreshVoxelData())); QMenu* handOptionsMenu = developerMenu->addMenu("Hands"); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlignForearmsWithWrists, 0, false); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 11e1131da4..67a4163c67 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -414,7 +414,6 @@ namespace MenuOption { const QString Log = "Log"; const QString Logout = "Logout"; const QString LowVelocityFilter = "Low Velocity Filter"; - const QString LowerDetailAsPoints = "Lower Detail as Points"; const QString MetavoxelEditor = "Metavoxel Editor..."; const QString Metavoxels = "Metavoxels"; const QString Mirror = "Mirror"; diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index 2d4e9e7459..10a211f61b 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -640,63 +640,6 @@ void PointBuffer::render(bool cursor) { _buffer.release(); } -VoxelPointBuffer::VoxelPointBuffer(const BufferPointVector& points, const QVector& hermite) : - PointBuffer(points), - _hermite(hermite), - _hermiteCount(hermite.size()) { -} - -static void renderHermiteData(QVector& hermite, int hermiteCount, QOpenGLBuffer& hermiteBuffer) { - if (hermiteCount > 0 && Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData)) { - if (!hermiteBuffer.isCreated()) { - hermiteBuffer.create(); - hermiteBuffer.bind(); - hermiteBuffer.allocate(hermite.constData(), hermite.size() * sizeof(glm::vec3)); - hermite.clear(); - - } else { - hermiteBuffer.bind(); - } - - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - - glVertexPointer(3, GL_FLOAT, 0, 0); - - Application::getInstance()->getDeferredLightingEffect()->getSimpleProgram().bind(); - - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - glNormal3f(0.0f, 1.0f, 0.0f); - - glLineWidth(2.0f); - - glDrawArrays(GL_LINES, 0, hermiteCount); - - glLineWidth(1.0f); - - DefaultMetavoxelRendererImplementation::getBaseVoxelProgram().bind(); - - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - - hermiteBuffer.release(); - } -} - -void VoxelPointBuffer::render(bool cursor) { - DefaultMetavoxelRendererImplementation::getPointProgram().bind(); - - glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); - - PointBuffer::render(cursor); - - glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); - - DefaultMetavoxelRendererImplementation::getBaseVoxelProgram().bind(); - - renderHermiteData(_hermite, _hermiteCount, _hermiteBuffer); -} - const int HeightfieldBuffer::HEIGHT_BORDER = 1; const int HeightfieldBuffer::SHARED_EDGE = 1; const int HeightfieldBuffer::HEIGHT_EXTENSION = 2 * HeightfieldBuffer::HEIGHT_BORDER + HeightfieldBuffer::SHARED_EDGE; @@ -1175,7 +1118,38 @@ void VoxelBuffer::render(bool cursor) { _vertexBuffer.release(); _indexBuffer.release(); - renderHermiteData(_hermite, _hermiteCount, _hermiteBuffer); + if (_hermiteCount > 0 && Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData)) { + if (!_hermiteBuffer.isCreated()) { + _hermiteBuffer.create(); + _hermiteBuffer.bind(); + _hermiteBuffer.allocate(_hermite.constData(), _hermite.size() * sizeof(glm::vec3)); + _hermite.clear(); + + } else { + _hermiteBuffer.bind(); + } + + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + + glVertexPointer(3, GL_FLOAT, 0, 0); + + Application::getInstance()->getDeferredLightingEffect()->getSimpleProgram().bind(); + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glNormal3f(0.0f, 1.0f, 0.0f); + + glLineWidth(1.0f); + + glDrawArrays(GL_LINES, 0, _hermiteCount); + + DefaultMetavoxelRendererImplementation::getBaseVoxelProgram().bind(); + + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + + _hermiteBuffer.release(); + } } BufferDataAttribute::BufferDataAttribute(const QString& name) : @@ -1644,14 +1618,12 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { if (!info.isLeaf) { return DEFAULT_ORDER; } - const int EDGES_PER_CUBE = 12; - BufferData* buffer = NULL; VoxelColorDataPointer color = info.inputValues.at(0).getInlineValue(); VoxelMaterialDataPointer material = info.inputValues.at(1).getInlineValue(); VoxelHermiteDataPointer hermite = info.inputValues.at(2).getInlineValue(); - if (color && hermite && (material || !Menu::getInstance()->isOptionChecked(MenuOption::LowerDetailAsPoints))) { + if (color && hermite) { QVector vertices; QVector indices; QVector hermiteSegments; @@ -1686,6 +1658,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { QVector planeIndices(expanded * expanded); QVector lastPlaneIndices(expanded * expanded); + const int EDGES_PER_CUBE = 12; EdgeCrossing crossings[EDGES_PER_CUBE]; float highest = size - 1.0f; @@ -2187,151 +2160,6 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) { } buffer = new VoxelBuffer(vertices, indices, hermiteSegments, material ? material->getMaterials() : QVector()); - - } else if (color && hermite) { - BufferPointVector points; - QVector hermiteSegments; - - const QVector& colorContents = color->getContents(); - const QVector& hermiteContents = hermite->getContents(); - int size = color->getSize(); - int area = size * size; - int limit = size - 1; - - const QRgb* colorZ = colorContents.constData(); - int offset3 = size + 1; - int offset5 = area + 1; - int offset6 = area + size; - int offset7 = offset6 + 1; - const int MAX_ALPHA_TOTAL = MetavoxelNode::CHILD_COUNT * EIGHT_BIT_MAXIMUM; - float step = info.size / limit; - glm::vec4 minimum(info.minimum.x + step * 0.5f, info.minimum.y + step * 0.5f, info.minimum.z + step * 0.5f, 0.0f); - - const QRgb* hermiteData = hermiteContents.constData(); - int hermiteStride = hermite->getSize() * VoxelHermiteData::EDGE_COUNT; - int hermiteArea = hermiteStride * hermite->getSize(); - bool displayHermite = Menu::getInstance()->isOptionChecked(MenuOption::DisplayHermiteData); - - EdgeCrossing crossings[EDGES_PER_CUBE]; - - for (int z = 0; z < limit; z++) { - const QRgb* colorY = colorZ; - for (int y = 0; y < limit; y++) { - const QRgb* colorX = colorY; - for (int x = 0; x < limit; x++) { - QRgb c0 = colorX[0], c1 = colorX[1], c2 = colorX[size], c3 = colorX[offset3], c4 = colorX[area], - c5 = colorX[offset5], c6 = colorX[offset6], c7 = colorX[offset7]; - colorX++; - int a0 = qAlpha(c0), a1 = qAlpha(c1), a2 = qAlpha(c2), a3 = qAlpha(c3), - a4 = qAlpha(c4), a5 = qAlpha(c5), a6 = qAlpha(c6), a7 = qAlpha(c7); - int alphaTotal = a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7; - if (alphaTotal == 0 || alphaTotal == MAX_ALPHA_TOTAL) { - continue; - } - const QRgb* hermiteBase = hermiteData + z * hermiteArea + y * hermiteStride + - x * VoxelHermiteData::EDGE_COUNT; - int crossingCount = 0; - if (a0 != a1) { - QRgb hermite = hermiteBase[0]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 0.0f); - crossing.normal = unpackNormal(hermite); - } - if (a0 != a2) { - QRgb hermite = hermiteBase[1]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f); - crossing.normal = unpackNormal(hermite); - } - if (a0 != a4) { - QRgb hermite = hermiteBase[2]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(0.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); - crossing.normal = unpackNormal(hermite); - } - if (a1 != a3) { - QRgb hermite = hermiteBase[VoxelHermiteData::EDGE_COUNT + 1]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f); - crossing.normal = unpackNormal(hermite); - } - if (a1 != a5) { - QRgb hermite = hermiteBase[VoxelHermiteData::EDGE_COUNT + 2]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(1.0f, 0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); - crossing.normal = unpackNormal(hermite); - } - if (a2 != a3) { - QRgb hermite = hermiteBase[hermiteStride]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 0.0f); - crossing.normal = unpackNormal(hermite); - } - if (a2 != a6) { - QRgb hermite = hermiteBase[hermiteStride + 2]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(0.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); - crossing.normal = unpackNormal(hermite); - } - if (a3 != a7) { - QRgb hermite = hermiteBase[hermiteStride + VoxelHermiteData::EDGE_COUNT + 2]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(1.0f, 1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL); - crossing.normal = unpackNormal(hermite); - } - if (a4 != a5) { - QRgb hermite = hermiteBase[hermiteArea]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 0.0f, 1.0f); - crossing.normal = unpackNormal(hermite); - } - if (a4 != a6) { - QRgb hermite = hermiteBase[hermiteArea + 1]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(0.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f); - crossing.normal = unpackNormal(hermite); - } - if (a5 != a7) { - QRgb hermite = hermiteBase[hermiteArea + VoxelHermiteData::EDGE_COUNT + 1]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(1.0f, qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f); - crossing.normal = unpackNormal(hermite); - } - if (a6 != a7) { - QRgb hermite = hermiteBase[hermiteArea + hermiteStride]; - EdgeCrossing& crossing = crossings[crossingCount++]; - crossing.point = glm::vec3(qAlpha(hermite) * EIGHT_BIT_MAXIMUM_RECIPROCAL, 1.0f, 1.0f); - crossing.normal = unpackNormal(hermite); - } - glm::vec3 normal; - glm::vec3 position; - for (int i = 0; i < crossingCount; i++) { - const EdgeCrossing& crossing = crossings[i]; - position += crossing.point; - normal += crossing.normal; - if (displayHermite) { - glm::vec3 base = glm::vec3(minimum) + (glm::vec3(x, y, z) + crossing.point) * step; - hermiteSegments.append(base); - hermiteSegments.append(base + crossing.normal * step); - } - } - normal = safeNormalize(normal); - BufferPoint point = { minimum + (glm::vec4(x, y, z, 1.0f) + - glm::vec4(position / (float)crossingCount, 0.0f)) * step, - { (quint8)((qRed(c0) * a0 + qRed(c1) * a1 + qRed(c2) * a2 + qRed(c3) * a3 + qRed(c4) * a4 + - qRed(c5) * a5 + qRed(c6) * a6 + qRed(c7) * a7) / alphaTotal), - (quint8)((qGreen(c0) * a0 + qGreen(c1) * a1 + qGreen(c2) * a2 + qGreen(c3) * a3 + qGreen(c4) * a4 + - qGreen(c5) * a5 + qGreen(c6) * a6 + qGreen(c7) * a7) / alphaTotal), - (quint8)((qBlue(c0) * a0 + qBlue(c1) * a1 + qBlue(c2) * a2 + qBlue(c3) * a3 + qBlue(c4) * a4 + - qBlue(c5) * a5 + qBlue(c6) * a6 + qBlue(c7) * a7) / alphaTotal) }, - { (quint8)(normal.x * 127.0f), (quint8)(normal.y * 127.0f), (quint8)(normal.z * 127.0f) } }; - points.append(point); - } - colorY += size; - } - colorZ += area; - } - buffer = new VoxelPointBuffer(points, hermiteSegments); } BufferDataPointer pointer(buffer); info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(pointer)); diff --git a/interface/src/MetavoxelSystem.h b/interface/src/MetavoxelSystem.h index e8987a3f5e..52706aab56 100644 --- a/interface/src/MetavoxelSystem.h +++ b/interface/src/MetavoxelSystem.h @@ -146,21 +146,6 @@ private: int _pointCount; }; -/// Contains the information necessary to render a group of voxels as points. -class VoxelPointBuffer : public PointBuffer { -public: - - VoxelPointBuffer(const BufferPointVector& points, const QVector& hermite); - - virtual void render(bool cursor = false); - -private: - - QVector _hermite; - int _hermiteCount; - QOpenGLBuffer _hermiteBuffer; -}; - /// Contains the information necessary to render a heightfield block. class HeightfieldBuffer : public BufferData { public: From 1990419eebb74aa332c951fdebbd7b243081e5e5 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 8 Oct 2014 15:15:49 -0700 Subject: [PATCH 107/179] first cut at correct handle hide/show behavior and rotate overlay hide/show behavior --- examples/libraries/entitySelectionTool.js | 372 +++++++++++++++++++--- 1 file changed, 323 insertions(+), 49 deletions(-) diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index d9cf2c54fd..a1dd1d2032 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -31,6 +31,13 @@ SelectionDisplay = (function () { var handleHoverColor = { red: 224, green: 67, blue: 36 }; var handleHoverAlpha = 1.0; + var yawHandleRotation; + var pitchHandleRotation; + var rollHandleRotation; + var yawCenter; + var pitchCenter; + var rollCenter; + var rotateHandleColor = { red: 0, green: 0, blue: 0 }; var rotateHandleAlpha = 0.7; @@ -412,10 +419,6 @@ SelectionDisplay = (function () { var pitchCorner; var rollCorner; - var yawHandleRotation; - var pitchHandleRotation; - var rollHandleRotation; - // determine which bottom corner we are closest to /*------------------------------ example: @@ -448,6 +451,18 @@ SelectionDisplay = (function () { y: top + rotateHandleOffset, z: near - rotateHandleOffset}; + yawCenter = { x: center.x, + y: bottom, + z: center.z }; + + pitchCenter = { x: center.x, + y: center.y, + z: far }; + + rollCenter = { x: left, + y: center.y, + z: center.z}; + } else { yawHandleRotation = Quat.fromVec3Degrees({ x: 90, y: 270, z: 0 }); pitchHandleRotation = Quat.fromVec3Degrees({ x: 180, y: 270, z: 0 }); @@ -465,6 +480,19 @@ SelectionDisplay = (function () { y: top + rotateHandleOffset, z: near - rotateHandleOffset}; + + yawCenter = { x: center.x, + y: bottom, + z: center.z }; + + pitchCenter = { x: left, + y: center.y, + z: center.z }; + + rollCenter = { x: center.x, + y: center.y, + z: near}; + } } else { // must be BLF or BLN @@ -485,6 +513,19 @@ SelectionDisplay = (function () { y: top + rotateHandleOffset, z: far + rotateHandleOffset}; + yawCenter = { x: center.x, + y: bottom, + z: center.z }; + + pitchCenter = { x: right, + y: center.y, + z: center.z }; + + rollCenter = { x: center.x, + y: center.y, + z: far}; + + } else { yawHandleRotation = Quat.fromVec3Degrees({ x: 90, y: 180, z: 0 }); @@ -502,8 +543,40 @@ SelectionDisplay = (function () { rollCorner = { x: right + rotateHandleOffset, y: top + rotateHandleOffset, z: far + rotateHandleOffset}; + + yawCenter = { x: center.x, + y: bottom, + z: center.z }; + + pitchCenter = { x: center.x, + y: center.y, + z: near }; + + rollCenter = { x: right, + y: center.y, + z: center.z}; + + } } + + + print("select() with mode:" + mode); + var rotateHandlesVisible = true; + var translateHandlesVisible = true; + var stretchHandlesVisible = true; + if (mode == "ROTATE_YAW" || mode == "ROTATE_PITCH" || mode == "ROTATE_ROLL" || mode == "TRANSLATE_XZ") { + rotateHandlesVisible = false; + translateHandlesVisible = false; + stretchHandlesVisible = false; + } else if (mode == "TRANSLATE_UP_DOWN") { + rotateHandlesVisible = false; + stretchHandlesVisible = false; + } else if (mode != "UNKNOWN") { + // every other mode is a stretch mode... + rotateHandlesVisible = false; + translateHandlesVisible = false; + } Overlays.editOverlay(highlightBox, { visible: false }); @@ -516,37 +589,37 @@ SelectionDisplay = (function () { }); - Overlays.editOverlay(grabberMoveUp, { visible: true, position: { x: center.x, y: top + grabberMoveUpOffset, z: center.z } }); + Overlays.editOverlay(grabberMoveUp, { visible: translateHandlesVisible, position: { x: center.x, y: top + grabberMoveUpOffset, z: center.z } }); - Overlays.editOverlay(grabberLBN, { visible: true, position: { x: left, y: bottom, z: near } }); - Overlays.editOverlay(grabberRBN, { visible: true, position: { x: right, y: bottom, z: near } }); - Overlays.editOverlay(grabberLBF, { visible: true, position: { x: left, y: bottom, z: far } }); - Overlays.editOverlay(grabberRBF, { visible: true, position: { x: right, y: bottom, z: far } }); - Overlays.editOverlay(grabberLTN, { visible: true, position: { x: left, y: top, z: near } }); - Overlays.editOverlay(grabberRTN, { visible: true, position: { x: right, y: top, z: near } }); - Overlays.editOverlay(grabberLTF, { visible: true, position: { x: left, y: top, z: far } }); - Overlays.editOverlay(grabberRTF, { visible: true, position: { x: right, y: top, z: far } }); + Overlays.editOverlay(grabberLBN, { visible: stretchHandlesVisible, position: { x: left, y: bottom, z: near } }); + Overlays.editOverlay(grabberRBN, { visible: stretchHandlesVisible, position: { x: right, y: bottom, z: near } }); + Overlays.editOverlay(grabberLBF, { visible: stretchHandlesVisible, position: { x: left, y: bottom, z: far } }); + Overlays.editOverlay(grabberRBF, { visible: stretchHandlesVisible, position: { x: right, y: bottom, z: far } }); + Overlays.editOverlay(grabberLTN, { visible: stretchHandlesVisible, position: { x: left, y: top, z: near } }); + Overlays.editOverlay(grabberRTN, { visible: stretchHandlesVisible, position: { x: right, y: top, z: near } }); + Overlays.editOverlay(grabberLTF, { visible: stretchHandlesVisible, position: { x: left, y: top, z: far } }); + Overlays.editOverlay(grabberRTF, { visible: stretchHandlesVisible, position: { x: right, y: top, z: far } }); - Overlays.editOverlay(grabberTOP, { visible: true, position: { x: center.x, y: top, z: center.z } }); - Overlays.editOverlay(grabberBOTTOM, { visible: true, position: { x: center.x, y: bottom, z: center.z } }); - Overlays.editOverlay(grabberLEFT, { visible: true, position: { x: left, y: center.y, z: center.z } }); - Overlays.editOverlay(grabberRIGHT, { visible: true, position: { x: right, y: center.y, z: center.z } }); - Overlays.editOverlay(grabberNEAR, { visible: true, position: { x: center.x, y: center.y, z: near } }); - Overlays.editOverlay(grabberFAR, { visible: true, position: { x: center.x, y: center.y, z: far } }); + Overlays.editOverlay(grabberTOP, { visible: stretchHandlesVisible, position: { x: center.x, y: top, z: center.z } }); + Overlays.editOverlay(grabberBOTTOM, { visible: stretchHandlesVisible, position: { x: center.x, y: bottom, z: center.z } }); + Overlays.editOverlay(grabberLEFT, { visible: stretchHandlesVisible, position: { x: left, y: center.y, z: center.z } }); + Overlays.editOverlay(grabberRIGHT, { visible: stretchHandlesVisible, position: { x: right, y: center.y, z: center.z } }); + Overlays.editOverlay(grabberNEAR, { visible: stretchHandlesVisible, position: { x: center.x, y: center.y, z: near } }); + Overlays.editOverlay(grabberFAR, { visible: stretchHandlesVisible, position: { x: center.x, y: center.y, z: far } }); - Overlays.editOverlay(grabberEdgeTR, { visible: true, position: { x: right, y: top, z: center.z } }); - Overlays.editOverlay(grabberEdgeTL, { visible: true, position: { x: left, y: top, z: center.z } }); - Overlays.editOverlay(grabberEdgeTF, { visible: true, position: { x: center.x, y: top, z: far } }); - Overlays.editOverlay(grabberEdgeTN, { visible: true, position: { x: center.x, y: top, z: near } }); - Overlays.editOverlay(grabberEdgeBR, { visible: true, position: { x: right, y: bottom, z: center.z } }); - Overlays.editOverlay(grabberEdgeBL, { visible: true, position: { x: left, y: bottom, z: center.z } }); - Overlays.editOverlay(grabberEdgeBF, { visible: true, position: { x: center.x, y: bottom, z: far } }); - Overlays.editOverlay(grabberEdgeBN, { visible: true, position: { x: center.x, y: bottom, z: near } }); - Overlays.editOverlay(grabberEdgeNR, { visible: true, position: { x: right, y: center.y, z: near } }); - Overlays.editOverlay(grabberEdgeNL, { visible: true, position: { x: left, y: center.y, z: near } }); - Overlays.editOverlay(grabberEdgeFR, { visible: true, position: { x: right, y: center.y, z: far } }); - Overlays.editOverlay(grabberEdgeFL, { visible: true, position: { x: left, y: center.y, z: far } }); + Overlays.editOverlay(grabberEdgeTR, { visible: stretchHandlesVisible, position: { x: right, y: top, z: center.z } }); + Overlays.editOverlay(grabberEdgeTL, { visible: stretchHandlesVisible, position: { x: left, y: top, z: center.z } }); + Overlays.editOverlay(grabberEdgeTF, { visible: stretchHandlesVisible, position: { x: center.x, y: top, z: far } }); + Overlays.editOverlay(grabberEdgeTN, { visible: stretchHandlesVisible, position: { x: center.x, y: top, z: near } }); + Overlays.editOverlay(grabberEdgeBR, { visible: stretchHandlesVisible, position: { x: right, y: bottom, z: center.z } }); + Overlays.editOverlay(grabberEdgeBL, { visible: stretchHandlesVisible, position: { x: left, y: bottom, z: center.z } }); + Overlays.editOverlay(grabberEdgeBF, { visible: stretchHandlesVisible, position: { x: center.x, y: bottom, z: far } }); + Overlays.editOverlay(grabberEdgeBN, { visible: stretchHandlesVisible, position: { x: center.x, y: bottom, z: near } }); + Overlays.editOverlay(grabberEdgeNR, { visible: stretchHandlesVisible, position: { x: right, y: center.y, z: near } }); + Overlays.editOverlay(grabberEdgeNL, { visible: stretchHandlesVisible, position: { x: left, y: center.y, z: near } }); + Overlays.editOverlay(grabberEdgeFR, { visible: stretchHandlesVisible, position: { x: right, y: center.y, z: far } }); + Overlays.editOverlay(grabberEdgeFL, { visible: stretchHandlesVisible, position: { x: left, y: center.y, z: far } }); Overlays.editOverlay(baseOfEntityProjectionOverlay, @@ -561,15 +634,10 @@ SelectionDisplay = (function () { dimensions: { x: properties.dimensions.x, y: properties.dimensions.z }, rotation: properties.rotation, }); - - + Overlays.editOverlay(rotateOverlayInner, { visible: false, - position: { x: properties.position.x, - y: properties.position.y - (properties.dimensions.y / 2), - z: properties.position.z}, - size: innerRadius, innerRadius: 0.9, alpha: innerAlpha @@ -578,10 +646,6 @@ SelectionDisplay = (function () { Overlays.editOverlay(rotateOverlayOuter, { visible: false, - position: { x: properties.position.x, - y: properties.position.y - (properties.dimensions.y / 2), - z: properties.position.z}, - size: outerRadius, innerRadius: 0.9, startAt: 0, @@ -592,10 +656,6 @@ SelectionDisplay = (function () { Overlays.editOverlay(rotateOverlayCurrent, { visible: false, - position: { x: properties.position.x, - y: properties.position.y - (properties.dimensions.y / 2), - z: properties.position.z}, - size: outerRadius, startAt: 0, endAt: 0, @@ -603,9 +663,9 @@ SelectionDisplay = (function () { }); // TODO: we have not implemented the rotating handle/controls yet... so for now, these handles are hidden - Overlays.editOverlay(yawHandle, { visible: false, position: yawCorner, rotation: yawHandleRotation}); - Overlays.editOverlay(pitchHandle, { visible: false, position: pitchCorner, rotation: pitchHandleRotation}); - Overlays.editOverlay(rollHandle, { visible: false, position: rollCorner, rotation: rollHandleRotation}); + Overlays.editOverlay(yawHandle, { visible: rotateHandlesVisible, position: yawCorner, rotation: yawHandleRotation}); + Overlays.editOverlay(pitchHandle, { visible: rotateHandlesVisible, position: pitchCorner, rotation: pitchHandleRotation}); + Overlays.editOverlay(rollHandle, { visible: rotateHandlesVisible, position: rollCorner, rotation: rollHandleRotation}); Entities.editEntity(entityID, { localRenderAlpha: 0.1 }); }; @@ -1440,7 +1500,25 @@ SelectionDisplay = (function () { Entities.editEntity(currentSelection, selectedEntityProperties); tooltip.updateText(selectedEntityProperties); that.select(currentSelection, false); // TODO: this should be more than highlighted - }; + }; + + that.rotateYaw = function(event) { + if (!entitySelected || mode !== "ROTATE_YAW") { + return; // not allowed + } + }; + + that.rotatePitch = function(event) { + if (!entitySelected || mode !== "ROTATE_PITCH") { + return; // not allowed + } + }; + + that.rotateRoll = function(event) { + if (!entitySelected || mode !== "ROTATE_ROLL") { + return; // not allowed + } + }; that.checkMove = function() { if (currentSelection.isKnownID && @@ -1477,6 +1555,36 @@ SelectionDisplay = (function () { case grabberMoveUp: mode = "TRANSLATE_UP_DOWN"; somethingClicked = true; + + // in translate mode, we hide our stretch handles... + Overlays.editOverlay(grabberLBN, { visible: false }); + Overlays.editOverlay(grabberLBF, { visible: false }); + Overlays.editOverlay(grabberRBN, { visible: false }); + Overlays.editOverlay(grabberRBF, { visible: false }); + Overlays.editOverlay(grabberLTN, { visible: false }); + Overlays.editOverlay(grabberLTF, { visible: false }); + Overlays.editOverlay(grabberRTN, { visible: false }); + Overlays.editOverlay(grabberRTF, { visible: false }); + + Overlays.editOverlay(grabberTOP, { visible: false }); + Overlays.editOverlay(grabberBOTTOM, { visible: false }); + Overlays.editOverlay(grabberLEFT, { visible: false }); + Overlays.editOverlay(grabberRIGHT, { visible: false }); + Overlays.editOverlay(grabberNEAR, { visible: false }); + Overlays.editOverlay(grabberFAR, { visible: false }); + + Overlays.editOverlay(grabberEdgeTR, { visible: false }); + Overlays.editOverlay(grabberEdgeTL, { visible: false }); + Overlays.editOverlay(grabberEdgeTF, { visible: false }); + Overlays.editOverlay(grabberEdgeTN, { visible: false }); + Overlays.editOverlay(grabberEdgeBR, { visible: false }); + Overlays.editOverlay(grabberEdgeBL, { visible: false }); + Overlays.editOverlay(grabberEdgeBF, { visible: false }); + Overlays.editOverlay(grabberEdgeBN, { visible: false }); + Overlays.editOverlay(grabberEdgeNR, { visible: false }); + Overlays.editOverlay(grabberEdgeNL, { visible: false }); + Overlays.editOverlay(grabberEdgeFR, { visible: false }); + Overlays.editOverlay(grabberEdgeFL, { visible: false }); break; case grabberRBN: @@ -1559,20 +1667,128 @@ SelectionDisplay = (function () { } } + // if one of the items above was clicked, then we know we are in translate or stretch mode, and we + // should hide our rotate handles... + if (somethingClicked) { + Overlays.editOverlay(yawHandle, { visible: false }); + Overlays.editOverlay(pitchHandle, { visible: false }); + Overlays.editOverlay(rollHandle, { visible: false }); + + if (mode != "TRANSLATE_UP_DOWN") { + Overlays.editOverlay(grabberMoveUp, { visible: false }); + } + } + if (!somethingClicked) { + + print("rotate handle case..."); + // After testing our stretch handles, then check out rotate handles Overlays.editOverlay(yawHandle, { ignoreRayIntersection: false }); Overlays.editOverlay(pitchHandle, { ignoreRayIntersection: false }); Overlays.editOverlay(rollHandle, { ignoreRayIntersection: false }); var result = Overlays.findRayIntersection(pickRay); + + var overlayOrientation; + var overlayCenter; + if (result.intersects) { switch(result.overlayID) { + case yawHandle: + mode = "ROTATE_YAW"; + somethingClicked = true; + overlayOrientation = yawHandleRotation; + overlayCenter = yawCenter; + break; + + case pitchHandle: + mode = "ROTATE_PITCH"; + somethingClicked = true; + overlayOrientation = pitchHandleRotation; + overlayCenter = pitchCenter; + break; + + case rollHandle: + mode = "ROTATE_ROLL"; + somethingClicked = true; + overlayOrientation = rollHandleRotation; + overlayCenter = rollCenter; + break; + default: print("mousePressEvent()...... " + overlayNames[result.overlayID]); mode = "UNKNOWN"; break; } } + + print(" somethingClicked:" + somethingClicked); + print(" mode:" + mode); + + if (somethingClicked) { + + // TODO: need to place correctly.... + print(" attempting to show overlays:" + somethingClicked); + + Overlays.editOverlay(rotateOverlayInner, + { + visible: true, + rotation: overlayOrientation, + position: overlayCenter + }); + + Overlays.editOverlay(rotateOverlayOuter, + { + visible: true, + rotation: overlayOrientation, + position: overlayCenter + }); + + Overlays.editOverlay(rotateOverlayCurrent, + { + visible: true, + rotation: overlayOrientation, + position: overlayCenter + }); + + Overlays.editOverlay(yawHandle, { visible: false }); + Overlays.editOverlay(pitchHandle, { visible: false }); + Overlays.editOverlay(rollHandle, { visible: false }); + + + Overlays.editOverlay(yawHandle, { visible: false }); + Overlays.editOverlay(pitchHandle, { visible: false }); + Overlays.editOverlay(rollHandle, { visible: false }); + Overlays.editOverlay(grabberMoveUp, { visible: false }); + Overlays.editOverlay(grabberLBN, { visible: false }); + Overlays.editOverlay(grabberLBF, { visible: false }); + Overlays.editOverlay(grabberRBN, { visible: false }); + Overlays.editOverlay(grabberRBF, { visible: false }); + Overlays.editOverlay(grabberLTN, { visible: false }); + Overlays.editOverlay(grabberLTF, { visible: false }); + Overlays.editOverlay(grabberRTN, { visible: false }); + Overlays.editOverlay(grabberRTF, { visible: false }); + + Overlays.editOverlay(grabberTOP, { visible: false }); + Overlays.editOverlay(grabberBOTTOM, { visible: false }); + Overlays.editOverlay(grabberLEFT, { visible: false }); + Overlays.editOverlay(grabberRIGHT, { visible: false }); + Overlays.editOverlay(grabberNEAR, { visible: false }); + Overlays.editOverlay(grabberFAR, { visible: false }); + + Overlays.editOverlay(grabberEdgeTR, { visible: false }); + Overlays.editOverlay(grabberEdgeTL, { visible: false }); + Overlays.editOverlay(grabberEdgeTF, { visible: false }); + Overlays.editOverlay(grabberEdgeTN, { visible: false }); + Overlays.editOverlay(grabberEdgeBR, { visible: false }); + Overlays.editOverlay(grabberEdgeBL, { visible: false }); + Overlays.editOverlay(grabberEdgeBF, { visible: false }); + Overlays.editOverlay(grabberEdgeBN, { visible: false }); + Overlays.editOverlay(grabberEdgeNR, { visible: false }); + Overlays.editOverlay(grabberEdgeNL, { visible: false }); + Overlays.editOverlay(grabberEdgeFR, { visible: false }); + Overlays.editOverlay(grabberEdgeFL, { visible: false }); + } } if (!somethingClicked) { @@ -1614,6 +1830,15 @@ SelectionDisplay = (function () { that.mouseMoveEvent = function(event) { //print("mouseMoveEvent()... mode:" + mode); switch (mode) { + case "ROTATE_YAW": + that.rotateYaw(event); + break; + case "ROTATE_PITCH": + that.rotatePitch(event); + break; + case "ROTATE_ROLL": + that.rotateRoll(event); + break; case "TRANSLATE_UP_DOWN": that.translateUpDown(event); break; @@ -1671,6 +1896,54 @@ SelectionDisplay = (function () { }; that.mouseReleaseEvent = function(event) { + var showHandles = false; + // hide our rotation overlays..., and show our handles + if (mode == "ROTATE_YAW" || mode == "ROTATE_PITCH" || mode == "ROTATE_ROLL") { + Overlays.editOverlay(rotateOverlayInner, { visible: false }); + Overlays.editOverlay(rotateOverlayOuter, { visible: false }); + Overlays.editOverlay(rotateOverlayCurrent, { visible: false }); + showHandles = true; + } + + if (mode != "UNKNOWN") { + showHandles = true; + } + + if (showHandles) { + Overlays.editOverlay(yawHandle, { visible: true }); + Overlays.editOverlay(pitchHandle, { visible: true }); + Overlays.editOverlay(rollHandle, { visible: true }); + Overlays.editOverlay(grabberMoveUp, { visible: true }); + Overlays.editOverlay(grabberLBN, { visible: true }); + Overlays.editOverlay(grabberLBF, { visible: true }); + Overlays.editOverlay(grabberRBN, { visible: true }); + Overlays.editOverlay(grabberRBF, { visible: true }); + Overlays.editOverlay(grabberLTN, { visible: true }); + Overlays.editOverlay(grabberLTF, { visible: true }); + Overlays.editOverlay(grabberRTN, { visible: true }); + Overlays.editOverlay(grabberRTF, { visible: true }); + + Overlays.editOverlay(grabberTOP, { visible: true }); + Overlays.editOverlay(grabberBOTTOM, { visible: true }); + Overlays.editOverlay(grabberLEFT, { visible: true }); + Overlays.editOverlay(grabberRIGHT, { visible: true }); + Overlays.editOverlay(grabberNEAR, { visible: true }); + Overlays.editOverlay(grabberFAR, { visible: true }); + + Overlays.editOverlay(grabberEdgeTR, { visible: true }); + Overlays.editOverlay(grabberEdgeTL, { visible: true }); + Overlays.editOverlay(grabberEdgeTF, { visible: true }); + Overlays.editOverlay(grabberEdgeTN, { visible: true }); + Overlays.editOverlay(grabberEdgeBR, { visible: true }); + Overlays.editOverlay(grabberEdgeBL, { visible: true }); + Overlays.editOverlay(grabberEdgeBF, { visible: true }); + Overlays.editOverlay(grabberEdgeBN, { visible: true }); + Overlays.editOverlay(grabberEdgeNR, { visible: true }); + Overlays.editOverlay(grabberEdgeNL, { visible: true }); + Overlays.editOverlay(grabberEdgeFR, { visible: true }); + Overlays.editOverlay(grabberEdgeFL, { visible: true }); + } + mode = "UNKNOWN"; // if something is selected, then reset the "original" properties for any potential next click+move operation @@ -1679,6 +1952,7 @@ SelectionDisplay = (function () { selectedEntityPropertiesOriginalPosition = properties.position; selectedEntityPropertiesOriginalDimensions = properties.dimensions; } + }; Controller.mousePressEvent.connect(that.mousePressEvent); From 01bef6be6dd30ab7c31bde26eced40c9b3af54f4 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 8 Oct 2014 15:28:29 -0700 Subject: [PATCH 108/179] remove unused cameraPushback variable --- interface/src/Application.cpp | 14 ++++++-------- interface/src/Application.h | 1 - 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 16537ee6dc..c90a5ade9f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -153,7 +153,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _lastQueriedViewFrustum(), _lastQueriedTime(usecTimestampNow()), _mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)), - _cameraPushback(0.0f), _scaleMirror(1.0f), _rotateMirror(0.0f), _raiseMirror(0.0f), @@ -658,13 +657,12 @@ void Application::paintGL() { ViewFrustumOffset viewFrustumOffset = Menu::getInstance()->getViewFrustumOffset(); // set the camera to third-person view but offset so we can see the frustum - _viewFrustumOffsetCamera.setPosition(_myCamera.getPosition()); - _viewFrustumOffsetCamera.setRotation(_myCamera.getRotation() * glm::quat(glm::radians(glm::vec3( - viewFrustumOffset.pitch, viewFrustumOffset.yaw, viewFrustumOffset.roll)))); - // TODO: PHILIP - // Fix Frustum offset and up - //_viewFrustumOffsetCamera.setUpShift(viewFrustumOffset.up); - //_viewFrustumOffsetCamera.setDistance(viewFrustumOffset.distance); + glm::quat frustumRotation = glm::quat(glm::radians(glm::vec3(viewFrustumOffset.pitch, viewFrustumOffset.yaw, viewFrustumOffset.roll))); + + _viewFrustumOffsetCamera.setPosition(_myCamera.getPosition() + + frustumRotation * glm::vec3(0.0f, viewFrustumOffset.up, -viewFrustumOffset.distance)); + + _viewFrustumOffsetCamera.setRotation(_myCamera.getRotation() * frustumRotation); _viewFrustumOffsetCamera.initialize(); // force immediate snap to ideal position and orientation _viewFrustumOffsetCamera.update(1.f/_fps); diff --git a/interface/src/Application.h b/interface/src/Application.h index ca26cffab8..248c4325bf 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -519,7 +519,6 @@ private: QRect _mirrorViewRect; RearMirrorTools* _rearMirrorTools; - float _cameraPushback; glm::mat4 _untranslatedViewMatrix; glm::vec3 _viewMatrixTranslation; glm::mat4 _projectionMatrix; From 4daa379b033f6eb841f42d1006aa013dee6712a6 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 8 Oct 2014 15:32:56 -0700 Subject: [PATCH 109/179] use sweet alert for nice error messages in domain-settings --- .../resources/web/css/sweet-alert.css | 602 ++++++++++++++++++ domain-server/resources/web/header.html | 1 + domain-server/resources/web/js/settings.js | 19 +- .../resources/web/js/sweet-alert.min.js | 1 + .../resources/web/settings/index.shtml | 2 + 5 files changed, 613 insertions(+), 12 deletions(-) create mode 100755 domain-server/resources/web/css/sweet-alert.css create mode 100755 domain-server/resources/web/js/sweet-alert.min.js diff --git a/domain-server/resources/web/css/sweet-alert.css b/domain-server/resources/web/css/sweet-alert.css new file mode 100755 index 0000000000..eba0fa065d --- /dev/null +++ b/domain-server/resources/web/css/sweet-alert.css @@ -0,0 +1,602 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:400,600,700,300); +.sweet-overlay { + background-color: rgba(0, 0, 0, 0.4); + position: fixed; + left: 0; + right: 0; + top: 0; + bottom: 0; + display: none; + z-index: 1000; } + +.sweet-alert { + background-color: white; + font-family: 'Open Sans', sans-serif; + width: 478px; + padding: 17px; + border-radius: 5px; + text-align: center; + position: fixed; + left: 50%; + top: 50%; + margin-left: -256px; + margin-top: -200px; + overflow: hidden; + display: none; + z-index: 2000; } + @media all and (max-width: 540px) { + .sweet-alert { + width: auto; + margin-left: 0; + margin-right: 0; + left: 15px; + right: 15px; } } + .sweet-alert h2 { + color: #575757; + font-size: 30px; + text-align: center; + font-weight: 600; + text-transform: none; + position: relative; } + .sweet-alert p { + color: #797979; + font-size: 16px; + text-align: center; + font-weight: 300; + position: relative; + margin: 0; + line-height: normal; } + .sweet-alert button { + background-color: #AEDEF4; + color: white; + border: none; + box-shadow: none; + font-size: 17px; + font-weight: 500; + border-radius: 5px; + padding: 10px 32px; + margin: 26px 5px 0 5px; + cursor: pointer; } + .sweet-alert button:focus { + outline: none; + box-shadow: 0 0 2px rgba(128, 179, 235, 0.5), inset 0 0 0 1px rgba(0, 0, 0, 0.05); } + .sweet-alert button:hover { + background-color: #a1d9f2; } + .sweet-alert button:active { + background-color: #81ccee; } + .sweet-alert button.cancel { + background-color: #D0D0D0; } + .sweet-alert button.cancel:hover { + background-color: #c8c8c8; } + .sweet-alert button.cancel:active { + background-color: #b6b6b6; } + .sweet-alert button.cancel:focus { + box-shadow: rgba(197, 205, 211, 0.8) 0px 0px 2px, rgba(0, 0, 0, 0.0470588) 0px 0px 0px 1px inset !important; } + .sweet-alert[data-has-cancel-button=false] button { + box-shadow: none !important; } + .sweet-alert .icon { + width: 80px; + height: 80px; + border: 4px solid gray; + border-radius: 50%; + margin: 20px auto; + position: relative; + box-sizing: content-box; } + .sweet-alert .icon.error { + border-color: #F27474; } + .sweet-alert .icon.error .x-mark { + position: relative; + display: block; } + .sweet-alert .icon.error .line { + position: absolute; + height: 5px; + width: 47px; + background-color: #F27474; + display: block; + top: 37px; + border-radius: 2px; } + .sweet-alert .icon.error .line.left { + -webkit-transform: rotate(45deg); + transform: rotate(45deg); + left: 17px; } + .sweet-alert .icon.error .line.right { + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); + right: 16px; } + .sweet-alert .icon.warning { + border-color: #F8BB86; } + .sweet-alert .icon.warning .body { + position: absolute; + width: 5px; + height: 47px; + left: 50%; + top: 10px; + border-radius: 2px; + margin-left: -2px; + background-color: #F8BB86; } + .sweet-alert .icon.warning .dot { + position: absolute; + width: 7px; + height: 7px; + border-radius: 50%; + margin-left: -3px; + left: 50%; + bottom: 10px; + background-color: #F8BB86; } + .sweet-alert .icon.info { + border-color: #C9DAE1; } + .sweet-alert .icon.info::before { + content: ""; + position: absolute; + width: 5px; + height: 29px; + left: 50%; + bottom: 17px; + border-radius: 2px; + margin-left: -2px; + background-color: #C9DAE1; } + .sweet-alert .icon.info::after { + content: ""; + position: absolute; + width: 7px; + height: 7px; + border-radius: 50%; + margin-left: -3px; + top: 19px; + background-color: #C9DAE1; } + .sweet-alert .icon.success { + border-color: #A5DC86; } + .sweet-alert .icon.success::before, .sweet-alert .icon.success::after { + content: ''; + border-radius: 50%; + position: absolute; + width: 60px; + height: 120px; + background: white; + transform: rotate(45deg); } + .sweet-alert .icon.success::before { + border-radius: 120px 0 0 120px; + top: -7px; + left: -33px; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); + -webkit-transform-origin: 60px 60px; + transform-origin: 60px 60px; } + .sweet-alert .icon.success::after { + border-radius: 0 120px 120px 0; + top: -11px; + left: 30px; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); + -webkit-transform-origin: 0px 60px; + transform-origin: 0px 60px; } + .sweet-alert .icon.success .placeholder { + width: 80px; + height: 80px; + border: 4px solid rgba(165, 220, 134, 0.2); + border-radius: 50%; + box-sizing: content-box; + position: absolute; + left: -4px; + top: -4px; + z-index: 2; } + .sweet-alert .icon.success .fix { + width: 5px; + height: 90px; + background-color: white; + position: absolute; + left: 28px; + top: 8px; + z-index: 1; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); } + .sweet-alert .icon.success .line { + height: 5px; + background-color: #A5DC86; + display: block; + border-radius: 2px; + position: absolute; + z-index: 2; } + .sweet-alert .icon.success .line.tip { + width: 25px; + left: 14px; + top: 46px; + -webkit-transform: rotate(45deg); + transform: rotate(45deg); } + .sweet-alert .icon.success .line.long { + width: 47px; + right: 8px; + top: 38px; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); } + .sweet-alert .icon.custom { + background-size: contain; + border-radius: 0; + border: none; + background-position: center center; + background-repeat: no-repeat; } + +/* + * Animations + */ +@-webkit-keyframes showSweetAlert { + 0% { + transform: scale(0.7); + -webkit-transform: scale(0.7); } + 45% { + transform: scale(1.05); + -webkit-transform: scale(1.05); } + 80% { + transform: scale(0.95); + -webkit-tranform: scale(0.95); } + 100% { + transform: scale(1); + -webkit-transform: scale(1); } } +@-moz-keyframes showSweetAlert { + 0% { + transform: scale(0.7); + -webkit-transform: scale(0.7); } + 45% { + transform: scale(1.05); + -webkit-transform: scale(1.05); } + 80% { + transform: scale(0.95); + -webkit-tranform: scale(0.95); } + 100% { + transform: scale(1); + -webkit-transform: scale(1); } } +@keyframes showSweetAlert { + 0% { + transform: scale(0.7); + -webkit-transform: scale(0.7); } + 45% { + transform: scale(1.05); + -webkit-transform: scale(1.05); } + 80% { + transform: scale(0.95); + -webkit-tranform: scale(0.95); } + 100% { + transform: scale(1); + -webkit-transform: scale(1); } } +@-webkit-keyframes hideSweetAlert { + 0% { + transform: scale(1); + -webkit-transform: scale(1); } + 100% { + transform: scale(0.5); + -webkit-transform: scale(0.5); } } +@-moz-keyframes hideSweetAlert { + 0% { + transform: scale(1); + -webkit-transform: scale(1); } + 100% { + transform: scale(0.5); + -webkit-transform: scale(0.5); } } +@keyframes hideSweetAlert { + 0% { + transform: scale(1); + -webkit-transform: scale(1); } + 100% { + transform: scale(0.5); + -webkit-transform: scale(0.5); } } +.showSweetAlert { + -webkit-animation: showSweetAlert 0.3s; + -moz-animation: showSweetAlert 0.3s; + animation: showSweetAlert 0.3s; } + +.hideSweetAlert { + -webkit-animation: hideSweetAlert 0.2s; + -moz-animation: hideSweetAlert 0.2s; + animation: hideSweetAlert 0.2s; } + +@-webkit-keyframes animateSuccessTip { + 0% { + width: 0; + left: 1px; + top: 19px; } + 54% { + width: 0; + left: 1px; + top: 19px; } + 70% { + width: 50px; + left: -8px; + top: 37px; } + 84% { + width: 17px; + left: 21px; + top: 48px; } + 100% { + width: 25px; + left: 14px; + top: 45px; } } +@-moz-keyframes animateSuccessTip { + 0% { + width: 0; + left: 1px; + top: 19px; } + 54% { + width: 0; + left: 1px; + top: 19px; } + 70% { + width: 50px; + left: -8px; + top: 37px; } + 84% { + width: 17px; + left: 21px; + top: 48px; } + 100% { + width: 25px; + left: 14px; + top: 45px; } } +@keyframes animateSuccessTip { + 0% { + width: 0; + left: 1px; + top: 19px; } + 54% { + width: 0; + left: 1px; + top: 19px; } + 70% { + width: 50px; + left: -8px; + top: 37px; } + 84% { + width: 17px; + left: 21px; + top: 48px; } + 100% { + width: 25px; + left: 14px; + top: 45px; } } +@-webkit-keyframes animateSuccessLong { + 0% { + width: 0; + right: 46px; + top: 54px; } + 65% { + width: 0; + right: 46px; + top: 54px; } + 84% { + width: 55px; + right: 0px; + top: 35px; } + 100% { + width: 47px; + right: 8px; + top: 38px; } } +@-moz-keyframes animateSuccessLong { + 0% { + width: 0; + right: 46px; + top: 54px; } + 65% { + width: 0; + right: 46px; + top: 54px; } + 84% { + width: 55px; + right: 0px; + top: 35px; } + 100% { + width: 47px; + right: 8px; + top: 38px; } } +@keyframes animateSuccessLong { + 0% { + width: 0; + right: 46px; + top: 54px; } + 65% { + width: 0; + right: 46px; + top: 54px; } + 84% { + width: 55px; + right: 0px; + top: 35px; } + 100% { + width: 47px; + right: 8px; + top: 38px; } } +@-webkit-keyframes rotatePlaceholder { + 0% { + transform: rotate(-45deg); + -webkit-transform: rotate(-45deg); } + 5% { + transform: rotate(-45deg); + -webkit-transform: rotate(-45deg); } + 12% { + transform: rotate(-405deg); + -webkit-transform: rotate(-405deg); } + 100% { + transform: rotate(-405deg); + -webkit-transform: rotate(-405deg); } } +@-moz-keyframes rotatePlaceholder { + 0% { + transform: rotate(-45deg); + -webkit-transform: rotate(-45deg); } + 5% { + transform: rotate(-45deg); + -webkit-transform: rotate(-45deg); } + 12% { + transform: rotate(-405deg); + -webkit-transform: rotate(-405deg); } + 100% { + transform: rotate(-405deg); + -webkit-transform: rotate(-405deg); } } +@keyframes rotatePlaceholder { + 0% { + transform: rotate(-45deg); + -webkit-transform: rotate(-45deg); } + 5% { + transform: rotate(-45deg); + -webkit-transform: rotate(-45deg); } + 12% { + transform: rotate(-405deg); + -webkit-transform: rotate(-405deg); } + 100% { + transform: rotate(-405deg); + -webkit-transform: rotate(-405deg); } } +.animateSuccessTip { + -webkit-animation: animateSuccessTip 0.75s; + -moz-animation: animateSuccessTip 0.75s; + animation: animateSuccessTip 0.75s; } + +.animateSuccessLong { + -webkit-animation: animateSuccessLong 0.75s; + -moz-animation: animateSuccessLong 0.75s; + animation: animateSuccessLong 0.75s; } + +.icon.success.animate::after { + -webkit-animation: rotatePlaceholder 4.25s ease-in; + -moz-animation: rotatePlaceholder 4.25s ease-in; + animation: rotatePlaceholder 4.25s ease-in; } + +@-webkit-keyframes animateErrorIcon { + 0% { + transform: rotateX(100deg); + -webkit-transform: rotateX(100deg); + opacity: 0; } + 100% { + transform: rotateX(0deg); + -webkit-transform: rotateX(0deg); + opacity: 1; } } +@-moz-keyframes animateErrorIcon { + 0% { + transform: rotateX(100deg); + -webkit-transform: rotateX(100deg); + opacity: 0; } + 100% { + transform: rotateX(0deg); + -webkit-transform: rotateX(0deg); + opacity: 1; } } +@keyframes animateErrorIcon { + 0% { + transform: rotateX(100deg); + -webkit-transform: rotateX(100deg); + opacity: 0; } + 100% { + transform: rotateX(0deg); + -webkit-transform: rotateX(0deg); + opacity: 1; } } +.animateErrorIcon { + -webkit-animation: animateErrorIcon 0.5s; + -moz-animation: animateErrorIcon 0.5s; + animation: animateErrorIcon 0.5s; } + +@-webkit-keyframes animateXMark { + 0% { + transform: scale(0.4); + -webkit-transform: scale(0.4); + margin-top: 26px; + opacity: 0; } + 50% { + transform: scale(0.4); + -webkit-transform: scale(0.4); + margin-top: 26px; + opacity: 0; } + 80% { + transform: scale(1.15); + -webkit-transform: scale(1.15); + margin-top: -6px; } + 100% { + transform: scale(1); + -webkit-transform: scale(1); + margin-top: 0; + opacity: 1; } } +@-moz-keyframes animateXMark { + 0% { + transform: scale(0.4); + -webkit-transform: scale(0.4); + margin-top: 26px; + opacity: 0; } + 50% { + transform: scale(0.4); + -webkit-transform: scale(0.4); + margin-top: 26px; + opacity: 0; } + 80% { + transform: scale(1.15); + -webkit-transform: scale(1.15); + margin-top: -6px; } + 100% { + transform: scale(1); + -webkit-transform: scale(1); + margin-top: 0; + opacity: 1; } } +@keyframes animateXMark { + 0% { + transform: scale(0.4); + -webkit-transform: scale(0.4); + margin-top: 26px; + opacity: 0; } + 50% { + transform: scale(0.4); + -webkit-transform: scale(0.4); + margin-top: 26px; + opacity: 0; } + 80% { + transform: scale(1.15); + -webkit-transform: scale(1.15); + margin-top: -6px; } + 100% { + transform: scale(1); + -webkit-transform: scale(1); + margin-top: 0; + opacity: 1; } } +.animateXMark { + -webkit-animation: animateXMark 0.5s; + -moz-animation: animateXMark 0.5s; + animation: animateXMark 0.5s; } + +/*@include keyframes(simpleRotate) { + 0% { transform: rotateY(0deg); } + 100% { transform: rotateY(-360deg); } +} +.simpleRotate { + @include animation('simpleRotate 0.75s'); +}*/ +@-webkit-keyframes pulseWarning { + 0% { + border-color: #F8D486; } + 100% { + border-color: #F8BB86; } } +@-moz-keyframes pulseWarning { + 0% { + border-color: #F8D486; } + 100% { + border-color: #F8BB86; } } +@keyframes pulseWarning { + 0% { + border-color: #F8D486; } + 100% { + border-color: #F8BB86; } } +.pulseWarning { + -webkit-animation: pulseWarning 0.75s infinite alternate; + -moz-animation: pulseWarning 0.75s infinite alternate; + animation: pulseWarning 0.75s infinite alternate; } + +@-webkit-keyframes pulseWarningIns { + 0% { + background-color: #F8D486; } + 100% { + background-color: #F8BB86; } } +@-moz-keyframes pulseWarningIns { + 0% { + background-color: #F8D486; } + 100% { + background-color: #F8BB86; } } +@keyframes pulseWarningIns { + 0% { + background-color: #F8D486; } + 100% { + background-color: #F8BB86; } } +.pulseWarningIns { + -webkit-animation: pulseWarningIns 0.75s infinite alternate; + -moz-animation: pulseWarningIns 0.75s infinite alternate; + animation: pulseWarningIns 0.75s infinite alternate; } diff --git a/domain-server/resources/web/header.html b/domain-server/resources/web/header.html index 5abf8fa028..66f48637c5 100644 --- a/domain-server/resources/web/header.html +++ b/domain-server/resources/web/header.html @@ -6,6 +6,7 @@ +