aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
authorDan Lake2012-02-01 16:25:35 -0800
committerDan Lake2012-02-01 16:25:35 -0800
commitc10193c72b1f029a958f04d2f5d7ee384e693aaa (patch)
tree052ec7e973c15b158310511197affad14eb9c64f /OpenSim/Region/Physics
parentTrigger event when prims are scheduled for an update. This gives modules earl... (diff)
parentSmall optimization to last commit (diff)
downloadopensim-SC_OLD-c10193c72b1f029a958f04d2f5d7ee384e693aaa.zip
opensim-SC_OLD-c10193c72b1f029a958f04d2f5d7ee384e693aaa.tar.gz
opensim-SC_OLD-c10193c72b1f029a958f04d2f5d7ee384e693aaa.tar.bz2
opensim-SC_OLD-c10193c72b1f029a958f04d2f5d7ee384e693aaa.tar.xz
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs33
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs4
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODECharacter.cs40
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdeScene.cs32
4 files changed, 90 insertions, 19 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index 7704002..e9a849c 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -72,6 +72,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
72 72
73 private bool m_initialized = false; 73 private bool m_initialized = false;
74 74
75 private int m_detailedStatsStep = 0;
76
75 public IMesher mesher; 77 public IMesher mesher;
76 private float m_meshLOD; 78 private float m_meshLOD;
77 public float MeshLOD 79 public float MeshLOD
@@ -192,6 +194,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
192 m_meshLOD = 8f; 194 m_meshLOD = 8f;
193 m_sculptLOD = 32f; 195 m_sculptLOD = 32f;
194 196
197 m_detailedStatsStep = 0; // disabled
198
195 m_maxSubSteps = 10; 199 m_maxSubSteps = 10;
196 m_fixedTimeStep = 1f / 60f; 200 m_fixedTimeStep = 1f / 60f;
197 m_maxCollisionsPerFrame = 2048; 201 m_maxCollisionsPerFrame = 2048;
@@ -209,8 +213,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
209 parms.deactivationTime = 0.2f; 213 parms.deactivationTime = 0.2f;
210 parms.linearSleepingThreshold = 0.8f; 214 parms.linearSleepingThreshold = 0.8f;
211 parms.angularSleepingThreshold = 1.0f; 215 parms.angularSleepingThreshold = 1.0f;
212 parms.ccdMotionThreshold = 0.5f; // set to zero to disable 216 parms.ccdMotionThreshold = 0.0f; // set to zero to disable
213 parms.ccdSweptSphereRadius = 0.2f; 217 parms.ccdSweptSphereRadius = 0.0f;
218 parms.contactProcessingThreshold = 0.1f;
214 219
215 parms.terrainFriction = 0.5f; 220 parms.terrainFriction = 0.5f;
216 parms.terrainHitFraction = 0.8f; 221 parms.terrainHitFraction = 0.8f;
@@ -231,6 +236,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
231 _meshSculptedPrim = pConfig.GetBoolean("MeshSculptedPrim", _meshSculptedPrim); 236 _meshSculptedPrim = pConfig.GetBoolean("MeshSculptedPrim", _meshSculptedPrim);
232 _forceSimplePrimMeshing = pConfig.GetBoolean("ForceSimplePrimMeshing", _forceSimplePrimMeshing); 237 _forceSimplePrimMeshing = pConfig.GetBoolean("ForceSimplePrimMeshing", _forceSimplePrimMeshing);
233 238
239 m_detailedStatsStep = pConfig.GetInt("DetailedStatsStep", m_detailedStatsStep);
234 m_meshLOD = pConfig.GetFloat("MeshLevelOfDetail", m_meshLOD); 240 m_meshLOD = pConfig.GetFloat("MeshLevelOfDetail", m_meshLOD);
235 m_sculptLOD = pConfig.GetFloat("SculptLevelOfDetail", m_sculptLOD); 241 m_sculptLOD = pConfig.GetFloat("SculptLevelOfDetail", m_sculptLOD);
236 242
@@ -253,6 +259,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
253 parms.angularSleepingThreshold = pConfig.GetFloat("AngularSleepingThreshold", parms.angularSleepingThreshold); 259 parms.angularSleepingThreshold = pConfig.GetFloat("AngularSleepingThreshold", parms.angularSleepingThreshold);
254 parms.ccdMotionThreshold = pConfig.GetFloat("CcdMotionThreshold", parms.ccdMotionThreshold); 260 parms.ccdMotionThreshold = pConfig.GetFloat("CcdMotionThreshold", parms.ccdMotionThreshold);
255 parms.ccdSweptSphereRadius = pConfig.GetFloat("CcdSweptSphereRadius", parms.ccdSweptSphereRadius); 261 parms.ccdSweptSphereRadius = pConfig.GetFloat("CcdSweptSphereRadius", parms.ccdSweptSphereRadius);
262 parms.contactProcessingThreshold = pConfig.GetFloat("ContactProcessingThreshold", parms.contactProcessingThreshold);
256 263
257 parms.terrainFriction = pConfig.GetFloat("TerrainFriction", parms.terrainFriction); 264 parms.terrainFriction = pConfig.GetFloat("TerrainFriction", parms.terrainFriction);
258 parms.terrainHitFraction = pConfig.GetFloat("TerrainHitFraction", parms.terrainHitFraction); 265 parms.terrainHitFraction = pConfig.GetFloat("TerrainHitFraction", parms.terrainHitFraction);
@@ -398,6 +405,14 @@ public class BSScene : PhysicsScene, IPhysicsParameters
398 } 405 }
399 } 406 }
400 407
408 if (m_detailedStatsStep > 0)
409 {
410 if ((m_simulationStep % m_detailedStatsStep) == 0)
411 {
412 BulletSimAPI.DumpBulletStatistics();
413 }
414 }
415
401 // TODO: FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation. 416 // TODO: FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation.
402 return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f; 417 return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f;
403 } 418 }
@@ -671,6 +686,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
671 new PhysParameterEntry("MaxSubStep", "In simulation step, maximum number of substeps"), 686 new PhysParameterEntry("MaxSubStep", "In simulation step, maximum number of substeps"),
672 new PhysParameterEntry("FixedTimeStep", "In simulation step, seconds of one substep (1/60)"), 687 new PhysParameterEntry("FixedTimeStep", "In simulation step, seconds of one substep (1/60)"),
673 new PhysParameterEntry("MaxObjectMass", "Maximum object mass (10000.01)"), 688 new PhysParameterEntry("MaxObjectMass", "Maximum object mass (10000.01)"),
689 new PhysParameterEntry("DetailedStats", "Frames between outputting detailed phys stats. Zero is off"),
674 690
675 new PhysParameterEntry("DefaultFriction", "Friction factor used on new objects"), 691 new PhysParameterEntry("DefaultFriction", "Friction factor used on new objects"),
676 new PhysParameterEntry("DefaultDensity", "Density for new objects" ), 692 new PhysParameterEntry("DefaultDensity", "Density for new objects" ),
@@ -685,6 +701,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
685 new PhysParameterEntry("AngularSleepingThreshold", "Seconds to measure angular movement before considering static" ), 701 new PhysParameterEntry("AngularSleepingThreshold", "Seconds to measure angular movement before considering static" ),
686 // new PhysParameterEntry("CcdMotionThreshold", "" ), 702 // new PhysParameterEntry("CcdMotionThreshold", "" ),
687 // new PhysParameterEntry("CcdSweptSphereRadius", "" ), 703 // new PhysParameterEntry("CcdSweptSphereRadius", "" ),
704 new PhysParameterEntry("ContactProcessingThreshold", "Distance between contacts before doing collision check" ),
688 705
689 new PhysParameterEntry("TerrainFriction", "Factor to reduce movement against terrain surface" ), 706 new PhysParameterEntry("TerrainFriction", "Factor to reduce movement against terrain surface" ),
690 new PhysParameterEntry("TerrainHitFraction", "Distance to measure hit collisions" ), 707 new PhysParameterEntry("TerrainHitFraction", "Distance to measure hit collisions" ),
@@ -715,6 +732,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
715 string lparm = parm.ToLower(); 732 string lparm = parm.ToLower();
716 switch (lparm) 733 switch (lparm)
717 { 734 {
735 case "detailedstats": m_detailedStatsStep = (int)val; break;
718 case "meshlod": m_meshLOD = (int)val; break; 736 case "meshlod": m_meshLOD = (int)val; break;
719 case "sculptlod": m_sculptLOD = (int)val; break; 737 case "sculptlod": m_sculptLOD = (int)val; break;
720 case "maxsubstep": m_maxSubSteps = (int)val; break; 738 case "maxsubstep": m_maxSubSteps = (int)val; break;
@@ -725,7 +743,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
725 case "defaultdensity": m_params[0].defaultDensity = val; break; 743 case "defaultdensity": m_params[0].defaultDensity = val; break;
726 case "defaultrestitution": m_params[0].defaultRestitution = val; break; 744 case "defaultrestitution": m_params[0].defaultRestitution = val; break;
727 case "collisionmargin": m_params[0].collisionMargin = val; break; 745 case "collisionmargin": m_params[0].collisionMargin = val; break;
728 case "gravity": m_params[0].gravity = val; TaintedUpdateParameter(lparm, PhysParameterEntry.APPLY_TO_NONE, val); break; 746 case "gravity": m_params[0].gravity = val; TaintedUpdateParameter(lparm, PhysParameterEntry.APPLY_TO_NONE, val); break;
729 747
730 case "lineardamping": UpdateParameterPrims(ref m_params[0].linearDamping, lparm, localID, val); break; 748 case "lineardamping": UpdateParameterPrims(ref m_params[0].linearDamping, lparm, localID, val); break;
731 case "angulardamping": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break; 749 case "angulardamping": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break;
@@ -734,6 +752,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
734 case "angularsleepingthreshold": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break; 752 case "angularsleepingthreshold": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break;
735 case "ccdmotionthreshold": UpdateParameterPrims(ref m_params[0].ccdMotionThreshold, lparm, localID, val); break; 753 case "ccdmotionthreshold": UpdateParameterPrims(ref m_params[0].ccdMotionThreshold, lparm, localID, val); break;
736 case "ccdsweptsphereradius": UpdateParameterPrims(ref m_params[0].ccdSweptSphereRadius, lparm, localID, val); break; 754 case "ccdsweptsphereradius": UpdateParameterPrims(ref m_params[0].ccdSweptSphereRadius, lparm, localID, val); break;
755 case "contactprocessingthreshold": UpdateParameterPrims(ref m_params[0].contactProcessingThreshold, lparm, localID, val); break;
737 756
738 // set a terrain physical feature and cause terrain to be recalculated 757 // set a terrain physical feature and cause terrain to be recalculated
739 case "terrainfriction": m_params[0].terrainFriction = val; TaintedUpdateParameter("terrain", 0, val); break; 758 case "terrainfriction": m_params[0].terrainFriction = val; TaintedUpdateParameter("terrain", 0, val); break;
@@ -741,10 +760,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
741 case "terrainrestitution": m_params[0].terrainRestitution = val; TaintedUpdateParameter("terrain", 0, val); break; 760 case "terrainrestitution": m_params[0].terrainRestitution = val; TaintedUpdateParameter("terrain", 0, val); break;
742 // set an avatar physical feature and cause avatar(s) to be recalculated 761 // set an avatar physical feature and cause avatar(s) to be recalculated
743 case "avatarfriction": UpdateParameterAvatars(ref m_params[0].avatarFriction, "avatar", localID, val); break; 762 case "avatarfriction": UpdateParameterAvatars(ref m_params[0].avatarFriction, "avatar", localID, val); break;
744 case "avatardensity": UpdateParameterAvatars(ref m_params[0].avatarDensity, "avatar", localID, val); break; 763 case "avatardensity": UpdateParameterAvatars(ref m_params[0].avatarDensity, "avatar", localID, val); break;
745 case "avatarrestitution": UpdateParameterAvatars(ref m_params[0].avatarRestitution, "avatar", localID, val); break; 764 case "avatarrestitution": UpdateParameterAvatars(ref m_params[0].avatarRestitution, "avatar", localID, val); break;
746 case "avatarcapsuleradius": UpdateParameterAvatars(ref m_params[0].avatarCapsuleRadius, "avatar", localID, val); break; 765 case "avatarcapsuleradius": UpdateParameterAvatars(ref m_params[0].avatarCapsuleRadius, "avatar", localID, val); break;
747 case "avatarcapsuleheight": UpdateParameterAvatars(ref m_params[0].avatarCapsuleHeight, "avatar", localID, val); break; 766 case "avatarcapsuleheight": UpdateParameterAvatars(ref m_params[0].avatarCapsuleHeight, "avatar", localID, val); break;
748 767
749 default: ret = false; break; 768 default: ret = false; break;
750 } 769 }
@@ -816,6 +835,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
816 bool ret = true; 835 bool ret = true;
817 switch (parm.ToLower()) 836 switch (parm.ToLower())
818 { 837 {
838 case "detailedstats": val = (int)m_detailedStatsStep; break;
819 case "meshlod": val = (float)m_meshLOD; break; 839 case "meshlod": val = (float)m_meshLOD; break;
820 case "sculptlod": val = (float)m_sculptLOD; break; 840 case "sculptlod": val = (float)m_sculptLOD; break;
821 case "maxsubstep": val = (float)m_maxSubSteps; break; 841 case "maxsubstep": val = (float)m_maxSubSteps; break;
@@ -835,6 +855,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
835 case "angularsleepingthreshold": val = m_params[0].angularDamping; break; 855 case "angularsleepingthreshold": val = m_params[0].angularDamping; break;
836 case "ccdmotionthreshold": val = m_params[0].ccdMotionThreshold; break; 856 case "ccdmotionthreshold": val = m_params[0].ccdMotionThreshold; break;
837 case "ccdsweptsphereradius": val = m_params[0].ccdSweptSphereRadius; break; 857 case "ccdsweptsphereradius": val = m_params[0].ccdSweptSphereRadius; break;
858 case "contactprocessingthreshold": val = m_params[0].contactProcessingThreshold; break;
838 859
839 case "terrainfriction": val = m_params[0].terrainFriction; break; 860 case "terrainfriction": val = m_params[0].terrainFriction; break;
840 case "terrainhitfraction": val = m_params[0].terrainHitFraction; break; 861 case "terrainhitfraction": val = m_params[0].terrainHitFraction; break;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
index a610c8d..d12bd7d 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
@@ -122,6 +122,7 @@ public struct ConfigurationParameters
122 public float angularSleepingThreshold; 122 public float angularSleepingThreshold;
123 public float ccdMotionThreshold; 123 public float ccdMotionThreshold;
124 public float ccdSweptSphereRadius; 124 public float ccdSweptSphereRadius;
125 public float contactProcessingThreshold;
125 126
126 public float terrainFriction; 127 public float terrainFriction;
127 public float terrainHitFraction; 128 public float terrainHitFraction;
@@ -248,6 +249,9 @@ public static extern RaycastHit RayTest(uint worldID, uint id, Vector3 from, Vec
248[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 249[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
249public static extern Vector3 RecoverFromPenetration(uint worldID, uint id); 250public static extern Vector3 RecoverFromPenetration(uint worldID, uint id);
250 251
252[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
253public static extern void DumpBulletStatistics();
254
251// Log a debug message 255// Log a debug message
252[UnmanagedFunctionPointer(CallingConvention.Cdecl)] 256[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
253public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg); 257public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg);
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index 68999fc..7c1c046 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -134,9 +134,18 @@ namespace OpenSim.Region.Physics.OdePlugin
134 | CollisionCategories.Body 134 | CollisionCategories.Body
135 | CollisionCategories.Character 135 | CollisionCategories.Character
136 | CollisionCategories.Land); 136 | CollisionCategories.Land);
137 internal IntPtr Body = IntPtr.Zero; 137 /// <summary>
138 /// Body for dynamics simulation
139 /// </summary>
140 internal IntPtr Body { get; private set; }
141
138 private OdeScene _parent_scene; 142 private OdeScene _parent_scene;
139 internal IntPtr Shell = IntPtr.Zero; 143
144 /// <summary>
145 /// Collision geometry
146 /// </summary>
147 internal IntPtr Shell { get; private set; }
148
140 private IntPtr Amotor = IntPtr.Zero; 149 private IntPtr Amotor = IntPtr.Zero;
141 private d.Mass ShellMass; 150 private d.Mass ShellMass;
142 151
@@ -1018,6 +1027,13 @@ namespace OpenSim.Region.Physics.OdePlugin
1018 /// <param name="tensor"></param> 1027 /// <param name="tensor"></param>
1019 private void CreateOdeStructures(float npositionX, float npositionY, float npositionZ, float tensor) 1028 private void CreateOdeStructures(float npositionX, float npositionY, float npositionZ, float tensor)
1020 { 1029 {
1030 if (!(Shell == IntPtr.Zero && Body == IntPtr.Zero && Amotor == IntPtr.Zero))
1031 {
1032 m_log.ErrorFormat(
1033 "[ODE CHARACTER]: Creating ODE structures for {0} even though some already exist. Shell = {1}, Body = {2}, Amotor = {3}",
1034 Name, Shell, Body, Amotor);
1035 }
1036
1021 int dAMotorEuler = 1; 1037 int dAMotorEuler = 1;
1022// _parent_scene.waitForSpaceUnlock(_parent_scene.space); 1038// _parent_scene.waitForSpaceUnlock(_parent_scene.space);
1023 if (CAPSULE_LENGTH <= 0) 1039 if (CAPSULE_LENGTH <= 0)
@@ -1032,6 +1048,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1032 CAPSULE_RADIUS = 0.01f; 1048 CAPSULE_RADIUS = 0.01f;
1033 } 1049 }
1034 1050
1051// lock (OdeScene.UniversalColliderSyncObject)
1035 Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH); 1052 Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH);
1036 1053
1037 d.GeomSetCategoryBits(Shell, (int)m_collisionCategories); 1054 d.GeomSetCategoryBits(Shell, (int)m_collisionCategories);
@@ -1135,6 +1152,14 @@ namespace OpenSim.Region.Physics.OdePlugin
1135 /// </summary> 1152 /// </summary>
1136 internal void DestroyOdeStructures() 1153 internal void DestroyOdeStructures()
1137 { 1154 {
1155 // Create avatar capsule and related ODE data
1156 if (Shell == IntPtr.Zero || Body == IntPtr.Zero || Amotor == IntPtr.Zero)
1157 {
1158 m_log.ErrorFormat(
1159 "[ODE CHARACTER]: Destroying ODE structures for {0} even though some are already null. Shell = {1}, Body = {2}, Amotor = {3}",
1160 Name, Shell, Body, Amotor);
1161 }
1162
1138 // destroy avatar capsule and related ODE data 1163 // destroy avatar capsule and related ODE data
1139 if (Amotor != IntPtr.Zero) 1164 if (Amotor != IntPtr.Zero)
1140 { 1165 {
@@ -1155,7 +1180,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1155 1180
1156 if (Shell != IntPtr.Zero) 1181 if (Shell != IntPtr.Zero)
1157 { 1182 {
1183// lock (OdeScene.UniversalColliderSyncObject)
1158 d.GeomDestroy(Shell); 1184 d.GeomDestroy(Shell);
1185
1159 _parent_scene.geom_name_map.Remove(Shell); 1186 _parent_scene.geom_name_map.Remove(Shell);
1160 _parent_scene.actor_name_map.Remove(Shell); 1187 _parent_scene.actor_name_map.Remove(Shell);
1161 1188
@@ -1260,15 +1287,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1260 { 1287 {
1261 if (m_tainted_isPhysical) 1288 if (m_tainted_isPhysical)
1262 { 1289 {
1263 // Create avatar capsule and related ODE data
1264 if (!(Shell == IntPtr.Zero && Body == IntPtr.Zero && Amotor == IntPtr.Zero))
1265 {
1266 m_log.Warn("[ODE CHARACTER]: re-creating the following avatar ODE data for " + Name + ", even though it already exists - "
1267 + (Shell!=IntPtr.Zero ? "Shell ":"")
1268 + (Body!=IntPtr.Zero ? "Body ":"")
1269 + (Amotor!=IntPtr.Zero ? "Amotor ":""));
1270 }
1271
1272 CreateOdeStructures(_position.X, _position.Y, _position.Z, m_tensor); 1290 CreateOdeStructures(_position.X, _position.Y, _position.Z, m_tensor);
1273 _parent_scene.AddCharacter(this); 1291 _parent_scene.AddCharacter(this);
1274 } 1292 }
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
index 228eca9..4530c09 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
@@ -105,6 +105,32 @@ namespace OpenSim.Region.Physics.OdePlugin
105 private readonly ILog m_log; 105 private readonly ILog m_log;
106 // private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>(); 106 // private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>();
107 107
108 /// <summary>
109 /// Provide a sync object so that only one thread calls d.Collide() at a time across all OdeScene instances.
110 /// </summary>
111 /// <remarks>
112 /// With ODE as of r1755 (though also tested on r1860), only one thread can call d.Collide() at a
113 /// time, even where physics objects are in entirely different ODE worlds. This is because generating contacts
114 /// uses a static cache at the ODE level.
115 ///
116 /// Without locking, simulators running multiple regions will eventually crash with a native stack trace similar
117 /// to
118 ///
119 /// mono() [0x489171]
120 /// mono() [0x4d154f]
121 /// /lib/x86_64-linux-gnu/libpthread.so.0(+0xfc60) [0x7f6ded592c60]
122 /// .../opensim/bin/libode-x86_64.so(_ZN6Opcode11OBBCollider8_CollideEPKNS_14AABBNoLeafNodeE+0xd7a) [0x7f6dd822628a]
123 ///
124 /// ODE provides an experimental option to cache in thread local storage but compiling ODE with this option
125 /// causes OpenSimulator to immediately crash with a native stack trace similar to
126 ///
127 /// mono() [0x489171]
128 /// mono() [0x4d154f]
129 /// /lib/x86_64-linux-gnu/libpthread.so.0(+0xfc60) [0x7f03c9849c60]
130 /// .../opensim/bin/libode-x86_64.so(_Z12dCollideCCTLP6dxGeomS0_iP12dContactGeomi+0x92) [0x7f03b44bcf82]
131 /// </remarks>
132 internal static Object UniversalColliderSyncObject = new Object();
133
108 private Random fluidRandomizer = new Random(Environment.TickCount); 134 private Random fluidRandomizer = new Random(Environment.TickCount);
109 135
110 private const uint m_regionWidth = Constants.RegionSize; 136 private const uint m_regionWidth = Constants.RegionSize;
@@ -799,7 +825,9 @@ namespace OpenSim.Region.Physics.OdePlugin
799 if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) 825 if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact))
800 return; 826 return;
801 827
802 count = d.Collide(g1, g2, contacts.Length, contacts, d.ContactGeom.SizeOf); 828 lock (OdeScene.UniversalColliderSyncObject)
829 count = d.Collide(g1, g2, contacts.Length, contacts, d.ContactGeom.SizeOf);
830
803 if (count > contacts.Length) 831 if (count > contacts.Length)
804 m_log.Error("[ODE SCENE]: Got " + count + " contacts when we asked for a maximum of " + contacts.Length); 832 m_log.Error("[ODE SCENE]: Got " + count + " contacts when we asked for a maximum of " + contacts.Length);
805 } 833 }
@@ -1525,7 +1553,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1525 chr.CollidingGround = false; 1553 chr.CollidingGround = false;
1526 chr.CollidingObj = false; 1554 chr.CollidingObj = false;
1527 1555
1528 // test the avatar's geometry for collision with the space 1556 // Test the avatar's geometry for collision with the space
1529 // This will return near and the space that they are the closest to 1557 // This will return near and the space that they are the closest to
1530 // And we'll run this again against the avatar and the space segment 1558 // And we'll run this again against the avatar and the space segment
1531 // This will return with a bunch of possible objects in the space segment 1559 // This will return with a bunch of possible objects in the space segment