aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/OdePlugin/OdeScene.cs')
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdeScene.cs142
1 files changed, 131 insertions, 11 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
index 842ff91..fa65945 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
@@ -131,6 +131,41 @@ namespace OpenSim.Region.Physics.OdePlugin
131 /// </remarks> 131 /// </remarks>
132 internal static Object UniversalColliderSyncObject = new Object(); 132 internal static Object UniversalColliderSyncObject = new Object();
133 133
134 /// <summary>
135 /// Is stats collecting enabled for this ODE scene?
136 /// </summary>
137 public bool CollectStats { get; set; }
138
139 /// <summary>
140 /// Statistics for this scene.
141 /// </summary>
142 private Dictionary<string, float> m_stats = new Dictionary<string, float>();
143
144 /// <summary>
145 /// Stat name for recording the number of milliseconds that ODE spends in native collision code.
146 /// </summary>
147 public const string ODENativeCollisionFrameMsStatName = "ODENativeCollisionFrameMS";
148
149 /// <summary>
150 /// Used to hold tick numbers for stat collection purposes.
151 /// </summary>
152 private int m_nativeCollisionTickRecorder;
153
154 /// <summary>
155 /// A messy way to tell if we need to avoid adding a collision time because this was already done in the callback.
156 /// </summary>
157 private bool m_inCollisionTiming;
158
159 /// <summary>
160 /// Used in calculating physics frame time dilation
161 /// </summary>
162 private int tickCountFrameRun;
163
164 /// <summary>
165 /// Used in calculating physics frame time dilation
166 /// </summary>
167 private int latertickcount;
168
134 private Random fluidRandomizer = new Random(Environment.TickCount); 169 private Random fluidRandomizer = new Random(Environment.TickCount);
135 170
136 private const uint m_regionWidth = Constants.RegionSize; 171 private const uint m_regionWidth = Constants.RegionSize;
@@ -345,9 +380,6 @@ namespace OpenSim.Region.Physics.OdePlugin
345 private OdePrim cp1; 380 private OdePrim cp1;
346 private OdeCharacter cc2; 381 private OdeCharacter cc2;
347 private OdePrim cp2; 382 private OdePrim cp2;
348 private int tickCountFrameRun;
349
350 private int latertickcount=0;
351 //private int cStartStop = 0; 383 //private int cStartStop = 0;
352 //private string cDictKey = ""; 384 //private string cDictKey = "";
353 385
@@ -440,6 +472,8 @@ namespace OpenSim.Region.Physics.OdePlugin
440 // Initialize the mesh plugin 472 // Initialize the mesh plugin
441 public override void Initialise(IMesher meshmerizer, IConfigSource config) 473 public override void Initialise(IMesher meshmerizer, IConfigSource config)
442 { 474 {
475 m_stats[ODENativeCollisionFrameMsStatName] = 0;
476
443 mesher = meshmerizer; 477 mesher = meshmerizer;
444 m_config = config; 478 m_config = config;
445 // Defaults 479 // Defaults
@@ -464,6 +498,8 @@ namespace OpenSim.Region.Physics.OdePlugin
464 IConfig physicsconfig = m_config.Configs["ODEPhysicsSettings"]; 498 IConfig physicsconfig = m_config.Configs["ODEPhysicsSettings"];
465 if (physicsconfig != null) 499 if (physicsconfig != null)
466 { 500 {
501 CollectStats = physicsconfig.GetBoolean("collect_stats", false);
502
467 gravityx = physicsconfig.GetFloat("world_gravityx", 0f); 503 gravityx = physicsconfig.GetFloat("world_gravityx", 0f);
468 gravityy = physicsconfig.GetFloat("world_gravityy", 0f); 504 gravityy = physicsconfig.GetFloat("world_gravityy", 0f);
469 gravityz = physicsconfig.GetFloat("world_gravityz", -9.8f); 505 gravityz = physicsconfig.GetFloat("world_gravityz", -9.8f);
@@ -765,6 +801,62 @@ namespace OpenSim.Region.Physics.OdePlugin
765 #region Collision Detection 801 #region Collision Detection
766 802
767 /// <summary> 803 /// <summary>
804 /// Collides two geometries.
805 /// </summary>
806 /// <returns></returns>
807 /// <param name='geom1'></param>
808 /// <param name='geom2'>/param>
809 /// <param name='maxContacts'></param>
810 /// <param name='contactsArray'></param>
811 /// <param name='contactGeomSize'></param>
812 private int CollideGeoms(
813 IntPtr geom1, IntPtr geom2, int maxContacts, Ode.NET.d.ContactGeom[] contactsArray, int contactGeomSize)
814 {
815 int count;
816
817 lock (OdeScene.UniversalColliderSyncObject)
818 {
819 // We do this inside the lock so that we don't count any delay in acquiring it
820 if (CollectStats)
821 m_nativeCollisionTickRecorder = Util.EnvironmentTickCount();
822
823 count = d.Collide(geom1, geom2, maxContacts, contactsArray, contactGeomSize);
824 }
825
826 // We do this outside the lock so that any waiting threads aren't held up, though the effect is probably
827 // negligable
828 if (CollectStats)
829 m_stats[ODENativeCollisionFrameMsStatName]
830 += Util.EnvironmentTickCountSubtract(m_nativeCollisionTickRecorder);
831
832 return count;
833 }
834
835 /// <summary>
836 /// Collide two spaces or a space and a geometry.
837 /// </summary>
838 /// <param name='space1'></param>
839 /// <param name='space2'>/param>
840 /// <param name='data'></param>
841 private void CollideSpaces(IntPtr space1, IntPtr space2, IntPtr data)
842 {
843 if (CollectStats)
844 {
845 m_inCollisionTiming = true;
846 m_nativeCollisionTickRecorder = Util.EnvironmentTickCount();
847 }
848
849 d.SpaceCollide2(space1, space2, data, nearCallback);
850
851 if (CollectStats && m_inCollisionTiming)
852 {
853 m_stats[ODENativeCollisionFrameMsStatName]
854 += Util.EnvironmentTickCountSubtract(m_nativeCollisionTickRecorder);
855 m_inCollisionTiming = false;
856 }
857 }
858
859 /// <summary>
768 /// This is our near callback. A geometry is near a body 860 /// This is our near callback. A geometry is near a body
769 /// </summary> 861 /// </summary>
770 /// <param name="space">The space that contains the geoms. Remember, spaces are also geoms</param> 862 /// <param name="space">The space that contains the geoms. Remember, spaces are also geoms</param>
@@ -772,6 +864,13 @@ namespace OpenSim.Region.Physics.OdePlugin
772 /// <param name="g2">another geometry or space</param> 864 /// <param name="g2">another geometry or space</param>
773 private void near(IntPtr space, IntPtr g1, IntPtr g2) 865 private void near(IntPtr space, IntPtr g1, IntPtr g2)
774 { 866 {
867 if (CollectStats && m_inCollisionTiming)
868 {
869 m_stats[ODENativeCollisionFrameMsStatName]
870 += Util.EnvironmentTickCountSubtract(m_nativeCollisionTickRecorder);
871 m_inCollisionTiming = false;
872 }
873
775// m_log.DebugFormat("[PHYSICS]: Colliding {0} and {1} in {2}", g1, g2, space); 874// m_log.DebugFormat("[PHYSICS]: Colliding {0} and {1} in {2}", g1, g2, space);
776 // no lock here! It's invoked from within Simulate(), which is thread-locked 875 // no lock here! It's invoked from within Simulate(), which is thread-locked
777 876
@@ -789,7 +888,7 @@ namespace OpenSim.Region.Physics.OdePlugin
789 // contact points in the space 888 // contact points in the space
790 try 889 try
791 { 890 {
792 d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); 891 CollideSpaces(g1, g2, IntPtr.Zero);
793 } 892 }
794 catch (AccessViolationException) 893 catch (AccessViolationException)
795 { 894 {
@@ -832,6 +931,7 @@ namespace OpenSim.Region.Physics.OdePlugin
832 931
833 // Figure out how many contact points we have 932 // Figure out how many contact points we have
834 int count = 0; 933 int count = 0;
934
835 try 935 try
836 { 936 {
837 // Colliding Geom To Geom 937 // Colliding Geom To Geom
@@ -843,8 +943,7 @@ namespace OpenSim.Region.Physics.OdePlugin
843 if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) 943 if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact))
844 return; 944 return;
845 945
846 lock (OdeScene.UniversalColliderSyncObject) 946 count = CollideGeoms(g1, g2, contacts.Length, contacts, d.ContactGeom.SizeOf);
847 count = d.Collide(g1, g2, contacts.Length, contacts, d.ContactGeom.SizeOf);
848 947
849 if (count > contacts.Length) 948 if (count > contacts.Length)
850 m_log.Error("[ODE SCENE]: Got " + count + " contacts when we asked for a maximum of " + contacts.Length); 949 m_log.Error("[ODE SCENE]: Got " + count + " contacts when we asked for a maximum of " + contacts.Length);
@@ -1578,7 +1677,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1578 // and we'll run it again on all of them. 1677 // and we'll run it again on all of them.
1579 try 1678 try
1580 { 1679 {
1581 d.SpaceCollide2(space, chr.Shell, IntPtr.Zero, nearCallback); 1680 CollideSpaces(space, chr.Shell, IntPtr.Zero);
1582 } 1681 }
1583 catch (AccessViolationException) 1682 catch (AccessViolationException)
1584 { 1683 {
@@ -1593,6 +1692,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1593 //} 1692 //}
1594 } 1693 }
1595 1694
1695// if (framecount % 55 == 0)
1696// m_log.DebugFormat("Processed {0} collisions", _perloopContact.Count);
1697
1596 List<OdePrim> removeprims = null; 1698 List<OdePrim> removeprims = null;
1597 foreach (OdePrim chr in _activeprims) 1699 foreach (OdePrim chr in _activeprims)
1598 { 1700 {
@@ -1604,7 +1706,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1604 { 1706 {
1605 if (space != IntPtr.Zero && chr.prim_geom != IntPtr.Zero && chr.m_taintremove == false) 1707 if (space != IntPtr.Zero && chr.prim_geom != IntPtr.Zero && chr.m_taintremove == false)
1606 { 1708 {
1607 d.SpaceCollide2(space, chr.prim_geom, IntPtr.Zero, nearCallback); 1709 CollideSpaces(space, chr.prim_geom, IntPtr.Zero);
1608 } 1710 }
1609 else 1711 else
1610 { 1712 {
@@ -2226,7 +2328,8 @@ namespace OpenSim.Region.Physics.OdePlugin
2226 /// <param name="prim"></param> 2328 /// <param name="prim"></param>
2227 internal void RemovePrimThreadLocked(OdePrim prim) 2329 internal void RemovePrimThreadLocked(OdePrim prim)
2228 { 2330 {
2229//Console.WriteLine("RemovePrimThreadLocked " + prim.m_primName); 2331// m_log.DebugFormat("[ODE SCENE]: Removing physical prim {0} {1}", prim.Name, prim.LocalID);
2332
2230 lock (prim) 2333 lock (prim)
2231 { 2334 {
2232 RemoveCollisionEventReporting(prim); 2335 RemoveCollisionEventReporting(prim);
@@ -2688,7 +2791,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2688 /// It calls the methods that report back to the object owners.. (scenepresence, SceneObjectGroup) 2791 /// It calls the methods that report back to the object owners.. (scenepresence, SceneObjectGroup)
2689 /// </summary> 2792 /// </summary>
2690 /// <param name="timeStep"></param> 2793 /// <param name="timeStep"></param>
2691 /// <returns></returns> 2794 /// <returns>The number of frames simulated over that period.</returns>
2692 public override float Simulate(float timeStep) 2795 public override float Simulate(float timeStep)
2693 { 2796 {
2694 if (framecount >= int.MaxValue) 2797 if (framecount >= int.MaxValue)
@@ -3189,7 +3292,7 @@ namespace OpenSim.Region.Physics.OdePlugin
3189 public override bool IsThreaded 3292 public override bool IsThreaded
3190 { 3293 {
3191 // for now we won't be multithreaded 3294 // for now we won't be multithreaded
3192 get { return (false); } 3295 get { return false; }
3193 } 3296 }
3194 3297
3195 #region ODE Specific Terrain Fixes 3298 #region ODE Specific Terrain Fixes
@@ -3954,5 +4057,22 @@ namespace OpenSim.Region.Physics.OdePlugin
3954 ds.SetViewpoint(ref xyz, ref hpr); 4057 ds.SetViewpoint(ref xyz, ref hpr);
3955 } 4058 }
3956#endif 4059#endif
4060
4061 public override Dictionary<string, float> GetStats()
4062 {
4063 if (!CollectStats)
4064 return null;
4065
4066 Dictionary<string, float> returnStats;
4067
4068 lock (OdeLock)
4069 {
4070 returnStats = new Dictionary<string, float>(m_stats);
4071
4072 m_stats[ODENativeCollisionFrameMsStatName] = 0;
4073 }
4074
4075 return returnStats;
4076 }
3957 } 4077 }
3958} \ No newline at end of file 4078} \ No newline at end of file