aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorTeravus Ovares2008-12-10 23:46:20 +0000
committerTeravus Ovares2008-12-10 23:46:20 +0000
commit7f80eff06732969f0d7f89e8774fc212123557e6 (patch)
tree0f927e87faa0012e0be938d3f5d62155c2be083e
parent* refactor: Move test infrastructure code to its own package so that it can b... (diff)
downloadopensim-SC_OLD-7f80eff06732969f0d7f89e8774fc212123557e6.zip
opensim-SC_OLD-7f80eff06732969f0d7f89e8774fc212123557e6.tar.gz
opensim-SC_OLD-7f80eff06732969f0d7f89e8774fc212123557e6.tar.bz2
opensim-SC_OLD-7f80eff06732969f0d7f89e8774fc212123557e6.tar.xz
* Committing a slightly distilled version of nlin's ODECharacter race condition eliminator.
* The modifications that I made were only so that it didn't require changes to the public physics api.
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODECharacter.cs134
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdePlugin.cs50
2 files changed, 139 insertions, 45 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index 6957cca..666fa86 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -26,10 +26,12 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Reflection;
29using OpenMetaverse; 30using OpenMetaverse;
30using Ode.NET; 31using Ode.NET;
31using OpenSim.Framework; 32using OpenSim.Framework;
32using OpenSim.Region.Physics.Manager; 33using OpenSim.Region.Physics.Manager;
34using log4net;
33 35
34namespace OpenSim.Region.Physics.OdePlugin 36namespace OpenSim.Region.Physics.OdePlugin
35{ 37{
@@ -55,7 +57,7 @@ namespace OpenSim.Region.Physics.OdePlugin
55 } 57 }
56 public class OdeCharacter : PhysicsActor 58 public class OdeCharacter : PhysicsActor
57 { 59 {
58 //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 60 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 61
60 private PhysicsVector _position; 62 private PhysicsVector _position;
61 private d.Vector3 _zeroPosition; 63 private d.Vector3 _zeroPosition;
@@ -89,6 +91,10 @@ namespace OpenSim.Region.Physics.OdePlugin
89 private bool m_hackSentFly = false; 91 private bool m_hackSentFly = false;
90 public uint m_localID = 0; 92 public uint m_localID = 0;
91 public bool m_returnCollisions = false; 93 public bool m_returnCollisions = false;
94 // taints and their non-tainted counterparts
95 public bool m_isPhysical = false; // the current physical status
96 public bool m_tainted_isPhysical = false; // set when the physical status is tainted (false=not existing in physics engine, true=existing)
97 private float m_tainted_CAPSULE_LENGTH; // set when the capsule length changes.
92 98
93 private float m_buoyancy = 0f; 99 private float m_buoyancy = 0f;
94 100
@@ -108,10 +114,10 @@ namespace OpenSim.Region.Physics.OdePlugin
108 | CollisionCategories.Body 114 | CollisionCategories.Body
109 | CollisionCategories.Character 115 | CollisionCategories.Character
110 | CollisionCategories.Land); 116 | CollisionCategories.Land);
111 public IntPtr Body; 117 public IntPtr Body = IntPtr.Zero;
112 private OdeScene _parent_scene; 118 private OdeScene _parent_scene;
113 public IntPtr Shell; 119 public IntPtr Shell = IntPtr.Zero;
114 public IntPtr Amotor; 120 public IntPtr Amotor = IntPtr.Zero;
115 public d.Mass ShellMass; 121 public d.Mass ShellMass;
116 public bool collidelock = false; 122 public bool collidelock = false;
117 123
@@ -147,14 +153,16 @@ namespace OpenSim.Region.Physics.OdePlugin
147 } 153 }
148 CAPSULE_LENGTH = (size.Z * 1.15f) - CAPSULE_RADIUS * 2.0f; 154 CAPSULE_LENGTH = (size.Z * 1.15f) - CAPSULE_RADIUS * 2.0f;
149 //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); 155 //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString());
156 m_tainted_CAPSULE_LENGTH = CAPSULE_LENGTH;
157
158 m_isPhysical = false; // current status: no ODE information exists
159 m_tainted_isPhysical = true; // new tainted status: need to create ODE information
150 160
151 lock (_parent_scene.OdeLock) 161 lock (_parent_scene.OdeLock)
152 { 162 {
153 AvatarGeomAndBodyCreation(pos.X, pos.Y, pos.Z, m_tensor); 163 _parent_scene.AddPhysicsActorTaint(this);
154 } 164 }
155 m_name = avName; 165 m_name = avName;
156 parent_scene.geom_name_map[Shell] = avName;
157 parent_scene.actor_name_map[Shell] = (PhysicsActor) this;
158 } 166 }
159 167
160 public override int PhysicsActorType 168 public override int PhysicsActorType
@@ -389,27 +397,13 @@ namespace OpenSim.Region.Physics.OdePlugin
389 m_pidControllerActive = true; 397 m_pidControllerActive = true;
390 lock (_parent_scene.OdeLock) 398 lock (_parent_scene.OdeLock)
391 { 399 {
392 d.JointDestroy(Amotor);
393
394 PhysicsVector SetSize = value; 400 PhysicsVector SetSize = value;
395 float prevCapsule = CAPSULE_LENGTH; 401 m_tainted_CAPSULE_LENGTH = (SetSize.Z * 1.15f) - CAPSULE_RADIUS * 2.0f;
396 // float capsuleradius = CAPSULE_RADIUS;
397 //capsuleradius = 0.2f;
398
399 CAPSULE_LENGTH = (SetSize.Z * 1.15f) - CAPSULE_RADIUS * 2.0f;
400 //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); 402 //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString());
401 d.BodyDestroy(Body);
402
403 _parent_scene.waitForSpaceUnlock(_parent_scene.space);
404 403
405 d.GeomDestroy(Shell);
406 AvatarGeomAndBodyCreation(_position.X, _position.Y,
407 _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor);
408 Velocity = new PhysicsVector(0f, 0f, 0f); 404 Velocity = new PhysicsVector(0f, 0f, 0f);
409
410 } 405 }
411 _parent_scene.geom_name_map[Shell] = m_name; 406 _parent_scene.AddPhysicsActorTaint(this);
412 _parent_scene.actor_name_map[Shell] = (PhysicsActor) this;
413 } 407 }
414 } 408 }
415 409
@@ -419,9 +413,12 @@ namespace OpenSim.Region.Physics.OdePlugin
419 /// <param name="npositionX"></param> 413 /// <param name="npositionX"></param>
420 /// <param name="npositionY"></param> 414 /// <param name="npositionY"></param>
421 /// <param name="npositionZ"></param> 415 /// <param name="npositionZ"></param>
416
417 // WARNING: This MUST NOT be called outside of ProcessTaints, else we can have unsynchronized access
418 // to ODE internals. ProcessTaints is called from within thread-locked Simulate(), so it is the only
419 // place that is safe to call this routine AvatarGeomAndBodyCreation.
422 private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ, float tensor) 420 private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ, float tensor)
423 { 421 {
424
425 int dAMotorEuler = 1; 422 int dAMotorEuler = 1;
426 _parent_scene.waitForSpaceUnlock(_parent_scene.space); 423 _parent_scene.waitForSpaceUnlock(_parent_scene.space);
427 Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH); 424 Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH);
@@ -477,9 +474,6 @@ namespace OpenSim.Region.Physics.OdePlugin
477 // 474 //
478 //m_log.Info("[PHYSICSAV]: Rotation: " + bodyrotation.M00 + " : " + bodyrotation.M01 + " : " + bodyrotation.M02 + " : " + bodyrotation.M10 + " : " + bodyrotation.M11 + " : " + bodyrotation.M12 + " : " + bodyrotation.M20 + " : " + bodyrotation.M21 + " : " + bodyrotation.M22); 475 //m_log.Info("[PHYSICSAV]: Rotation: " + bodyrotation.M00 + " : " + bodyrotation.M01 + " : " + bodyrotation.M02 + " : " + bodyrotation.M10 + " : " + bodyrotation.M11 + " : " + bodyrotation.M12 + " : " + bodyrotation.M20 + " : " + bodyrotation.M21 + " : " + bodyrotation.M22);
479 //standupStraight(); 476 //standupStraight();
480
481
482
483 } 477 }
484 478
485 // 479 //
@@ -872,17 +866,8 @@ namespace OpenSim.Region.Physics.OdePlugin
872 { 866 {
873 lock (_parent_scene.OdeLock) 867 lock (_parent_scene.OdeLock)
874 { 868 {
875 // Kill the Amotor 869 m_tainted_isPhysical = false;
876 d.JointDestroy(Amotor); 870 _parent_scene.AddPhysicsActorTaint(this);
877
878 //kill the Geometry
879 _parent_scene.waitForSpaceUnlock(_parent_scene.space);
880
881 d.GeomDestroy(Shell);
882 _parent_scene.geom_name_map.Remove(Shell);
883
884 //kill the body
885 d.BodyDestroy(Body);
886 } 871 }
887 } 872 }
888 873
@@ -922,5 +907,78 @@ namespace OpenSim.Region.Physics.OdePlugin
922 return true; 907 return true;
923 return false; 908 return false;
924 } 909 }
910
911 public void ProcessTaints(float timestep)
912 {
913
914 if (m_tainted_isPhysical != m_isPhysical)
915 {
916 if (m_tainted_isPhysical)
917 {
918 // Create avatar capsule and related ODE data
919 if (!(Shell == IntPtr.Zero && Body == IntPtr.Zero && Amotor == IntPtr.Zero))
920 {
921 m_log.Warn("[PHYSICS]: re-creating the following avatar ODE data, even though it already exists - "
922 + (Shell!=IntPtr.Zero ? "Shell ":"")
923 + (Body!=IntPtr.Zero ? "Body ":"")
924 + (Amotor!=IntPtr.Zero ? "Amotor ":"") );
925 }
926 AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z, m_tensor);
927
928 _parent_scene.geom_name_map[Shell] = m_name;
929 _parent_scene.actor_name_map[Shell] = (PhysicsActor)this;
930 }
931 else
932 {
933 // destroy avatar capsule and related ODE data
934
935 // Kill the Amotor
936 d.JointDestroy(Amotor);
937 Amotor = IntPtr.Zero;
938
939 //kill the Geometry
940 _parent_scene.waitForSpaceUnlock(_parent_scene.space);
941
942 d.GeomDestroy(Shell);
943 _parent_scene.geom_name_map.Remove(Shell);
944 Shell = IntPtr.Zero;
945
946 //kill the body
947 d.BodyDestroy(Body);
948 Body=IntPtr.Zero;
949 }
950
951 m_isPhysical = m_tainted_isPhysical;
952 }
953
954 if (m_tainted_CAPSULE_LENGTH != CAPSULE_LENGTH)
955 {
956 if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero)
957 {
958
959 m_pidControllerActive = true;
960 // no lock needed on _parent_scene.OdeLock because we are called from within the thread lock in OdePlugin's simulate()
961 d.JointDestroy(Amotor);
962 float prevCapsule = CAPSULE_LENGTH;
963 CAPSULE_LENGTH = m_tainted_CAPSULE_LENGTH;
964 //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString());
965 d.BodyDestroy(Body);
966 d.GeomDestroy(Shell);
967 AvatarGeomAndBodyCreation(_position.X, _position.Y,
968 _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor);
969 Velocity = new PhysicsVector(0f, 0f, 0f);
970
971 _parent_scene.geom_name_map[Shell] = m_name;
972 _parent_scene.actor_name_map[Shell] = (PhysicsActor)this;
973 }
974 else
975 {
976 m_log.Warn("[PHYSICS]: trying to change capsule size, but the following ODE data is missing - "
977 + (Shell==IntPtr.Zero ? "Shell ":"")
978 + (Body==IntPtr.Zero ? "Body ":"")
979 + (Amotor==IntPtr.Zero ? "Amotor ":"") );
980 }
981 }
982 }
925 } 983 }
926} 984}
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
index a875d84..b066d0c 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
@@ -213,6 +213,7 @@ namespace OpenSim.Region.Physics.OdePlugin
213 private List<OdePrim> _prims = new List<OdePrim>(); 213 private List<OdePrim> _prims = new List<OdePrim>();
214 private List<OdePrim> _activeprims = new List<OdePrim>(); 214 private List<OdePrim> _activeprims = new List<OdePrim>();
215 private List<OdePrim> _taintedPrim = new List<OdePrim>(); 215 private List<OdePrim> _taintedPrim = new List<OdePrim>();
216 private List<OdeCharacter> _taintedActors = new List<OdeCharacter>();
216 private List<d.ContactGeom> _perloopContact = new List<d.ContactGeom>(); 217 private List<d.ContactGeom> _perloopContact = new List<d.ContactGeom>();
217 private List<PhysicsActor> _collisionEventPrim = new List<PhysicsActor>(); 218 private List<PhysicsActor> _collisionEventPrim = new List<PhysicsActor>();
218 public Dictionary<IntPtr, String> geom_name_map = new Dictionary<IntPtr, String>(); 219 public Dictionary<IntPtr, String> geom_name_map = new Dictionary<IntPtr, String>();
@@ -1793,6 +1794,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1793 /// <param name="prim"></param> 1794 /// <param name="prim"></param>
1794 public override void AddPhysicsActorTaint(PhysicsActor prim) 1795 public override void AddPhysicsActorTaint(PhysicsActor prim)
1795 { 1796 {
1797
1796 if (prim is OdePrim) 1798 if (prim is OdePrim)
1797 { 1799 {
1798 OdePrim taintedprim = ((OdePrim) prim); 1800 OdePrim taintedprim = ((OdePrim) prim);
@@ -1801,6 +1803,16 @@ namespace OpenSim.Region.Physics.OdePlugin
1801 if (!(_taintedPrim.Contains(taintedprim))) 1803 if (!(_taintedPrim.Contains(taintedprim)))
1802 _taintedPrim.Add(taintedprim); 1804 _taintedPrim.Add(taintedprim);
1803 } 1805 }
1806 return;
1807 }
1808 else if (prim is OdeCharacter)
1809 {
1810 OdeCharacter taintedchar = ((OdeCharacter)prim);
1811 lock (_taintedActors)
1812 {
1813 if (!(_taintedActors.Contains(taintedchar)))
1814 _taintedActors.Add(taintedchar);
1815 }
1804 } 1816 }
1805 } 1817 }
1806 1818
@@ -1869,17 +1881,30 @@ namespace OpenSim.Region.Physics.OdePlugin
1869 //{ 1881 //{
1870 // ode.dlock(world); 1882 // ode.dlock(world);
1871 try 1883 try
1872 { 1884 {
1873 lock (_characters) 1885 // Insert, remove Characters
1886 bool processedtaints = false;
1887
1888 lock (_taintedActors)
1874 { 1889 {
1875 foreach (OdeCharacter actor in _characters) 1890 if (_taintedActors.Count > 0)
1876 { 1891 {
1877 if (actor != null) 1892 foreach (OdeCharacter character in _taintedActors)
1878 actor.Move(timeStep); 1893 {
1894
1895 character.ProcessTaints(timeStep);
1896
1897 processedtaints = true;
1898 //character.m_collisionscore = 0;
1899 }
1900
1901 if (processedtaints)
1902 _taintedActors.Clear();
1879 } 1903 }
1880 } 1904 }
1881 1905
1882 bool processedtaints = false; 1906 // Modify other objects in the scene.
1907 processedtaints = false;
1883 1908
1884 lock (_taintedPrim) 1909 lock (_taintedPrim)
1885 { 1910 {
@@ -1898,9 +1923,20 @@ namespace OpenSim.Region.Physics.OdePlugin
1898 } 1923 }
1899 1924
1900 if (processedtaints) 1925 if (processedtaints)
1901 _taintedPrim = new List<OdePrim>(); 1926 _taintedPrim.Clear();
1927 }
1928
1929 // Move characters
1930 lock (_characters)
1931 {
1932 foreach (OdeCharacter actor in _characters)
1933 {
1934 if (actor != null)
1935 actor.Move(timeStep);
1936 }
1902 } 1937 }
1903 1938
1939 // Move other active objects
1904 lock (_activeprims) 1940 lock (_activeprims)
1905 { 1941 {
1906 foreach (OdePrim prim in _activeprims) 1942 foreach (OdePrim prim in _activeprims)