overte-HifiExperiments/examples/toyball.js
2014-01-22 09:18:01 -08:00

283 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// toyball.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 toy ball catch and throw game.
// It reads the controller, watches for button presses and 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.
//
//
// maybe we should make these constants...
var LEFT_PALM = 0;
var LEFT_TIP = 1;
var LEFT_BUTTON_FWD = 5;
var LEFT_BUTTON_3 = 3;
var RIGHT_PALM = 2;
var RIGHT_TIP = 3;
var RIGHT_BUTTON_FWD = 11;
var RIGHT_BUTTON_3 = 9;
var leftBallAlreadyInHand = false;
var rightBallAlreadyInHand = false;
var leftHandParticle;
var rightHandParticle;
var throwSound = 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");
function getBallHoldPosition(leftHand) {
var normal;
var tipPosition;
if (leftHand) {
normal = Controller.getSpatialControlNormal(LEFT_PALM);
tipPosition = Controller.getSpatialControlPosition(LEFT_TIP);
} else {
normal = Controller.getSpatialControlNormal(RIGHT_PALM);
tipPosition = Controller.getSpatialControlPosition(RIGHT_TIP);
}
var BALL_FORWARD_OFFSET = 0.08; // put the ball a bit forward of fingers
position = { x: BALL_FORWARD_OFFSET * normal.x,
y: BALL_FORWARD_OFFSET * normal.y,
z: BALL_FORWARD_OFFSET * normal.z };
position.x += tipPosition.x;
position.y += tipPosition.y;
position.z += tipPosition.z;
return position;
}
var wantDebugging = false;
function debugPrint(message) {
if (wantDebugging) {
print(message);
}
}
function checkController() {
var numberOfButtons = Controller.getNumberOfButtons();
var numberOfTriggers = Controller.getNumberOfTriggers();
var numberOfSpatialControls = Controller.getNumberOfSpatialControls();
var controllersPerTrigger = numberOfSpatialControls / numberOfTriggers;
// this is expected for hydras
if (!(numberOfButtons==12 && numberOfTriggers == 2 && controllersPerTrigger == 2)) {
debugPrint("no hydra connected?");
return; // bail if no hydra
}
var leftGrabButtonPressed = (Controller.isButtonPressed(LEFT_BUTTON_FWD) || Controller.isButtonPressed(LEFT_BUTTON_3));
var rightGrabButtonPressed = (Controller.isButtonPressed(RIGHT_BUTTON_FWD) || Controller.isButtonPressed(RIGHT_BUTTON_3));
var leftPalmPosition = Controller.getSpatialControlPosition(LEFT_PALM);
var rightPalmPosition = Controller.getSpatialControlPosition(RIGHT_PALM);
var targetRadius = 3.0;
var exitEarly = false;
// If I don't currently have a ball in my left hand, then try to catch closest one
if (!leftBallAlreadyInHand && leftGrabButtonPressed) {
var closestParticle = Particles.findClosestParticle(leftPalmPosition, targetRadius);
if (closestParticle.isKnownID) {
debugPrint("LEFT HAND- CAUGHT SOMETHING!!");
leftBallAlreadyInHand = true;
leftHandParticle = closestParticle;
var ballPosition = getBallHoldPosition(true);
var properties = { position: { x: ballPosition.x / TREE_SCALE,
y: ballPosition.y / TREE_SCALE,
z: ballPosition.z / TREE_SCALE },
velocity : { x: 0, y: 0, z: 0}, inHand: true };
Particles.editParticle(leftHandParticle, properties);
var options = new AudioInjectionOptions();
options.position = ballPosition;
options.volume = 1.0;
Audio.playSound(catchSound, options);
exitEarly = true;
}
}
// If I don't currently have a ball in my right hand, then try to catch closest one
if (!rightBallAlreadyInHand && rightGrabButtonPressed) {
var closestParticle = Particles.findClosestParticle(rightPalmPosition, targetRadius);
if (closestParticle.isKnownID) {
debugPrint("RIGHT HAND- CAUGHT SOMETHING!!");
rightBallAlreadyInHand = true;
rightHandParticle = closestParticle;
var ballPosition = getBallHoldPosition(false); // false == right hand
var properties = { position: { x: ballPosition.x / TREE_SCALE,
y: ballPosition.y / TREE_SCALE,
z: ballPosition.z / TREE_SCALE },
velocity : { x: 0, y: 0, z: 0}, inHand: true };
Particles.editParticle(rightHandParticle, properties);
var options = new AudioInjectionOptions();
options.position = ballPosition;
options.volume = 1.0;
Audio.playSound(catchSound, options);
exitEarly = true;
}
}
// If we did one of the actions above, then exit now
if (exitEarly) {
debugPrint("exiting early - caught something");
return;
}
// change ball color logic...
//
//if (wasButtonJustPressed()) {
// rotateColor();
//}
// LEFT HAND -- If '3' is pressed, and not holding a ball, make a new one
if (Controller.isButtonPressed(LEFT_BUTTON_3) && !leftBallAlreadyInHand) {
leftBallAlreadyInHand = true;
var ballPosition = getBallHoldPosition(true); // true == left hand
var properties = { position: { x: ballPosition.x / TREE_SCALE,
y: ballPosition.y / TREE_SCALE,
z: ballPosition.z / TREE_SCALE },
velocity: { x: 0, y: 0, z: 0},
gravity: { x: 0, y: 0, z: 0},
inHand: true,
radius: 0.05 / TREE_SCALE,
color: { red: 255, green: 0, blue: 0 },
lifetime: 30
};
leftHandParticle = Particles.addParticle(properties);
// Play a new ball sound
var options = new AudioInjectionOptions();
options.position = ballPosition;
options.volume = 1.0;
Audio.playSound(catchSound, options);
exitEarly = true;
}
// RIGHT HAND -- If '3' is pressed, and not holding a ball, make a new one
if (Controller.isButtonPressed(RIGHT_BUTTON_3) && !rightBallAlreadyInHand) {
rightBallAlreadyInHand = true;
var ballPosition = getBallHoldPosition(false); // false == right hand
var properties = { position: { x: ballPosition.x / TREE_SCALE,
y: ballPosition.y / TREE_SCALE,
z: ballPosition.z / TREE_SCALE },
velocity: { x: 0, y: 0, z: 0},
gravity: { x: 0, y: 0, z: 0},
inHand: true,
radius: 0.05 / TREE_SCALE,
color: { red: 255, green: 255, blue: 0 },
lifetime: 30
};
rightHandParticle = Particles.addParticle(properties);
// Play a new ball sound
var options = new AudioInjectionOptions();
options.position = ballPosition;
options.volume = 1.0;
Audio.playSound(catchSound, options);
exitEarly = true;
}
// If we did one of the actions above, then exit now
if (exitEarly) {
debugPrint("exiting early - ball created");
return;
}
if (leftBallAlreadyInHand) {
// If holding the ball keep it in the palm
if (leftGrabButtonPressed) {
debugPrint(">>>>> LEFT-BALL IN HAND, grabbing, hold and move");
var ballPosition = getBallHoldPosition(true); // true == left hand
var properties = { position: { x: ballPosition.x / TREE_SCALE,
y: ballPosition.y / TREE_SCALE,
z: ballPosition.z / TREE_SCALE },
};
Particles.editParticle(leftHandParticle, properties);
} else {
debugPrint(">>>>> LEFT-BALL IN HAND, not grabbing, THROW!!!");
// If toy ball just released, add velocity to it!
var tipVelocity = Controller.getSpatialControlVelocity(LEFT_TIP);
var THROWN_VELOCITY_SCALING = 1.5;
var properties = {
velocity: { x: (tipVelocity.x * THROWN_VELOCITY_SCALING) / TREE_SCALE,
y: (tipVelocity.y * THROWN_VELOCITY_SCALING) / TREE_SCALE,
z: (tipVelocity.z * THROWN_VELOCITY_SCALING) / TREE_SCALE } ,
inHand: false,
gravity: { x: 0, y: -2 / TREE_SCALE, z: 0},
};
Particles.editParticle(leftHandParticle, properties);
leftBallAlreadyInHand = false;
leftHandParticle = false;
var options = new AudioInjectionOptions();
options.position = ballPosition;
options.volume = 1.0;
Audio.playSound(throwSound, options);
}
}
if (rightBallAlreadyInHand) {
// If holding the ball keep it in the palm
if (rightGrabButtonPressed) {
debugPrint(">>>>> RIGHT-BALL IN HAND, grabbing, hold and move");
var ballPosition = getBallHoldPosition(false); // false == right hand
var properties = { position: { x: ballPosition.x / TREE_SCALE,
y: ballPosition.y / TREE_SCALE,
z: ballPosition.z / TREE_SCALE },
};
Particles.editParticle(rightHandParticle, properties);
} else {
debugPrint(">>>>> RIGHT-BALL IN HAND, not grabbing, THROW!!!");
// If toy ball just released, add velocity to it!
var tipVelocity = Controller.getSpatialControlVelocity(RIGHT_TIP);
var THROWN_VELOCITY_SCALING = 1.5;
var properties = {
velocity: { x: (tipVelocity.x * THROWN_VELOCITY_SCALING) / TREE_SCALE,
y: (tipVelocity.y * THROWN_VELOCITY_SCALING) / TREE_SCALE,
z: (tipVelocity.z * THROWN_VELOCITY_SCALING) / TREE_SCALE } ,
inHand: false,
gravity: { x: 0, y: -2 / TREE_SCALE, z: 0},
};
Particles.editParticle(rightHandParticle, properties);
rightBallAlreadyInHand = false;
rightHandParticle = false;
var options = new AudioInjectionOptions();
options.position = ballPosition;
options.volume = 1.0;
Audio.playSound(throwSound, options);
}
}
}
// register the call back so it fires before each data send
Agent.willSendVisualDataCallback.connect(checkController);