mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Adds proper 3d sound?
Looks like loading the footstep files every time a sound is played becomes a problem rather quickly.
This commit is contained in:
parent
b5a979c82e
commit
65008f7d54
@ -1,5 +1,6 @@
|
||||
use rodio::SpatialSink;
|
||||
use crate::audio::fader::Fader;
|
||||
use vek::*;
|
||||
|
||||
#[derive(PartialEq, Clone, Copy)]
|
||||
pub enum AudioType {
|
||||
@ -20,6 +21,7 @@ pub struct Channel {
|
||||
audio_type: AudioType,
|
||||
state: ChannelState,
|
||||
fader: Fader,
|
||||
pub pos: Vec3::<f32>,
|
||||
}
|
||||
|
||||
impl Channel {
|
||||
@ -30,16 +32,18 @@ impl Channel {
|
||||
audio_type: AudioType::Music,
|
||||
state: ChannelState::Playing,
|
||||
fader: Fader::fade_in(0.0),
|
||||
pos: Vec3::zero(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sfx(id: usize, sink: SpatialSink) -> Self {
|
||||
pub fn sfx(id: usize, sink: SpatialSink, pos: Vec3::<f32>) -> Self {
|
||||
Self {
|
||||
id,
|
||||
sink,
|
||||
audio_type: AudioType::Sfx,
|
||||
state: ChannelState::Playing,
|
||||
fader: Fader::fade_in(0.0),
|
||||
pos
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,6 +68,10 @@ impl Channel {
|
||||
self.sink.set_volume(volume);
|
||||
}
|
||||
|
||||
pub fn set_emitter_position(&mut self, pos: [f32; 3]) {
|
||||
self.sink.set_emitter_position(pos);
|
||||
}
|
||||
|
||||
pub fn set_left_ear_position(&mut self, pos: [f32; 3]) {
|
||||
self.sink.set_left_ear_position(pos);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ const RIGHT_EAR : [f32; 3] = [-1.0, 0.0, 0.0];
|
||||
const EAR_LEFT : Vec3<f32> = Vec3::new(1.0, 0.0, 0.0);
|
||||
const EAR_RIGHT : Vec3<f32> = Vec3::new(-1.0, 0.0, 0.0);
|
||||
|
||||
const LISTEN_DISTANCE : f32 = 25.0;
|
||||
const FALLOFF : f32 = 0.13;
|
||||
|
||||
|
||||
pub struct AudioFrontend {
|
||||
@ -26,8 +26,12 @@ pub struct AudioFrontend {
|
||||
|
||||
sfx_volume: f32,
|
||||
music_volume: f32,
|
||||
listener_pos_left: Vec3::<f32>,
|
||||
listener_pos_right: Vec3::<f32>,
|
||||
|
||||
listener_pos: Vec3::<f32>,
|
||||
listener_ori: Vec3::<f32>,
|
||||
|
||||
listener_pos_left: [f32; 3],
|
||||
listener_pos_right: [f32; 3],
|
||||
}
|
||||
|
||||
impl AudioFrontend {
|
||||
@ -41,8 +45,10 @@ impl AudioFrontend {
|
||||
next_channel_id: 0,
|
||||
sfx_volume: 1.0,
|
||||
music_volume: 1.0,
|
||||
listener_pos_left: Vec3::from_slice(&LEFT_EAR),
|
||||
listener_pos_right: Vec3::from_slice(&RIGHT_EAR),
|
||||
listener_pos: Vec3::zero(),
|
||||
listener_ori: Vec3::zero(),
|
||||
listener_pos_left: [0.0; 3],
|
||||
listener_pos_right: [0.0; 3],
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,8 +62,10 @@ impl AudioFrontend {
|
||||
next_channel_id: 0,
|
||||
sfx_volume: 1.0,
|
||||
music_volume: 1.0,
|
||||
listener_pos_left: Vec3::from_slice(&LEFT_EAR),
|
||||
listener_pos_right: Vec3::from_slice(&RIGHT_EAR),
|
||||
listener_pos: Vec3::zero(),
|
||||
listener_ori: Vec3::zero(),
|
||||
listener_pos_left: [0.0; 3],
|
||||
listener_pos_right: [0.0; 3],
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,31 +92,47 @@ impl AudioFrontend {
|
||||
self.next_channel_id += 1;
|
||||
|
||||
if let Some(device) = &self.audio_device {
|
||||
let pos = pos / LISTEN_DISTANCE;
|
||||
let sink = SpatialSink::new(device, pos.into_array(),
|
||||
self.listener_pos_left.into_array(),
|
||||
self.listener_pos_right.into_array());
|
||||
let calc_pos = [
|
||||
(pos.x - self.listener_pos.x) * FALLOFF,
|
||||
(pos.y - self.listener_pos.y) * FALLOFF,
|
||||
(pos.z - self.listener_pos.z) * FALLOFF,
|
||||
];
|
||||
let sink = SpatialSink::new(device, calc_pos,
|
||||
self.listener_pos_left,
|
||||
self.listener_pos_right);
|
||||
|
||||
let file = assets::load_file(&sound, &["wav"]).unwrap();
|
||||
let sound = Decoder::new(file).unwrap();
|
||||
|
||||
sink.append(sound);
|
||||
|
||||
self.channels.push(Channel::sfx(id, sink));
|
||||
self.channels.push(Channel::sfx(id, sink, pos));
|
||||
}
|
||||
|
||||
id
|
||||
}
|
||||
|
||||
pub fn set_listener_pos(&mut self, pos: &Vec3::<f32>) {
|
||||
let pos_left = (pos.clone() + EAR_LEFT) / LISTEN_DISTANCE;
|
||||
let pos_right = (pos.clone() + EAR_RIGHT) / LISTEN_DISTANCE;
|
||||
pub fn set_listener_pos(&mut self, pos: &Vec3::<f32>, ori: &Vec3::<f32>) {
|
||||
self.listener_pos = pos.clone();
|
||||
self.listener_ori = ori.normalized();
|
||||
|
||||
self.listener_pos_left = pos_left.clone();
|
||||
self.listener_pos_right = pos_right.clone();
|
||||
let up = Vec3::new(0.0, 0.0, 1.0);
|
||||
|
||||
let pos_left = up.cross(self.listener_ori.clone()).normalized();
|
||||
dbg!(pos_left);
|
||||
let pos_right = self.listener_ori.cross(up.clone()).normalized();
|
||||
dbg!(pos_right);
|
||||
|
||||
self.listener_pos_left = pos_left.into_array();
|
||||
self.listener_pos_right = pos_right.into_array();
|
||||
|
||||
for channel in self.channels.iter_mut() {
|
||||
if channel.get_audio_type() == AudioType::Sfx {
|
||||
channel.set_emitter_position([
|
||||
(channel.pos.x - self.listener_pos.x) * FALLOFF,
|
||||
(channel.pos.y - self.listener_pos.y) * FALLOFF,
|
||||
(channel.pos.z - self.listener_pos.z) * FALLOFF,
|
||||
]);
|
||||
channel.set_left_ear_position(pos_left.into_array());
|
||||
channel.set_right_ear_position(pos_right.into_array());
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ use crate::{
|
||||
};
|
||||
use common::comp::{
|
||||
Pos,
|
||||
Ori,
|
||||
Body,
|
||||
CharacterState,
|
||||
MovementState::*,
|
||||
@ -29,17 +30,19 @@ impl SoundMgr {
|
||||
}
|
||||
|
||||
pub fn maintain(&mut self, audio: &mut AudioFrontend, client: &Client) {
|
||||
let time = client.state().get_time();
|
||||
let tick = client.get_tick();
|
||||
let ecs = client.state().ecs();
|
||||
let dt = client.state().get_delta_time();
|
||||
// Get player position.
|
||||
let player_pos = ecs
|
||||
.read_storage::<Pos>()
|
||||
.get(client.entity())
|
||||
.map_or(Vec3::zero(), |pos| pos.0);
|
||||
|
||||
audio.set_listener_pos(&player_pos);
|
||||
let player_ori = ecs
|
||||
.read_storage::<Ori>()
|
||||
.get(client.entity())
|
||||
.map_or(Vec3::zero(), |pos| pos.0);
|
||||
|
||||
audio.set_listener_pos(&player_pos, &player_ori);
|
||||
|
||||
for (entity, pos, body, character) in (
|
||||
&ecs.entities(),
|
||||
|
Loading…
Reference in New Issue
Block a user