mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:24:00 +02:00
Merge pull request #9231 from PhilipRosedale/ambisonic
Entity script for ambisonic sound emitter
This commit is contained in:
commit
14445c37fe
1 changed files with 130 additions and 0 deletions
130
scripts/tutorials/entity_scripts/ambientSound.js
Normal file
130
scripts/tutorials/entity_scripts/ambientSound.js
Normal file
|
@ -0,0 +1,130 @@
|
|||
// 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)
|
||||
//
|
||||
// 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 entity;
|
||||
var ambientSound;
|
||||
var center;
|
||||
var soundPlaying = false;
|
||||
var checkTimer = false;
|
||||
var _this;
|
||||
|
||||
var WANT_COLOR_CHANGE = true;
|
||||
var COLOR_OFF = { red: 128, green: 128, blue: 128 };
|
||||
var COLOR_ON = { red: 255, green: 0, blue: 0 };
|
||||
|
||||
var WANT_DEBUG = true;
|
||||
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 props = Entities.getEntityProperties(entity);
|
||||
var HYSTERESIS_FRACTION = 0.1;
|
||||
var props = Entities.getEntityProperties(entity, [ "position" ]);
|
||||
center = props.position;
|
||||
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, 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 } );
|
||||
}
|
||||
} 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();
|
||||
}
|
||||
};
|
||||
|
||||
})
|
Loading…
Reference in a new issue