diff options
Diffstat (limited to 'OpenSim/Region/Physics/OdePlugin/OdeScene.cs')
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 91 |
1 files changed, 52 insertions, 39 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index c3279c6..43d852b 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs | |||
@@ -219,9 +219,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
219 | private readonly List<d.ContactGeom> _perloopContact = new List<d.ContactGeom>(); | 219 | private readonly List<d.ContactGeom> _perloopContact = new List<d.ContactGeom>(); |
220 | 220 | ||
221 | /// <summary> | 221 | /// <summary> |
222 | /// A list of actors that should receive collision events. | 222 | /// A dictionary of actors that should receive collision events. |
223 | /// </summary> | 223 | /// </summary> |
224 | private readonly List<PhysicsActor> _collisionEventPrim = new List<PhysicsActor>(); | 224 | private readonly Dictionary<uint, PhysicsActor> _collisionEventPrim = new Dictionary<uint, PhysicsActor>(); |
225 | |||
226 | /// <summary> | ||
227 | /// A dictionary of collision event changes that are waiting to be processed. | ||
228 | /// </summary> | ||
229 | private readonly Dictionary<uint, PhysicsActor> _collisionEventPrimChanges = new Dictionary<uint, PhysicsActor>(); | ||
225 | 230 | ||
226 | private readonly HashSet<OdeCharacter> _badCharacter = new HashSet<OdeCharacter>(); | 231 | private readonly HashSet<OdeCharacter> _badCharacter = new HashSet<OdeCharacter>(); |
227 | public Dictionary<IntPtr, String> geom_name_map = new Dictionary<IntPtr, String>(); | 232 | public Dictionary<IntPtr, String> geom_name_map = new Dictionary<IntPtr, String>(); |
@@ -1301,8 +1306,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1301 | { | 1306 | { |
1302 | case ActorTypes.Agent: | 1307 | case ActorTypes.Agent: |
1303 | cc1 = (OdeCharacter)p1; | 1308 | cc1 = (OdeCharacter)p1; |
1304 | obj2LocalID = cc1.m_localID; | 1309 | obj2LocalID = cc1.LocalID; |
1305 | cc1.AddCollisionEvent(cc2.m_localID, contact); | 1310 | cc1.AddCollisionEvent(cc2.LocalID, contact); |
1306 | //ctype = (int)CollisionCategories.Character; | 1311 | //ctype = (int)CollisionCategories.Character; |
1307 | 1312 | ||
1308 | //if (cc1.CollidingObj) | 1313 | //if (cc1.CollidingObj) |
@@ -1317,8 +1322,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1317 | if (p1 is OdePrim) | 1322 | if (p1 is OdePrim) |
1318 | { | 1323 | { |
1319 | cp1 = (OdePrim) p1; | 1324 | cp1 = (OdePrim) p1; |
1320 | obj2LocalID = cp1.m_localID; | 1325 | obj2LocalID = cp1.LocalID; |
1321 | cp1.AddCollisionEvent(cc2.m_localID, contact); | 1326 | cp1.AddCollisionEvent(cc2.LocalID, contact); |
1322 | } | 1327 | } |
1323 | //ctype = (int)CollisionCategories.Geom; | 1328 | //ctype = (int)CollisionCategories.Geom; |
1324 | 1329 | ||
@@ -1354,8 +1359,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1354 | if (p1 is OdeCharacter) | 1359 | if (p1 is OdeCharacter) |
1355 | { | 1360 | { |
1356 | cc1 = (OdeCharacter) p1; | 1361 | cc1 = (OdeCharacter) p1; |
1357 | obj2LocalID = cc1.m_localID; | 1362 | obj2LocalID = cc1.LocalID; |
1358 | cc1.AddCollisionEvent(cp2.m_localID, contact); | 1363 | cc1.AddCollisionEvent(cp2.LocalID, contact); |
1359 | //ctype = (int)CollisionCategories.Character; | 1364 | //ctype = (int)CollisionCategories.Character; |
1360 | 1365 | ||
1361 | //if (cc1.CollidingObj) | 1366 | //if (cc1.CollidingObj) |
@@ -1370,8 +1375,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1370 | if (p1 is OdePrim) | 1375 | if (p1 is OdePrim) |
1371 | { | 1376 | { |
1372 | cp1 = (OdePrim) p1; | 1377 | cp1 = (OdePrim) p1; |
1373 | obj2LocalID = cp1.m_localID; | 1378 | obj2LocalID = cp1.LocalID; |
1374 | cp1.AddCollisionEvent(cp2.m_localID, contact); | 1379 | cp1.AddCollisionEvent(cp2.LocalID, contact); |
1375 | //ctype = (int)CollisionCategories.Geom; | 1380 | //ctype = (int)CollisionCategories.Geom; |
1376 | 1381 | ||
1377 | //if (cp1.CollidingObj) | 1382 | //if (cp1.CollidingObj) |
@@ -1633,13 +1638,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1633 | /// <param name="obj"></param> | 1638 | /// <param name="obj"></param> |
1634 | internal void AddCollisionEventReporting(PhysicsActor obj) | 1639 | internal void AddCollisionEventReporting(PhysicsActor obj) |
1635 | { | 1640 | { |
1636 | // m_log.DebugFormat("[PHYSICS]: Adding {0} to collision event reporting", obj.SOPName); | 1641 | // m_log.DebugFormat("[PHYSICS]: Adding {0} {1} to collision event reporting", obj.SOPName, obj.LocalID); |
1637 | 1642 | ||
1638 | lock (_collisionEventPrim) | 1643 | lock (_collisionEventPrimChanges) |
1639 | { | 1644 | _collisionEventPrimChanges[obj.LocalID] = obj; |
1640 | if (!_collisionEventPrim.Contains(obj)) | ||
1641 | _collisionEventPrim.Add(obj); | ||
1642 | } | ||
1643 | } | 1645 | } |
1644 | 1646 | ||
1645 | /// <summary> | 1647 | /// <summary> |
@@ -1648,10 +1650,10 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1648 | /// <param name="obj"></param> | 1650 | /// <param name="obj"></param> |
1649 | internal void RemoveCollisionEventReporting(PhysicsActor obj) | 1651 | internal void RemoveCollisionEventReporting(PhysicsActor obj) |
1650 | { | 1652 | { |
1651 | // m_log.DebugFormat("[PHYSICS]: Removing {0} from collision event reporting", obj.SOPName); | 1653 | // m_log.DebugFormat("[PHYSICS]: Removing {0} {1} from collision event reporting", obj.SOPName, obj.LocalID); |
1652 | 1654 | ||
1653 | lock (_collisionEventPrim) | 1655 | lock (_collisionEventPrimChanges) |
1654 | _collisionEventPrim.Remove(obj); | 1656 | _collisionEventPrimChanges[obj.LocalID] = null; |
1655 | } | 1657 | } |
1656 | 1658 | ||
1657 | #region Add/Remove Entities | 1659 | #region Add/Remove Entities |
@@ -1752,9 +1754,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1752 | public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, | 1754 | public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, |
1753 | Vector3 size, Quaternion rotation, bool isPhysical, uint localid) | 1755 | Vector3 size, Quaternion rotation, bool isPhysical, uint localid) |
1754 | { | 1756 | { |
1755 | #if SPAM | 1757 | // m_log.DebugFormat("[ODE SCENE]: Adding physics actor to {0} {1}", primName, localid); |
1756 | m_log.DebugFormat("[PHYSICS]: Adding physics actor to {0}", primName); | ||
1757 | #endif | ||
1758 | 1758 | ||
1759 | return AddPrim(primName, position, size, rotation, pbs, isPhysical, localid); | 1759 | return AddPrim(primName, position, size, rotation, pbs, isPhysical, localid); |
1760 | } | 1760 | } |
@@ -2663,6 +2663,22 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); | |||
2663 | // m_physicsiterations = 10; | 2663 | // m_physicsiterations = 10; |
2664 | // } | 2664 | // } |
2665 | 2665 | ||
2666 | // We change _collisionEventPrimChanges to avoid locking _collisionEventPrim itself and causing potential | ||
2667 | // deadlock if the collision event tries to lock something else later on which is already locked by a | ||
2668 | // caller that is adding or removing the collision event. | ||
2669 | lock (_collisionEventPrimChanges) | ||
2670 | { | ||
2671 | foreach (KeyValuePair<uint, PhysicsActor> kvp in _collisionEventPrimChanges) | ||
2672 | { | ||
2673 | if (kvp.Value == null) | ||
2674 | _collisionEventPrim.Remove(kvp.Key); | ||
2675 | else | ||
2676 | _collisionEventPrim[kvp.Key] = kvp.Value; | ||
2677 | } | ||
2678 | |||
2679 | _collisionEventPrimChanges.Clear(); | ||
2680 | } | ||
2681 | |||
2666 | if (SupportsNINJAJoints) | 2682 | if (SupportsNINJAJoints) |
2667 | { | 2683 | { |
2668 | DeleteRequestedJoints(); // this must be outside of the lock (OdeLock) to avoid deadlocks | 2684 | DeleteRequestedJoints(); // this must be outside of the lock (OdeLock) to avoid deadlocks |
@@ -2790,25 +2806,22 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); | |||
2790 | 2806 | ||
2791 | collision_optimized(); | 2807 | collision_optimized(); |
2792 | 2808 | ||
2793 | lock (_collisionEventPrim) | 2809 | foreach (PhysicsActor obj in _collisionEventPrim.Values) |
2794 | { | 2810 | { |
2795 | foreach (PhysicsActor obj in _collisionEventPrim) | 2811 | // m_log.DebugFormat("[PHYSICS]: Assessing {0} {1} for collision events", obj.SOPName, obj.LocalID); |
2796 | { | ||
2797 | // m_log.DebugFormat("[PHYSICS]: Assessing {0} for collision events", obj.SOPName); | ||
2798 | 2812 | ||
2799 | switch ((ActorTypes)obj.PhysicsActorType) | 2813 | switch ((ActorTypes)obj.PhysicsActorType) |
2800 | { | 2814 | { |
2801 | case ActorTypes.Agent: | 2815 | case ActorTypes.Agent: |
2802 | OdeCharacter cobj = (OdeCharacter)obj; | 2816 | OdeCharacter cobj = (OdeCharacter)obj; |
2803 | cobj.AddCollisionFrameTime(100); | 2817 | cobj.AddCollisionFrameTime(100); |
2804 | cobj.SendCollisions(); | 2818 | cobj.SendCollisions(); |
2805 | break; | 2819 | break; |
2806 | 2820 | ||
2807 | case ActorTypes.Prim: | 2821 | case ActorTypes.Prim: |
2808 | OdePrim pobj = (OdePrim)obj; | 2822 | OdePrim pobj = (OdePrim)obj; |
2809 | pobj.SendCollisions(); | 2823 | pobj.SendCollisions(); |
2810 | break; | 2824 | break; |
2811 | } | ||
2812 | } | 2825 | } |
2813 | } | 2826 | } |
2814 | 2827 | ||
@@ -3731,7 +3744,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name); | |||
3731 | { | 3744 | { |
3732 | if (prm.CollisionScore > 0) | 3745 | if (prm.CollisionScore > 0) |
3733 | { | 3746 | { |
3734 | returncolliders.Add(prm.m_localID, prm.CollisionScore); | 3747 | returncolliders.Add(prm.LocalID, prm.CollisionScore); |
3735 | cnt++; | 3748 | cnt++; |
3736 | prm.CollisionScore = 0f; | 3749 | prm.CollisionScore = 0f; |
3737 | if (cnt > 25) | 3750 | if (cnt > 25) |