From a6fd5d5c8bcd135d934e694b7abfb65fe08779bd Mon Sep 17 00:00:00 2001 From: DaforLynx Date: Sat, 9 Apr 2022 01:01:26 -0700 Subject: [PATCH] Some organization. Faster volume lerping. --- voxygen/src/audio/ambient.rs | 312 +++++++++++++++++------------------ voxygen/src/audio/mod.rs | 17 +- voxygen/src/scene/mod.rs | 4 - 3 files changed, 163 insertions(+), 170 deletions(-) diff --git a/voxygen/src/audio/ambient.rs b/voxygen/src/audio/ambient.rs index 437d6d2108..14aa0cf89d 100644 --- a/voxygen/src/audio/ambient.rs +++ b/voxygen/src/audio/ambient.rs @@ -23,7 +23,6 @@ pub struct AmbientCollection { tracks: Vec, } -/// Configuration for a single music track in the soundtrack #[derive(Debug, Deserialize)] pub struct AmbientItem { path: String, @@ -46,55 +45,50 @@ impl AmbientMgr { camera: &Camera, ) { let ambience_volume = audio.get_ambience_volume(); - // iterate through each tag + // Iterate through each tag for tag in AmbientChannelTag::iter() { - // check if current conditions necessitate the current tag at all - let should_create: bool = match tag { - AmbientChannelTag::Wind => self.check_wind_necessity(client, camera), - AmbientChannelTag::Rain => self.check_rain_necessity(client, camera), - AmbientChannelTag::Thunder => self.check_thunder_necessity(client), - AmbientChannelTag::Leaves => self.check_leaves_necessity(client, camera), - }; - // if the conditions warrant creating a channel of that tag - if should_create && audio.get_ambient_channel(tag).is_none() { - // iterate through the supposed number of channels - one for each tag + // If the conditions warrant creating a channel of that tag + if self.check_ambience_necessity(tag, client, camera) + && audio.get_ambient_channel(tag).is_none() + { + // Iterate through the supposed number of channels - one for each tag for index in 0..AmbientChannelTag::iter().len() { - // if index would exceed current number of channels, create a new one with + // If index would exceed current number of channels, create a new one with // current tag if index >= audio.ambient_channels.len() { audio.new_ambient_channel(tag); break; } } - // even if the conditions don't warrant the creation of a + // If the conditions don't warrant the creation of a // channel with that tag, but a channel with - // that tag remains nonetheless, run the code + // that tag remains nonetheless, run the volume code } else if audio.get_ambient_channel(tag).is_some() { for index in 0..AmbientChannelTag::iter().len() { - // update with sfx volume + // Update with sfx volume audio.ambient_channels[index].set_volume(ambience_volume); - // if current channel's tag is not the current tag, move on to next channel + // If current channel's tag is not the current tag, move on to next channel if audio.ambient_channels[index].get_tag() == tag { - // maintain: get the correct multiplier of whatever the tag of the current + // Maintain: get the correct multiplier of whatever the tag of the current // channel is let target_volume = audio.ambient_channels[index].maintain(state, client, camera); - // get multiplier of the current channel + // Get multiplier of the current channel let initial_volume = audio.ambient_channels[index].get_multiplier(); - // lerp multiplier of current channel + // Lerp multiplier of current channel audio.ambient_channels[index].set_multiplier(Lerp::lerp( initial_volume, target_volume, - 0.01, + 0.03, )); - // set the duration of the loop to whatever the current value is (0.0 by + // Set the duration of the loop to whatever the current value is (0.0 by // default) let next_track_change = audio.ambient_channels[index].get_next_track_change(); - // if the sound should loop at this point: + // If the sound should loop at this point: if audio.ambient_channels[index] .get_began_playing() .elapsed() @@ -103,92 +97,94 @@ impl AmbientMgr { { let ambience = self.ambience.read(); let track = ambience.tracks.iter().find(|track| track.tag == tag); - // set the channel's start point at this instant + // Set the channel's start point at this instant audio.ambient_channels[index].set_began_playing(Instant::now()); if let Some(track) = track { - // set loop duration to the one specified in the ron + // Set loop duration to the one specified in the ron audio.ambient_channels[index].set_next_track_change(track.length); - // play the file of the current tag at the current multiplier + // Play the file of the current tag at the current multiplier let current_multiplier = audio.ambient_channels[index].get_multiplier(); audio.play_ambient(tag, &track.path, current_multiplier); } }; - // remove channel if not playing + // Remove channel if not playing if audio.ambient_channels[index].get_multiplier() == 0.0 { audio.ambient_channels[index].stop(); audio.ambient_channels.remove(index); }; - // move on to next tag + // Move on to next tag break; } else { - // channel tag and current tag don't match, move on to next channel + // Channel tag and current tag don't match, move on to next channel continue; } } } else { - // no need to run code at all, move on to the next tag + // No need to run code at all, move on to the next tag continue; } } } - fn check_wind_necessity(&mut self, client: &Client, camera: &Camera) -> bool { - let focus_off = camera.get_focus_pos().map(f32::trunc); - let cam_pos = camera.dependents().cam_pos + focus_off; + fn check_ambience_necessity( + &mut self, + tag: AmbientChannelTag, + client: &Client, + camera: &Camera, + ) -> bool { + match tag { + AmbientChannelTag::Wind => { + let focus_off = camera.get_focus_pos().map(f32::trunc); + let cam_pos = camera.dependents().cam_pos + focus_off; - let (terrain_alt, tree_density) = if let Some(chunk) = client.current_chunk() { - (chunk.meta().alt(), chunk.meta().tree_density()) - } else { - (0.0, 0.0) - }; + let (terrain_alt, tree_density) = if let Some(chunk) = client.current_chunk() { + (chunk.meta().alt(), chunk.meta().tree_density()) + } else { + (0.0, 0.0) + }; - // Wind volume increases with altitude - let alt_multiplier = (cam_pos.z / 1200.0).abs(); + let alt_multiplier = (cam_pos.z / 1200.0).abs(); - // Tree density factors into wind volume. The more trees, - // the lower wind volume. The trees make more of an impact - // the closer the camera is to the ground. - let tree_multiplier = - ((1.0 - tree_density) + ((cam_pos.z - terrain_alt).abs() / 150.0).powi(2)).min(1.0); + let tree_multiplier = ((1.0 - tree_density) + + ((cam_pos.z - terrain_alt).abs() / 150.0).powi(2)) + .min(1.0); - return alt_multiplier * tree_multiplier > 0.0; - } + return alt_multiplier * tree_multiplier > 0.0; + }, + AmbientChannelTag::Rain => { + let focus_off = camera.get_focus_pos().map(f32::trunc); + let cam_pos = camera.dependents().cam_pos + focus_off; - fn check_rain_necessity(&mut self, client: &Client, camera: &Camera) -> bool { - let focus_off = camera.get_focus_pos().map(f32::trunc); - let cam_pos = camera.dependents().cam_pos + focus_off; + let terrain_alt = if let Some(chunk) = client.current_chunk() { + chunk.meta().alt() + } else { + 0.0 + }; + let camera_multiplier = + 1.0 - ((cam_pos.z - terrain_alt).abs() / 75.0).powi(2).min(1.0); - let terrain_alt = if let Some(chunk) = client.current_chunk() { - chunk.meta().alt() - } else { - 0.0 - }; - // make rain diminish with camera distance above terrain - let camera_multiplier = 1.0 - ((cam_pos.z - terrain_alt).abs() / 75.0).powi(2).min(1.0); + return client.weather_at_player().rain > 0.001 || camera_multiplier > 0.0; + }, + AmbientChannelTag::Thunder => return client.weather_at_player().rain * 500.0 > 0.7, + AmbientChannelTag::Leaves => { + let focus_off = camera.get_focus_pos().map(f32::trunc); + let cam_pos = camera.dependents().cam_pos + focus_off; - client.weather_at_player().rain > 0.001 || camera_multiplier > 0.0 - } + let (terrain_alt, tree_density) = if let Some(chunk) = client.current_chunk() { + (chunk.meta().alt(), chunk.meta().tree_density()) + } else { + (0.0, 0.0) + }; + let tree_multiplier = 1.0 + - (((1.0 - tree_density) + + ((cam_pos.z - terrain_alt + 20.0).abs() / 150.0).powi(2)) + .min(1.0)); - fn check_thunder_necessity(&mut self, client: &Client) -> bool { - client.weather_at_player().rain * 500.0 > 0.7 - } - - fn check_leaves_necessity(&mut self, client: &Client, camera: &Camera) -> bool { - let focus_off = camera.get_focus_pos().map(f32::trunc); - let cam_pos = camera.dependents().cam_pos + focus_off; - - let (terrain_alt, tree_density) = if let Some(chunk) = client.current_chunk() { - (chunk.meta().alt(), chunk.meta().tree_density()) - } else { - (0.0, 0.0) - }; - let tree_multiplier = 1.0 - - (((1.0 - tree_density) + ((cam_pos.z - terrain_alt + 20.0).abs() / 150.0).powi(2)) - .min(1.0)); - - return tree_multiplier > 0.1; + return tree_multiplier > 0.1; + }, + } } } @@ -199,16 +195,7 @@ impl AmbientChannel { let focus_off = camera.get_focus_pos().map(f32::trunc); let cam_pos = camera.dependents().cam_pos + focus_off; - let mut target_volume: f32 = match tag { - // Get target volume of wind - AmbientChannelTag::Wind => self.get_wind_volume(client, camera), - // Get target volume of rain - AmbientChannelTag::Rain => self.get_rain_volume(client, camera), - // Get target volume of thunder - AmbientChannelTag::Thunder => self.get_thunder_volume(client), - // Get target volume of leaves - AmbientChannelTag::Leaves => self.get_leaves_volume(client, camera), - }; + let mut target_volume: f32 = self.get_ambience_volume(tag, client, camera); target_volume = self.check_camera(state, client, cam_pos, target_volume); @@ -228,7 +215,7 @@ impl AmbientChannel { } else { 0.0 }; - // Checks if the camera is underwater to stop ambient sounds + // Checks if the camera is underwater to diminish ambient sounds if state .terrain() .get((cam_pos).map(|e| e.floor() as i32)) @@ -245,88 +232,97 @@ impl AmbientChannel { volume_multiplier.clamped(0.0, 1.0) } - fn get_wind_volume(&mut self, client: &Client, camera: &Camera) -> f32 { - let focus_off = camera.get_focus_pos().map(f32::trunc); - let cam_pos = camera.dependents().cam_pos + focus_off; - // Float from around -30.0 to 30.0 - let client_wind_speed_sq = client.weather_at_player().wind.magnitude_squared(); + // Gets appropriate volume for each tag + fn get_ambience_volume( + &mut self, + tag: AmbientChannelTag, + client: &Client, + camera: &Camera, + ) -> f32 { + match tag { + AmbientChannelTag::Wind => { + let focus_off = camera.get_focus_pos().map(f32::trunc); + let cam_pos = camera.dependents().cam_pos + focus_off; - let (terrain_alt, tree_density) = if let Some(chunk) = client.current_chunk() { - (chunk.meta().alt(), chunk.meta().tree_density()) - } else { - (0.0, 0.0) - }; + let (terrain_alt, tree_density) = if let Some(chunk) = client.current_chunk() { + (chunk.meta().alt(), chunk.meta().tree_density()) + } else { + (0.0, 0.0) + }; - // Wind volume increases with altitude - let alt_multiplier = (cam_pos.z / 1200.0).abs(); + // Wind volume increases with altitude + let alt_multiplier = (cam_pos.z / 1200.0).abs(); - // Tree density factors into wind volume. The more trees, - // the lower wind volume. The trees make more of an impact - // the closer the camera is to the ground. - let tree_multiplier = - ((1.0 - tree_density) + ((cam_pos.z - terrain_alt).abs() / 150.0).powi(2)).min(1.0); + // Tree density factors into wind volume. The more trees, + // the lower wind volume. The trees make more of an impact + // the closer the camera is to the ground. + let tree_multiplier = ((1.0 - tree_density) + + ((cam_pos.z - terrain_alt).abs() / 150.0).powi(2)) + .min(1.0); - // Lastly, we of course have to take into account actual wind speed from - // weathersim - let wind_speed_multiplier = (client_wind_speed_sq / 30.0_f32.powi(2)).min(1.0); + // Lastly, we of course have to take into account actual wind speed from + // weathersim + // Client wind speed is a float approx. -30.0 to 30.0 (polarity depending on + // direction) + let wind_speed_multiplier = (client.weather_at_player().wind.magnitude_squared() + / 30.0_f32.powi(2)) + .min(1.0); - return alt_multiplier - * tree_multiplier - * (wind_speed_multiplier + ((cam_pos.z - terrain_alt).abs() / 150.0).powi(2)).min(1.0); - } + return alt_multiplier + * tree_multiplier + * (wind_speed_multiplier + ((cam_pos.z - terrain_alt).abs() / 150.0).powi(2)) + .min(1.0); + }, + AmbientChannelTag::Rain => { + let focus_off = camera.get_focus_pos().map(f32::trunc); + let cam_pos = camera.dependents().cam_pos + focus_off; - fn get_rain_volume(&mut self, client: &Client, camera: &Camera) -> f32 { - // multipler at end will have to change depending on how intense rain normally - // is + let terrain_alt = if let Some(chunk) = client.current_chunk() { + chunk.meta().alt() + } else { + 0.0 + }; + // Make rain diminish with camera distance above terrain + let camera_multiplier = + 1.0 - ((cam_pos.z - terrain_alt).abs() / 75.0).powi(2).min(1.0); - // TODO: make rain diminish with distance above terrain - let focus_off = camera.get_focus_pos().map(f32::trunc); - let cam_pos = camera.dependents().cam_pos + focus_off; + let rain_intensity = (client.weather_at_player().rain * 500.0) * camera_multiplier; - let terrain_alt = if let Some(chunk) = client.current_chunk() { - chunk.meta().alt() - } else { - 0.0 - }; - // make rain diminish with camera distance above terrain - let camera_multiplier = 1.0 - ((cam_pos.z - terrain_alt).abs() / 75.0).powi(2).min(1.0); + return rain_intensity.min(0.9); + }, + AmbientChannelTag::Thunder => { + let rain_intensity = client.weather_at_player().rain * 500.0; - let rain_intensity = (client.weather_at_player().rain * 500.0) * camera_multiplier; + if rain_intensity < 0.7 { + 0.0 + } else { + rain_intensity + } + }, + AmbientChannelTag::Leaves => { + let focus_off = camera.get_focus_pos().map(f32::trunc); + let cam_pos = camera.dependents().cam_pos + focus_off; - return rain_intensity.min(0.9); - } + let (terrain_alt, tree_density) = if let Some(chunk) = client.current_chunk() { + (chunk.meta().alt(), chunk.meta().tree_density()) + } else { + (0.0, 0.0) + }; - fn get_thunder_volume(&mut self, client: &Client) -> f32 { - let thunder_intensity = client.weather_at_player().rain * 500.0; + // Tree density factors into leaves volume. The more trees, + // the higher volume. The trees make more of an impact + // the closer the camera is to the ground + let tree_multiplier = 1.0 + - (((1.0 - tree_density) + + ((cam_pos.z - terrain_alt + 20.0).abs() / 150.0).powi(2)) + .min(1.0)); - if thunder_intensity < 0.7 { - 0.0 - } else { - thunder_intensity - } - } - - fn get_leaves_volume(&mut self, client: &Client, camera: &Camera) -> f32 { - let focus_off = camera.get_focus_pos().map(f32::trunc); - let cam_pos = camera.dependents().cam_pos + focus_off; - - let (terrain_alt, tree_density) = if let Some(chunk) = client.current_chunk() { - (chunk.meta().alt(), chunk.meta().tree_density()) - } else { - (0.0, 0.0) - }; - - // Tree density factors into leaves volume. The more trees, - // the higher volume. The trees make more of an impact - // the closer the camera is to the ground - let tree_multiplier = 1.0 - - (((1.0 - tree_density) + ((cam_pos.z - terrain_alt + 20.0).abs() / 150.0).powi(2)) - .min(1.0)); - - if tree_multiplier > 0.1 { - tree_multiplier - } else { - 0.0 + if tree_multiplier > 0.1 { + tree_multiplier + } else { + 0.0 + } + }, } } } diff --git a/voxygen/src/audio/mod.rs b/voxygen/src/audio/mod.rs index 78091460af..d9a78286cc 100644 --- a/voxygen/src/audio/mod.rs +++ b/voxygen/src/audio/mod.rs @@ -331,7 +331,7 @@ impl AudioFrontend { Ok(()) } - // plays a file at a given volume in the channel with a given tag + // Plays a file at a given volume in the channel with a given tag fn play_ambient( &mut self, channel_tag: AmbientChannelTag, @@ -346,7 +346,7 @@ impl AudioFrontend { } } - // adds a new ambient channel of the given tag at zero volume + // Adds a new ambient channel of the given tag at zero volume fn new_ambient_channel(&mut self, channel_tag: AmbientChannelTag) { if let Some(audio_stream) = &self.audio_stream { let ambient_channel = AmbientChannel::new(audio_stream, channel_tag, 0.0); @@ -354,7 +354,7 @@ impl AudioFrontend { } } - // retrieves the channel currently having the given tag + // Retrieves the channel currently having the given tag fn get_ambient_channel( &mut self, channel_tag: AmbientChannelTag, @@ -379,7 +379,8 @@ impl AudioFrontend { } } - // sets the volume of the channel with the given tag to the given volume + // Unused code that may be useful in the future: + // Sets the volume of the channel with the given tag to the given volume // fn set_ambient_volume(&mut self, channel_tag: AmbientChannelTag, // volume_multiplier: f32) { if self.audio_stream.is_some() { // let sfx_volume = self.get_sfx_volume(); @@ -390,7 +391,7 @@ impl AudioFrontend { // } // } - // retrieves volume (pre-sfx-setting) of the channel with a given tag + // Retrieves volume (pre-sfx-setting) of the channel with a given tag // fn get_ambient_volume(&mut self, channel_tag: AmbientChannelTag) -> f32 { // if self.audio_stream.is_some() { // if let Some(channel) = self.get_ambient_channel(channel_tag) { @@ -462,13 +463,13 @@ impl AudioFrontend { } } - // this retrieves the current setting for sfx volume + // Retrieves the current setting for sfx volume pub fn get_sfx_volume(&self) -> f32 { self.sfx_volume * self.master_volume } - // this retrieves the current setting for ambience volume + // Retrieves the current setting for ambience volume pub fn get_ambience_volume(&self) -> f32 { self.ambience_volume * self.master_volume } - // this retrieves the current setting for music volume + // Retrieves the current setting for music volume pub fn get_music_volume(&self) -> f32 { self.music_volume * self.master_volume } pub fn sfx_enabled(&self) -> bool { self.get_sfx_volume() > 0.0 } diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs index e047d8b3f7..db8242ed2d 100644 --- a/voxygen/src/scene/mod.rs +++ b/voxygen/src/scene/mod.rs @@ -103,8 +103,6 @@ pub struct Scene { pub sfx_mgr: SfxMgr, music_mgr: MusicMgr, ambient_mgr: AmbientMgr, - // ambient_wind_mgr: AmbientWindMgr, - // ambient_rain_mgr: AmbientRainMgr, } pub struct SceneData<'a> { @@ -321,8 +319,6 @@ impl Scene { ambient_mgr: AmbientMgr { ambience: ambient::load_ambience_items(), }, - // ambient_wind_mgr: AmbientWindMgr::default(), - // ambient_rain_mgr: AmbientRainMgr::default(), } }