mirror of
https://github.com/overte-org/overte.git
synced 2025-04-25 20:16:16 +02:00
164 lines
6.1 KiB
JavaScript
164 lines
6.1 KiB
JavaScript
//
|
||
// voxelDrumming.js
|
||
// hifi
|
||
//
|
||
// Created by Brad Hefta-Gaub on 2/14/14.
|
||
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
|
||
//
|
||
// This is an example script that demonstrates use of the Overlays, Controller, and Audio classes
|
||
//
|
||
// It adds Hydra controller "fingertip on voxels" drumming
|
||
//
|
||
|
||
Menu.addMenuItem({
|
||
menuName: "Developer > Hand Options",
|
||
menuItemName: "Voxel Drumming",
|
||
isCheckable: true,
|
||
isChecked: false
|
||
});
|
||
|
||
var collisionCenter = new Array();
|
||
collisionCenter[0] = { x: 0, y: 0, z: 0};
|
||
collisionCenter[1] = { x: 0, y: 0, z: 0};
|
||
|
||
var collisionAge = new Array();
|
||
collisionAge[0] = 0;
|
||
collisionAge[1] = 0;
|
||
|
||
var collisionDuration = new Array();
|
||
collisionDuration[0] = 0;
|
||
collisionDuration[1] = 0;
|
||
|
||
var isColliding = new Array();
|
||
isColliding[0] = false;
|
||
isColliding[1] = false;
|
||
|
||
var highlightVoxel = Overlays.addOverlay("cube",
|
||
{
|
||
position: { x: 0, y: 0, z: 0},
|
||
size: 0,
|
||
color: { red: 0, green: 0, blue: 0 },
|
||
visible: false,
|
||
lineWidth: 3,
|
||
solid: false
|
||
});
|
||
|
||
var collisionBubble = new Array();
|
||
collisionBubble[0] = Overlays.addOverlay("sphere",
|
||
{
|
||
position: { x: 0, y: 0, z: 0},
|
||
size: 0,
|
||
color: { red: 0, green: 0, blue: 0 },
|
||
alpha: 0.5,
|
||
visible: false
|
||
});
|
||
collisionBubble[1] = Overlays.addOverlay("sphere",
|
||
{
|
||
position: { x: 0, y: 0, z: 0},
|
||
size: 0,
|
||
color: { red: 0, green: 0, blue: 0 },
|
||
alpha: 0.5,
|
||
visible: false
|
||
});
|
||
|
||
var audioOptions = new AudioInjectionOptions();
|
||
audioOptions.position = { x: MyAvatar.position.x, y: MyAvatar.position.y + 1, z: MyAvatar.position.z };
|
||
audioOptions.volume = 1;
|
||
|
||
|
||
function clamp(valueToClamp, minValue, maxValue) {
|
||
return Math.max(minValue, Math.min(maxValue, valueToClamp));
|
||
}
|
||
|
||
function produceCollisionSound(deltaTime, palm, voxelDetail) {
|
||
// Collision between finger and a voxel plays sound
|
||
|
||
var palmVelocity = Controller.getSpatialControlVelocity(palm * 2);
|
||
var speed = Vec3.length(palmVelocity);
|
||
var fingerTipPosition = Controller.getSpatialControlPosition(palm * 2 + 1);
|
||
|
||
var LOWEST_FREQUENCY = 100.0;
|
||
var HERTZ_PER_RGB = 3.0;
|
||
var DECAY_PER_SAMPLE = 0.0005;
|
||
var DURATION_MAX = 2.0;
|
||
var MIN_VOLUME = 0.1;
|
||
var volume = MIN_VOLUME + clamp(speed, 0.0, (1.0 - MIN_VOLUME));
|
||
var duration = volume;
|
||
|
||
collisionCenter[palm] = fingerTipPosition;
|
||
collisionAge[palm] = deltaTime;
|
||
collisionDuration[palm] = duration;
|
||
|
||
var voxelBrightness = voxelDetail.red + voxelDetail.green + voxelDetail.blue;
|
||
var frequency = LOWEST_FREQUENCY + (voxelBrightness * HERTZ_PER_RGB);
|
||
|
||
audioOptions.position = fingerTipPosition;
|
||
Audio.startDrumSound(volume, frequency, DURATION_MAX, DECAY_PER_SAMPLE, audioOptions);
|
||
}
|
||
|
||
function update(deltaTime) {
|
||
// Voxel Drumming with fingertips if enabled
|
||
if (Menu.isOptionChecked("Voxel Drumming")) {
|
||
|
||
for (var palm = 0; palm < 2; palm++) {
|
||
var fingerTipPosition = Controller.getSpatialControlPosition(palm * 2 + 1);
|
||
|
||
var voxel = Voxels.getVoxelEnclosingPoint(fingerTipPosition);
|
||
if (voxel.s > 0) {
|
||
if (!isColliding[palm]) {
|
||
// Collision has just started
|
||
isColliding[palm] = true;
|
||
produceCollisionSound(deltaTime, palm, voxel);
|
||
|
||
// Set highlight voxel
|
||
Overlays.editOverlay(highlightVoxel,
|
||
{
|
||
position: { x: voxel.x, y: voxel.y, z: voxel.z},
|
||
size: voxel.s + 0.002,
|
||
color: { red: voxel.red + 128, green: voxel.green + 128, blue: voxel.blue + 128 },
|
||
visible: true
|
||
});
|
||
}
|
||
} else {
|
||
if (isColliding[palm]) {
|
||
// Collision has just ended
|
||
isColliding[palm] = false;
|
||
Overlays.editOverlay(highlightVoxel, { visible: false });
|
||
}
|
||
}
|
||
|
||
if (collisionAge[palm] > 0) {
|
||
collisionAge[palm] += deltaTime;
|
||
}
|
||
|
||
// If hand/voxel collision has happened, render a little expanding sphere
|
||
if (collisionAge[palm] > 0) {
|
||
var opacity = clamp(1 - (collisionAge[palm] / collisionDuration[palm]), 0, 1);
|
||
var size = collisionAge[palm] * 0.25;
|
||
|
||
Overlays.editOverlay(collisionBubble[palm],
|
||
{
|
||
position: { x: collisionCenter[palm].x, y: collisionCenter[palm].y, z: collisionCenter[palm].z},
|
||
size: size,
|
||
color: { red: 255, green: 0, blue: 0 },
|
||
alpha: 0.5 * opacity,
|
||
visible: true
|
||
});
|
||
|
||
if (collisionAge[palm] > collisionDuration[palm]) {
|
||
collisionAge[palm] = 0;
|
||
Overlays.editOverlay(collisionBubble[palm], { visible: false });
|
||
}
|
||
}
|
||
} // palm loop
|
||
} // menu item check
|
||
}
|
||
Script.update.connect(update);
|
||
|
||
function scriptEnding() {
|
||
Overlays.deleteOverlay(highlightVoxel);
|
||
Overlays.deleteOverlay(collisionBubble[0]);
|
||
Overlays.deleteOverlay(collisionBubble[1]);
|
||
Menu.removeMenuItem("Developer > Hand Options","Voxel Drumming");
|
||
}
|
||
Script.scriptEnding.connect(scriptEnding);
|