diff options
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | 27 | ||||
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 177 |
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 | } |