Skip to content

Instantly share code, notes, and snippets.

@thoys
Created May 2, 2014 21:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thoys/94bf1991202441434060 to your computer and use it in GitHub Desktop.
Save thoys/94bf1991202441434060 to your computer and use it in GitHub Desktop.
function length(v) {
return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
}
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
function getModelHoldPosition(whichSide) {
var normal;
var tipPosition;
if (whichSide == LEFT_PALM) {
normal = Controller.getSpatialControlNormal(LEFT_PALM);
tipPosition = Controller.getSpatialControlPosition(LEFT_TIP);
} else {
normal = Controller.getSpatialControlNormal(RIGHT_PALM);
tipPosition = Controller.getSpatialControlPosition(RIGHT_TIP);
}
var MODEL_FORWARD_OFFSET = 0.00; // put the model a bit forward of fingers
position = { x: MODEL_FORWARD_OFFSET * normal.x,
y: MODEL_FORWARD_OFFSET * normal.y,
z: MODEL_FORWARD_OFFSET * normal.z };
position.x += tipPosition.x;
position.y += tipPosition.y;
position.z += tipPosition.z;
return position;
}
function printVector(v) {
print(v.x + ", " + v.y + ", " + v.z + "\n");
}
function vMinus(a, b) {
var rval = { x: a.x - b.x, y: a.y - b.y, z: a.z - b.z };
return rval;
}
// First, load two percussion sounds to be used on the sticks
var drum1 = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/MusicalInstruments/shaker.raw");
var drum2 = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/MusicalInstruments/shaker.raw");
var pitch = 0.0;
var yaw = 0.0;
var roll = -50.0;
var rotation = Quat.fromPitchYawRollDegrees(pitch, yaw, roll)
var originalProperties = {
position: { x: MyAvatar.position.x,
y: MyAvatar.position.y,
z: MyAvatar.position.z },
radius : 0.1,
color: { red: 0,
green: 255,
blue: 0 },
modelURL: "http://blog.maximillianmerlin.com/models/SingleShaker.fbx",
modelRotation: rotation
};
var shaker1 = Models.addModel(originalProperties);
var shaker2 = Models.addModel(originalProperties);
// State Machine:
// 0 = not triggered
// 1 = triggered, waiting to stop to play sound
var state = new Array();
state[0] = 0;
state[1] = 0;
var strokeSpeed = new Array();
strokeSpeed[0] = 0.0;
strokeSpeed[1] = 0.0;
function checkSticks(deltaTime) {
Models.editModel(shaker1, {
position: getModelHoldPosition(LEFT_PALM)
});
Models.editModel(shaker2, {
position: getModelHoldPosition(RIGHT_PALM)
});
for (var palm = 0; palm < 2; palm++) {
var palmVelocity = Controller.getSpatialControlVelocity(palm * 2 + 1);
var speed = length(palmVelocity);
const TRIGGER_SPEED = 0.30; // Lower this value to let you 'drum' more gently
const STOP_SPEED = 0.01; // Speed below which a sound will trigger
const GAIN = 0.5; // Loudness compared to stick velocity
const AVERAGING = 0.2; // How far back to sample trailing velocity
// Measure trailing average stroke speed to ultimately set volume
strokeSpeed[palm] = (1.0 - AVERAGING) * strokeSpeed[palm] + AVERAGING * (speed * GAIN);
if (state[palm] == 0) {
// Waiting for downward speed to indicate stroke
if ((palmVelocity.y < 0.0) && (strokeSpeed[palm] > TRIGGER_SPEED)) {
state[palm] = 1;
}
} else if (state[palm] == 1) {
// Waiting for change in velocity direction or slowing to trigger drum sound
if ((palmVelocity.y > 0.0) || (speed < STOP_SPEED)) {
state[palm] = 0;
var options = new AudioInjectionOptions();
options.position = Controller.getSpatialControlPosition(palm * 2 + 1);
if (strokeSpeed[palm] > 1.0) { strokeSpeed[palm] = 1.0; }
options.volume = strokeSpeed[palm];
//print(newProperties);
if (palm == 0) {
Audio.playSound(drum1, options);
} else {
Audio.playSound(drum2, options);
}
}
}
}
}
// Connect a call back that happens every frame
Script.update.connect(checkSticks);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment