diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 9ae8dfbbad..c1b57814f7 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -329,6 +329,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP private Prioritizer m_prioritizer; private bool m_disableFacelights = false; + private const uint MaxTransferBytesPerPacket = 600; + + /// /// List used in construction of data blocks for an object update packet. This is to stop us having to /// continually recreate it. @@ -2738,7 +2741,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP else { int processedLength = 0; - int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; +// int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; + + int maxChunkSize = (int) MaxTransferBytesPerPacket; int packetNumber = 0; while (processedLength < req.AssetInf.Data.Length) @@ -12205,7 +12210,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// private static int CalculateNumPackets(byte[] data) { - const uint m_maxPacketSize = 600; +// const uint m_maxPacketSize = 600; + uint m_maxPacketSize = MaxTransferBytesPerPacket; int numPackets = 1; if (data == null) diff --git a/OpenSim/Region/Framework/Scenes/CollisionSounds.cs b/OpenSim/Region/Framework/Scenes/CollisionSounds.cs new file mode 100644 index 0000000000..5d4302730c --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/CollisionSounds.cs @@ -0,0 +1,271 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +// Ubit 2012 + +using System; +using System.Collections.Generic; +using OpenMetaverse; +using OpenSim.Framework; + +namespace OpenSim.Region.Framework.Scenes +{ + public static class CollisionSounds + { + // defines for cases + // only know one UUID for now (woodflesh) + + private const int MaxMaterials = 7; + // part part + private static UUID snd_StoneStone = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_StoneMetal = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_StoneGlass = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_StoneWood = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_StoneFlesh = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_StonePlastic = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_StoneRubber = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + + private static UUID snd_MetalStone = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_MetalMetal = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_MetalGlass = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_MetalWood = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_MetalFlesh = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_MetalPlastic = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_MetalRubber = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + + private static UUID snd_GlassStone = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_GlassMetal = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_GlassGlass = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_GlassWood = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_GlassFlesh = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_GlassPlastic = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_GlassRubber = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + + private static UUID snd_WoodStone = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_WoodMetal = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_WoodGlass = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_WoodWood = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_WoodFlesh = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_WoodPlastic = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_WoodRubber = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + + private static UUID snd_FleshStone = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_FleshMetal = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_FleshGlass = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_FleshWood = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_FleshFlesh = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_FleshPlastic = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_FleshRubber = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + + private static UUID snd_PlasticStone = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_PlasticMetal = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_PlasticGlass = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_PlasticWood = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_PlasticFlesh = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_PlasticPlastic = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_PlasticRubber = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + + private static UUID snd_RubberStone = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_RubberMetal = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_RubberGlass = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_RubberWood = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_RubberFlesh = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_RubberPlastic = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_RubberRubber = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + + // terrain part + private static UUID snd_TerrainStone = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_TerrainMetal = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_TerrainGlass = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_TerrainWood = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_TerrainFlesh = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_TerrainPlastic = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + private static UUID snd_TerrainRubber = new UUID("c80260ba-41fd-8a46-768a-6bf236360e3a"); + + public static UUID[] m_TerrainPart = { + snd_TerrainStone, + snd_TerrainMetal, + snd_TerrainGlass, + snd_TerrainWood, + snd_TerrainFlesh, + snd_TerrainPlastic, + snd_TerrainRubber + }; + + public static UUID[] m_PartPart = { + snd_StoneStone, snd_StoneMetal, snd_StoneGlass, snd_StoneWood, snd_StoneFlesh, snd_StonePlastic, snd_StoneRubber, + snd_MetalStone, snd_MetalMetal, snd_MetalGlass, snd_MetalWood, snd_MetalFlesh, snd_MetalPlastic, snd_MetalRubber, + snd_GlassStone, snd_GlassMetal, snd_GlassGlass, snd_GlassWood, snd_GlassFlesh, snd_GlassPlastic, snd_GlassRubber, + snd_WoodStone, snd_WoodMetal, snd_WoodGlass, snd_WoodWood, snd_WoodFlesh, snd_WoodPlastic, snd_WoodRubber, + snd_FleshStone, snd_FleshMetal, snd_FleshGlass, snd_FleshWood, snd_FleshFlesh, snd_FleshPlastic, snd_FleshRubber, + snd_PlasticStone, snd_PlasticMetal, snd_PlasticGlass, snd_PlasticWood, snd_PlasticFlesh, snd_PlasticPlastic, snd_PlasticRubber, + snd_RubberStone, snd_RubberMetal, snd_RubberGlass, snd_RubberWood, snd_RubberFlesh, snd_RubberPlastic, snd_RubberRubber + }; + + public static void PartCollisionSound(SceneObjectPart part,List Colliders) + { + if(Colliders.Count == 0 || part == null) + return; + + if (part.VolumeDetectActive || (part.Flags & PrimFlags.Physics) == 0) + return; + + if (part.ParentGroup == null) + return; + + if (part.CollisionSound == part.invalidCollisionSoundUUID) + return; + + UUID soundID; + int otherMaterial; + + Vector3 position = part.AbsolutePosition; + + if (part.CollisionSound != UUID.Zero) + { + if (part.CollisionSoundVolume > 0.0f) + part.SendCollisionSound(part.CollisionSound, part.CollisionSoundVolume, position); + return; + } + + int thisMaterial = (int) part.Material; + if (thisMaterial >= MaxMaterials) + thisMaterial = 3; + + int thisMatScaled = thisMaterial * MaxMaterials; + int index; + + bool doneownsound = false; + + foreach (uint Id in Colliders) + { + if (Id == 0) + { + if (!doneownsound) + { + soundID = m_TerrainPart[thisMaterial]; + part.SendCollisionSound(soundID, 1.0, position); + doneownsound = true; + } + continue; + } + + SceneObjectPart otherPart = part.ParentGroup.Scene.GetSceneObjectPart(Id); + if (otherPart != null) + { + if (otherPart.CollisionSound == part.invalidCollisionSoundUUID || otherPart.VolumeDetectActive) + continue; + if (otherPart.CollisionSound != UUID.Zero) + otherPart.SendCollisionSound(otherPart.CollisionSound, otherPart.CollisionSoundVolume, position); + else + { + otherMaterial = (int)otherPart.Material; + if (otherMaterial >= MaxMaterials) + otherMaterial = 3; + index = thisMatScaled + otherMaterial; + soundID = m_PartPart[index]; + if (doneownsound) + otherPart.SendCollisionSound(soundID, 1.0, position); + else + { + part.SendCollisionSound(soundID, 1.0, position); + doneownsound = true; + } + } + } +/* avatars get notification let them trigger the sound + else if (!doneownsound) + { + ScenePresence av = part.ParentGroup.Scene.GetScenePresence(Id); + if (av != null && (!av.IsChildAgent)) + { + index = thisMatScaled + 4; // flesh + soundID = m_PartPart[index]; + part.SendCollisionSound(soundID, 1.0); + doneownsound = true; + } + } + */ + } + } + + public static void AvatarCollisionSound(ScenePresence av, List Colliders) + { + if (Colliders.Count == 0 || av == null) + return; + + UUID soundID; + int otherMaterial; + + int thisMaterial = 3; + + int thisMatScaled = thisMaterial * MaxMaterials; + int index; +// bool doneownsound = false; + + Vector3 position = av.AbsolutePosition; + + foreach (uint Id in Colliders) + { + if (Id == 0) + { + continue; + } + + SceneObjectPart otherPart = av.Scene.GetSceneObjectPart(Id); + if (otherPart != null) + { + if (otherPart.CollisionSound == otherPart.invalidCollisionSoundUUID) + continue; + if (otherPart.CollisionSound != UUID.Zero) + otherPart.SendCollisionSound(otherPart.CollisionSound, otherPart.CollisionSoundVolume, position); + else + { + otherMaterial = (int)otherPart.Material; + if (otherMaterial >= MaxMaterials) + otherMaterial = 3; + index = thisMatScaled + otherMaterial; + soundID = m_PartPart[index]; + otherPart.SendCollisionSound(soundID, 1.0, position); + } + } +/* + else if (!doneownsound) + { + ScenePresence otherav = av.Scene.GetScenePresence(Id); + if (otherav != null && (!otherav.IsChildAgent)) + { + soundID = snd_FleshFlesh; + av.SendCollisionSound(soundID, 1.0); + doneownsound = true; + } + } + */ + } + } + + } +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index a1f434e567..221a32bf3e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -188,6 +188,7 @@ namespace OpenSim.Region.Framework.Scenes public double SoundRadius; + public uint TimeStampFull; public uint TimeStampLastActivity; // Will be used for AutoReturn @@ -332,6 +333,8 @@ namespace OpenSim.Region.Framework.Scenes private UUID m_collisionSound; private float m_collisionSoundVolume; + private DateTime LastColSoundSentTime; + private SOPVehicle m_vehicle = null; @@ -371,6 +374,7 @@ namespace OpenSim.Region.Framework.Scenes // this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from // the prim into an agent inventory (Linden client reports that the "Object not found for drop" in its log m_inventory = new SceneObjectPartInventory(this); + LastColSoundSentTime = DateTime.UtcNow; } /// @@ -1347,11 +1351,13 @@ namespace OpenSim.Region.Framework.Scenes set { m_sitAnimation = value; } } + public UUID invalidCollisionSoundUUID = new UUID("ffffffff-ffff-ffff-ffff-ffffffffffff"); + public UUID CollisionSound { get { return m_collisionSound; } set - { + { m_collisionSound = value; aggregateScriptEvents(); } @@ -2640,7 +2646,6 @@ namespace OpenSim.Region.Framework.Scenes else { - // calculate things that started colliding this time // and build up list of colliders this time foreach (uint localid in collissionswith.Keys) @@ -2665,12 +2670,13 @@ namespace OpenSim.Region.Framework.Scenes foreach (uint localID in endedColliders) m_lastColliders.Remove(localID); } + // play the sound. bool IsNotVolumeDtc = !VolumeDetectActive; - if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f && IsNotVolumeDtc) - SendSound(CollisionSound.ToString(), CollisionSoundVolume, true, (byte)0, 0, false, false); + if (IsNotVolumeDtc && startedColliders.Count > 0 && CollisionSound != invalidCollisionSoundUUID) + CollisionSounds.PartCollisionSound(this, startedColliders); SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart); if (IsNotVolumeDtc) @@ -3204,6 +3210,35 @@ namespace OpenSim.Region.Framework.Scenes } } + public void SendCollisionSound(UUID soundID, double volume, Vector3 position) + { + if (soundID == UUID.Zero) + return; + + ISoundModule soundModule = ParentGroup.Scene.RequestModuleInterface(); + if (soundModule == null) + return; + + if (volume > 1) + volume = 1; + if (volume < 0) + volume = 0; + + DateTime now = DateTime.UtcNow; + if((now - LastColSoundSentTime).Milliseconds < 200) // reduce rate to 5 per sec per part ?? + return; + + LastColSoundSentTime = now; + + UUID ownerID = OwnerID; + UUID objectID = ParentGroup.RootPart.UUID; + UUID parentID = ParentGroup.UUID; + ulong regionHandle = ParentGroup.Scene.RegionInfo.RegionHandle; + + soundModule.TriggerSound(soundID, ownerID, objectID, parentID, volume, position, regionHandle, 0 ); + } + + /// /// Send a terse update to all clients /// @@ -4757,7 +4792,7 @@ namespace OpenSim.Region.Framework.Scenes pa.OnCollisionUpdate -= PhysicsCollision; - bool hassound = ( CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f); + bool hassound = ( CollisionSound != invalidCollisionSoundUUID); scriptEvents CombinedEvents = AggregateScriptEvents; // merge with root part diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 8a6a6b4d92..913942f3f5 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3432,7 +3432,7 @@ namespace OpenSim.Region.Framework.Scenes //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong - PhysicsActor.SubscribeEvents(500); + PhysicsActor.SubscribeEvents(100); PhysicsActor.LocalID = LocalId; } @@ -4325,6 +4325,8 @@ namespace OpenSim.Region.Framework.Scenes // do event notification if (startedColliders.Count > 0) { + CollisionSounds.AvatarCollisionSound(this, startedColliders); + ColliderArgs StartCollidingMessage = new ColliderArgs(); List colliding = new List(); foreach (uint localId in startedColliders) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index c7e59ac1c8..25330029ba 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4627,7 +4627,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llCollisionSound(string impact_sound, double impact_volume) { m_host.AddScriptLPS(1); - + + if(impact_sound == "") + { + m_host.CollisionSoundVolume = (float)impact_volume; + m_host.CollisionSound = m_host.invalidCollisionSoundUUID; + return; + } // TODO: Parameter check logic required. UUID soundId = UUID.Zero; if (!UUID.TryParse(impact_sound, out soundId)) @@ -4643,8 +4649,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } m_host.TaskInventory.LockItemsForRead(false); } - m_host.CollisionSound = soundId; m_host.CollisionSoundVolume = (float)impact_volume; + m_host.CollisionSound = soundId; } public LSL_String llGetAnimation(string id) diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 5cad8836f2..1c59d4511c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -847,6 +847,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; + part.CollisionSound = UUID.Zero; AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); EventQueue.Clear(); m_Script.ResetVars(); @@ -873,6 +874,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; + part.CollisionSound = UUID.Zero; AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); EventQueue.Clear();