aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2011-11-21 21:04:24 +0000
committerJustin Clark-Casey (justincc)2011-11-21 21:04:24 +0000
commit7480f2fd0e5482d366890b34d4aca72c887e02c3 (patch)
treed0ff0bc3decfc18907fbc77d2579c95578f3ec67 /OpenSim/Region/Physics
parentsimplify operation of OdeScene._perloopContact (diff)
downloadopensim-SC-7480f2fd0e5482d366890b34d4aca72c887e02c3.zip
opensim-SC-7480f2fd0e5482d366890b34d4aca72c887e02c3.tar.gz
opensim-SC-7480f2fd0e5482d366890b34d4aca72c887e02c3.tar.bz2
opensim-SC-7480f2fd0e5482d366890b34d4aca72c887e02c3.tar.xz
Restore defects list. In hindsight, the reason for this is becuase we can't remove the character whilst iterating over the list.
This commit also removes locking on OdeScene._characters since code is single threaded
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODECharacter.cs27
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdeScene.cs177
2 files changed, 112 insertions, 92 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index 5a7626e..cfe64f2 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -862,11 +862,10 @@ namespace OpenSim.Region.Physics.OdePlugin
862 /// Called from Simulate 862 /// Called from Simulate
863 /// This is the avatar's movement control + PID Controller 863 /// This is the avatar's movement control + PID Controller
864 /// </summary> 864 /// </summary>
865 /// <remarks> 865 /// <param name="defects">The character will be added to this list if there is something wrong (non-finite
866 /// This routine will remove the character from the physics scene if it detects something wrong (non-finite
867 /// position or velocity). 866 /// position or velocity).
868 /// </remarks> 867 /// </param>
869 internal void Move() 868 internal void Move(List<OdeCharacter> defects)
870 { 869 {
871 // no lock; for now it's only called from within Simulate() 870 // no lock; for now it's only called from within Simulate()
872 871
@@ -891,8 +890,7 @@ namespace OpenSim.Region.Physics.OdePlugin
891 "[ODE CHARACTER]: Avatar position of {0} for {1} is non-finite! Removing from physics scene.", 890 "[ODE CHARACTER]: Avatar position of {0} for {1} is non-finite! Removing from physics scene.",
892 localPos, Name); 891 localPos, Name);
893 892
894 _parent_scene.RemoveCharacter(this); 893 defects.Add(this);
895 DestroyOdeStructures();
896 894
897 return; 895 return;
898 } 896 }
@@ -1031,15 +1029,19 @@ namespace OpenSim.Region.Physics.OdePlugin
1031 "[ODE CHARACTER]: Got a NaN force vector {0} in Move() for {1}. Removing character from physics scene.", 1029 "[ODE CHARACTER]: Got a NaN force vector {0} in Move() for {1}. Removing character from physics scene.",
1032 vec, Name); 1030 vec, Name);
1033 1031
1034 _parent_scene.RemoveCharacter(this); 1032 defects.Add(this);
1035 DestroyOdeStructures(); 1033
1034 return;
1036 } 1035 }
1037 } 1036 }
1038 1037
1039 /// <summary> 1038 /// <summary>
1040 /// Updates the reported position and velocity. This essentially sends the data up to ScenePresence. 1039 /// Updates the reported position and velocity. This essentially sends the data up to ScenePresence.
1041 /// </summary> 1040 /// </summary>
1042 internal void UpdatePositionAndVelocity() 1041 /// <param name="defects">The character will be added to this list if there is something wrong (non-finite
1042 /// position or velocity).
1043 /// </param>
1044 internal void UpdatePositionAndVelocity(List<OdeCharacter> defects)
1043 { 1045 {
1044 // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! 1046 // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
1045 d.Vector3 newPos; 1047 d.Vector3 newPos;
@@ -1050,11 +1052,12 @@ namespace OpenSim.Region.Physics.OdePlugin
1050 catch (NullReferenceException) 1052 catch (NullReferenceException)
1051 { 1053 {
1052 bad = true; 1054 bad = true;
1053 _parent_scene.RemoveCharacter(this); 1055 defects.Add(this);
1054 DestroyOdeStructures();
1055 newPos = new d.Vector3(_position.X, _position.Y, _position.Z); 1056 newPos = new d.Vector3(_position.X, _position.Y, _position.Z);
1056 base.RaiseOutOfBounds(_position); // Tells ScenePresence that there's a problem! 1057 base.RaiseOutOfBounds(_position); // Tells ScenePresence that there's a problem!
1057 m_log.WarnFormat("[ODE CHARACTER]: Avatar Null reference for Avatar {0}, physical actor {1}", Name, m_uuid); 1058 m_log.WarnFormat("[ODE CHARACTER]: Avatar Null reference for Avatar {0}, physical actor {1}", Name, m_uuid);
1059
1060 return;
1058 } 1061 }
1059 1062
1060 // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!) 1063 // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!)
@@ -1134,7 +1137,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1134 /// <summary> 1137 /// <summary>
1135 /// Used internally to destroy the ODE structures associated with this character. 1138 /// Used internally to destroy the ODE structures associated with this character.
1136 /// </summary> 1139 /// </summary>
1137 private void DestroyOdeStructures() 1140 internal void DestroyOdeStructures()
1138 { 1141 {
1139 // destroy avatar capsule and related ODE data 1142 // destroy avatar capsule and related ODE data
1140 if (Amotor != IntPtr.Zero) 1143 if (Amotor != IntPtr.Zero)
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
index 7db188f..89568b6 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
@@ -189,7 +189,11 @@ namespace OpenSim.Region.Physics.OdePlugin
189 public d.TriCallback triCallback; 189 public d.TriCallback triCallback;
190 public d.TriArrayCallback triArrayCallback; 190 public d.TriArrayCallback triArrayCallback;
191 191
192 /// <summary>
193 /// Avatars in the physics scene.
194 /// </summary>
192 private readonly HashSet<OdeCharacter> _characters = new HashSet<OdeCharacter>(); 195 private readonly HashSet<OdeCharacter> _characters = new HashSet<OdeCharacter>();
196
193 private readonly HashSet<OdePrim> _prims = new HashSet<OdePrim>(); 197 private readonly HashSet<OdePrim> _prims = new HashSet<OdePrim>();
194 private readonly HashSet<OdePrim> _activeprims = new HashSet<OdePrim>(); 198 private readonly HashSet<OdePrim> _activeprims = new HashSet<OdePrim>();
195 199
@@ -254,6 +258,14 @@ namespace OpenSim.Region.Physics.OdePlugin
254 /// </remarks> 258 /// </remarks>
255 public Dictionary<IntPtr, PhysicsActor> actor_name_map = new Dictionary<IntPtr, PhysicsActor>(); 259 public Dictionary<IntPtr, PhysicsActor> actor_name_map = new Dictionary<IntPtr, PhysicsActor>();
256 260
261 /// <summary>
262 /// Defects list to remove characters that no longer have finite positions due to some other bug.
263 /// </summary>
264 /// <remarks>
265 /// Used repeatedly in Simulate() but initialized once here.
266 /// </remarks>
267 private readonly List<OdeCharacter> defects = new List<OdeCharacter>();
268
257 private bool m_NINJA_physics_joints_enabled = false; 269 private bool m_NINJA_physics_joints_enabled = false;
258 //private Dictionary<String, IntPtr> jointpart_name_map = new Dictionary<String,IntPtr>(); 270 //private Dictionary<String, IntPtr> jointpart_name_map = new Dictionary<String,IntPtr>();
259 private readonly Dictionary<String, List<PhysicsJoint>> joints_connecting_actor = new Dictionary<String, List<PhysicsJoint>>(); 271 private readonly Dictionary<String, List<PhysicsJoint>> joints_connecting_actor = new Dictionary<String, List<PhysicsJoint>>();
@@ -1515,45 +1527,42 @@ namespace OpenSim.Region.Physics.OdePlugin
1515 { 1527 {
1516 _perloopContact.Clear(); 1528 _perloopContact.Clear();
1517 1529
1518 lock (_characters) 1530 foreach (OdeCharacter chr in _characters)
1519 { 1531 {
1520 foreach (OdeCharacter chr in _characters) 1532 // Reset the collision values to false
1533 // since we don't know if we're colliding yet
1534
1535 // For some reason this can happen. Don't ask...
1536 //
1537 if (chr == null)
1538 continue;
1539
1540 if (chr.Shell == IntPtr.Zero || chr.Body == IntPtr.Zero)
1541 continue;
1542
1543 chr.IsColliding = false;
1544 chr.CollidingGround = false;
1545 chr.CollidingObj = false;
1546
1547 // test the avatar's geometry for collision with the space
1548 // This will return near and the space that they are the closest to
1549 // And we'll run this again against the avatar and the space segment
1550 // This will return with a bunch of possible objects in the space segment
1551 // and we'll run it again on all of them.
1552 try
1521 { 1553 {
1522 // Reset the collision values to false 1554 d.SpaceCollide2(space, chr.Shell, IntPtr.Zero, nearCallback);
1523 // since we don't know if we're colliding yet 1555 }
1524 1556 catch (AccessViolationException)
1525 // For some reason this can happen. Don't ask... 1557 {
1526 // 1558 m_log.Warn("[PHYSICS]: Unable to space collide");
1527 if (chr == null)
1528 continue;
1529
1530 if (chr.Shell == IntPtr.Zero || chr.Body == IntPtr.Zero)
1531 continue;
1532
1533 chr.IsColliding = false;
1534 chr.CollidingGround = false;
1535 chr.CollidingObj = false;
1536
1537 // test the avatar's geometry for collision with the space
1538 // This will return near and the space that they are the closest to
1539 // And we'll run this again against the avatar and the space segment
1540 // This will return with a bunch of possible objects in the space segment
1541 // and we'll run it again on all of them.
1542 try
1543 {
1544 d.SpaceCollide2(space, chr.Shell, IntPtr.Zero, nearCallback);
1545 }
1546 catch (AccessViolationException)
1547 {
1548 m_log.Warn("[PHYSICS]: Unable to space collide");
1549 }
1550 //float terrainheight = GetTerrainHeightAtXY(chr.Position.X, chr.Position.Y);
1551 //if (chr.Position.Z + (chr.Velocity.Z * timeStep) < terrainheight + 10)
1552 //{
1553 //chr.Position.Z = terrainheight + 10.0f;
1554 //forcedZ = true;
1555 //}
1556 } 1559 }
1560 //float terrainheight = GetTerrainHeightAtXY(chr.Position.X, chr.Position.Y);
1561 //if (chr.Position.Z + (chr.Velocity.Z * timeStep) < terrainheight + 10)
1562 //{
1563 //chr.Position.Z = terrainheight + 10.0f;
1564 //forcedZ = true;
1565 //}
1557 } 1566 }
1558 1567
1559 lock (_activeprims) 1568 lock (_activeprims)
@@ -1716,28 +1725,22 @@ namespace OpenSim.Region.Physics.OdePlugin
1716 1725
1717 internal void AddCharacter(OdeCharacter chr) 1726 internal void AddCharacter(OdeCharacter chr)
1718 { 1727 {
1719 lock (_characters) 1728 if (!_characters.Contains(chr))
1720 { 1729 {
1721 if (!_characters.Contains(chr)) 1730 _characters.Add(chr);
1722 {
1723 _characters.Add(chr);
1724 1731
1725 if (chr.bad) 1732 if (chr.bad)
1726 m_log.ErrorFormat("[PHYSICS] Added BAD actor {0} to characters list", chr.m_uuid); 1733 m_log.ErrorFormat("[PHYSICS] Added BAD actor {0} to characters list", chr.m_uuid);
1727 }
1728 } 1734 }
1729 } 1735 }
1730 1736
1731 internal void RemoveCharacter(OdeCharacter chr) 1737 internal void RemoveCharacter(OdeCharacter chr)
1732 { 1738 {
1733 lock (_characters) 1739 if (_characters.Contains(chr))
1734 { 1740 {
1735 if (_characters.Contains(chr)) 1741 _characters.Remove(chr);
1736 { 1742 geom_name_map.Remove(chr.Shell);
1737 _characters.Remove(chr); 1743 actor_name_map.Remove(chr.Shell);
1738 geom_name_map.Remove(chr.Shell);
1739 actor_name_map.Remove(chr.Shell);
1740 }
1741 } 1744 }
1742 } 1745 }
1743 1746
@@ -2797,13 +2800,21 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
2797 } 2800 }
2798 2801
2799 // Move characters 2802 // Move characters
2800 lock (_characters) 2803 foreach (OdeCharacter actor in _characters)
2801 { 2804 {
2802 foreach (OdeCharacter actor in _characters) 2805 if (actor != null)
2806 actor.Move(defects);
2807 }
2808
2809 if (defects.Count != 0)
2810 {
2811 foreach (OdeCharacter actor in defects)
2803 { 2812 {
2804 if (actor != null) 2813 RemoveCharacter(actor);
2805 actor.Move(); 2814 actor.DestroyOdeStructures();
2806 } 2815 }
2816
2817 defects.Clear();
2807 } 2818 }
2808 2819
2809 // Move other active objects 2820 // Move other active objects
@@ -2860,18 +2871,26 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
2860 timeLeft -= ODE_STEPSIZE; 2871 timeLeft -= ODE_STEPSIZE;
2861 } 2872 }
2862 2873
2863 lock (_characters) 2874 foreach (OdeCharacter actor in _characters)
2864 { 2875 {
2865 foreach (OdeCharacter actor in _characters) 2876 if (actor != null)
2866 { 2877 {
2867 if (actor != null) 2878 if (actor.bad)
2868 { 2879 m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid);
2869 if (actor.bad)
2870 m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid);
2871 2880
2872 actor.UpdatePositionAndVelocity(); 2881 actor.UpdatePositionAndVelocity(defects);
2873 } 2882 }
2883 }
2884
2885 if (defects.Count != 0)
2886 {
2887 foreach (OdeCharacter actor in defects)
2888 {
2889 RemoveCharacter(actor);
2890 actor.DestroyOdeStructures();
2874 } 2891 }
2892
2893 defects.Clear();
2875 } 2894 }
2876 2895
2877 lock (_activeprims) 2896 lock (_activeprims)
@@ -3899,30 +3918,28 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
3899 } 3918 }
3900 } 3919 }
3901 ds.SetColor(1.0f, 0.0f, 0.0f); 3920 ds.SetColor(1.0f, 0.0f, 0.0f);
3902 lock (_characters) 3921
3922 foreach (OdeCharacter chr in _characters)
3903 { 3923 {
3904 foreach (OdeCharacter chr in _characters) 3924 if (chr.Shell != IntPtr.Zero)
3905 { 3925 {
3906 if (chr.Shell != IntPtr.Zero) 3926 IntPtr body = d.GeomGetBody(chr.Shell);
3907 {
3908 IntPtr body = d.GeomGetBody(chr.Shell);
3909 3927
3910 d.Vector3 pos; 3928 d.Vector3 pos;
3911 d.GeomCopyPosition(chr.Shell, out pos); 3929 d.GeomCopyPosition(chr.Shell, out pos);
3912 //d.BodyCopyPosition(body, out pos); 3930 //d.BodyCopyPosition(body, out pos);
3913 3931
3914 d.Matrix3 R; 3932 d.Matrix3 R;
3915 d.GeomCopyRotation(chr.Shell, out R); 3933 d.GeomCopyRotation(chr.Shell, out R);
3916 //d.BodyCopyRotation(body, out R); 3934 //d.BodyCopyRotation(body, out R);
3917 3935
3918 ds.DrawCapsule(ref pos, ref R, chr.Size.Z, 0.35f); 3936 ds.DrawCapsule(ref pos, ref R, chr.Size.Z, 0.35f);
3919 d.Vector3 sides = new d.Vector3(); 3937 d.Vector3 sides = new d.Vector3();
3920 sides.X = 0.5f; 3938 sides.X = 0.5f;
3921 sides.Y = 0.5f; 3939 sides.Y = 0.5f;
3922 sides.Z = 0.5f; 3940 sides.Z = 0.5f;
3923 3941
3924 ds.DrawBox(ref pos, ref R, ref sides); 3942 ds.DrawBox(ref pos, ref R, ref sides);
3925 }
3926 } 3943 }
3927 } 3944 }
3928 } 3945 }