diff options
Diffstat (limited to 'OpenSim/Region/Physics/OdePlugin/OdeScene.cs')
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 142 |
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 |