From 59826c15cea3ba4aa647d5d9545341d3e6df731f Mon Sep 17 00:00:00 2001
From: Melanie
Date: Mon, 14 May 2012 01:21:10 +0200
Subject: Allow non-gods to deed no-mod objects

---
 OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 0089c7d..29465c0 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -2338,7 +2338,10 @@ namespace OpenSim.Region.Framework.Scenes
                 }
                 else
                 {
-                    if (!Permissions.CanEditObject(sog.UUID, remoteClient.AgentId))
+                    if (!Permissions.IsGod(remoteClient.AgentId) && sog.OwnerID != remoteClient.AgentId)
+                        continue;
+
+                    if (!Permissions.CanTransferObject(sog.UUID, groupID))
                         continue;
 
                     if (sog.GroupID != groupID)
-- 
cgit v1.1


From e78043cb705520d1754a1a9450a4f82ff3deba53 Mon Sep 17 00:00:00 2001
From: Melanie
Date: Mon, 14 May 2012 01:32:22 +0200
Subject: Check parcel entry permissions when moving objects

---
 OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index f9c2193..fd25194 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -3752,7 +3752,8 @@ namespace OpenSim.Region.Framework.Scenes
                         }
                         if ((change & ObjectChangeType.Position) != 0)
                         {
-                            UpdateGroupPosition(data.position);
+                            if (m_scene.Permissions.CanObjectEntry(group.UUID, false, data.position))
+                                UpdateGroupPosition(data.position);
                             updateType = updatetype.groupterse;
                         }
                         else
-- 
cgit v1.1


From e3c376156c37fe8bf1b0e0b69cb4acd655d3528f Mon Sep 17 00:00:00 2001
From: Melanie
Date: Mon, 14 May 2012 22:45:54 +0200
Subject: Completely revamp collision handling. Now works as it is supposed to.

---
 .../Region/Framework/Scenes/SceneObjectGroup.cs    |  11 -
 OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 672 ++++++---------------
 .../Scenes/Serialization/SceneObjectSerializer.cs  |   7 +
 .../Shared/Api/Implementation/LSL_Api.cs           |  21 +-
 4 files changed, 189 insertions(+), 522 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index fd25194..a6551c1 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -755,17 +755,6 @@ namespace OpenSim.Region.Framework.Scenes
             get { return true; }
         }
         
-        private bool m_passCollision;
-        public bool PassCollision
-        {
-            get { return m_passCollision; }
-            set
-            {
-                m_passCollision = value;
-                HasGroupChanged = true;
-            }
-        }
-
         public bool IsSelected
         {
             get { return m_isSelected; }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index b0bc188..f7edd31 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -271,7 +271,8 @@ namespace OpenSim.Region.Framework.Scenes
         private string m_touchName = String.Empty;
         private UndoRedoState m_UndoRedo = null;
 
-        private bool m_passTouches;
+        private bool m_passTouches = false;
+        private bool m_passCollisions = false;
 
         protected Vector3 m_acceleration;
         protected Vector3 m_angularVelocity;
@@ -571,6 +572,7 @@ namespace OpenSim.Region.Framework.Scenes
             }
         }
 
+        [XmlIgnore]
         public bool PassTouches
         {
             get { return m_passTouches; }
@@ -583,6 +585,18 @@ namespace OpenSim.Region.Framework.Scenes
             }
         }
 
+        public bool PassCollisions
+        {
+            get { return m_passCollisions; }
+            set
+            {
+                m_passCollisions = value;
+
+                if (ParentGroup != null)
+                    ParentGroup.HasGroupChanged = true;
+            }
+        }
+
         public bool IsSelected
         {
             get { return m_isSelected; }
@@ -2433,546 +2447,202 @@ namespace OpenSim.Region.Framework.Scenes
         {
         }
 
-        public void PhysicsCollision(EventArgs e)
+        private bool CollisionFilteredOut(SceneObjectPart dest, UUID objectID, string objectName)
         {
-//            m_log.DebugFormat("Invoking PhysicsCollision on {0} {1} {2}", Name, LocalId, UUID);
-
-            // single threaded here
-
-            CollisionEventUpdate a = (CollisionEventUpdate)e;
-            Dictionary<uint, ContactPoint> collissionswith = a.m_objCollisionList;
-            List<uint> thisHitColliders = new List<uint>();
-            List<uint> endedColliders = new List<uint>();
-            List<uint> startedColliders = new List<uint>();
-
-            // calculate things that started colliding this time
-            // and build up list of colliders this time
-            foreach (uint localid in collissionswith.Keys)
-            {
-                thisHitColliders.Add(localid);
-                if (!m_lastColliders.Contains(localid))
-                {
-                    startedColliders.Add(localid);
-                }
-                //m_log.Debug("[OBJECT]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString());
-            }
-
-            // calculate things that ended colliding
-            foreach (uint localID in m_lastColliders)
-            {
-                if (!thisHitColliders.Contains(localID))
-                {
-                    endedColliders.Add(localID);
-                }
-            }
+            if(dest.CollisionFilter.Count == 0)
+                return false;
 
-            //add the items that started colliding this time to the last colliders list.
-            foreach (uint localID in startedColliders)
+            if (dest.CollisionFilter.ContainsValue(objectID.ToString()) ||
+                dest.CollisionFilter.ContainsValue(objectID.ToString() + objectName) ||
+                dest.CollisionFilter.ContainsValue(UUID.Zero.ToString() + objectName))
             {
-                m_lastColliders.Add(localID);
-            }
-            // remove things that ended colliding from the last colliders list
-            foreach (uint localID in endedColliders)
-            {
-                m_lastColliders.Remove(localID);
+                if (dest.CollisionFilter.ContainsKey(1))
+                    return false;
+                return true;
             }
 
-            if (ParentGroup.IsDeleted)
-                return;
+            if (dest.CollisionFilter.ContainsKey(1))
+                return true;
 
-            // play the sound.
-            if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f)
-            {
-                SendSound(CollisionSound.ToString(), CollisionSoundVolume, true, (byte)0, 0, false, false);
-            }
+            return false;
+        }
 
-            if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision_start) != 0)
-            {
-                // do event notification
-                if (startedColliders.Count > 0)
-                {
-                    ColliderArgs StartCollidingMessage = new ColliderArgs();
-                    List<DetectedObject> colliding = new List<DetectedObject>();
-                    foreach (uint localId in startedColliders)
-                    {
-                        if (localId == 0)
-                            continue;
+        private DetectedObject CreateDetObject(SceneObjectPart obj)
+        {
+            DetectedObject detobj = new DetectedObject();
+            detobj.keyUUID = obj.UUID;
+            detobj.nameStr = obj.Name;
+            detobj.ownerUUID = obj.OwnerID;
+            detobj.posVector = obj.AbsolutePosition;
+            detobj.rotQuat = obj.GetWorldRotation();
+            detobj.velVector = obj.Velocity;
+            detobj.colliderType = 0;
+            detobj.groupUUID = obj.GroupID;
 
-                        if (ParentGroup.Scene == null)
-                            return;
+            return detobj;
+        }
 
-                        SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId);
-                        string data = "";
-                        if (obj != null)
-                        {
-                            if (ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString())
-                                || ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
-                            {
-                                bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
-                                //If it is 1, it is to accept ONLY collisions from this object
-                                if (found)
-                                {
-                                    DetectedObject detobj = new DetectedObject();
-                                    detobj.keyUUID = obj.UUID;
-                                    detobj.nameStr = obj.Name;
-                                    detobj.ownerUUID = obj.OwnerID;
-                                    detobj.posVector = obj.AbsolutePosition;
-                                    detobj.rotQuat = obj.GetWorldRotation();
-                                    detobj.velVector = obj.Velocity;
-                                    detobj.colliderType = 0;
-                                    detobj.groupUUID = obj.GroupID;
-                                    colliding.Add(detobj);
-                                }
-                                //If it is 0, it is to not accept collisions from this object
-                                else
-                                {
-                                }
-                            }
-                            else
-                            {
-                                bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
-                                //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work
-                                if (!found)
-                                {
-                                    DetectedObject detobj = new DetectedObject();
-                                    detobj.keyUUID = obj.UUID;
-                                    detobj.nameStr = obj.Name;
-                                    detobj.ownerUUID = obj.OwnerID;
-                                    detobj.posVector = obj.AbsolutePosition;
-                                    detobj.rotQuat = obj.GetWorldRotation();
-                                    detobj.velVector = obj.Velocity;
-                                    detobj.colliderType = 0;
-                                    detobj.groupUUID = obj.GroupID;
-                                    colliding.Add(detobj);
-                                }
-                            }
-                        }
-                        else
-                        {
-                            ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence av)
-                            {
-                                if (av.LocalId == localId)
-                                {
-                                    if (ParentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
-                                        || ParentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
-                                    {
-                                        bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
-                                        //If it is 1, it is to accept ONLY collisions from this avatar
-                                        if (found)
-                                        {
-                                            DetectedObject detobj = new DetectedObject();
-                                            detobj.keyUUID = av.UUID;
-                                            detobj.nameStr = av.ControllingClient.Name;
-                                            detobj.ownerUUID = av.UUID;
-                                            detobj.posVector = av.AbsolutePosition;
-                                            detobj.rotQuat = av.Rotation;
-                                            detobj.velVector = av.Velocity;
-                                            detobj.colliderType = 0;
-                                            detobj.groupUUID = av.ControllingClient.ActiveGroupId;
-                                            colliding.Add(detobj);
-                                        }
-                                        //If it is 0, it is to not accept collisions from this avatar
-                                        else
-                                        {
-                                        }
-                                    }
-                                    else
-                                    {
-                                        bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
-                                        //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
-                                        if (!found)
-                                        {
-                                            DetectedObject detobj = new DetectedObject();
-                                            detobj.keyUUID = av.UUID;
-                                            detobj.nameStr = av.ControllingClient.Name;
-                                            detobj.ownerUUID = av.UUID;
-                                            detobj.posVector = av.AbsolutePosition;
-                                            detobj.rotQuat = av.Rotation;
-                                            detobj.velVector = av.Velocity;
-                                            detobj.colliderType = 0;
-                                            detobj.groupUUID = av.ControllingClient.ActiveGroupId;
-                                            colliding.Add(detobj);
-                                        }
-                                    }
+        private DetectedObject CreateDetObject(ScenePresence av)
+        {
+            DetectedObject detobj = new DetectedObject();
+            detobj.keyUUID = av.UUID;
+            detobj.nameStr = av.ControllingClient.Name;
+            detobj.ownerUUID = av.UUID;
+            detobj.posVector = av.AbsolutePosition;
+            detobj.rotQuat = av.Rotation;
+            detobj.velVector = av.Velocity;
+            detobj.colliderType = 0;
+            detobj.groupUUID = av.ControllingClient.ActiveGroupId;
 
-                                }
-                            });
-                        }
-                    }
+            return detobj;
+        }
 
-                    if (colliding.Count > 0)
-                    {
-                        StartCollidingMessage.Colliders = colliding;
+        private DetectedObject CreateDetObjectForGround()
+        {
+            DetectedObject detobj = new DetectedObject();
+            detobj.keyUUID = UUID.Zero;
+            detobj.nameStr = "";
+            detobj.ownerUUID = UUID.Zero;
+            detobj.posVector = ParentGroup.RootPart.AbsolutePosition;
+            detobj.rotQuat = Quaternion.Identity;
+            detobj.velVector = Vector3.Zero;
+            detobj.colliderType = 0;
+            detobj.groupUUID = UUID.Zero;
 
-                        if (ParentGroup.Scene == null)
-                            return;
+            return detobj;
+        }
 
-//                        if (m_parentGroup.PassCollision == true)
-//                        {
-//                            //TODO: Add pass to root prim!
-//                        }
+        private ColliderArgs CreateColliderArgs(SceneObjectPart dest, List<uint> colliders)
+        {
+            ColliderArgs colliderArgs = new ColliderArgs();
+            List<DetectedObject> colliding = new List<DetectedObject>();
+            foreach (uint localId in colliders)
+            {
+                if (localId == 0)
+                    continue;
 
-                        ParentGroup.Scene.EventManager.TriggerScriptCollidingStart(LocalId, StartCollidingMessage);
-                    }
+                SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId);
+                if (obj != null)
+                {
+                    if (!dest.CollisionFilteredOut(this, obj.UUID, obj.Name))
+                        colliding.Add(CreateDetObject(obj));
                 }
-            }
-
-            if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision) != 0)
-            {
-                if (m_lastColliders.Count > 0)
+                else
                 {
-                    ColliderArgs CollidingMessage = new ColliderArgs();
-                    List<DetectedObject> colliding = new List<DetectedObject>();
-                    foreach (uint localId in m_lastColliders)
+                    ScenePresence av = ParentGroup.Scene.GetScenePresence(localId);
+                    if (av != null && (!av.IsChildAgent))
                     {
-                        // always running this check because if the user deletes the object it would return a null reference.
-                        if (localId == 0)
-                            continue;
-                        
-                        if (ParentGroup.Scene == null)
-                            return;
-                        
-                        SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId);
-                        string data = "";
-                        if (obj != null)
-                        {
-                            if (ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString())
-                                || ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
-                            {
-                                bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
-                                //If it is 1, it is to accept ONLY collisions from this object
-                                if (found)
-                                {
-                                    DetectedObject detobj = new DetectedObject();
-                                    detobj.keyUUID = obj.UUID;
-                                    detobj.nameStr = obj.Name;
-                                    detobj.ownerUUID = obj.OwnerID;
-                                    detobj.posVector = obj.AbsolutePosition;
-                                    detobj.rotQuat = obj.GetWorldRotation();
-                                    detobj.velVector = obj.Velocity;
-                                    detobj.colliderType = 0;
-                                    detobj.groupUUID = obj.GroupID;
-                                    colliding.Add(detobj);
-                                }
-                                //If it is 0, it is to not accept collisions from this object
-                                else
-                                {
-                                }
-                            }
-                            else
-                            {
-                                bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
-                                //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work
-                                if (!found)
-                                {
-                                    DetectedObject detobj = new DetectedObject();
-                                    detobj.keyUUID = obj.UUID;
-                                    detobj.nameStr = obj.Name;
-                                    detobj.ownerUUID = obj.OwnerID;
-                                    detobj.posVector = obj.AbsolutePosition;
-                                    detobj.rotQuat = obj.GetWorldRotation();
-                                    detobj.velVector = obj.Velocity;
-                                    detobj.colliderType = 0;
-                                    detobj.groupUUID = obj.GroupID;
-                                    colliding.Add(detobj);
-                                }
-                            }
-                        }
-                        else
-                        {
-                            ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence av)
-                            {
-                                if (av.LocalId == localId)
-                                {
-                                    if (ParentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
-                                        || ParentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
-                                    {
-                                        bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
-                                        //If it is 1, it is to accept ONLY collisions from this avatar
-                                        if (found)
-                                        {
-                                            DetectedObject detobj = new DetectedObject();
-                                            detobj.keyUUID = av.UUID;
-                                            detobj.nameStr = av.ControllingClient.Name;
-                                            detobj.ownerUUID = av.UUID;
-                                            detobj.posVector = av.AbsolutePosition;
-                                            detobj.rotQuat = av.Rotation;
-                                            detobj.velVector = av.Velocity;
-                                            detobj.colliderType = 0;
-                                            detobj.groupUUID = av.ControllingClient.ActiveGroupId;
-                                            colliding.Add(detobj);
-                                        }
-                                        //If it is 0, it is to not accept collisions from this avatar
-                                        else
-                                        {
-                                        }
-                                    }
-                                    else
-                                    {
-                                        bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
-                                        //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
-                                        if (!found)
-                                        {
-                                            DetectedObject detobj = new DetectedObject();
-                                            detobj.keyUUID = av.UUID;
-                                            detobj.nameStr = av.ControllingClient.Name;
-                                            detobj.ownerUUID = av.UUID;
-                                            detobj.posVector = av.AbsolutePosition;
-                                            detobj.rotQuat = av.Rotation;
-                                            detobj.velVector = av.Velocity;
-                                            detobj.colliderType = 0;
-                                            detobj.groupUUID = av.ControllingClient.ActiveGroupId;
-                                            colliding.Add(detobj);
-                                        }
-                                    }
-
-                                }
-                            });
-                        }
-                    }
-                    if (colliding.Count > 0)
-                    {
-                        CollidingMessage.Colliders = colliding;
-                        
-                        if (ParentGroup.Scene == null)
-                            return;
-                        
-                        ParentGroup.Scene.EventManager.TriggerScriptColliding(LocalId, CollidingMessage);
+                        if (!dest.CollisionFilteredOut(this, av.UUID, av.Name))
+                            colliding.Add(CreateDetObject(av));
                     }
                 }
             }
-            
-            if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision_end) != 0)
-            {
-                if (endedColliders.Count > 0)
-                {
-                    ColliderArgs EndCollidingMessage = new ColliderArgs();
-                    List<DetectedObject> colliding = new List<DetectedObject>();
-                    foreach (uint localId in endedColliders)
-                    {
-                        if (localId == 0)
-                            continue;
 
-                        if (ParentGroup.Scene == null)
-                            return;
+            colliderArgs.Colliders = colliding;
 
-                        SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId);
-                        string data = "";
-                        if (obj != null)
-                        {
-                            if (ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || ParentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
-                            {
-                                bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
-                                //If it is 1, it is to accept ONLY collisions from this object
-                                if (found)
-                                {
-                                    DetectedObject detobj = new DetectedObject();
-                                    detobj.keyUUID = obj.UUID;
-                                    detobj.nameStr = obj.Name;
-                                    detobj.ownerUUID = obj.OwnerID;
-                                    detobj.posVector = obj.AbsolutePosition;
-                                    detobj.rotQuat = obj.GetWorldRotation();
-                                    detobj.velVector = obj.Velocity;
-                                    detobj.colliderType = 0;
-                                    detobj.groupUUID = obj.GroupID;
-                                    colliding.Add(detobj);
-                                }
-                                //If it is 0, it is to not accept collisions from this object
-                                else
-                                {
-                                }
-                            }
-                            else
-                            {
-                                bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
-                                //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work
-                                if (!found)
-                                {
-                                    DetectedObject detobj = new DetectedObject();
-                                    detobj.keyUUID = obj.UUID;
-                                    detobj.nameStr = obj.Name;
-                                    detobj.ownerUUID = obj.OwnerID;
-                                    detobj.posVector = obj.AbsolutePosition;
-                                    detobj.rotQuat = obj.GetWorldRotation();
-                                    detobj.velVector = obj.Velocity;
-                                    detobj.colliderType = 0;
-                                    detobj.groupUUID = obj.GroupID;
-                                    colliding.Add(detobj);
-                                }
-                            }
-                        }
-                        else
-                        {
-                            ParentGroup.Scene.ForEachRootScenePresence(delegate(ScenePresence av)
-                            {
-                                if (av.LocalId == localId)
-                                {
-                                    if (ParentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString())
-                                        || ParentGroup.RootPart.CollisionFilter.ContainsValue(av.Name))
-                                    {
-                                        bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
-                                        //If it is 1, it is to accept ONLY collisions from this avatar
-                                        if (found)
-                                        {
-                                            DetectedObject detobj = new DetectedObject();
-                                            detobj.keyUUID = av.UUID;
-                                            detobj.nameStr = av.ControllingClient.Name;
-                                            detobj.ownerUUID = av.UUID;
-                                            detobj.posVector = av.AbsolutePosition;
-                                            detobj.rotQuat = av.Rotation;
-                                            detobj.velVector = av.Velocity;
-                                            detobj.colliderType = 0;
-                                            detobj.groupUUID = av.ControllingClient.ActiveGroupId;
-                                            colliding.Add(detobj);
-                                        }
-                                        //If it is 0, it is to not accept collisions from this avatar
-                                        else
-                                        {
-                                        }
-                                    }
-                                    else
-                                    {
-                                        bool found = ParentGroup.RootPart.CollisionFilter.TryGetValue(1, out data);
-                                        //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
-                                        if (!found)
-                                        {
-                                            DetectedObject detobj = new DetectedObject();
-                                            detobj.keyUUID = av.UUID;
-                                            detobj.nameStr = av.ControllingClient.Name;
-                                            detobj.ownerUUID = av.UUID;
-                                            detobj.posVector = av.AbsolutePosition;
-                                            detobj.rotQuat = av.Rotation;
-                                            detobj.velVector = av.Velocity;
-                                            detobj.colliderType = 0;
-                                            detobj.groupUUID = av.ControllingClient.ActiveGroupId;
-                                            colliding.Add(detobj);
-                                        }
-                                    }
+            return colliderArgs;
+        }
 
-                                }
-                            });
-                        }
-                    }
-                    
-                    if (colliding.Count > 0)
-                    {
-                        EndCollidingMessage.Colliders = colliding;
-                        
-                        if (ParentGroup.Scene == null)
-                            return;
-                        
-                        ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd(LocalId, EndCollidingMessage);
-                    }
-                }
-            }
+        private delegate void ScriptCollidingNotification(uint localID, ColliderArgs message);
+
+        private void SendCollisionEvent(scriptEvents ev, List<uint> colliders, ScriptCollidingNotification notify)
+        {
+            bool sendToRoot = false;
+            ColliderArgs CollidingMessage;
 
-            if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_start) != 0)
+            if (colliders.Count > 0)
             {
-                if (startedColliders.Count > 0)
+                if ((ScriptEvents & ev) != 0)
                 {
-                    ColliderArgs LandStartCollidingMessage = new ColliderArgs();
-                    List<DetectedObject> colliding = new List<DetectedObject>();
-                    foreach (uint localId in startedColliders)
-                    {
-                        if (localId == 0)
-                        {
-                            //Hope that all is left is ground!
-                            DetectedObject detobj = new DetectedObject();
-                            detobj.keyUUID = UUID.Zero;
-                            detobj.nameStr = "";
-                            detobj.ownerUUID = UUID.Zero;
-                            detobj.posVector = ParentGroup.RootPart.AbsolutePosition;
-                            detobj.rotQuat = Quaternion.Identity;
-                            detobj.velVector = Vector3.Zero;
-                            detobj.colliderType = 0;
-                            detobj.groupUUID = UUID.Zero;
-                            colliding.Add(detobj);
-                        }
-                    }
-
-                    if (colliding.Count > 0)
-                    {
-                        LandStartCollidingMessage.Colliders = colliding;
+                    CollidingMessage = CreateColliderArgs(this, colliders);
 
-                        if (ParentGroup.Scene == null)
-                            return;
+                    if (CollidingMessage.Colliders.Count > 0)
+                        notify(LocalId, CollidingMessage);
 
-                        ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart(LocalId, LandStartCollidingMessage);
-                    }
+                    if (PassCollisions)
+                        sendToRoot = true;
+                }
+                else
+                {
+                    if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.collision_start) != 0)
+                        sendToRoot = true;
+                }
+                if (sendToRoot && ParentGroup.RootPart != this)
+                {
+                    CollidingMessage = CreateColliderArgs(ParentGroup.RootPart, colliders);
+                    if (CollidingMessage.Colliders.Count > 0)
+                        notify(ParentGroup.RootPart.LocalId, CollidingMessage);
                 }
             }
+        }
 
-            if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.land_collision) != 0)
+        private void SendLandCollisionEvent(scriptEvents ev, ScriptCollidingNotification notify)
+        {
+            if ((ParentGroup.RootPart.ScriptEvents & ev) != 0)
             {
-                if (m_lastColliders.Count > 0)
-                {
-                    ColliderArgs LandCollidingMessage = new ColliderArgs();
-                    List<DetectedObject> colliding = new List<DetectedObject>();
-                    foreach (uint localId in startedColliders)
-                    {
-                        if (localId == 0)
-                        {
-                            //Hope that all is left is ground!
-                            DetectedObject detobj = new DetectedObject();
-                            detobj.keyUUID = UUID.Zero;
-                            detobj.nameStr = "";
-                            detobj.ownerUUID = UUID.Zero;
-                            detobj.posVector = ParentGroup.RootPart.AbsolutePosition;
-                            detobj.rotQuat = Quaternion.Identity;
-                            detobj.velVector = Vector3.Zero;
-                            detobj.colliderType = 0;
-                            detobj.groupUUID = UUID.Zero;
-                            colliding.Add(detobj);
-                        }
-                    }
+                ColliderArgs LandCollidingMessage = new ColliderArgs();
+                List<DetectedObject> colliding = new List<DetectedObject>();
+                    
+                colliding.Add(CreateDetObjectForGround());
+                LandCollidingMessage.Colliders = colliding;
 
-                    if (colliding.Count > 0)
-                    {
-                        LandCollidingMessage.Colliders = colliding;
+                notify(LocalId, LandCollidingMessage);
+            }
+        }
 
-                        if (ParentGroup.Scene == null)
-                            return;
+        public void PhysicsCollision(EventArgs e)
+        {
+            if (ParentGroup.Scene == null || ParentGroup.IsDeleted)
+                return;
 
-                        ParentGroup.Scene.EventManager.TriggerScriptLandColliding(LocalId, LandCollidingMessage);
-                    }
-                }
+            // single threaded here
+            CollisionEventUpdate a = (CollisionEventUpdate)e;
+            Dictionary<uint, ContactPoint> collissionswith = a.m_objCollisionList;
+            List<uint> thisHitColliders = new List<uint>();
+            List<uint> endedColliders = new List<uint>();
+            List<uint> startedColliders = new List<uint>();
+
+            // calculate things that started colliding this time
+            // and build up list of colliders this time
+            foreach (uint localid in collissionswith.Keys)
+            {
+                thisHitColliders.Add(localid);
+                if (!m_lastColliders.Contains(localid))
+                    startedColliders.Add(localid);
             }
 
-            if ((ParentGroup.RootPart.ScriptEvents & scriptEvents.land_collision_end) != 0)
+            // calculate things that ended colliding
+            foreach (uint localID in m_lastColliders)
             {
-                if (endedColliders.Count > 0)
-                {
-                    ColliderArgs LandEndCollidingMessage = new ColliderArgs();
-                    List<DetectedObject> colliding = new List<DetectedObject>();
-                    foreach (uint localId in startedColliders)
-                    {
-                        if (localId == 0)
-                        {
-                            //Hope that all is left is ground!
-                            DetectedObject detobj = new DetectedObject();
-                            detobj.keyUUID = UUID.Zero;
-                            detobj.nameStr = "";
-                            detobj.ownerUUID = UUID.Zero;
-                            detobj.posVector = ParentGroup.RootPart.AbsolutePosition;
-                            detobj.rotQuat = Quaternion.Identity;
-                            detobj.velVector = Vector3.Zero;
-                            detobj.colliderType = 0;
-                            detobj.groupUUID = UUID.Zero;
-                            colliding.Add(detobj);
-                        }
-                    }
+                if (!thisHitColliders.Contains(localID))
+                    endedColliders.Add(localID);
+            }
 
-                    if (colliding.Count > 0)
-                    {
-                        LandEndCollidingMessage.Colliders = colliding;
+            //add the items that started colliding this time to the last colliders list.
+            foreach (uint localID in startedColliders)
+                m_lastColliders.Add(localID);
 
-                        if (ParentGroup.Scene == null)
-                            return;
+            // remove things that ended colliding from the last colliders list
+            foreach (uint localID in endedColliders)
+                m_lastColliders.Remove(localID);
 
-                        ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd(LocalId, LandEndCollidingMessage);
-                    }
-                }
+            // play the sound.
+            if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f)
+                SendSound(CollisionSound.ToString(), CollisionSoundVolume, true, (byte)0, 0, false, false);
+
+            SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart);
+            SendCollisionEvent(scriptEvents.collision      , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding);
+            SendCollisionEvent(scriptEvents.collision_end  , endedColliders  , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd);
+
+            if (startedColliders.Contains(0))
+            {
+                if (m_lastColliders.Contains(0))
+                    SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding);
+                else
+                    SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart);
             }
+            if (endedColliders.Contains(0))
+                SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd);
         }
 
         public void PhysicsOutOfBounds(Vector3 pos)
@@ -4724,7 +4394,7 @@ namespace OpenSim.Region.Framework.Scenes
 //                                ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
 //                                ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
 //                                ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
-                                ((AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
+                                ((AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || ((ParentGroup.RootPart.AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
 //                                (CollisionSound != UUID.Zero)
                                 )
                             {
@@ -5077,7 +4747,7 @@ namespace OpenSim.Region.Framework.Scenes
 //                    ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) ||
 //                    ((AggregateScriptEvents & scriptEvents.land_collision) != 0) ||
 //                    ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) ||
-                    ((AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
+                    ((AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || ((ParentGroup.RootPart.AggregateScriptEvents & PhyscicsNeededSubsEvents) != 0) || (CollisionSound != UUID.Zero)
                     )
                 {
                     // subscribe to physics updates.
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 1cd8189..151eba2 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -307,6 +307,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
             m_SOPXmlProcessors.Add("Name", ProcessName);
             m_SOPXmlProcessors.Add("Material", ProcessMaterial);
             m_SOPXmlProcessors.Add("PassTouches", ProcessPassTouches);
+            m_SOPXmlProcessors.Add("PassCollisions", ProcessPassCollisions);
             m_SOPXmlProcessors.Add("RegionHandle", ProcessRegionHandle);
             m_SOPXmlProcessors.Add("ScriptAccessPin", ProcessScriptAccessPin);
             m_SOPXmlProcessors.Add("GroupPosition", ProcessGroupPosition);
@@ -506,6 +507,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
             obj.PassTouches = Util.ReadBoolean(reader);
         }
 
+        private static void ProcessPassCollisions(SceneObjectPart obj, XmlTextReader reader)
+        {
+            obj.PassCollisions = Util.ReadBoolean(reader);
+        }
+
         private static void ProcessRegionHandle(SceneObjectPart obj, XmlTextReader reader)
         {
             obj.RegionHandle = (ulong)reader.ReadElementContentAsLong("RegionHandle", String.Empty);
@@ -1246,6 +1252,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
             writer.WriteElementString("Name", sop.Name);
             writer.WriteElementString("Material", sop.Material.ToString());
             writer.WriteElementString("PassTouches", sop.PassTouches.ToString().ToLower());
+            writer.WriteElementString("PassCollisions", sop.PassCollisions.ToString().ToLower());
             writer.WriteElementString("RegionHandle", sop.RegionHandle.ToString());
             writer.WriteElementString("ScriptAccessPin", sop.ScriptAccessPin.ToString());
 
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 6523c2d..edabc2e 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -3198,14 +3198,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
         {
             m_host.AddScriptLPS(1);
             m_host.CollisionFilter.Clear();
-            if (id != null)
-            {
-                m_host.CollisionFilter.Add(accept,id);
-            }
-            else
-            {
-                m_host.CollisionFilter.Add(accept,name);
-            }
+            UUID objectID;
+
+            if (!UUID.TryParse(id, out objectID))
+                objectID = UUID.Zero;
+            
+            if (objectID == UUID.Zero && name == "")
+                return;
+
+            m_host.CollisionFilter.Add(accept,objectID.ToString() + name);
         }
 
         public void llTakeControls(int controls, int accept, int pass_on)
@@ -5023,11 +5024,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             m_host.AddScriptLPS(1);
             if (pass == 0)
             {
-                m_host.ParentGroup.PassCollision = false;
+                m_host.PassCollisions = false;
             }
             else
             {
-                m_host.ParentGroup.PassCollision = true;
+                m_host.PassCollisions = true;
             }
         }
 
-- 
cgit v1.1