diff options
author | Melanie | 2012-10-30 01:02:20 +0000 |
---|---|---|
committer | Melanie | 2012-10-30 01:02:20 +0000 |
commit | 48569e856a9c9ced207652b10e2abde94c849687 (patch) | |
tree | 8955c0206f1822f4bbb44466fae74e18923d125c /OpenSim/Region/CoreModules | |
parent | Merge branch 'avination' into careminster (diff) | |
parent | Make MeshAssetReceived private. (diff) | |
download | opensim-SC-48569e856a9c9ced207652b10e2abde94c849687.zip opensim-SC-48569e856a9c9ced207652b10e2abde94c849687.tar.gz opensim-SC-48569e856a9c9ced207652b10e2abde94c849687.tar.bz2 opensim-SC-48569e856a9c9ced207652b10e2abde94c849687.tar.xz |
Merge branch 'master' into careminster
Conflicts:
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
Diffstat (limited to 'OpenSim/Region/CoreModules')
-rw-r--r-- | OpenSim/Region/CoreModules/World/Sound/SoundModule.cs | 315 |
1 files changed, 274 insertions, 41 deletions
diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs index a2f0950..513a8f5 100644 --- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs +++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
@@ -24,56 +24,110 @@ | |||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | |||
28 | using System; | 27 | using System; |
28 | using System.IO; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | |||
29 | using Nini.Config; | 32 | using Nini.Config; |
30 | using OpenMetaverse; | 33 | using OpenMetaverse; |
34 | using log4net; | ||
35 | using Mono.Addins; | ||
36 | |||
31 | using OpenSim.Framework; | 37 | using OpenSim.Framework; |
32 | using OpenSim.Region.Framework.Interfaces; | 38 | using OpenSim.Region.Framework.Interfaces; |
33 | using OpenSim.Region.Framework.Scenes; | 39 | using OpenSim.Region.Framework.Scenes; |
34 | using System.Reflection; | ||
35 | using log4net; | ||
36 | 40 | ||
37 | namespace OpenSim.Region.CoreModules.World.Sound | 41 | namespace OpenSim.Region.CoreModules.World.Sound |
38 | { | 42 | { |
39 | public class SoundModule : IRegionModule, ISoundModule | 43 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SoundModule")] |
44 | public class SoundModule : INonSharedRegionModule, ISoundModule | ||
40 | { | 45 | { |
41 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 46 | private static readonly ILog m_log = LogManager.GetLogger( |
42 | 47 | MethodBase.GetCurrentMethod().DeclaringType); | |
43 | protected Scene m_scene; | 48 | |
44 | 49 | private Scene m_scene; | |
45 | public void Initialise(Scene scene, IConfigSource source) | 50 | |
51 | public bool Enabled { get; private set; } | ||
52 | |||
53 | public float MaxDistance { get; private set; } | ||
54 | |||
55 | #region INonSharedRegionModule | ||
56 | |||
57 | public void Initialise(IConfigSource configSource) | ||
58 | { | ||
59 | IConfig config = configSource.Configs["Sounds"]; | ||
60 | |||
61 | if (config == null) | ||
62 | { | ||
63 | Enabled = true; | ||
64 | MaxDistance = 100.0f; | ||
65 | } | ||
66 | else | ||
67 | { | ||
68 | Enabled = config.GetString("Module", "OpenSim.Region.CoreModules.dll:SoundModule") == | ||
69 | Path.GetFileName(Assembly.GetExecutingAssembly().Location) | ||
70 | + ":" + MethodBase.GetCurrentMethod().DeclaringType.Name; | ||
71 | MaxDistance = config.GetFloat("MaxDistance", 100.0f); | ||
72 | } | ||
73 | } | ||
74 | |||
75 | public void AddRegion(Scene scene) { } | ||
76 | |||
77 | public void RemoveRegion(Scene scene) | ||
46 | { | 78 | { |
79 | m_scene.EventManager.OnClientLogin -= OnNewClient; | ||
80 | } | ||
81 | |||
82 | public void RegionLoaded(Scene scene) | ||
83 | { | ||
84 | if (!Enabled) | ||
85 | return; | ||
86 | |||
47 | m_scene = scene; | 87 | m_scene = scene; |
48 | 88 | m_scene.EventManager.OnClientLogin += OnNewClient; | |
49 | m_scene.EventManager.OnNewClient += OnNewClient; | 89 | |
50 | |||
51 | m_scene.RegisterModuleInterface<ISoundModule>(this); | 90 | m_scene.RegisterModuleInterface<ISoundModule>(this); |
52 | } | 91 | } |
53 | 92 | ||
54 | public void PostInitialise() {} | 93 | public void Close() { } |
55 | public void Close() {} | 94 | |
95 | public Type ReplaceableInterface | ||
96 | { | ||
97 | get { return typeof(ISoundModule); } | ||
98 | } | ||
99 | |||
56 | public string Name { get { return "Sound Module"; } } | 100 | public string Name { get { return "Sound Module"; } } |
57 | public bool IsSharedModule { get { return false; } } | 101 | |
58 | 102 | #endregion | |
103 | |||
104 | #region Event Handlers | ||
105 | |||
59 | private void OnNewClient(IClientAPI client) | 106 | private void OnNewClient(IClientAPI client) |
60 | { | 107 | { |
61 | client.OnSoundTrigger += TriggerSound; | 108 | client.OnSoundTrigger += TriggerSound; |
62 | } | 109 | } |
63 | 110 | ||
111 | #endregion | ||
112 | |||
113 | #region ISoundModule | ||
114 | |||
64 | public virtual void PlayAttachedSound( | 115 | public virtual void PlayAttachedSound( |
65 | UUID soundID, UUID ownerID, UUID objectID, double gain, Vector3 position, byte flags, float radius) | 116 | UUID soundID, UUID ownerID, UUID objectID, double gain, Vector3 position, byte flags, float radius) |
66 | { | 117 | { |
67 | SceneObjectPart part = m_scene.GetSceneObjectPart(objectID); | 118 | SceneObjectPart part; |
68 | if (part == null) | 119 | if (!m_scene.TryGetSceneObjectPart(objectID, out part)) |
69 | return; | 120 | return; |
70 | 121 | ||
71 | SceneObjectGroup grp = part.ParentGroup; | 122 | SceneObjectGroup grp = part.ParentGroup; |
72 | 123 | ||
124 | if (radius == 0) | ||
125 | radius = MaxDistance; | ||
126 | |||
73 | m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) | 127 | m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) |
74 | { | 128 | { |
75 | double dis = Util.GetDistanceTo(sp.AbsolutePosition, position); | 129 | double dis = Util.GetDistanceTo(sp.AbsolutePosition, position); |
76 | if (dis > 100.0) // Max audio distance | 130 | if (dis > MaxDistance) // Max audio distance |
77 | return; | 131 | return; |
78 | 132 | ||
79 | if (grp.IsAttachment) | 133 | if (grp.IsAttachment) |
@@ -85,26 +139,22 @@ namespace OpenSim.Region.CoreModules.World.Sound | |||
85 | dis = 0; | 139 | dis = 0; |
86 | } | 140 | } |
87 | 141 | ||
88 | float thisSpGain; | ||
89 | |||
90 | // Scale by distance | 142 | // Scale by distance |
91 | if (radius == 0) | 143 | double thisSpGain = gain * ((radius - dis) / radius); |
92 | thisSpGain = (float)((double)gain * ((100.0 - dis) / 100.0)); | ||
93 | else | ||
94 | thisSpGain = (float)((double)gain * ((radius - dis) / radius)); | ||
95 | 144 | ||
96 | sp.ControllingClient.SendPlayAttachedSound(soundID, objectID, ownerID, thisSpGain, flags); | 145 | sp.ControllingClient.SendPlayAttachedSound(soundID, objectID, |
146 | ownerID, (float)thisSpGain, flags); | ||
97 | }); | 147 | }); |
98 | } | 148 | } |
99 | 149 | ||
100 | public virtual void TriggerSound( | 150 | public virtual void TriggerSound( |
101 | UUID soundId, UUID ownerID, UUID objectID, UUID parentID, double gain, Vector3 position, UInt64 handle, float radius) | 151 | UUID soundId, UUID ownerID, UUID objectID, UUID parentID, double gain, Vector3 position, UInt64 handle, float radius) |
102 | { | 152 | { |
103 | SceneObjectPart part = m_scene.GetSceneObjectPart(objectID); | 153 | SceneObjectPart part; |
104 | if (part == null) | 154 | if (!m_scene.TryGetSceneObjectPart(objectID, out part)) |
105 | { | 155 | { |
106 | ScenePresence sp; | 156 | ScenePresence sp; |
107 | if (!m_scene.TryGetScenePresence(objectID, out sp)) | 157 | if (!m_scene.TryGetScenePresence(ownerID, out sp)) |
108 | return; | 158 | return; |
109 | } | 159 | } |
110 | else | 160 | else |
@@ -118,24 +168,207 @@ namespace OpenSim.Region.CoreModules.World.Sound | |||
118 | } | 168 | } |
119 | } | 169 | } |
120 | 170 | ||
171 | if (radius == 0) | ||
172 | radius = MaxDistance; | ||
173 | |||
121 | m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) | 174 | m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) |
122 | { | 175 | { |
123 | double dis = Util.GetDistanceTo(sp.AbsolutePosition, position); | 176 | double dis = Util.GetDistanceTo(sp.AbsolutePosition, position); |
124 | 177 | ||
125 | if (dis > 100.0) // Max audio distance | 178 | if (dis > MaxDistance) // Max audio distance |
126 | return; | 179 | return; |
127 | 180 | ||
128 | float thisSpGain; | ||
129 | |||
130 | // Scale by distance | 181 | // Scale by distance |
131 | if (radius == 0) | 182 | double thisSpGain = gain * ((radius - dis) / radius); |
132 | thisSpGain = (float)((double)gain * ((100.0 - dis) / 100.0)); | 183 | |
184 | sp.ControllingClient.SendTriggeredSound(soundId, ownerID, | ||
185 | objectID, parentID, handle, position, | ||
186 | (float)thisSpGain); | ||
187 | }); | ||
188 | } | ||
189 | |||
190 | public virtual void StopSound(UUID objectID) | ||
191 | { | ||
192 | SceneObjectPart m_host; | ||
193 | if (!m_scene.TryGetSceneObjectPart(objectID, out m_host)) | ||
194 | return; | ||
195 | |||
196 | StopSound(m_host); | ||
197 | } | ||
198 | |||
199 | private static void StopSound(SceneObjectPart m_host) | ||
200 | { | ||
201 | m_host.AdjustSoundGain(0); | ||
202 | // Xantor 20080528: Clear prim data of sound instead | ||
203 | if (m_host.ParentGroup.LoopSoundSlavePrims.Contains(m_host)) | ||
204 | { | ||
205 | if (m_host.ParentGroup.LoopSoundMasterPrim == m_host) | ||
206 | { | ||
207 | foreach (SceneObjectPart part in m_host.ParentGroup.LoopSoundSlavePrims) | ||
208 | { | ||
209 | part.Sound = UUID.Zero; | ||
210 | part.SoundFlags = 1 << 5; | ||
211 | part.SoundRadius = 0; | ||
212 | part.ScheduleFullUpdate(); | ||
213 | part.SendFullUpdateToAllClients(); | ||
214 | } | ||
215 | m_host.ParentGroup.LoopSoundMasterPrim = null; | ||
216 | m_host.ParentGroup.LoopSoundSlavePrims.Clear(); | ||
217 | } | ||
133 | else | 218 | else |
134 | thisSpGain = (float)((double)gain * ((radius - dis) / radius)); | 219 | { |
220 | m_host.Sound = UUID.Zero; | ||
221 | m_host.SoundFlags = 1 << 5; | ||
222 | m_host.SoundRadius = 0; | ||
223 | m_host.ScheduleFullUpdate(); | ||
224 | m_host.SendFullUpdateToAllClients(); | ||
225 | } | ||
226 | } | ||
227 | else | ||
228 | { | ||
229 | m_host.Sound = UUID.Zero; | ||
230 | m_host.SoundFlags = 1 << 5; | ||
231 | m_host.SoundRadius = 0; | ||
232 | m_host.ScheduleFullUpdate(); | ||
233 | m_host.SendFullUpdateToAllClients(); | ||
234 | } | ||
235 | } | ||
135 | 236 | ||
136 | sp.ControllingClient.SendTriggeredSound( | 237 | public virtual void PreloadSound(UUID objectID, UUID soundID, float radius) |
137 | soundId, ownerID, objectID, parentID, handle, position, thisSpGain); | 238 | { |
239 | SceneObjectPart part; | ||
240 | if (soundID == UUID.Zero | ||
241 | || !m_scene.TryGetSceneObjectPart(objectID, out part)) | ||
242 | { | ||
243 | return; | ||
244 | } | ||
245 | |||
246 | if (radius == 0) | ||
247 | radius = MaxDistance; | ||
248 | |||
249 | m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) | ||
250 | { | ||
251 | if (!(Util.GetDistanceTo(sp.AbsolutePosition, part.AbsolutePosition) >= MaxDistance)) | ||
252 | sp.ControllingClient.SendPreLoadSound(objectID, objectID, soundID); | ||
138 | }); | 253 | }); |
139 | } | 254 | } |
255 | |||
256 | // Xantor 20080528 we should do this differently. | ||
257 | // 1) apply the sound to the object | ||
258 | // 2) schedule full update | ||
259 | // just sending the sound out once doesn't work so well when other avatars come in view later on | ||
260 | // or when the prim gets moved, changed, sat on, whatever | ||
261 | // see large number of mantises (mantes?) | ||
262 | // 20080530 Updated to remove code duplication | ||
263 | // 20080530 Stop sound if there is one, otherwise volume only changes don't work | ||
264 | public void LoopSound(UUID objectID, UUID soundID, | ||
265 | double volume, double radius, bool isMaster) | ||
266 | { | ||
267 | SceneObjectPart m_host; | ||
268 | if (!m_scene.TryGetSceneObjectPart(objectID, out m_host)) | ||
269 | return; | ||
270 | |||
271 | if (isMaster) | ||
272 | m_host.ParentGroup.LoopSoundMasterPrim = m_host; | ||
273 | |||
274 | if (m_host.Sound != UUID.Zero) | ||
275 | StopSound(m_host); | ||
276 | |||
277 | m_host.Sound = soundID; | ||
278 | m_host.SoundGain = volume; | ||
279 | m_host.SoundFlags = 1; // looping | ||
280 | m_host.SoundRadius = radius; | ||
281 | |||
282 | m_host.ScheduleFullUpdate(); | ||
283 | m_host.SendFullUpdateToAllClients(); | ||
284 | } | ||
285 | |||
286 | public void SendSound(UUID objectID, UUID soundID, double volume, | ||
287 | bool triggered, byte flags, float radius, bool useMaster, | ||
288 | bool isMaster) | ||
289 | { | ||
290 | if (soundID == UUID.Zero) | ||
291 | return; | ||
292 | |||
293 | SceneObjectPart part; | ||
294 | if (!m_scene.TryGetSceneObjectPart(objectID, out part)) | ||
295 | return; | ||
296 | |||
297 | volume = Util.Clip((float)volume, 0, 1); | ||
298 | |||
299 | UUID parentID = part.ParentGroup.UUID; | ||
300 | |||
301 | Vector3 position = part.AbsolutePosition; // region local | ||
302 | ulong regionHandle = m_scene.RegionInfo.RegionHandle; | ||
303 | |||
304 | if (useMaster) | ||
305 | { | ||
306 | if (isMaster) | ||
307 | { | ||
308 | if (triggered) | ||
309 | TriggerSound(soundID, part.OwnerID, part.UUID, parentID, volume, position, regionHandle, radius); | ||
310 | else | ||
311 | PlayAttachedSound(soundID, part.OwnerID, part.UUID, volume, position, flags, radius); | ||
312 | part.ParentGroup.PlaySoundMasterPrim = part; | ||
313 | if (triggered) | ||
314 | TriggerSound(soundID, part.OwnerID, part.UUID, parentID, volume, position, regionHandle, radius); | ||
315 | else | ||
316 | PlayAttachedSound(soundID, part.OwnerID, part.UUID, volume, position, flags, radius); | ||
317 | foreach (SceneObjectPart prim in part.ParentGroup.PlaySoundSlavePrims) | ||
318 | { | ||
319 | position = prim.AbsolutePosition; // region local | ||
320 | if (triggered) | ||
321 | TriggerSound(soundID, part.OwnerID, prim.UUID, parentID, volume, position, regionHandle, radius); | ||
322 | else | ||
323 | PlayAttachedSound(soundID, part.OwnerID, prim.UUID, volume, position, flags, radius); | ||
324 | } | ||
325 | part.ParentGroup.PlaySoundSlavePrims.Clear(); | ||
326 | part.ParentGroup.PlaySoundMasterPrim = null; | ||
327 | } | ||
328 | else | ||
329 | { | ||
330 | part.ParentGroup.PlaySoundSlavePrims.Add(part); | ||
331 | } | ||
332 | } | ||
333 | else | ||
334 | { | ||
335 | if (triggered) | ||
336 | TriggerSound(soundID, part.OwnerID, part.UUID, parentID, volume, position, regionHandle, radius); | ||
337 | else | ||
338 | PlayAttachedSound(soundID, part.OwnerID, part.UUID, volume, position, flags, radius); | ||
339 | } | ||
340 | } | ||
341 | |||
342 | public void TriggerSoundLimited(UUID objectID, UUID sound, | ||
343 | double volume, Vector3 min, Vector3 max) | ||
344 | { | ||
345 | if (sound == UUID.Zero) | ||
346 | return; | ||
347 | |||
348 | SceneObjectPart part; | ||
349 | if (!m_scene.TryGetSceneObjectPart(objectID, out part)) | ||
350 | return; | ||
351 | |||
352 | m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) | ||
353 | { | ||
354 | double dis = Util.GetDistanceTo(sp.AbsolutePosition, | ||
355 | part.AbsolutePosition); | ||
356 | |||
357 | if (dis > MaxDistance) // Max audio distance | ||
358 | return; | ||
359 | else if (!Util.IsInsideBox(sp.AbsolutePosition, min, max)) | ||
360 | return; | ||
361 | |||
362 | // Scale by distance | ||
363 | double thisSpGain = volume * ((MaxDistance - dis) / MaxDistance); | ||
364 | |||
365 | sp.ControllingClient.SendTriggeredSound(sound, part.OwnerID, | ||
366 | part.UUID, part.ParentGroup.UUID, | ||
367 | m_scene.RegionInfo.RegionHandle, | ||
368 | part.AbsolutePosition, (float)thisSpGain); | ||
369 | }); | ||
370 | } | ||
371 | |||
372 | #endregion | ||
140 | } | 373 | } |
141 | } | 374 | } |