Merge branch 'master' into careminster

Conflicts:
	OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
avinationmerge
Melanie 2012-06-02 01:40:42 +01:00
commit 522f36345d
3 changed files with 270 additions and 93 deletions

View File

@ -1512,10 +1512,6 @@ namespace OpenSim.Region.Framework.Scenes
StatsReporter.AddPhysicsFPS(physicsFPS); StatsReporter.AddPhysicsFPS(physicsFPS);
StatsReporter.AddTimeDilation(TimeDilation); StatsReporter.AddTimeDilation(TimeDilation);
StatsReporter.AddFPS(1); StatsReporter.AddFPS(1);
StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
// frameMS currently records work frame times, not total frame times (work + any required sleep to // frameMS currently records work frame times, not total frame times (work + any required sleep to
// reach min frame time. // reach min frame time.
@ -1524,7 +1520,6 @@ namespace OpenSim.Region.Framework.Scenes
StatsReporter.addAgentMS(agentMS); StatsReporter.addAgentMS(agentMS);
StatsReporter.addPhysicsMS(physicsMS + physicsMS2); StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
StatsReporter.addOtherMS(otherMS); StatsReporter.addOtherMS(otherMS);
StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS()); StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
if (LoginsDisabled && Frame == 20) if (LoginsDisabled && Frame == 20)

View File

@ -222,6 +222,10 @@ namespace OpenSim.Region.Framework.Scenes
m_report.Close(); m_report.Close();
} }
/// <summary>
/// Sets the number of milliseconds between stat updates.
/// </summary>
/// <param name='ms'></param>
public void SetUpdateMS(int ms) public void SetUpdateMS(int ms)
{ {
statsUpdatesEveryMS = ms; statsUpdatesEveryMS = ms;
@ -297,6 +301,16 @@ namespace OpenSim.Region.Framework.Scenes
sleeptime = m_sleeptimeMS * perframe; sleeptime = m_sleeptimeMS * perframe;
} }
m_rootAgents = m_scene.SceneGraph.GetRootAgentCount();
m_childAgents = m_scene.SceneGraph.GetChildAgentCount();
m_numPrim = m_scene.SceneGraph.GetTotalObjectsCount();
m_activePrim = m_scene.SceneGraph.GetActiveObjectsCount();
m_activeScripts = m_scene.SceneGraph.GetActiveScriptsCount();
// FIXME: Checking for stat sanity is a complex approach. What we really need to do is fix the code
// so that stat numbers are always consistent.
CheckStatSanity();
// other MS is actually simulation time // other MS is actually simulation time
// m_otherMS = m_frameMS - m_physicsMS - m_imageMS - m_netMS - m_agentMS; // m_otherMS = m_frameMS - m_physicsMS - m_imageMS - m_netMS - m_agentMS;
// m_imageMS m_netMS are not included in m_frameMS // m_imageMS m_netMS are not included in m_frameMS
@ -462,13 +476,6 @@ namespace OpenSim.Region.Framework.Scenes
m_timeDilation = td; m_timeDilation = td;
} }
public void SetRootAgents(int rootAgents)
{
m_rootAgents = rootAgents;
CheckStatSanity();
}
internal void CheckStatSanity() internal void CheckStatSanity()
{ {
if (m_rootAgents < 0 || m_childAgents < 0) if (m_rootAgents < 0 || m_childAgents < 0)
@ -485,22 +492,6 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public void SetChildAgents(int childAgents)
{
m_childAgents = childAgents;
CheckStatSanity();
}
public void SetObjects(int objects)
{
m_numPrim = objects;
}
public void SetActiveObjects(int objects)
{
m_activePrim = objects;
}
public void AddFPS(int frames) public void AddFPS(int frames)
{ {
m_fps += frames; m_fps += frames;
@ -587,11 +578,6 @@ namespace OpenSim.Region.Framework.Scenes
m_scriptLinesPerSecond += count; m_scriptLinesPerSecond += count;
} }
public void SetActiveScripts(int count)
{
m_activeScripts = count;
}
public void AddPacketsStats(int inPackets, int outPackets, int unAckedBytes) public void AddPacketsStats(int inPackets, int outPackets, int unAckedBytes)
{ {
AddInPackets(inPackets); AddInPackets(inPackets);

View File

@ -30,20 +30,21 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
using System.IO;
using System.Diagnostics;
using log4net; using log4net;
using Nini.Config; using Nini.Config;
using Ode.NET; using Ode.NET;
using OpenMetaverse;
#if USE_DRAWSTUFF #if USE_DRAWSTUFF
using Drawstuff.NET; using Drawstuff.NET;
#endif #endif
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.Physics.Manager; using OpenSim.Region.Physics.Manager;
using OpenMetaverse;
namespace OpenSim.Region.Physics.OdePlugin namespace OpenSim.Region.Physics.OdePlugin
{ {
@ -54,15 +55,15 @@ namespace OpenSim.Region.Physics.OdePlugin
End = 2 End = 2
} }
public struct sCollisionData // public struct sCollisionData
{ // {
public uint ColliderLocalId; // public uint ColliderLocalId;
public uint CollidedWithLocalId; // public uint CollidedWithLocalId;
public int NumberOfCollisions; // public int NumberOfCollisions;
public int CollisionType; // public int CollisionType;
public int StatusIndicator; // public int StatusIndicator;
public int lastframe; // public int lastframe;
} // }
[Flags] [Flags]
public enum CollisionCategories : int public enum CollisionCategories : int
@ -142,20 +143,114 @@ namespace OpenSim.Region.Physics.OdePlugin
private Dictionary<string, float> m_stats = new Dictionary<string, float>(); private Dictionary<string, float> m_stats = new Dictionary<string, float>();
/// <summary> /// <summary>
/// Stat name for recording the number of milliseconds that ODE spends in native collision code. /// Stat name for total number of avatars in this ODE scene.
/// </summary> /// </summary>
public const string ODENativeCollisionFrameMsStatName = "ODENativeCollisionFrameMS"; public const string ODETotalAvatarsStatName = "ODETotalAvatars";
/// <summary>
/// Stat name for total number of prims in this ODE scene.
/// </summary>
public const string ODETotalPrimsStatName = "ODETotalPrims";
/// <summary>
/// Stat name for total number of prims with active physics in this ODE scene.
/// </summary>
public const string ODEActivePrimsStatName = "ODEActivePrims";
/// <summary>
/// Stat name for the total time spent in ODE frame processing.
/// </summary>
/// <remarks>
/// A sanity check for the main scene loop physics time.
/// </remarks>
public const string ODETotalFrameMsStatName = "ODETotalFrameMS";
/// <summary>
/// Stat name for time spent processing avatar taints per frame
/// </summary>
public const string ODEAvatarTaintMsStatName = "ODEAvatarTaintFrameMS";
/// <summary>
/// Stat name for time spent processing prim taints per frame
/// </summary>
public const string ODEPrimTaintMsStatName = "ODEPrimTaintFrameMS";
/// <summary>
/// Stat name for time spent calculating avatar forces per frame.
/// </summary>
public const string ODEAvatarForcesFrameMsStatName = "ODEAvatarForcesFrameMS";
/// <summary>
/// Stat name for time spent calculating prim forces per frame
/// </summary>
public const string ODEPrimForcesFrameMsStatName = "ODEPrimForcesFrameMS";
/// <summary>
/// Stat name for time spent fulfilling raycasting requests per frame
/// </summary>
public const string ODERaycastingFrameMsStatName = "ODERaycastingFrameMS";
/// <summary>
/// Stat name for time spent in native code that actually steps through the simulation.
/// </summary>
public const string ODENativeStepFrameMsStatName = "ODENativeStepFrameMS";
/// <summary>
/// Stat name for the number of milliseconds that ODE spends in native space collision code.
/// </summary>
public const string ODENativeSpaceCollisionFrameMsStatName = "ODENativeSpaceCollisionFrameMS";
/// <summary>
/// Stat name for milliseconds that ODE spends in native geom collision code.
/// </summary>
public const string ODENativeGeomCollisionFrameMsStatName = "ODENativeGeomCollisionFrameMS";
/// <summary>
/// Time spent in collision processing that is not spent in native space or geom collision code.
/// </summary>
public const string ODEOtherCollisionFrameMsStatName = "ODEOtherCollisionFrameMS";
/// <summary>
/// Stat name for time spent notifying listeners of collisions
/// </summary>
public const string ODECollisionNotificationFrameMsStatName = "ODECollisionNotificationFrameMS";
/// <summary>
/// Stat name for milliseconds spent updating avatar position and velocity
/// </summary>
public const string ODEAvatarUpdateFrameMsStatName = "ODEAvatarUpdateFrameMS";
/// <summary>
/// Stat name for the milliseconds spent updating prim position and velocity
/// </summary>
public const string ODEPrimUpdateFrameMsStatName = "ODEPrimUpdateFrameMS";
/// <summary>
/// Stat name for avatar collisions with another entity.
/// </summary>
public const string ODEAvatarContactsStatsName = "ODEAvatarContacts";
/// <summary>
/// Stat name for prim collisions with another entity.
/// </summary>
public const string ODEPrimContactsStatName = "ODEPrimContacts";
/// <summary> /// <summary>
/// Used to hold tick numbers for stat collection purposes. /// Used to hold tick numbers for stat collection purposes.
/// </summary> /// </summary>
private int m_nativeCollisionTickRecorder; private int m_nativeCollisionStartTick;
/// <summary> /// <summary>
/// A messy way to tell if we need to avoid adding a collision time because this was already done in the callback. /// A messy way to tell if we need to avoid adding a collision time because this was already done in the callback.
/// </summary> /// </summary>
private bool m_inCollisionTiming; private bool m_inCollisionTiming;
/// <summary>
/// A temporary holder for the number of avatar collisions in a frame, so we can work out how many object
/// collisions occured using the _perloopcontact if stats collection is enabled.
/// </summary>
private int m_tempAvatarCollisionsThisFrame;
/// <summary> /// <summary>
/// Used in calculating physics frame time dilation /// Used in calculating physics frame time dilation
/// </summary> /// </summary>
@ -472,7 +567,7 @@ namespace OpenSim.Region.Physics.OdePlugin
// Initialize the mesh plugin // Initialize the mesh plugin
public override void Initialise(IMesher meshmerizer, IConfigSource config) public override void Initialise(IMesher meshmerizer, IConfigSource config)
{ {
m_stats[ODENativeCollisionFrameMsStatName] = 0; InitializeExtraStats();
mesher = meshmerizer; mesher = meshmerizer;
m_config = config; m_config = config;
@ -818,7 +913,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
// We do this inside the lock so that we don't count any delay in acquiring it // We do this inside the lock so that we don't count any delay in acquiring it
if (CollectStats) if (CollectStats)
m_nativeCollisionTickRecorder = Util.EnvironmentTickCount(); m_nativeCollisionStartTick = Util.EnvironmentTickCount();
count = d.Collide(geom1, geom2, maxContacts, contactsArray, contactGeomSize); count = d.Collide(geom1, geom2, maxContacts, contactsArray, contactGeomSize);
} }
@ -826,8 +921,8 @@ namespace OpenSim.Region.Physics.OdePlugin
// We do this outside the lock so that any waiting threads aren't held up, though the effect is probably // We do this outside the lock so that any waiting threads aren't held up, though the effect is probably
// negligable // negligable
if (CollectStats) if (CollectStats)
m_stats[ODENativeCollisionFrameMsStatName] m_stats[ODENativeGeomCollisionFrameMsStatName]
+= Util.EnvironmentTickCountSubtract(m_nativeCollisionTickRecorder); += Util.EnvironmentTickCountSubtract(m_nativeCollisionStartTick);
return count; return count;
} }
@ -843,15 +938,15 @@ namespace OpenSim.Region.Physics.OdePlugin
if (CollectStats) if (CollectStats)
{ {
m_inCollisionTiming = true; m_inCollisionTiming = true;
m_nativeCollisionTickRecorder = Util.EnvironmentTickCount(); m_nativeCollisionStartTick = Util.EnvironmentTickCount();
} }
d.SpaceCollide2(space1, space2, data, nearCallback); d.SpaceCollide2(space1, space2, data, nearCallback);
if (CollectStats && m_inCollisionTiming) if (CollectStats && m_inCollisionTiming)
{ {
m_stats[ODENativeCollisionFrameMsStatName] m_stats[ODENativeSpaceCollisionFrameMsStatName]
+= Util.EnvironmentTickCountSubtract(m_nativeCollisionTickRecorder); += Util.EnvironmentTickCountSubtract(m_nativeCollisionStartTick);
m_inCollisionTiming = false; m_inCollisionTiming = false;
} }
} }
@ -866,8 +961,8 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
if (CollectStats && m_inCollisionTiming) if (CollectStats && m_inCollisionTiming)
{ {
m_stats[ODENativeCollisionFrameMsStatName] m_stats[ODENativeSpaceCollisionFrameMsStatName]
+= Util.EnvironmentTickCountSubtract(m_nativeCollisionTickRecorder); += Util.EnvironmentTickCountSubtract(m_nativeCollisionStartTick);
m_inCollisionTiming = false; m_inCollisionTiming = false;
} }
@ -945,6 +1040,10 @@ namespace OpenSim.Region.Physics.OdePlugin
count = CollideGeoms(g1, g2, contacts.Length, contacts, d.ContactGeom.SizeOf); count = CollideGeoms(g1, g2, contacts.Length, contacts, d.ContactGeom.SizeOf);
// All code after this is only relevant if we have any collisions
if (count <= 0)
return;
if (count > contacts.Length) if (count > contacts.Length)
m_log.Error("[ODE SCENE]: Got " + count + " contacts when we asked for a maximum of " + contacts.Length); m_log.Error("[ODE SCENE]: Got " + count + " contacts when we asked for a maximum of " + contacts.Length);
} }
@ -1212,14 +1311,12 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
_perloopContact.Add(curContact); _perloopContact.Add(curContact);
// If we're colliding against terrain
if (name1 == "Terrain" || name2 == "Terrain") if (name1 == "Terrain" || name2 == "Terrain")
{ {
// If we're moving
if ((p2.PhysicsActorType == (int) ActorTypes.Agent) && if ((p2.PhysicsActorType == (int) ActorTypes.Agent) &&
(Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
{ {
// Use the movement terrain contact // Avatar is moving on terrain, use the movement terrain contact
AvatarMovementTerrainContact.geom = curContact; AvatarMovementTerrainContact.geom = curContact;
if (m_global_contactcount < maxContactsbeforedeath) if (m_global_contactcount < maxContactsbeforedeath)
@ -1232,7 +1329,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
if (p2.PhysicsActorType == (int)ActorTypes.Agent) if (p2.PhysicsActorType == (int)ActorTypes.Agent)
{ {
// Use the non moving terrain contact // Avatar is standing on terrain, use the non moving terrain contact
TerrainContact.geom = curContact; TerrainContact.geom = curContact;
if (m_global_contactcount < maxContactsbeforedeath) if (m_global_contactcount < maxContactsbeforedeath)
@ -1327,13 +1424,11 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
else else
{ {
// we're colliding with prim or avatar
// check if we're moving
if ((p2.PhysicsActorType == (int)ActorTypes.Agent)) if ((p2.PhysicsActorType == (int)ActorTypes.Agent))
{ {
if ((Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) if ((Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
{ {
// Use the Movement prim contact // Avatar is moving on a prim, use the Movement prim contact
AvatarMovementprimContact.geom = curContact; AvatarMovementprimContact.geom = curContact;
if (m_global_contactcount < maxContactsbeforedeath) if (m_global_contactcount < maxContactsbeforedeath)
@ -1344,9 +1439,8 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
else else
{ {
// Use the non movement contact // Avatar is standing still on a prim, use the non movement contact
contact.geom = curContact; contact.geom = curContact;
_perloopContact.Add(curContact);
if (m_global_contactcount < maxContactsbeforedeath) if (m_global_contactcount < maxContactsbeforedeath)
{ {
@ -1454,7 +1548,7 @@ namespace OpenSim.Region.Physics.OdePlugin
break; break;
} }
} }
//m_log.DebugFormat("[Collsion]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth)); //m_log.DebugFormat("[Collision]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth));
//m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z)); //m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z));
} }
} }
@ -1692,8 +1786,11 @@ namespace OpenSim.Region.Physics.OdePlugin
//} //}
} }
// if (framecount % 55 == 0) if (CollectStats)
// m_log.DebugFormat("Processed {0} collisions", _perloopContact.Count); {
m_tempAvatarCollisionsThisFrame = _perloopContact.Count;
m_stats[ODEAvatarContactsStatsName] += m_tempAvatarCollisionsThisFrame;
}
List<OdePrim> removeprims = null; List<OdePrim> removeprims = null;
foreach (OdePrim chr in _activeprims) foreach (OdePrim chr in _activeprims)
@ -1727,6 +1824,9 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
} }
if (CollectStats)
m_stats[ODEPrimContactsStatName] += _perloopContact.Count - m_tempAvatarCollisionsThisFrame;
if (removeprims != null) if (removeprims != null)
{ {
foreach (OdePrim chr in removeprims) foreach (OdePrim chr in removeprims)
@ -2785,21 +2885,23 @@ namespace OpenSim.Region.Physics.OdePlugin
/// <summary> /// <summary>
/// This is our main simulate loop /// This is our main simulate loop
/// </summary>
/// <remarks>
/// It's thread locked by a Mutex in the scene. /// It's thread locked by a Mutex in the scene.
/// It holds Collisions, it instructs ODE to step through the physical reactions /// It holds Collisions, it instructs ODE to step through the physical reactions
/// It moves the objects around in memory /// It moves the objects around in memory
/// It calls the methods that report back to the object owners.. (scenepresence, SceneObjectGroup) /// It calls the methods that report back to the object owners.. (scenepresence, SceneObjectGroup)
/// </summary> /// </remarks>
/// <param name="timeStep"></param> /// <param name="timeStep"></param>
/// <returns>The number of frames simulated over that period.</returns> /// <returns>The number of frames simulated over that period.</returns>
public override float Simulate(float timeStep) public override float Simulate(float timeStep)
{ {
int startFrameTick = CollectStats ? Util.EnvironmentTickCount() : 0;
int tempTick = 0, tempTick2 = 0;
if (framecount >= int.MaxValue) if (framecount >= int.MaxValue)
framecount = 0; framecount = 0;
//if (m_worldOffset != Vector3.Zero)
// return 0;
framecount++; framecount++;
float fps = 0; float fps = 0;
@ -2807,7 +2909,7 @@ namespace OpenSim.Region.Physics.OdePlugin
float timeLeft = timeStep; float timeLeft = timeStep;
//m_log.Info(timeStep.ToString()); //m_log.Info(timeStep.ToString());
// step_time += timeStep; // step_time += timeSte
// //
// // If We're loaded down by something else, // // If We're loaded down by something else,
// // or debugging with the Visual Studio project on pause // // or debugging with the Visual Studio project on pause
@ -2873,6 +2975,9 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
try try
{ {
if (CollectStats)
tempTick = Util.EnvironmentTickCount();
lock (_taintedActors) lock (_taintedActors)
{ {
foreach (OdeCharacter character in _taintedActors) foreach (OdeCharacter character in _taintedActors)
@ -2881,6 +2986,13 @@ namespace OpenSim.Region.Physics.OdePlugin
_taintedActors.Clear(); _taintedActors.Clear();
} }
if (CollectStats)
{
tempTick2 = Util.EnvironmentTickCount();
m_stats[ODEAvatarTaintMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
tempTick = tempTick2;
}
lock (_taintedPrims) lock (_taintedPrims)
{ {
foreach (OdePrim prim in _taintedPrims) foreach (OdePrim prim in _taintedPrims)
@ -2911,6 +3023,13 @@ namespace OpenSim.Region.Physics.OdePlugin
_taintedPrims.Clear(); _taintedPrims.Clear();
} }
if (CollectStats)
{
tempTick2 = Util.EnvironmentTickCount();
m_stats[ODEPrimTaintMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
tempTick = tempTick2;
}
// Move characters // Move characters
foreach (OdeCharacter actor in _characters) foreach (OdeCharacter actor in _characters)
actor.Move(defects); actor.Move(defects);
@ -2930,6 +3049,13 @@ namespace OpenSim.Region.Physics.OdePlugin
defects.Clear(); defects.Clear();
} }
if (CollectStats)
{
tempTick2 = Util.EnvironmentTickCount();
m_stats[ODEAvatarForcesFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
tempTick = tempTick2;
}
// Move other active objects // Move other active objects
foreach (OdePrim prim in _activeprims) foreach (OdePrim prim in _activeprims)
{ {
@ -2937,14 +3063,35 @@ namespace OpenSim.Region.Physics.OdePlugin
prim.Move(timeStep); prim.Move(timeStep);
} }
if (CollectStats)
{
tempTick2 = Util.EnvironmentTickCount();
m_stats[ODEPrimForcesFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
tempTick = tempTick2;
}
//if ((framecount % m_randomizeWater) == 0) //if ((framecount % m_randomizeWater) == 0)
// randomizeWater(waterlevel); // randomizeWater(waterlevel);
//int RayCastTimeMS = m_rayCastManager.ProcessQueuedRequests(); //int RayCastTimeMS = m_rayCastManager.ProcessQueuedRequests();
m_rayCastManager.ProcessQueuedRequests(); m_rayCastManager.ProcessQueuedRequests();
if (CollectStats)
{
tempTick2 = Util.EnvironmentTickCount();
m_stats[ODERaycastingFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
tempTick = tempTick2;
}
collision_optimized(); collision_optimized();
if (CollectStats)
{
tempTick2 = Util.EnvironmentTickCount();
m_stats[ODEOtherCollisionFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
tempTick = tempTick2;
}
foreach (PhysicsActor obj in _collisionEventPrim.Values) foreach (PhysicsActor obj in _collisionEventPrim.Values)
{ {
// m_log.DebugFormat("[PHYSICS]: Assessing {0} {1} for collision events", obj.SOPName, obj.LocalID); // m_log.DebugFormat("[PHYSICS]: Assessing {0} {1} for collision events", obj.SOPName, obj.LocalID);
@ -2970,8 +3117,18 @@ namespace OpenSim.Region.Physics.OdePlugin
m_global_contactcount = 0; m_global_contactcount = 0;
if (CollectStats)
{
tempTick2 = Util.EnvironmentTickCount();
m_stats[ODECollisionNotificationFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
tempTick = tempTick2;
}
d.WorldQuickStep(world, ODE_STEPSIZE); d.WorldQuickStep(world, ODE_STEPSIZE);
if (CollectStats)
m_stats[ODENativeStepFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick);
d.JointGroupEmpty(contactgroup); d.JointGroupEmpty(contactgroup);
} }
catch (Exception e) catch (Exception e)
@ -2982,6 +3139,9 @@ namespace OpenSim.Region.Physics.OdePlugin
timeLeft -= ODE_STEPSIZE; timeLeft -= ODE_STEPSIZE;
} }
if (CollectStats)
tempTick = Util.EnvironmentTickCount();
foreach (OdeCharacter actor in _characters) foreach (OdeCharacter actor in _characters)
{ {
if (actor.bad) if (actor.bad)
@ -3005,6 +3165,13 @@ namespace OpenSim.Region.Physics.OdePlugin
defects.Clear(); defects.Clear();
} }
if (CollectStats)
{
tempTick2 = Util.EnvironmentTickCount();
m_stats[ODEAvatarUpdateFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
tempTick = tempTick2;
}
//if (timeStep < 0.2f) //if (timeStep < 0.2f)
foreach (OdePrim prim in _activeprims) foreach (OdePrim prim in _activeprims)
@ -3018,6 +3185,9 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
} }
if (CollectStats)
m_stats[ODEPrimUpdateFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick);
//DumpJointInfo(); //DumpJointInfo();
// Finished with all sim stepping. If requested, dump world state to file for debugging. // Finished with all sim stepping. If requested, dump world state to file for debugging.
@ -3039,7 +3209,7 @@ namespace OpenSim.Region.Physics.OdePlugin
d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix); d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix);
} }
latertickcount = Util.EnvironmentTickCount() - tickCountFrameRun; latertickcount = Util.EnvironmentTickCountSubtract(tickCountFrameRun);
// OpenSimulator above does 10 fps. 10 fps = means that the main thread loop and physics // OpenSimulator above does 10 fps. 10 fps = means that the main thread loop and physics
// has a max of 100 ms to run theoretically. // has a max of 100 ms to run theoretically.
@ -3059,6 +3229,9 @@ namespace OpenSim.Region.Physics.OdePlugin
tickCountFrameRun = Util.EnvironmentTickCount(); tickCountFrameRun = Util.EnvironmentTickCount();
} }
if (CollectStats)
m_stats[ODETotalFrameMsStatName] += Util.EnvironmentTickCountSubtract(startFrameTick);
return fps; return fps;
} }
@ -3868,26 +4041,19 @@ namespace OpenSim.Region.Physics.OdePlugin
public override Dictionary<uint, float> GetTopColliders() public override Dictionary<uint, float> GetTopColliders()
{ {
Dictionary<uint, float> returncolliders = new Dictionary<uint, float>(); Dictionary<uint, float> topColliders;
int cnt = 0;
lock (_prims) lock (_prims)
{ {
foreach (OdePrim prm in _prims) List<OdePrim> orderedPrims = new List<OdePrim>(_prims);
{ orderedPrims.OrderByDescending(p => p.CollisionScore).Take(25);
if (prm.CollisionScore > 0) topColliders = orderedPrims.ToDictionary(p => p.LocalID, p => p.CollisionScore);
{
returncolliders.Add(prm.LocalID, prm.CollisionScore); foreach (OdePrim p in _prims)
cnt++; p.CollisionScore = 0;
prm.CollisionScore = 0f;
if (cnt > 25)
{
break;
}
}
}
} }
return returncolliders; return topColliders;
} }
public override bool SupportsRayCast() public override bool SupportsRayCast()
@ -4069,10 +4235,40 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
returnStats = new Dictionary<string, float>(m_stats); returnStats = new Dictionary<string, float>(m_stats);
m_stats[ODENativeCollisionFrameMsStatName] = 0; // FIXME: This is a SUPER DUMB HACK until we can establish stats that aren't subject to a division by
// 3 from the SimStatsReporter.
returnStats[ODETotalAvatarsStatName] = _characters.Count * 3;
returnStats[ODETotalPrimsStatName] = _prims.Count * 3;
returnStats[ODEActivePrimsStatName] = _activeprims.Count * 3;
InitializeExtraStats();
} }
returnStats[ODEOtherCollisionFrameMsStatName]
= returnStats[ODEOtherCollisionFrameMsStatName]
- returnStats[ODENativeSpaceCollisionFrameMsStatName]
- returnStats[ODENativeGeomCollisionFrameMsStatName];
return returnStats; return returnStats;
} }
private void InitializeExtraStats()
{
m_stats[ODETotalFrameMsStatName] = 0;
m_stats[ODEAvatarTaintMsStatName] = 0;
m_stats[ODEPrimTaintMsStatName] = 0;
m_stats[ODEAvatarForcesFrameMsStatName] = 0;
m_stats[ODEPrimForcesFrameMsStatName] = 0;
m_stats[ODERaycastingFrameMsStatName] = 0;
m_stats[ODENativeStepFrameMsStatName] = 0;
m_stats[ODENativeSpaceCollisionFrameMsStatName] = 0;
m_stats[ODENativeGeomCollisionFrameMsStatName] = 0;
m_stats[ODEOtherCollisionFrameMsStatName] = 0;
m_stats[ODECollisionNotificationFrameMsStatName] = 0;
m_stats[ODEAvatarContactsStatsName] = 0;
m_stats[ODEPrimContactsStatName] = 0;
m_stats[ODEAvatarUpdateFrameMsStatName] = 0;
m_stats[ODEPrimUpdateFrameMsStatName] = 0;
}
} }
} }