diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 32c726266f..b79892d863 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1512,10 +1512,6 @@ namespace OpenSim.Region.Framework.Scenes
StatsReporter.AddPhysicsFPS(physicsFPS);
StatsReporter.AddTimeDilation(TimeDilation);
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
// reach min frame time.
@@ -1524,7 +1520,6 @@ namespace OpenSim.Region.Framework.Scenes
StatsReporter.addAgentMS(agentMS);
StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
StatsReporter.addOtherMS(otherMS);
- StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
if (LoginsDisabled && Frame == 20)
diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
index cb102d09d5..0efe4c4db7 100644
--- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
+++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
@@ -222,6 +222,10 @@ namespace OpenSim.Region.Framework.Scenes
m_report.Close();
}
+ ///
+ /// Sets the number of milliseconds between stat updates.
+ ///
+ ///
public void SetUpdateMS(int ms)
{
statsUpdatesEveryMS = ms;
@@ -296,6 +300,16 @@ namespace OpenSim.Region.Framework.Scenes
sparetime = TotalFrameTime;
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
// m_otherMS = m_frameMS - m_physicsMS - m_imageMS - m_netMS - m_agentMS;
@@ -462,13 +476,6 @@ namespace OpenSim.Region.Framework.Scenes
m_timeDilation = td;
}
- public void SetRootAgents(int rootAgents)
- {
- m_rootAgents = rootAgents;
- CheckStatSanity();
-
- }
-
internal void CheckStatSanity()
{
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)
{
m_fps += frames;
@@ -587,11 +578,6 @@ namespace OpenSim.Region.Framework.Scenes
m_scriptLinesPerSecond += count;
}
- public void SetActiveScripts(int count)
- {
- m_activeScripts = count;
- }
-
public void AddPacketsStats(int inPackets, int outPackets, int unAckedBytes)
{
AddInPackets(inPackets);
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
index fa659453c1..c6ecc68ae9 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
@@ -30,20 +30,21 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
-using System.IO;
-using System.Diagnostics;
using log4net;
using Nini.Config;
using Ode.NET;
+using OpenMetaverse;
#if USE_DRAWSTUFF
using Drawstuff.NET;
#endif
using OpenSim.Framework;
using OpenSim.Region.Physics.Manager;
-using OpenMetaverse;
namespace OpenSim.Region.Physics.OdePlugin
{
@@ -54,15 +55,15 @@ namespace OpenSim.Region.Physics.OdePlugin
End = 2
}
- public struct sCollisionData
- {
- public uint ColliderLocalId;
- public uint CollidedWithLocalId;
- public int NumberOfCollisions;
- public int CollisionType;
- public int StatusIndicator;
- public int lastframe;
- }
+// public struct sCollisionData
+// {
+// public uint ColliderLocalId;
+// public uint CollidedWithLocalId;
+// public int NumberOfCollisions;
+// public int CollisionType;
+// public int StatusIndicator;
+// public int lastframe;
+// }
[Flags]
public enum CollisionCategories : int
@@ -142,20 +143,114 @@ namespace OpenSim.Region.Physics.OdePlugin
private Dictionary m_stats = new Dictionary();
///
- /// 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.
///
- public const string ODENativeCollisionFrameMsStatName = "ODENativeCollisionFrameMS";
+ public const string ODETotalAvatarsStatName = "ODETotalAvatars";
+
+ ///
+ /// Stat name for total number of prims in this ODE scene.
+ ///
+ public const string ODETotalPrimsStatName = "ODETotalPrims";
+
+ ///
+ /// Stat name for total number of prims with active physics in this ODE scene.
+ ///
+ public const string ODEActivePrimsStatName = "ODEActivePrims";
+
+ ///
+ /// Stat name for the total time spent in ODE frame processing.
+ ///
+ ///
+ /// A sanity check for the main scene loop physics time.
+ ///
+ public const string ODETotalFrameMsStatName = "ODETotalFrameMS";
+
+ ///
+ /// Stat name for time spent processing avatar taints per frame
+ ///
+ public const string ODEAvatarTaintMsStatName = "ODEAvatarTaintFrameMS";
+
+ ///
+ /// Stat name for time spent processing prim taints per frame
+ ///
+ public const string ODEPrimTaintMsStatName = "ODEPrimTaintFrameMS";
+
+ ///
+ /// Stat name for time spent calculating avatar forces per frame.
+ ///
+ public const string ODEAvatarForcesFrameMsStatName = "ODEAvatarForcesFrameMS";
+
+ ///
+ /// Stat name for time spent calculating prim forces per frame
+ ///
+ public const string ODEPrimForcesFrameMsStatName = "ODEPrimForcesFrameMS";
+
+ ///
+ /// Stat name for time spent fulfilling raycasting requests per frame
+ ///
+ public const string ODERaycastingFrameMsStatName = "ODERaycastingFrameMS";
+
+ ///
+ /// Stat name for time spent in native code that actually steps through the simulation.
+ ///
+ public const string ODENativeStepFrameMsStatName = "ODENativeStepFrameMS";
+
+ ///
+ /// Stat name for the number of milliseconds that ODE spends in native space collision code.
+ ///
+ public const string ODENativeSpaceCollisionFrameMsStatName = "ODENativeSpaceCollisionFrameMS";
+
+ ///
+ /// Stat name for milliseconds that ODE spends in native geom collision code.
+ ///
+ public const string ODENativeGeomCollisionFrameMsStatName = "ODENativeGeomCollisionFrameMS";
+
+ ///
+ /// Time spent in collision processing that is not spent in native space or geom collision code.
+ ///
+ public const string ODEOtherCollisionFrameMsStatName = "ODEOtherCollisionFrameMS";
+
+ ///
+ /// Stat name for time spent notifying listeners of collisions
+ ///
+ public const string ODECollisionNotificationFrameMsStatName = "ODECollisionNotificationFrameMS";
+
+ ///
+ /// Stat name for milliseconds spent updating avatar position and velocity
+ ///
+ public const string ODEAvatarUpdateFrameMsStatName = "ODEAvatarUpdateFrameMS";
+
+ ///
+ /// Stat name for the milliseconds spent updating prim position and velocity
+ ///
+ public const string ODEPrimUpdateFrameMsStatName = "ODEPrimUpdateFrameMS";
+
+ ///
+ /// Stat name for avatar collisions with another entity.
+ ///
+ public const string ODEAvatarContactsStatsName = "ODEAvatarContacts";
+
+ ///
+ /// Stat name for prim collisions with another entity.
+ ///
+ public const string ODEPrimContactsStatName = "ODEPrimContacts";
///
/// Used to hold tick numbers for stat collection purposes.
///
- private int m_nativeCollisionTickRecorder;
+ private int m_nativeCollisionStartTick;
///
/// A messy way to tell if we need to avoid adding a collision time because this was already done in the callback.
///
private bool m_inCollisionTiming;
+ ///
+ /// 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.
+ ///
+ private int m_tempAvatarCollisionsThisFrame;
+
///
/// Used in calculating physics frame time dilation
///
@@ -472,7 +567,7 @@ namespace OpenSim.Region.Physics.OdePlugin
// Initialize the mesh plugin
public override void Initialise(IMesher meshmerizer, IConfigSource config)
{
- m_stats[ODENativeCollisionFrameMsStatName] = 0;
+ InitializeExtraStats();
mesher = meshmerizer;
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
if (CollectStats)
- m_nativeCollisionTickRecorder = Util.EnvironmentTickCount();
+ m_nativeCollisionStartTick = Util.EnvironmentTickCount();
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
// negligable
if (CollectStats)
- m_stats[ODENativeCollisionFrameMsStatName]
- += Util.EnvironmentTickCountSubtract(m_nativeCollisionTickRecorder);
+ m_stats[ODENativeGeomCollisionFrameMsStatName]
+ += Util.EnvironmentTickCountSubtract(m_nativeCollisionStartTick);
return count;
}
@@ -843,15 +938,15 @@ namespace OpenSim.Region.Physics.OdePlugin
if (CollectStats)
{
m_inCollisionTiming = true;
- m_nativeCollisionTickRecorder = Util.EnvironmentTickCount();
+ m_nativeCollisionStartTick = Util.EnvironmentTickCount();
}
d.SpaceCollide2(space1, space2, data, nearCallback);
if (CollectStats && m_inCollisionTiming)
{
- m_stats[ODENativeCollisionFrameMsStatName]
- += Util.EnvironmentTickCountSubtract(m_nativeCollisionTickRecorder);
+ m_stats[ODENativeSpaceCollisionFrameMsStatName]
+ += Util.EnvironmentTickCountSubtract(m_nativeCollisionStartTick);
m_inCollisionTiming = false;
}
}
@@ -866,8 +961,8 @@ namespace OpenSim.Region.Physics.OdePlugin
{
if (CollectStats && m_inCollisionTiming)
{
- m_stats[ODENativeCollisionFrameMsStatName]
- += Util.EnvironmentTickCountSubtract(m_nativeCollisionTickRecorder);
+ m_stats[ODENativeSpaceCollisionFrameMsStatName]
+ += Util.EnvironmentTickCountSubtract(m_nativeCollisionStartTick);
m_inCollisionTiming = false;
}
@@ -945,6 +1040,10 @@ namespace OpenSim.Region.Physics.OdePlugin
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)
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);
- // If we're colliding against terrain
if (name1 == "Terrain" || name2 == "Terrain")
{
- // If we're moving
if ((p2.PhysicsActorType == (int) ActorTypes.Agent) &&
(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;
if (m_global_contactcount < maxContactsbeforedeath)
@@ -1232,7 +1329,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{
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;
if (m_global_contactcount < maxContactsbeforedeath)
@@ -1327,13 +1424,11 @@ namespace OpenSim.Region.Physics.OdePlugin
}
else
{
- // we're colliding with prim or avatar
- // check if we're moving
if ((p2.PhysicsActorType == (int)ActorTypes.Agent))
{
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;
if (m_global_contactcount < maxContactsbeforedeath)
@@ -1344,9 +1439,8 @@ namespace OpenSim.Region.Physics.OdePlugin
}
else
{
- // Use the non movement contact
+ // Avatar is standing still on a prim, use the non movement contact
contact.geom = curContact;
- _perloopContact.Add(curContact);
if (m_global_contactcount < maxContactsbeforedeath)
{
@@ -1454,7 +1548,7 @@ namespace OpenSim.Region.Physics.OdePlugin
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));
}
}
@@ -1692,8 +1786,11 @@ namespace OpenSim.Region.Physics.OdePlugin
//}
}
-// if (framecount % 55 == 0)
-// m_log.DebugFormat("Processed {0} collisions", _perloopContact.Count);
+ if (CollectStats)
+ {
+ m_tempAvatarCollisionsThisFrame = _perloopContact.Count;
+ m_stats[ODEAvatarContactsStatsName] += m_tempAvatarCollisionsThisFrame;
+ }
List removeprims = null;
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)
{
foreach (OdePrim chr in removeprims)
@@ -2785,21 +2885,23 @@ namespace OpenSim.Region.Physics.OdePlugin
///
/// This is our main simulate loop
+ ///
+ ///
/// It's thread locked by a Mutex in the scene.
/// It holds Collisions, it instructs ODE to step through the physical reactions
/// It moves the objects around in memory
/// It calls the methods that report back to the object owners.. (scenepresence, SceneObjectGroup)
- ///
+ ///
///
/// The number of frames simulated over that period.
public override float Simulate(float timeStep)
{
+ int startFrameTick = CollectStats ? Util.EnvironmentTickCount() : 0;
+ int tempTick = 0, tempTick2 = 0;
+
if (framecount >= int.MaxValue)
framecount = 0;
- //if (m_worldOffset != Vector3.Zero)
- // return 0;
-
framecount++;
float fps = 0;
@@ -2807,7 +2909,7 @@ namespace OpenSim.Region.Physics.OdePlugin
float timeLeft = timeStep;
//m_log.Info(timeStep.ToString());
-// step_time += timeStep;
+// step_time += timeSte
//
// // If We're loaded down by something else,
// // or debugging with the Visual Studio project on pause
@@ -2873,6 +2975,9 @@ namespace OpenSim.Region.Physics.OdePlugin
{
try
{
+ if (CollectStats)
+ tempTick = Util.EnvironmentTickCount();
+
lock (_taintedActors)
{
foreach (OdeCharacter character in _taintedActors)
@@ -2881,6 +2986,13 @@ namespace OpenSim.Region.Physics.OdePlugin
_taintedActors.Clear();
}
+ if (CollectStats)
+ {
+ tempTick2 = Util.EnvironmentTickCount();
+ m_stats[ODEAvatarTaintMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
+ tempTick = tempTick2;
+ }
+
lock (_taintedPrims)
{
foreach (OdePrim prim in _taintedPrims)
@@ -2911,6 +3023,13 @@ namespace OpenSim.Region.Physics.OdePlugin
_taintedPrims.Clear();
}
+ if (CollectStats)
+ {
+ tempTick2 = Util.EnvironmentTickCount();
+ m_stats[ODEPrimTaintMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
+ tempTick = tempTick2;
+ }
+
// Move characters
foreach (OdeCharacter actor in _characters)
actor.Move(defects);
@@ -2930,6 +3049,13 @@ namespace OpenSim.Region.Physics.OdePlugin
defects.Clear();
}
+ if (CollectStats)
+ {
+ tempTick2 = Util.EnvironmentTickCount();
+ m_stats[ODEAvatarForcesFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
+ tempTick = tempTick2;
+ }
+
// Move other active objects
foreach (OdePrim prim in _activeprims)
{
@@ -2937,14 +3063,35 @@ namespace OpenSim.Region.Physics.OdePlugin
prim.Move(timeStep);
}
+ if (CollectStats)
+ {
+ tempTick2 = Util.EnvironmentTickCount();
+ m_stats[ODEPrimForcesFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
+ tempTick = tempTick2;
+ }
+
//if ((framecount % m_randomizeWater) == 0)
// randomizeWater(waterlevel);
//int RayCastTimeMS = m_rayCastManager.ProcessQueuedRequests();
m_rayCastManager.ProcessQueuedRequests();
+ if (CollectStats)
+ {
+ tempTick2 = Util.EnvironmentTickCount();
+ m_stats[ODERaycastingFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
+ tempTick = tempTick2;
+ }
+
collision_optimized();
+ if (CollectStats)
+ {
+ tempTick2 = Util.EnvironmentTickCount();
+ m_stats[ODEOtherCollisionFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
+ tempTick = tempTick2;
+ }
+
foreach (PhysicsActor obj in _collisionEventPrim.Values)
{
// m_log.DebugFormat("[PHYSICS]: Assessing {0} {1} for collision events", obj.SOPName, obj.LocalID);
@@ -2969,9 +3116,19 @@ namespace OpenSim.Region.Physics.OdePlugin
// "[PHYSICS]: Collision contacts to process this frame = {0}", m_global_contactcount);
m_global_contactcount = 0;
-
+
+ if (CollectStats)
+ {
+ tempTick2 = Util.EnvironmentTickCount();
+ m_stats[ODECollisionNotificationFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
+ tempTick = tempTick2;
+ }
+
d.WorldQuickStep(world, ODE_STEPSIZE);
+ if (CollectStats)
+ m_stats[ODENativeStepFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick);
+
d.JointGroupEmpty(contactgroup);
}
catch (Exception e)
@@ -2982,6 +3139,9 @@ namespace OpenSim.Region.Physics.OdePlugin
timeLeft -= ODE_STEPSIZE;
}
+ if (CollectStats)
+ tempTick = Util.EnvironmentTickCount();
+
foreach (OdeCharacter actor in _characters)
{
if (actor.bad)
@@ -3005,6 +3165,13 @@ namespace OpenSim.Region.Physics.OdePlugin
defects.Clear();
}
+ if (CollectStats)
+ {
+ tempTick2 = Util.EnvironmentTickCount();
+ m_stats[ODEAvatarUpdateFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick2, tempTick);
+ tempTick = tempTick2;
+ }
+
//if (timeStep < 0.2f)
foreach (OdePrim prim in _activeprims)
@@ -3018,6 +3185,9 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
+ if (CollectStats)
+ m_stats[ODEPrimUpdateFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick);
+
//DumpJointInfo();
// 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);
}
- latertickcount = Util.EnvironmentTickCount() - tickCountFrameRun;
+ latertickcount = Util.EnvironmentTickCountSubtract(tickCountFrameRun);
// OpenSimulator above does 10 fps. 10 fps = means that the main thread loop and physics
// has a max of 100 ms to run theoretically.
@@ -3059,6 +3229,9 @@ namespace OpenSim.Region.Physics.OdePlugin
tickCountFrameRun = Util.EnvironmentTickCount();
}
+ if (CollectStats)
+ m_stats[ODETotalFrameMsStatName] += Util.EnvironmentTickCountSubtract(startFrameTick);
+
return fps;
}
@@ -3868,26 +4041,19 @@ namespace OpenSim.Region.Physics.OdePlugin
public override Dictionary GetTopColliders()
{
- Dictionary returncolliders = new Dictionary();
- int cnt = 0;
+ Dictionary topColliders;
+
lock (_prims)
{
- foreach (OdePrim prm in _prims)
- {
- if (prm.CollisionScore > 0)
- {
- returncolliders.Add(prm.LocalID, prm.CollisionScore);
- cnt++;
- prm.CollisionScore = 0f;
- if (cnt > 25)
- {
- break;
- }
- }
- }
+ List orderedPrims = new List(_prims);
+ orderedPrims.OrderByDescending(p => p.CollisionScore).Take(25);
+ topColliders = orderedPrims.ToDictionary(p => p.LocalID, p => p.CollisionScore);
+
+ foreach (OdePrim p in _prims)
+ p.CollisionScore = 0;
}
- return returncolliders;
+ return topColliders;
}
public override bool SupportsRayCast()
@@ -4069,10 +4235,40 @@ namespace OpenSim.Region.Physics.OdePlugin
{
returnStats = new Dictionary(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;
}
+
+ 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;
+ }
}
}
\ No newline at end of file