design notes from meeting: ambient sound
This was SVN commit r3336.
This commit is contained in:
parent
7720378f6c
commit
c600e0a3e0
85
source/sound/ambient_design.txt
Normal file
85
source/sound/ambient_design.txt
Normal file
@ -0,0 +1,85 @@
|
||||
PLAYING AMBIENT SOUND WHEN CAMERA IS OVER BUILDING
|
||||
==================================================
|
||||
|
||||
data flow:
|
||||
C++ JS
|
||||
> list of visible entities (1)
|
||||
< list of sound requests and their weights
|
||||
list of changed sounds
|
||||
|
||||
C++ code generates list of entities on screen
|
||||
rationale: done in C++ for performance and to avoid having to expose the "patch" subdivision scheme to JS.
|
||||
UPDATE: this is much thornier than expected.
|
||||
1) we only want stuff that is visible to be played. hearing things off screen would be distressing and weird
|
||||
2) don't play sound for buildings in FoW, to prevent "audio spying"
|
||||
most straightforward way is simply scan all entities; if building, check against visible frustum.
|
||||
if inside AND within 3d distance cutoff of viewer pos, add to visible_building
|
||||
optimization for later: get all patches within 3d distance cutoff; discard all not within frustum; only test
|
||||
entities within those remaining patches.
|
||||
pass that to JS decideWhatToPlay
|
||||
it returns list of sounds it wants playing
|
||||
format: see AmbientSoundReq below
|
||||
C++ sound engine compares its list of currently sounds;
|
||||
fades out those no longer wanted and starts new ones immediately
|
||||
|
||||
|
||||
new entity properties needed:
|
||||
-----------------------------
|
||||
- ambientGroup: a soundGroup of several sounds; one is picked at random to be played (see below)
|
||||
- priority: to determine which entity should trump the others in a crowded city.
|
||||
|
||||
|
||||
// weight is so that we can play several ambient sounds at a time, but ones for buildings at edge of screen are quieter
|
||||
// values: 0..1; probably calculated from distance to camera
|
||||
type AmbientSoundReq = (SoundGroupString, weight)
|
||||
|
||||
// (suggestion only; may be revised if too much cacophony/constant sound results)
|
||||
JS_decideWhatToPlay(in HEntity visible_ents[], out AmbientSoundReq desired_ambient_sounds[])
|
||||
{
|
||||
// * "important" means the building is at center of attention and should mostly override the other sounds.
|
||||
// this is complicated as well. the camera may have any orientation, especially in cinematic mode;
|
||||
// that means we can't just rely on casting a ray from viewer through middle screen pixel to terrain.
|
||||
// our building list already covers only the visible ones, so we can use 3d distance from viewer
|
||||
// (without worrying about including buildings behind us i.e. out of sight).
|
||||
// important := fairly small distance (covers the case where users zoom really close to a building) OR
|
||||
// building is close to center of screen (as determined via ray cast method; skip this if the camera
|
||||
// is weird, i.e. looking above the horizon, in which case the ray cast would fail).
|
||||
// note: not playing sounds when looking down vertically at the town but zoomed out very far is ok (desirable even).
|
||||
if an entity is important(*)
|
||||
desired_ambient_sounds[i++] = ent.ambientGroup
|
||||
|
||||
forall ambient types (farm, dock etc.) in decreasing order of priority
|
||||
stop if >= 3 sounds in list
|
||||
if enough buildings on screen
|
||||
desired_ambient_sounds[i++] = ent.ambientGroup
|
||||
|
||||
maybe add some random variation to spice things up? (i.e. also play some other building sounds;
|
||||
don't always have one building override the others)
|
||||
}
|
||||
|
||||
|
||||
C++ code keeps a list of all active sounds:
|
||||
type ActiveSound = (Handle, SoundGroupString)
|
||||
ActiveSound active_sound_list[]
|
||||
|
||||
Handle startPlayingAmbient(soundGroup, weight)
|
||||
{
|
||||
filename = soundGroup.pickRandom()
|
||||
return snd_play(filename, globalAmbientVolume*soundGroup.volume*weight)
|
||||
}
|
||||
|
||||
updateAmbientSounds(desired_ambient_sounds)
|
||||
{
|
||||
for all in desired_ambient_sounds but not active_sound_list:
|
||||
handle = startPlayingAmbient(amb.group, amb.weight)
|
||||
active_sound_list[i++] = (handle, amb.group)
|
||||
|
||||
for all in active_sound_list but not desired_ambient_sounds:
|
||||
snd_fade(OUT, active.handle)
|
||||
}
|
||||
|
||||
|
||||
|
||||
RANDOMIZED SOUNDS
|
||||
==================================================
|
||||
(needed for ambient and normal battle sounds)
|
Loading…
Reference in New Issue
Block a user