From 0078b45a8f8b972708a1059f37e601d6ab1fff3b Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 10 Sep 2014 19:00:24 -0700 Subject: [PATCH] update headMove to have optional concept of a room that we cannot escape, update and rename butterflies script --- examples/butterflies.js | 234 ++++++++++++++++++ examples/headMove.js | 81 +++++- interface/src/Audio.cpp | 2 + .../src/entities/RenderableBoxEntityItem.cpp | 2 +- 4 files changed, 309 insertions(+), 10 deletions(-) create mode 100644 examples/butterflies.js diff --git a/examples/butterflies.js b/examples/butterflies.js new file mode 100644 index 0000000000..1f612ed4bf --- /dev/null +++ b/examples/butterflies.js @@ -0,0 +1,234 @@ +// +// butterflies.js +// +// +// Created by Adrian McCarlie on August 2, 2014 +// Modified by Brad Hefta-Gaub to use Entities on Sept. 3, 2014 +// Copyright 2014 High Fidelity, Inc. +// +// This sample script creates a swarm of butterfly entities that fly around the avatar. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + + +function getRandomFloat(min, max) { + return Math.random() * (max - min) + min; +} + +// Multiply vector by scalar +function vScalarMult(v, s) { + var rval = { x: v.x * s, y: v.y * s, z: v.z * s }; + return rval; +} + +// Create a random vector with individual lengths between a,b +function randVector(a, b) { + var rval = { x: a + Math.random() * (b - a), y: a + Math.random() * (b - a), z: a + Math.random() * (b - a) }; + return rval; +} + +// Returns a vector which is fraction of the way between a and b +function vInterpolate(a, b, fraction) { + var rval = { x: a.x + (b.x - a.x) * fraction, y: a.y + (b.y - a.y) * fraction, z: a.z + (b.z - a.z) * fraction }; + return rval; +} + +var startTimeInSeconds = new Date().getTime() / 1000; + +var lifeTime = 600; // lifetime of the butterflies in seconds +var range = 1.0; // Over what distance in meters do you want the flock to fly around +var frame = 0; + +var CHANCE_OF_MOVING = 0.9; +var BUTTERFLY_GRAVITY = 0;//-0.06; +var BUTTERFLY_FLAP_SPEED = 1.0; +var BUTTERFLY_VELOCITY = 0.55; +var DISTANCE_IN_FRONT_OF_ME = 1.5; +var DISTANCE_ABOVE_ME = 1.0; +var flockPosition = Vec3.sum(MyAvatar.position,Vec3.sum( + Vec3.multiply(Quat.getFront(MyAvatar.orientation), DISTANCE_ABOVE_ME), + Vec3.multiply(Quat.getFront(MyAvatar.orientation), DISTANCE_IN_FRONT_OF_ME))); + + +// set these pitch, yaw, roll to the needed values to orient the model as you want it +var pitchInDegrees = 270.0; +var yawInDegrees = 0.0; +var rollInDegrees = 0.0; +var pitchInRadians = pitchInDegrees / 180.0 * Math.PI; +var yawInRadians = yawInDegrees / 180.0 * Math.PI; +var rollInRadians = rollInDegrees / 180.0 * Math.PI; + +var rotation = Quat.fromPitchYawRollDegrees(pitchInDegrees, yawInDegrees, rollInDegrees);//experimental + +// This is our butterfly object +function defineButterfly(entityID, targetPosition) { + this.entityID = entityID; + this.previousFlapOffset = 0; + this.targetPosition = targetPosition; + this.moving = false; +} + +// Array of butterflies +var butterflies = []; +var numButterflies = 20; +function addButterfly() { + // Decide the size of butterfly + var color = { red: 100, green: 100, blue: 100 }; + var size = 0; + + size = 0.06 + Math.random() * 0.2; + + flockPosition = Vec3.sum(MyAvatar.position,Vec3.sum( + Vec3.multiply(Quat.getFront(MyAvatar.orientation), DISTANCE_ABOVE_ME), + Vec3.multiply(Quat.getFront(MyAvatar.orientation), DISTANCE_IN_FRONT_OF_ME))); + + var properties = { + type: "Model", + lifetime: lifeTime, + position: Vec3.sum(randVector(-range, range), flockPosition), + velocity: { x: 0, y: 0.0, z: 0 }, + gravity: { x: 0, y: 1.0, z: 0 }, + damping: 0.1, + radius : size, + color: color, + rotation: rotation, + animationURL: "http://business.ozblog.me/objects/butterfly/newButterfly2.fbx", + animationIsPlaying: true, + modelURL: "http://business.ozblog.me/objects/butterfly/newButterfly2.fbx" + }; + properties.position.z = properties.position.z+1; + butterflies.push(new defineButterfly(Entities.addEntity(properties), properties.position)); +} + +// Generate the butterflies +for (var i = 0; i < numButterflies; i++) { + addButterfly(); +} + +// Main update function +function updateButterflies(deltaTime) { + // Check to see if we've been running long enough that our butterflies are dead + var nowTimeInSeconds = new Date().getTime() / 1000; + if ((nowTimeInSeconds - startTimeInSeconds) >= lifeTime) { + // print("our butterflies are dying, stop our script"); + Script.stop(); + return; + } + + frame++; + // Only update every third frame + if ((frame % 3) == 0) { + flockPosition = Vec3.sum(MyAvatar.position,Vec3.sum( + Vec3.multiply(Quat.getFront(MyAvatar.orientation), DISTANCE_ABOVE_ME), + Vec3.multiply(Quat.getFront(MyAvatar.orientation), DISTANCE_IN_FRONT_OF_ME))); + + // Update all the butterflies + for (var i = 0; i < numButterflies; i++) { + entityID = butterflies[i].entityID; + var properties = Entities.getEntityProperties(entityID); + + if (properties.position.y > flockPosition.y + getRandomFloat(0.0,0.3)){ //0.3 //ceiling + properties.gravity.y = - 3.0; + properties.damping.y = 1.0; + properties.velocity.y = 0; + properties.velocity.x = properties.velocity.x; + properties.velocity.z = properties.velocity.z; + if (properties.velocity.x < 0.5){ + butterflies[i].moving = false; + } + if (properties.velocity.z < 0.5){ + butterflies[i].moving = false; + } + } + + if (properties.velocity.y <= -0.2) { + properties.velocity.y = 0.22; + properties.velocity.x = properties.velocity.x; + properties.velocity.z = properties.velocity.z; + } + + if (properties.position.y < flockPosition.y - getRandomFloat(0.0,0.3)) { //-0.3 // floor + properties.velocity.y = 0.9; + properties.gravity.y = - 4.0; + properties.velocity.x = properties.velocity.x; + properties.velocity.z = properties.velocity.z; + if (properties.velocity.x < 0.5){ + butterflies[i].moving = false; + } + if (properties.velocity.z < 0.5){ + butterflies[i].moving = false; + } + } + + + // Begin movement by getting a target + if (butterflies[i].moving == false) { + if (Math.random() < CHANCE_OF_MOVING) { + var targetPosition = Vec3.sum(randVector(-range, range), flockPosition); + if (targetPosition.x < 0) { + targetPosition.x = 0; + } + if (targetPosition.y < 0) { + targetPosition.y = 0; + } + if (targetPosition.z < 0) { + targetPosition.z = 0; + } + if (targetPosition.x > TREE_SCALE) { + targetPosition.x = TREE_SCALE; + } + if (targetPosition.y > TREE_SCALE) { + targetPosition.y = TREE_SCALE; + } + if (targetPosition.z > TREE_SCALE) { + targetPosition.z = TREE_SCALE; + } + butterflies[i].targetPosition = targetPosition; + butterflies[i].moving = true; + } + } + + // If we are moving, move towards the target + if (butterflies[i].moving) { + + var holding = properties.velocity.y; + + var desiredVelocity = Vec3.subtract(butterflies[i].targetPosition, properties.position); + desiredVelocity = vScalarMult(Vec3.normalize(desiredVelocity), BUTTERFLY_VELOCITY); + + properties.velocity = vInterpolate(properties.velocity, desiredVelocity, 0.5); + properties.velocity.y = holding ; + + + // If we are near the target, we should get a new target + if (Vec3.length(Vec3.subtract(properties.position, butterflies[i].targetPosition)) < (properties.radius / 1.0)) { + butterflies[i].moving = false; + } + + var yawRads = Math.atan2(properties.velocity.z, properties.velocity.x); + yawRads = yawRads + Math.PI / 2.0; + var newOrientation = Quat.fromPitchYawRollRadians(pitchInRadians, yawRads, rollInRadians); + properties.rotation = newOrientation; + } + + // Use a cosine wave offset to make it look like its flapping. + var offset = Math.cos(nowTimeInSeconds * BUTTERFLY_FLAP_SPEED) * (properties.radius); + properties.position.y = properties.position.y + (offset - butterflies[i].previousFlapOffset); + // Change position relative to previous offset. + butterflies[i].previousFlapOffset = offset; + Entities.editEntity(entityID, properties); + } + } +} + +// register the call back so it fires before each data send +Script.update.connect(updateButterflies); + +// Delete our little friends if script is stopped +Script.scriptEnding.connect(function() { + for (var i = 0; i < numButterflies; i++) { + Entities.deleteEntity(butterflies[i].entityID); + } +}); \ No newline at end of file diff --git a/examples/headMove.js b/examples/headMove.js index 704557b6e7..f2ff3e82a6 100644 --- a/examples/headMove.js +++ b/examples/headMove.js @@ -20,41 +20,104 @@ var HEAD_MOVE_DEAD_ZONE = 0.0; var HEAD_STRAFE_DEAD_ZONE = 0.0; var HEAD_ROTATE_DEAD_ZONE = 0.0; var HEAD_THRUST_FWD_SCALE = 12000.0; -var HEAD_THRUST_STRAFE_SCALE = 1000.0; -var HEAD_YAW_RATE = 2.0; +var HEAD_THRUST_STRAFE_SCALE = 2000.0; +var HEAD_YAW_RATE = 1.0; var HEAD_PITCH_RATE = 1.0; var HEAD_ROLL_THRUST_SCALE = 75.0; var HEAD_PITCH_LIFT_THRUST = 3.0; +var WALL_BOUNCE = 4000.0; + +// If these values are set to something +var maxVelocity = 1.25; +var noFly = true; + +//var roomLimits = { xMin: 618, xMax: 635.5, zMin: 528, zMax: 552.5 }; +var roomLimits = { xMin: -1, xMax: 0, zMin: 0, zMax: 0 }; + +function isInRoom(position) { + var BUFFER = 2.0; + if (roomLimits.xMin < 0) { + return false; + } + if ((position.x > (roomLimits.xMin - BUFFER)) && + (position.x < (roomLimits.xMax + BUFFER)) && + (position.z > (roomLimits.zMin - BUFFER)) && + (position.z < (roomLimits.zMax + BUFFER))) + { + return true; + } else { + return false; + } +} function moveWithHead(deltaTime) { + var thrust = { x: 0, y: 0, z: 0 }; + var position = MyAvatar.position; if (movingWithHead) { var deltaYaw = MyAvatar.getHeadFinalYaw() - headStartYaw; var deltaPitch = MyAvatar.getHeadDeltaPitch() - headStartDeltaPitch; - + var deltaRoll = MyAvatar.getHeadFinalRoll() - headStartRoll; + var velocity = MyAvatar.getVelocity(); var bodyLocalCurrentHeadVector = Vec3.subtract(MyAvatar.getHeadPosition(), MyAvatar.position); bodyLocalCurrentHeadVector = Vec3.multiplyQbyV(Quat.angleAxis(-deltaYaw, {x:0, y: 1, z:0}), bodyLocalCurrentHeadVector); var headDelta = Vec3.subtract(bodyLocalCurrentHeadVector, headStartPosition); headDelta = Vec3.multiplyQbyV(Quat.inverse(Camera.getOrientation()), headDelta); headDelta.y = 0.0; // Don't respond to any of the vertical component of head motion + var forward = Quat.getFront(Camera.getOrientation()); + var right = Quat.getRight(Camera.getOrientation()); + var up = Quat.getUp(Camera.getOrientation()); + if (noFly) { + forward.y = 0.0; + forward = Vec3.normalize(forward); + right.y = 0.0; + right = Vec3.normalize(right); + up = { x: 0, y: 1, z: 0}; + } + // Thrust based on leaning forward and side-to-side if (Math.abs(headDelta.z) > HEAD_MOVE_DEAD_ZONE) { - MyAvatar.addThrust(Vec3.multiply(Quat.getFront(Camera.getOrientation()), -headDelta.z * HEAD_THRUST_FWD_SCALE * deltaTime)); + if (Math.abs(Vec3.dot(velocity, forward)) < maxVelocity) { + thrust = Vec3.sum(thrust, Vec3.multiply(forward, -headDelta.z * HEAD_THRUST_FWD_SCALE * deltaTime)); + } } if (Math.abs(headDelta.x) > HEAD_STRAFE_DEAD_ZONE) { - MyAvatar.addThrust(Vec3.multiply(Quat.getRight(Camera.getOrientation()), headDelta.x * HEAD_THRUST_STRAFE_SCALE * deltaTime)); + if (Math.abs(Vec3.dot(velocity, right)) < maxVelocity) { + thrust = Vec3.sum(thrust, Vec3.multiply(right, headDelta.x * HEAD_THRUST_STRAFE_SCALE * deltaTime)); + } } if (Math.abs(deltaYaw) > HEAD_ROTATE_DEAD_ZONE) { - var orientation = Quat.multiply(Quat.angleAxis(deltaYaw * HEAD_YAW_RATE * deltaTime, {x:0, y: 1, z:0}), MyAvatar.orientation); + var orientation = Quat.multiply(Quat.angleAxis((deltaYaw + deltaRoll) * HEAD_YAW_RATE * deltaTime, {x:0, y: 1, z:0}), MyAvatar.orientation); MyAvatar.orientation = orientation; } // Thrust Up/Down based on head pitch - MyAvatar.addThrust(Vec3.multiply({ x:0, y:1, z:0 }, (MyAvatar.getHeadFinalPitch() - headStartFinalPitch) * HEAD_PITCH_LIFT_THRUST * deltaTime)); + if (!noFly) { + if ((Math.abs(Vec3.dot(velocity, up)) < maxVelocity)) { + thrust = Vec3.sum(thrust, Vec3.multiply({ x:0, y:1, z:0 }, (MyAvatar.getHeadFinalPitch() - headStartFinalPitch) * HEAD_PITCH_LIFT_THRUST * deltaTime)); + } + } // For head trackers, adjust pitch by head pitch MyAvatar.headPitch += deltaPitch * HEAD_PITCH_RATE * deltaTime; - // Thrust strafe based on roll ange - MyAvatar.addThrust(Vec3.multiply(Quat.getRight(Camera.getOrientation()), -(MyAvatar.getHeadFinalRoll() - headStartRoll) * HEAD_ROLL_THRUST_SCALE * deltaTime)); + } + if (isInRoom(position)) { + //print("In room!"); + // Impose constraints to keep you in the space + if (position.x < roomLimits.xMin) { + thrust.x += (roomLimits.xMin - position.x) * WALL_BOUNCE * deltaTime; + } else if (position.x > roomLimits.xMax) { + thrust.x += (roomLimits.xMax - position.x) * WALL_BOUNCE * deltaTime; + } + if (position.z < roomLimits.zMin) { + thrust.z += (roomLimits.zMin - position.z) * WALL_BOUNCE * deltaTime; + } else if (position.z > roomLimits.zMax) { + thrust.z += (roomLimits.zMax - position.z) * WALL_BOUNCE * deltaTime; + } + } + + // Check against movement box limits + + MyAvatar.addThrust(thrust); } Controller.keyPressEvent.connect(function(event) { diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 9086312bac..9427ec0525 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -644,6 +644,8 @@ void Audio::handleAudioInput() { _dcOffset = DC_OFFSET_AVERAGING * _dcOffset + (1.0f - DC_OFFSET_AVERAGING) * measuredDcOffset; } + _lastInputLoudness = fabs(loudness / NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL); + // If Noise Gate is enabled, check and turn the gate on and off if (!_audioSourceInjectEnabled && _noiseGateEnabled) { float averageOfAllSampleFrames = 0.0f; diff --git a/interface/src/entities/RenderableBoxEntityItem.cpp b/interface/src/entities/RenderableBoxEntityItem.cpp index 673f41574e..c5843bb31a 100644 --- a/interface/src/entities/RenderableBoxEntityItem.cpp +++ b/interface/src/entities/RenderableBoxEntityItem.cpp @@ -37,7 +37,7 @@ void RenderableBoxEntityItem::render(RenderArgs* args) { glm::quat rotation = getRotation(); - const bool useGlutCube = false; + const bool useGlutCube = true; if (useGlutCube) { glColor3ub(getColor()[RED_INDEX], getColor()[GREEN_INDEX], getColor()[BLUE_INDEX]);