diff --git a/examples/gun.js b/examples/gun.js index e9b1472700..c9c0d6d8da 100644 --- a/examples/gun.js +++ b/examples/gun.js @@ -51,7 +51,7 @@ function checkController() { var fingerTipController = palmController + 1; var fingerTipPosition = Controller.getSpatialControlPosition(fingerTipController); - var bulletSize = 0.25/TREE_SCALE; + var bulletSize = 0.05/TREE_SCALE; var palmInParticleSpace = { x: palmPosition.x/TREE_SCALE, @@ -73,7 +73,7 @@ function checkController() { y: tipInParticleSpace.y + palmToFingerTipVector.y/2, z: tipInParticleSpace.z + palmToFingerTipVector.z/2}; - var linearVelocity = 50; // 50 meters per second + var linearVelocity = 5; var velocity = { x: palmToFingerTipVector.x * linearVelocity, y: palmToFingerTipVector.y * linearVelocity, diff --git a/examples/movingVoxel.js b/examples/movingVoxel.js new file mode 100644 index 0000000000..44ab418aaf --- /dev/null +++ b/examples/movingVoxel.js @@ -0,0 +1,44 @@ +// +// This sample script creates a voxel moving back and forth in a line +// + +var position = { x: 0, y: 0, z: 0 }; +var oldPosition = { x: 0, y: 0, z:0 }; +var size = 0.25; +var direction = 1.0; +var range = 2.0; +var color = { r: 100, g: 50, b: 150 }; +var colorEdge = { r:255, g:250, b:175 }; +var frame = 0; +var thisColor = color; + +function moveVoxel() { + frame++; + if (frame % 3 == 0) { + // Get a new position + position.x += direction * size; + if (position.x < 0) { + direction *= -1.0; + position.x = 0; + thisColor = colorEdge; + } + if (position.x > range) { + direction *= -1.0; + position.x = range; + thisColor = colorEdge; + } + // Create a new voxel + Voxels.queueDestructiveVoxelAdd(position.x / TREE_SCALE, position.y / TREE_SCALE, position.z / TREE_SCALE, size / TREE_SCALE, thisColor.r, thisColor.g, thisColor.b); + // delete old voxel + Voxels.queueVoxelDelete(oldPosition.x / TREE_SCALE, oldPosition.y / TREE_SCALE, oldPosition.z / TREE_SCALE, size / TREE_SCALE); + // Copy old location to new + oldPosition.x = position.x; + oldPosition.y = position.y; + oldPosition.z = position.z; + thisColor = color; + } +} + +Voxels.setPacketsPerSecond(300); +// Connect a call back that happens every frame +Agent.willSendVisualDataCallback.connect(moveVoxel); \ No newline at end of file diff --git a/examples/paintGun.js b/examples/paintGun.js new file mode 100644 index 0000000000..f75df58314 --- /dev/null +++ b/examples/paintGun.js @@ -0,0 +1,112 @@ +// +// gun.js +// hifi +// +// Created by Brad Hefta-Gaub on 12/31/13. +// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// +// This is an example script that turns the hydra controllers into a particle gun. +// It reads the controller, watches for trigger pulls, and launches particles. +// The particles it creates have a script that when they collide with Voxels, the +// particle will change it's color to match the voxel it hits, and then delete the +// voxel. +// +// + +// initialize our triggers +var triggerPulled = new Array(); +var numberOfTriggers = Controller.getNumberOfTriggers(); +for (t = 0; t < numberOfTriggers; t++) { + triggerPulled[t] = false; +} + +function checkController() { + var numberOfTriggers = Controller.getNumberOfTriggers(); + var numberOfSpatialControls = Controller.getNumberOfSpatialControls(); + var controllersPerTrigger = numberOfSpatialControls / numberOfTriggers; + + // this is expected for hydras + if (numberOfTriggers == 2 && controllersPerTrigger == 2) { + for (var t = 0; t < numberOfTriggers; t++) { + var shootABullet = false; + var triggerValue = Controller.getTriggerValue(t); + + if (triggerPulled[t]) { + // must release to at least 0.1 + if (triggerValue < 0.1) { + triggerPulled[t] = false; // unpulled + } + } else { + // must pull to at least 0.9 + if (triggerValue > 0.9) { + triggerPulled[t] = true; // pulled + shootABullet = true; + } + } + + if (shootABullet) { + var palmController = t * controllersPerTrigger; + var palmPosition = Controller.getSpatialControlPosition(palmController); + + var fingerTipController = palmController + 1; + var fingerTipPosition = Controller.getSpatialControlPosition(fingerTipController); + + var bulletSize = 0.01/TREE_SCALE; + + var palmInParticleSpace = + { x: palmPosition.x/TREE_SCALE, + y: palmPosition.y/TREE_SCALE, + z: palmPosition.z/TREE_SCALE }; + + var tipInParticleSpace = + { x: fingerTipPosition.x/TREE_SCALE, + y: fingerTipPosition.y/TREE_SCALE, + z: fingerTipPosition.z/TREE_SCALE }; + + var palmToFingerTipVector = + { x: (tipInParticleSpace.x - palmInParticleSpace.x), + y: (tipInParticleSpace.y - palmInParticleSpace.y), + z: (tipInParticleSpace.z - palmInParticleSpace.z) }; + + // just off the front of the finger tip + var position = { x: tipInParticleSpace.x + palmToFingerTipVector.x/2, + y: tipInParticleSpace.y + palmToFingerTipVector.y/2, + z: tipInParticleSpace.z + palmToFingerTipVector.z/2}; + + var linearVelocity = 25; + + var velocity = { x: palmToFingerTipVector.x * linearVelocity, + y: palmToFingerTipVector.y * linearVelocity, + z: palmToFingerTipVector.z * linearVelocity }; + + var gravity = { x: 0, y: -0.1/TREE_SCALE, z: 0 }; // gravity has no effect on these bullets + var color = { red: 128, green: 128, blue: 128 }; + var damping = 0; // no damping + var inHand = false; + + // This is the script for the particles that this gun shoots. + var script = + " function collisionWithVoxel(voxel) { " + + " print('collisionWithVoxel(voxel)... '); " + + " print('myID=' + Particle.getID() + '\\n'); " + + " var voxelColor = voxel.getColor();" + + " print('voxelColor=' + voxelColor.red + ', ' + voxelColor.green + ', ' + voxelColor.blue + '\\n'); " + + " var myColor = Particle.getColor();" + + " print('myColor=' + myColor.red + ', ' + myColor.green + ', ' + myColor.blue + '\\n'); " + + " Particle.setColor(voxelColor); " + + " var voxelAt = voxel.getPosition();" + + " var voxelScale = voxel.getScale();" + + " Voxels.queueVoxelAdd(voxelAt.x, voxelAt.y, voxelAt.z, voxelScale, 255, 255, 0); " + + " print('Voxels.queueVoxelDelete(' + voxelAt.x + ', ' + voxelAt.y + ', ' + voxelAt.z + ', ' + voxelScale + ')... \\n'); " + + " } " + + " Particle.collisionWithVoxel.connect(collisionWithVoxel); "; + + Particles.queueParticleAdd(position, bulletSize, color, velocity, gravity, damping, inHand, script); + } + } + } +} + + +// register the call back so it fires before each data send +Agent.willSendVisualDataCallback.connect(checkController); diff --git a/examples/playSound.js b/examples/playSound.js index 36e8822b56..40cd80c3cb 100644 --- a/examples/playSound.js +++ b/examples/playSound.js @@ -1,5 +1,5 @@ // -// This sample script makes an occassional clapping sound at the location of your palm +// This sample script loads a sound file and plays it at the 'fingertip' of the // // First, load the clap sound from a URL @@ -11,7 +11,7 @@ function maybePlaySound() { var options = new AudioInjectionOptions();
 var palmPosition = Controller.getSpatialControlPosition(0); options.position = palmPosition; - options.volume = 0.1; + options.volume = 0.5; Audio.playSound(clap, options); } } diff --git a/examples/voxelBird.js b/examples/voxelBird.js new file mode 100644 index 0000000000..52bd06f36b --- /dev/null +++ b/examples/voxelBird.js @@ -0,0 +1,130 @@ +// +// This sample script moves a voxel around like a bird and sometimes makes tweeting noises +// + +function vLength(v) { + return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z); +} + +function printVector(v) { + print(v.x + ", " + v.y + ", " + v.z + "\n"); +} + +// 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; +} + +function vMinus(a, b) { + var rval = { x: a.x - b.x, y: a.y - b.y, z: a.z - b.z }; + return rval; +} + +function vPlus(a, b) { + var rval = { x: a.x + b.x, y: a.y + b.y, z: a.z + b.z }; + return rval; +} + +function vCopy(a, b) { + a.x = b.x; + a.y = b.y; + a.z = b.z; + return; +} + +// 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; +} + +// Decide what kind of bird we are +var tweet; +var which = Math.random(); +if (which < 1.0) { + tweet = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/bushtit_1.raw"); +} else if (which < 0.4) { + tweet = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/bushtit_2.raw"); +} else if (which < 0.6) { + tweet = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/bushtit_3.raw"); +} else { + tweet = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/mexicanWhipoorwill.raw"); +} + +var position = { x: 0, y: 0, z: 0 }; +var lastPosition = { x: 0, y: 0, z: 0 }; +var oldPosition = { x: 0, y: 0, z:0 }; +var targetPosition = { x: 0, y: 0, z: 0 }; + +var size = 0.125; +var range = 4.0; // Over what distance in meters do you want your bird to fly around +var color = { r: 100, g: 50, b: 150 }; +var colorEdge = { r:255, g:250, b:175 }; +var frame = 0; +var thisColor = color; +var moving = false; +var tweeting = 0; +var moved = true; + +var CHANCE_OF_MOVING = 0.05; +var CHANCE_OF_TWEETING = 0.05; + +function moveBird() { + frame++; + if (frame % 3 == 0) { + // Tweeting behavior + if (tweeting == 0) { + if (Math.random() < CHANCE_OF_TWEETING) { + //print("tweet!" + "\n"); + var options = new AudioInjectionOptions();
 + options.position = position; + options.volume = 0.75; + Audio.playSound(tweet, options); + tweeting = 10; + } + } else { + tweeting -= 1; + } + // Moving behavior + if (moving == false) { + if (Math.random() < CHANCE_OF_MOVING) { + targetPosition = randVector(0, range); + //printVector(position); + moving = true; + } + } + if (moving) { + position = vInterpolate(position, targetPosition, 0.5); + if (vLength(vMinus(position, targetPosition)) < (size / 2.0)) { + moved = false; + moving = false; + } else { + moved = true; + } + } + + if (tweeting > 0) { + // Change color of voxel to blinky red a bit while playing the sound + var blinkColor = { r: Math.random() * 255, g: 0, b: 0 }; + Voxels.queueDestructiveVoxelAdd(position.x / TREE_SCALE, + position.y / TREE_SCALE, + position.z / TREE_SCALE, + size / TREE_SCALE, + blinkColor.r, blinkColor.g, blinkColor.b); + } + if (moved) { + Voxels.queueDestructiveVoxelAdd(position.x / TREE_SCALE, position.y / TREE_SCALE, position.z / TREE_SCALE, size / TREE_SCALE, thisColor.r, thisColor.g, thisColor.b); + // delete old voxel + + Voxels.queueVoxelDelete(oldPosition.x / TREE_SCALE, oldPosition.y / TREE_SCALE, oldPosition.z / TREE_SCALE, size / TREE_SCALE); + // Copy old location to new + vCopy(oldPosition, position); + moved = false; + } + } +} + +Voxels.setPacketsPerSecond(10000); +// Connect a call back that happens every frame +Agent.willSendVisualDataCallback.connect(moveBird); \ No newline at end of file diff --git a/interface/src/BuckyBalls.cpp b/interface/src/BuckyBalls.cpp index e236a8ea7d..318126cc03 100644 --- a/interface/src/BuckyBalls.cpp +++ b/interface/src/BuckyBalls.cpp @@ -145,6 +145,7 @@ void BuckyBalls::simulate(float deltaTime) { } void BuckyBalls::render() { + glEnable(GL_LIGHTING); for (int i = 0; i < NUM_BBALLS; i++) { if (_bballColliding[i] > 0.f) { const float GRAB_BRIGHTEN = 1.15f;