mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-05-08 22:48:20 +02:00
283 lines
11 KiB
JavaScript
283 lines
11 KiB
JavaScript
//
|
||
// 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);
|