-
Notifications
You must be signed in to change notification settings - Fork 1
/
audio3D.js
158 lines (132 loc) · 4.77 KB
/
audio3D.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
*Creation : 22/04/2013
*Author : Fabien Daoulas
*Last update : 30/05/2013
* this script displays sound around the sphere
number of lines : 150
*/
private var radius : float = 5;
private var trans : Transition2D3D;
private var full : FullScreen;
private var sphericMesh : createSphericMesh;
////////////////////////
//////////init//////////
////////////////////////
public function initSound(){
trans = gameObject.GetComponent("Transition2D3D") as Transition2D3D;
full = gameObject.GetComponent("FullScreen") as FullScreen;
sphericMesh = gameObject.GetComponent("createSphericMesh") as createSphericMesh;
}
////////////////////////////////////////////
//////////create/place audiosource//////////
////////////////////////////////////////////
/*
*create gameobject with audiosource
*/
public function createAudio( t : Hashtable ) : GameObject{
// load sound at path stored in the hashtable and check if it is the right type (audioclip)
var clip : AudioClip = Resources.Load( t['path'] , AudioClip );
// test if sound exists in defaultDatas
if( !clip ){
Console.Warning("No audio -- " +t['path']+" -- found in resources");
return;
}
// create gameobject that will be the audio source
var g : GameObject = new GameObject();
// name it
g.name = "3D_sound_"+t['name'];
// add component audio source
g.AddComponent(AudioSource);
// add clip loaded previously
g.audio.clip = clip;
// place audio
placeAudioSources( float.Parse(t['theta']) , float.Parse(t['ratio']) , g );
// clip is heard like in the real world
g.audio.rolloffMode = AudioRolloffMode.Logarithmic;
return g;
}
/*
*place GO around the sphere
*/
private function placeAudioSources( theta : float , ratio : float , g : GameObject ){
// calculate phi (spheric coordinates) to position the gameobject in a 3D scene
if( ratio > 0.66 )
var phi : float = sphericMesh.calculatePHI( ratio , true );
else
phi = sphericMesh.calculatePHI( ratio , false );
//convert it to radian
theta = theta * Mathf.PI/180;
// give the gameobject the right position in world coordinates
g.transform.position = Vector3( radius * Mathf.Sin(theta) * Mathf.Cos(phi),
radius * Mathf.Sin(phi) + 1.3,
radius * Mathf.Cos(theta) * Mathf.Cos(phi) );
}
/////////////////////////////////
//////////run/stop clip//////////
/////////////////////////////////
private function playAudio3D( source : GameObject ){
if( !source.audio.isPlaying ){// if is not playing yet
// play audio
source.audio.Play();
// clip will not end
source.audio.loop = true;
}
else
return;
}
private function stopAudio3D( source : GameObject ){
source.audio.Stop();
}
/////////////////////////////////
//////////manage volume//////////
/////////////////////////////////
/*
*calculate the distance between gameObject and center of screen
*/
private function ComputeDistance( x:float , y:float ) : float{
//basic calculation of a distance
return Mathf.Sqrt((x - 0.5)*(x - 0.5) + (y - 0.5)*(y - 0.5));
}
/*
*manage volume of sound, a way to get surround effect
*/
private function manageVolume( d : float , g : GameObject , srcAudioPosViewPoint : Vector3 ){
// if audiosource is on the screen and in front of you
if( d < 1/Mathf.Sqrt(2) && srcAudioPosViewPoint.z > 0 )
g.audio.volume = 1;
// if audiosource is between distance = 5 and distance = 1/Mathf.Sqrt(2) then calculate the volume
else if( d < 5 && srcAudioPosViewPoint.z > 0 )
g.audio.volume = Mathf.Exp(5*(-Mathf.Sqrt(2) + 1/d));
else // if too far
g.audio.volume = 0;
}
//////////////////////////
//////////update//////////
//////////////////////////
public function updateSounds ( on3D : boolean, tabSound : Array ){
if( on3D ){// if in 3D view
//position viewpoint of audiosource
var srcAudioPosViewPoint : Vector3;
//distance between gameObject and center of screen
var Distance : float;
for(var i = 0; i < tabSound.length ; i++){// for each audiosource in the scene
if( (tabSound[i] as GameObject).GetComponent(AudioSource) == null )// check if gameobject has an audiosource
continue ;
// run clip if not playing
if( !(tabSound[i] as GameObject).audio.isPlaying )
playAudio3D( tabSound[i] );
if( (tabSound[i] as GameObject).audio.isPlaying ){
// get position of gameobject in screen coordinates
srcAudioPosViewPoint = Camera.main.WorldToViewportPoint( (tabSound[i] as GameObject).transform.position );
// calculate distance between center of screen and gameobject in screen coordinates
Distance = ComputeDistance( srcAudioPosViewPoint.x , srcAudioPosViewPoint.y );
// then compute increase/decrease volume depending on the value of distance
manageVolume( Distance , tabSound[i] , srcAudioPosViewPoint );
}//if
}//for
}//if
else{// if not in 3D view
for(i = 0; i < tabSound.length ; i++)
stopAudio3D( tabSound[i] );
}
}