aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/CollisionSounds.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/CollisionSounds.cs342
1 files changed, 342 insertions, 0 deletions
diff --git a/OpenSim/Region/Framework/Scenes/CollisionSounds.cs b/OpenSim/Region/Framework/Scenes/CollisionSounds.cs
new file mode 100644
index 0000000..63aafcd
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/CollisionSounds.cs
@@ -0,0 +1,342 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27// Ubit 2012
28
29using System;
30using System.Reflection;
31using System.Collections.Generic;
32using OpenMetaverse;
33using OpenSim.Framework;
34using log4net;
35
36namespace OpenSim.Region.Framework.Scenes
37{
38 public struct CollisionForSoundInfo
39 {
40 public uint colliderID;
41 public Vector3 position;
42 public float relativeVel;
43 }
44
45 public static class CollisionSounds
46 {
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48
49 private const int MaxMaterials = 7;
50 // part part
51
52 private static UUID snd_StoneStone = new UUID("be7295c0-a158-11e1-b3dd-0800200c9a66");
53 private static UUID snd_StoneMetal = new UUID("be7295c0-a158-11e1-b3dd-0800201c9a66");
54 private static UUID snd_StoneGlass = new UUID("be7295c0-a158-11e1-b3dd-0800202c9a66");
55 private static UUID snd_StoneWood = new UUID("be7295c0-a158-11e1-b3dd-0800203c9a66");
56 private static UUID snd_StoneFlesh = new UUID("be7295c0-a158-11e1-b3dd-0800204c9a66");
57 private static UUID snd_StonePlastic = new UUID("be7295c0-a158-11e1-b3dd-0800205c9a66");
58 private static UUID snd_StoneRubber = new UUID("be7295c0-a158-11e1-b3dd-0800206c9a66");
59
60 private static UUID snd_MetalMetal = new UUID("be7295c0-a158-11e1-b3dd-0801201c9a66");
61 private static UUID snd_MetalGlass = new UUID("be7295c0-a158-11e1-b3dd-0801202c9a66");
62 private static UUID snd_MetalWood = new UUID("be7295c0-a158-11e1-b3dd-0801203c9a66");
63 private static UUID snd_MetalFlesh = new UUID("be7295c0-a158-11e1-b3dd-0801204c9a66");
64 private static UUID snd_MetalPlastic = new UUID("be7295c0-a158-11e1-b3dd-0801205c9a66");
65 private static UUID snd_MetalRubber = new UUID("be7295c0-a158-11e1-b3dd-0801206c9a66");
66
67 private static UUID snd_GlassGlass = new UUID("be7295c0-a158-11e1-b3dd-0802202c9a66");
68 private static UUID snd_GlassWood = new UUID("be7295c0-a158-11e1-b3dd-0802203c9a66");
69 private static UUID snd_GlassFlesh = new UUID("be7295c0-a158-11e1-b3dd-0802204c9a66");
70 private static UUID snd_GlassPlastic = new UUID("be7295c0-a158-11e1-b3dd-0802205c9a66");
71 private static UUID snd_GlassRubber = new UUID("be7295c0-a158-11e1-b3dd-0802206c9a66");
72
73 private static UUID snd_WoodWood = new UUID("be7295c0-a158-11e1-b3dd-0803203c9a66");
74 private static UUID snd_WoodFlesh = new UUID("be7295c0-a158-11e1-b3dd-0803204c9a66");
75 private static UUID snd_WoodPlastic = new UUID("be7295c0-a158-11e1-b3dd-0803205c9a66");
76 private static UUID snd_WoodRubber = new UUID("be7295c0-a158-11e1-b3dd-0803206c9a66");
77
78 private static UUID snd_FleshFlesh = new UUID("be7295c0-a158-11e1-b3dd-0804204c9a66");
79 private static UUID snd_FleshPlastic = new UUID("be7295c0-a158-11e1-b3dd-0804205c9a66");
80 private static UUID snd_FleshRubber = new UUID("be7295c0-a158-11e1-b3dd-0804206c9a66");
81
82 private static UUID snd_PlasticPlastic = new UUID("be7295c0-a158-11e1-b3dd-0805205c9a66");
83 private static UUID snd_PlasticRubber = new UUID("be7295c0-a158-11e1-b3dd-0805206c9a66");
84
85 private static UUID snd_RubberRubber = new UUID("be7295c0-a158-11e1-b3dd-0806206c9a66");
86
87 // terrain part
88 private static UUID snd_TerrainStone = new UUID("be7295c0-a158-11e1-b3dd-0807200c9a66");
89 private static UUID snd_TerrainMetal = new UUID("be7295c0-a158-11e1-b3dd-0807200c9a66");
90 private static UUID snd_TerrainGlass = new UUID("be7295c0-a158-11e1-b3dd-0807200c9a66");
91 private static UUID snd_TerrainWood = new UUID("be7295c0-a158-11e1-b3dd-0807200c9a66");
92 private static UUID snd_TerrainFlesh = new UUID("be7295c0-a158-11e1-b3dd-0807200c9a66");
93 private static UUID snd_TerrainPlastic = new UUID("be7295c0-a158-11e1-b3dd-0807200c9a66");
94 private static UUID snd_TerrainRubber = new UUID("be7295c0-a158-11e1-b3dd-0807200c9a66");
95
96 public static UUID[] m_TerrainPart = {
97 snd_TerrainStone,
98 snd_TerrainMetal,
99 snd_TerrainGlass,
100 snd_TerrainWood,
101 snd_TerrainFlesh,
102 snd_TerrainPlastic,
103 snd_TerrainRubber
104 };
105
106 // simetric sounds
107 public static UUID[] m_PartPart = {
108 snd_StoneStone, snd_StoneMetal, snd_StoneGlass, snd_StoneWood, snd_StoneFlesh, snd_StonePlastic, snd_StoneRubber,
109 snd_StoneMetal, snd_MetalMetal, snd_MetalGlass, snd_MetalWood, snd_MetalFlesh, snd_MetalPlastic, snd_MetalRubber,
110 snd_StoneGlass, snd_MetalGlass, snd_GlassGlass, snd_GlassWood, snd_GlassFlesh, snd_GlassPlastic, snd_GlassRubber,
111 snd_StoneWood, snd_MetalWood, snd_GlassWood, snd_WoodWood, snd_WoodFlesh, snd_WoodPlastic, snd_WoodRubber,
112 snd_StoneFlesh, snd_MetalFlesh, snd_GlassFlesh, snd_WoodFlesh, snd_FleshFlesh, snd_FleshPlastic, snd_FleshRubber,
113 snd_StonePlastic, snd_MetalPlastic, snd_GlassPlastic, snd_WoodPlastic, snd_FleshPlastic, snd_PlasticPlastic, snd_PlasticRubber,
114 snd_StoneRubber, snd_MetalRubber, snd_GlassRubber, snd_WoodRubber, snd_FleshRubber, snd_PlasticRubber, snd_RubberRubber
115 };
116
117 public static void PartCollisionSound(SceneObjectPart part, List<CollisionForSoundInfo> collidersinfolist)
118 {
119 if (part.CollisionSoundType < 0)
120 return;
121
122 if (collidersinfolist.Count == 0 || part == null)
123 return;
124
125 if (part.VolumeDetectActive || (part.Flags & PrimFlags.Physics) == 0)
126 return;
127
128 SceneObjectGroup sog = part.ParentGroup;
129 if (sog == null || sog.IsDeleted || sog.inTransit)
130 return;
131
132 if(sog.CollisionSoundThrottled(part.CollisionSoundType))
133 return;
134
135 float volume = part.CollisionSoundVolume;
136
137 UUID soundID = part.CollisionSound;
138
139 bool HaveSound = false;
140 switch (part.CollisionSoundType)
141 {
142 case 0: // default sounds
143 volume = 1.0f;
144 break;
145 case 1: // selected sound
146 if(soundID == part.invalidCollisionSoundUUID)
147 return;
148 HaveSound = true;
149 break;
150 case 2: // default sounds with volume set by script
151 default:
152 break;
153 }
154
155 if (volume == 0.0f)
156 return;
157
158 bool doneownsound = false;
159
160 int thisMaterial = (int)part.Material;
161 if (thisMaterial >= MaxMaterials)
162 thisMaterial = 3;
163 int thisMatScaled = thisMaterial * MaxMaterials;
164
165 CollisionForSoundInfo colInfo;
166 uint id;
167
168 for(int i = 0; i < collidersinfolist.Count; i++)
169 {
170 colInfo = collidersinfolist[i];
171
172 id = colInfo.colliderID;
173 if (id == 0) // terrain collision
174 {
175 if (!doneownsound)
176 {
177 if (!HaveSound)
178 {
179 float vol = Math.Abs(colInfo.relativeVel);
180 if (vol < 0.2f)
181 continue;
182
183 vol *= vol * .0625f; // 4m/s == full volume
184 if (vol > 1.0f)
185 vol = 1.0f;
186
187 soundID = m_TerrainPart[thisMaterial];
188 volume *= vol;
189 }
190 part.SendCollisionSound(soundID, volume, colInfo.position);
191 doneownsound = true;
192 }
193 continue;
194 }
195
196 SceneObjectPart otherPart = sog.Scene.GetSceneObjectPart(id);
197 if (otherPart != null)
198 {
199 SceneObjectGroup othersog = otherPart.ParentGroup;
200 if(othersog == null || othersog.IsDeleted || othersog.inTransit)
201 continue;
202
203 int otherType = otherPart.CollisionSoundType;
204 if (otherType < 0 || otherPart.VolumeDetectActive)
205 continue;
206
207 if (!HaveSound)
208 {
209 if(othersog.CollisionSoundThrottled(otherType))
210 continue;
211
212 if (otherType == 1)
213 {
214 soundID = otherPart.CollisionSound;
215 volume = otherPart.CollisionSoundVolume;
216 if (volume == 0.0f)
217 continue;
218 }
219 else
220 {
221 if (otherType == 2)
222 {
223 volume = otherPart.CollisionSoundVolume;
224 if (volume == 0.0f)
225 continue;
226 }
227
228 float vol = Math.Abs(colInfo.relativeVel);
229 if (vol < 0.2f)
230 continue;
231
232 vol *= vol * .0625f; // 4m/s == full volume
233 if (vol > 1.0f)
234 vol = 1.0f;
235
236 int otherMaterial = (int)otherPart.Material;
237 if (otherMaterial >= MaxMaterials)
238 otherMaterial = 3;
239
240 soundID = m_PartPart[thisMatScaled + otherMaterial];
241 volume *= vol;
242 }
243 }
244
245 if (doneownsound)
246 otherPart.SendCollisionSound(soundID, volume, colInfo.position);
247 else
248 {
249 part.SendCollisionSound(soundID, volume, colInfo.position);
250 doneownsound = true;
251 }
252 }
253 }
254 }
255
256 public static void AvatarCollisionSound(ScenePresence av, List<CollisionForSoundInfo> collidersinfolist)
257 {
258 if (collidersinfolist.Count == 0 || av == null)
259 return;
260
261 UUID soundID;
262 int otherMaterial;
263
264 int thisMaterial = 4; // flesh
265
266 int thisMatScaled = thisMaterial * MaxMaterials;
267
268 // bool doneownsound = false;
269
270 CollisionForSoundInfo colInfo;
271 uint id;
272 float volume;
273
274 for(int i = 0; i< collidersinfolist.Count; i++)
275 {
276 colInfo = collidersinfolist[i];
277
278 id = colInfo.colliderID;
279
280 if (id == 0) // no terrain collision sounds for now
281 {
282 continue;
283// volume = Math.Abs(colInfo.relativeVel);
284// if (volume < 0.2f)
285// continue;
286
287 }
288
289 SceneObjectPart otherPart = av.Scene.GetSceneObjectPart(id);
290 if (otherPart != null)
291 {
292 if (otherPart.CollisionSoundType < 0)
293 continue;
294 if (otherPart.CollisionSoundType == 1 && otherPart.CollisionSoundVolume > 0f)
295 otherPart.SendCollisionSound(otherPart.CollisionSound, otherPart.CollisionSoundVolume, colInfo.position);
296 else
297 {
298 float volmod = 1.0f;
299 if (otherPart.CollisionSoundType == 2)
300 {
301 volmod = otherPart.CollisionSoundVolume;
302 if(volmod == 0.0)
303 continue;
304 }
305 volume = Math.Abs(colInfo.relativeVel);
306 // Most noral collisions (running into walls, stairs)
307 // should never be heard.
308 if (volume < 3.2f)
309 continue;
310// m_log.DebugFormat("Collision speed was {0}", volume);
311
312 // Cap to 0.2 times volume because climbing stairs should not be noisy
313 // Also changed scaling
314 volume *= volume * .0125f; // 4m/s == volume 0.2
315 if (volume > 0.2f)
316 volume = 0.2f;
317 otherMaterial = (int)otherPart.Material;
318 if (otherMaterial >= MaxMaterials)
319 otherMaterial = 3;
320
321 volume *= volmod;
322 soundID = m_PartPart[thisMatScaled + otherMaterial];
323 otherPart.SendCollisionSound(soundID, volume, colInfo.position);
324 }
325 continue;
326 }
327/*
328 else if (!doneownsound)
329 {
330 ScenePresence otherav = av.Scene.GetScenePresence(Id);
331 if (otherav != null && (!otherav.IsChildAgent))
332 {
333 soundID = snd_FleshFlesh;
334 av.SendCollisionSound(soundID, 1.0);
335 doneownsound = true;
336 }
337 }
338 */
339 }
340 }
341 }
342}