mirror of
https://github.com/overte-org/overte.git
synced 2025-04-26 12:16:18 +02:00
138 lines
5.6 KiB
JavaScript
138 lines
5.6 KiB
JavaScript
// ambientSound.js
|
|
//
|
|
// This entity script will allow you to create an ambient sound that loops when a person is within a given
|
|
// range of this entity. Great way to add one or more ambisonic soundfields to your environment.
|
|
//
|
|
// In the userData section for the entity, add/edit three values:
|
|
// userData.soundURL should be a string giving the URL to the sound file. Defaults to 100 meters if not set.
|
|
// userData.range should be an integer for the max distance away from the entity where the sound will be audible.
|
|
// userData.volume is the max volume at which the clip should play. Defaults to 1.0 full volume)
|
|
//
|
|
// The rotation of the entity is copied to the ambisonic field, so by rotating the entity you will rotate the
|
|
// direction in-which a certain sound comes from.
|
|
//
|
|
// Remember that the entity has to be visible to the user for the sound to play at all, so make sure the entity is
|
|
// large enough to be loaded at the range you set, particularly for large ranges.
|
|
//
|
|
// Copyright 2016 High Fidelity, Inc.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
(function(){
|
|
// This sample clip and range will be used if you don't add userData to the entity (see above)
|
|
var DEFAULT_RANGE = 100;
|
|
var DEFAULT_URL = "http://hifi-content.s3.amazonaws.com/ken/samples/forest_ambiX.wav";
|
|
var DEFAULT_VOLUME = 1.0;
|
|
|
|
var soundURL = "";
|
|
var range = DEFAULT_RANGE;
|
|
var maxVolume = DEFAULT_VOLUME;
|
|
var UPDATE_INTERVAL_MSECS = 100;
|
|
var rotation;
|
|
|
|
var entity;
|
|
var ambientSound;
|
|
var center;
|
|
var soundPlaying = false;
|
|
var checkTimer = false;
|
|
var _this;
|
|
|
|
var WANT_COLOR_CHANGE = false;
|
|
var COLOR_OFF = { red: 128, green: 128, blue: 128 };
|
|
var COLOR_ON = { red: 255, green: 0, blue: 0 };
|
|
|
|
var WANT_DEBUG = false;
|
|
function debugPrint(string) {
|
|
if (WANT_DEBUG) {
|
|
print(string);
|
|
}
|
|
}
|
|
|
|
this.updateSettings = function() {
|
|
// Check user data on the entity for any changes
|
|
var oldSoundURL = soundURL;
|
|
var props = Entities.getEntityProperties(entity, [ "userData" ]);
|
|
if (props.userData) {
|
|
var data = JSON.parse(props.userData);
|
|
if (data.soundURL && !(soundURL === data.soundURL)) {
|
|
soundURL = data.soundURL;
|
|
debugPrint("Read ambient sound URL: " + soundURL);
|
|
} else if (!data.soundURL) {
|
|
soundURL = DEFAULT_URL;
|
|
}
|
|
if (data.range && !(range === data.range)) {
|
|
range = data.range;
|
|
debugPrint("Read ambient sound range: " + range);
|
|
}
|
|
if (data.volume && !(maxVolume === data.volume)) {
|
|
maxVolume = data.volume;
|
|
debugPrint("Read ambient sound volume: " + maxVolume);
|
|
}
|
|
}
|
|
if (!(soundURL === oldSoundURL) || (soundURL === "")) {
|
|
debugPrint("Loading ambient sound into cache");
|
|
ambientSound = SoundCache.getSound(soundURL);
|
|
if (soundPlaying && soundPlaying.playing) {
|
|
soundPlaying.stop();
|
|
soundPlaying = false;
|
|
if (WANT_COLOR_CHANGE) {
|
|
Entities.editEntity(entity, { color: COLOR_OFF });
|
|
}
|
|
debugPrint("Restarting ambient sound");
|
|
}
|
|
}
|
|
}
|
|
|
|
this.preload = function(entityID) {
|
|
// Load the sound and range from the entity userData fields, and note the position of the entity.
|
|
debugPrint("Ambient sound preload");
|
|
entity = entityID;
|
|
_this = this;
|
|
checkTimer = Script.setInterval(this.maybeUpdate, UPDATE_INTERVAL_MSECS);
|
|
};
|
|
|
|
this.maybeUpdate = function() {
|
|
// Every UPDATE_INTERVAL_MSECS, update the volume of the ambient sound based on distance from my avatar
|
|
_this.updateSettings();
|
|
var HYSTERESIS_FRACTION = 0.1;
|
|
var props = Entities.getEntityProperties(entity, [ "position", "rotation" ]);
|
|
center = props.position;
|
|
rotation = props.rotation;
|
|
var distance = Vec3.length(Vec3.subtract(MyAvatar.position, center));
|
|
if (distance <= range) {
|
|
var volume = (1.0 - distance / range) * maxVolume;
|
|
if (!soundPlaying && ambientSound.downloaded) {
|
|
soundPlaying = Audio.playSound(ambientSound, { loop: true,
|
|
localOnly: true,
|
|
orientation: rotation,
|
|
volume: volume });
|
|
debugPrint("Starting ambient sound, volume: " + volume);
|
|
if (WANT_COLOR_CHANGE) {
|
|
Entities.editEntity(entity, { color: COLOR_ON });
|
|
}
|
|
|
|
} else if (soundPlaying && soundPlaying.playing) {
|
|
soundPlaying.setOptions( { volume: volume, orientation: rotation } );
|
|
}
|
|
|
|
} else if (soundPlaying && soundPlaying.playing && (distance > range * HYSTERESIS_FRACTION)) {
|
|
soundPlaying.stop();
|
|
soundPlaying = false;
|
|
Entities.editEntity(entity, { color: { red: 128, green: 128, blue: 128 }});
|
|
debugPrint("Out of range, stopping ambient sound");
|
|
}
|
|
}
|
|
|
|
this.unload = function(entityID) {
|
|
debugPrint("Ambient sound unload");
|
|
if (checkTimer) {
|
|
Script.clearInterval(checkTimer);
|
|
}
|
|
if (soundPlaying && soundPlaying.playing) {
|
|
soundPlaying.stop();
|
|
}
|
|
};
|
|
|
|
})
|