1use crayon::math::prelude::Vector3;
2
3use assets::prelude::AudioClipHandle;
4
5impl_handle!(AudioSourceHandle);
6
7#[derive(Debug, Copy, Clone)]
8pub struct AudioSource {
9 pub clip: AudioClipHandle,
11 pub volume: f32,
13 pub pitch: f32,
15 pub loops: AudioSourceWrap,
17 pub attenuation: Option<AudioSourceAttenuation>,
19}
20
21impl From<AudioClipHandle> for AudioSource {
22 fn from(clip: AudioClipHandle) -> Self {
23 AudioSource {
24 clip: clip,
25 volume: 1.0,
26 pitch: 1.0,
27 loops: AudioSourceWrap::Repeat(1),
28 attenuation: None,
29 }
30 }
31}
32
33#[derive(Debug, Copy, Clone)]
35pub enum AudioSourceWrap {
36 Repeat(u32),
37 Infinite,
38}
39
40#[derive(Debug, Copy, Clone)]
41pub struct AudioSourceAttenuation {
42 pub position: Vector3<f32>,
44 pub minimum_distance: f32,
47 pub attenuation: f32,
52}
53
54impl AudioSourceAttenuation {
55 pub fn new(minimum_distance: f32, attenuation: f32) -> Self {
56 assert!(minimum_distance > 0.0 && attenuation >= 0.0);
57
58 AudioSourceAttenuation {
59 position: Vector3::new(0.0, 0.0, 0.0),
60 minimum_distance: minimum_distance,
61 attenuation: attenuation,
62 }
63 }
64
65 pub fn volume<T>(&self, listener: T) -> f32
66 where
67 T: Into<Vector3<f32>>,
68 {
69 use crayon::math::prelude::InnerSpace;
70
71 let distance = (listener.into() - self.position)
72 .magnitude()
73 .max(self.minimum_distance);
74
75 let attenuation = self.attenuation * (distance - self.minimum_distance);
76 self.minimum_distance / (self.minimum_distance + attenuation)
77 }
78}