From 2d088faea4765e4f3824d9d30304c0501535436b Mon Sep 17 00:00:00 2001 From: jiminycrick Date: Sat, 7 Nov 2020 21:26:20 -0800 Subject: [PATCH] Wind transition smoothing --- voxygen/src/audio/channel.rs | 15 +-- voxygen/src/audio/mod.rs | 30 +++--- .../audio/sfx/event_mapper/movement/mod.rs | 8 +- voxygen/src/audio/sfx/mod.rs | 7 -- voxygen/src/audio/wind.rs | 94 ++++++++++++------- 5 files changed, 78 insertions(+), 76 deletions(-) diff --git a/voxygen/src/audio/channel.rs b/voxygen/src/audio/channel.rs index a343cc9176..af773cd1c5 100644 --- a/voxygen/src/audio/channel.rs +++ b/voxygen/src/audio/channel.rs @@ -21,7 +21,6 @@ use crate::audio::{ Listener, }; use rodio::{OutputStreamHandle, Sample, Sink, Source, SpatialSink}; -use std::time::Duration; use vek::*; #[derive(PartialEq, Clone, Copy)] @@ -148,6 +147,8 @@ pub struct WindChannel { impl WindChannel { pub fn set_volume(&mut self, volume: f32) { self.sink.set_volume(volume); } + pub fn volume(&mut self) -> f32 { self.sink.volume() } + pub fn new(stream: &OutputStreamHandle) -> Self { Self { sink: Sink::try_new(stream).unwrap(), @@ -203,18 +204,6 @@ impl SfxChannel { self.sink.append(source); } - pub fn play_with_reverb(&mut self, source: S) - where - S: Sized + Send + 'static, - ::Item: Sample, - ::Item: Sync, - ::Item: Send, - ::Item: std::fmt::Debug, - { - let source = source.buffered().reverb(Duration::from_millis(200), 0.2); - self.sink.append(source); - } - pub fn set_volume(&mut self, volume: f32) { self.sink.set_volume(volume); } pub fn is_done(&self) -> bool { self.sink.empty() } diff --git a/voxygen/src/audio/mod.rs b/voxygen/src/audio/mod.rs index 59235c34a6..4a885b27fe 100644 --- a/voxygen/src/audio/mod.rs +++ b/voxygen/src/audio/mod.rs @@ -212,24 +212,6 @@ impl AudioFrontend { } } - /// Play (once) an sfx file by file path at the give position and volume - /// but with reverb - pub fn play_reverb_sfx(&mut self, sound: &str, pos: Vec3, vol: Option) { - if self.audio_stream.is_some() { - let sound = self - .sound_cache - .load_sound(sound) - .amplify(vol.unwrap_or(1.0)); - - let listener = self.listener.clone(); - if let Some(channel) = self.get_sfx_channel() { - channel.set_pos(pos); - channel.update(&listener); - channel.play_with_reverb(sound); - } - } - } - fn play_wind(&mut self, sound: &str, volume_multiplier: f32) { if self.audio_stream.is_some() { if let Some(channel) = self.get_wind_channel(volume_multiplier) { @@ -261,6 +243,18 @@ impl AudioFrontend { } } + fn get_wind_volume(&mut self) -> f32 { + if self.audio_stream.is_some() { + if let Some(channel) = self.wind_channels.iter_mut().find(|_c| true) { + channel.volume() / self.sfx_volume + } else { + 0.0 + } + } else { + 0.0 + } + } + fn play_music(&mut self, sound: &str, channel_tag: MusicChannelTag) { if let Some(channel) = self.get_music_channel(channel_tag) { let file = assets::load_file(&sound, &["ogg"]).expect("Failed to load sound"); diff --git a/voxygen/src/audio/sfx/event_mapper/movement/mod.rs b/voxygen/src/audio/sfx/event_mapper/movement/mod.rs index 7ad6fb3ce2..37720d4c3b 100644 --- a/voxygen/src/audio/sfx/event_mapper/movement/mod.rs +++ b/voxygen/src/audio/sfx/event_mapper/movement/mod.rs @@ -114,7 +114,7 @@ impl EventMapper for MovementEventMapper { // it was dispatched internal_state.event = mapped_event; internal_state.on_ground = physics.on_ground; - if physics.in_fluid.is_some() { + if physics.in_liquid.is_some() { internal_state.in_water = true; } else { internal_state.in_water = false; @@ -182,8 +182,8 @@ impl MovementEventMapper { underfoot_block_kind: BlockKind, ) -> SfxEvent { // Match run / roll / swim state - if physics_state.in_fluid.is_some() && vel.magnitude() > 0.1 - || !previous_state.in_water && physics_state.in_fluid.is_some() + if physics_state.in_liquid.is_some() && vel.magnitude() > 0.1 + || !previous_state.in_water && physics_state.in_liquid.is_some() { return SfxEvent::Swim; } else if physics_state.on_ground && vel.magnitude() > 0.1 @@ -222,7 +222,7 @@ impl MovementEventMapper { vel: Vec3, underfoot_block_kind: BlockKind, ) -> SfxEvent { - if physics_state.in_fluid.is_some() && vel.magnitude() > 0.1 { + if physics_state.in_liquid.is_some() && vel.magnitude() > 0.1 { return SfxEvent::Swim; } else if physics_state.on_ground && vel.magnitude() > 0.1 { match underfoot_block_kind { diff --git a/voxygen/src/audio/sfx/mod.rs b/voxygen/src/audio/sfx/mod.rs index 41271bd087..241e651c05 100644 --- a/voxygen/src/audio/sfx/mod.rs +++ b/voxygen/src/audio/sfx/mod.rs @@ -254,10 +254,6 @@ impl SfxMgr { let ecs = state.ecs(); let focus_off = camera.get_focus_pos().map(f32::trunc); - let cave = match client.current_chunk() { - Some(chunk) => chunk.meta().cave_alt() != 0.0, - None => false, - }; let underwater = state .terrain() .get((camera.dependents().cam_pos + focus_off).map(|e| e.floor() as i32)) @@ -305,9 +301,6 @@ impl SfxMgr { if underwater { audio.play_underwater_sfx(sfx_file, position, event.vol); - } else if cave { - println!("Reverbbbbbbbbbb"); - audio.play_reverb_sfx(sfx_file, position, event.vol); } else { audio.play_sfx(sfx_file, position, event.vol); } diff --git a/voxygen/src/audio/wind.rs b/voxygen/src/audio/wind.rs index c7daf89a5e..909df1c8a6 100644 --- a/voxygen/src/audio/wind.rs +++ b/voxygen/src/audio/wind.rs @@ -2,13 +2,13 @@ use crate::{audio::AudioFrontend, scene::Camera}; use client::Client; use common::{assets, state::State, terrain::BlockKind, vol::ReadVol}; -use rand::{prelude::SliceRandom, thread_rng, Rng}; use serde::Deserialize; use std::time::Instant; use tracing::warn; -const DAY_START_SECONDS: u32 = 28800; // 8:00 -const DAY_END_SECONDS: u32 = 70200; // 19:30 +// For if we want wind to vary strength by time of day +//const DAY_START_SECONDS: u32 = 28800; // 8:00 +//const DAY_END_SECONDS: u32 = 70200; // 19:30 #[derive(Debug, Default, Deserialize)] struct WindCollection { @@ -21,32 +21,25 @@ pub struct WindItem { path: String, /// Length of the track in seconds length: f32, - /// Whether this track should play during day or night - timing: Option, + /* Whether this track should play during day or night + * timing: Option, */ } -/// Allows control over when a track should play based on in-game time of day -#[derive(Debug, Deserialize, PartialEq)] -enum DayPeriod { - /// 8:00 AM to 7:30 PM - Day, - /// 7:31 PM to 6:59 AM - Night, -} - -/// Determines whether the sound is stopped, playing, or fading -#[derive(Debug, Deserialize, PartialEq)] -enum PlayState { - Playing, - Stopped, - FadingOut, - FadingIn, -} +///// Allows control over when a track should play based on in-game time of day +//#[derive(Debug, Deserialize, PartialEq)] +//enum DayPeriod { +// /// 8:00 AM to 7:30 PM +// Day, +// /// 7:31 PM to 6:59 AM +// Night, +//} pub struct WindMgr { soundtrack: WindCollection, began_playing: Instant, next_track_change: f32, + volume: f32, + tree_multiplier: f32, } impl WindMgr { @@ -56,6 +49,8 @@ impl WindMgr { soundtrack: Self::load_soundtrack_items(), began_playing: Instant::now(), next_track_change: 0.0, + volume: 0.0, + tree_multiplier: 0.0, } } @@ -69,9 +64,27 @@ impl WindMgr { camera: &Camera, ) { if audio.sfx_enabled() && !self.soundtrack.tracks.is_empty() { - let alt_multiplier = ((Self::get_current_alt(client) - 250.0) / 1200.0).abs(); - let tree_multiplier = 1.0 - Self::get_current_tree_density(client); - let mut volume_multiplier = alt_multiplier * tree_multiplier; + let player_alt = Self::get_current_alt(client); + let terrain_alt = Self::get_current_terrain_alt(client); + + let alt_multiplier = (player_alt / 1200.0).abs(); + + let mut tree_multiplier = self.tree_multiplier; + let new_tree_multiplier = if (player_alt - terrain_alt) < 150.0 { + 1.0 - Self::get_current_tree_density(client) + } else { + 1.0 + }; + + if tree_multiplier < new_tree_multiplier { + tree_multiplier += 0.001; + } else if tree_multiplier > new_tree_multiplier { + tree_multiplier -= 0.001; + } + self.tree_multiplier = tree_multiplier; + + println!("tree multiplier: {}", tree_multiplier); + let mut volume_multiplier = alt_multiplier * self.tree_multiplier; let focus_off = camera.get_focus_pos().map(f32::trunc); let cam_pos = camera.dependents().cam_pos + focus_off; @@ -86,11 +99,24 @@ impl WindMgr { { volume_multiplier = volume_multiplier * 0.1; } - if cam_pos.z < Self::get_current_terrain_alt(client) { + if cam_pos.z < Self::get_current_terrain_alt(client) - 20.0 { volume_multiplier = 0.0; } - audio.set_wind_volume(volume_multiplier); + if volume_multiplier > 1.0 { + volume_multiplier = 1.0 + } + + let target_volume = volume_multiplier; + println!("target vol: {}", volume_multiplier); + + println!("current_wind_volume: {}", self.volume); + self.volume = audio.get_wind_volume(); + if self.volume < target_volume { + audio.set_wind_volume(self.volume + 0.001); + } else if self.volume > target_volume { + audio.set_wind_volume(self.volume - 0.001); + } if self.began_playing.elapsed().as_secs_f32() > self.next_track_change { //let game_time = (state.get_time_of_day() as u64 % 86400) as u32; @@ -105,13 +131,13 @@ impl WindMgr { } } - fn get_current_day_period(game_time: u32) -> DayPeriod { - if game_time > DAY_START_SECONDS && game_time < DAY_END_SECONDS { - DayPeriod::Day - } else { - DayPeriod::Night - } - } + //fn get_current_day_period(game_time: u32) -> DayPeriod { + // if game_time > DAY_START_SECONDS && game_time < DAY_END_SECONDS { + // DayPeriod::Day + // } else { + // DayPeriod::Night + // } + //} fn get_current_alt(client: &Client) -> f32 { match client.current_position() {