diff options
author | Teravus Ovares | 2008-12-10 23:46:20 +0000 |
---|---|---|
committer | Teravus Ovares | 2008-12-10 23:46:20 +0000 |
commit | 7f80eff06732969f0d7f89e8774fc212123557e6 (patch) | |
tree | 0f927e87faa0012e0be938d3f5d62155c2be083e | |
parent | * refactor: Move test infrastructure code to its own package so that it can b... (diff) | |
download | opensim-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.cs | 134 | ||||
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | 50 |
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 | ||
28 | using System; | 28 | using System; |
29 | using System.Reflection; | ||
29 | using OpenMetaverse; | 30 | using OpenMetaverse; |
30 | using Ode.NET; | 31 | using Ode.NET; |
31 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
32 | using OpenSim.Region.Physics.Manager; | 33 | using OpenSim.Region.Physics.Manager; |
34 | using log4net; | ||
33 | 35 | ||
34 | namespace OpenSim.Region.Physics.OdePlugin | 36 | namespace 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) |