diff options
-rw-r--r-- | OpenSim/Region/Application/OpenSim.cs | 3 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Commands/UserCommandsModule.cs | 189 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs | 108 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 18 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SimStatsReporter.cs | 48 | ||||
-rw-r--r-- | OpenSim/Region/Physics/Manager/PhysicsScene.cs | 14 | ||||
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 139 | ||||
-rw-r--r-- | bin/OpenSimDefaults.ini | 30 |
8 files changed, 469 insertions, 80 deletions
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index daae3e6..caf74cf 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs | |||
@@ -28,6 +28,7 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Diagnostics; | ||
31 | using System.IO; | 32 | using System.IO; |
32 | using System.Reflection; | 33 | using System.Reflection; |
33 | using System.Text; | 34 | using System.Text; |
@@ -138,7 +139,7 @@ namespace OpenSim | |||
138 | m_log.Info("===================================================================="); | 139 | m_log.Info("===================================================================="); |
139 | m_log.Info("========================= STARTING OPENSIM ========================="); | 140 | m_log.Info("========================= STARTING OPENSIM ========================="); |
140 | m_log.Info("===================================================================="); | 141 | m_log.Info("===================================================================="); |
141 | 142 | ||
142 | //m_log.InfoFormat("[OPENSIM MAIN]: GC Is Server GC: {0}", GCSettings.IsServerGC.ToString()); | 143 | //m_log.InfoFormat("[OPENSIM MAIN]: GC Is Server GC: {0}", GCSettings.IsServerGC.ToString()); |
143 | // http://msdn.microsoft.com/en-us/library/bb384202.aspx | 144 | // http://msdn.microsoft.com/en-us/library/bb384202.aspx |
144 | //GCSettings.LatencyMode = GCLatencyMode.Batch; | 145 | //GCSettings.LatencyMode = GCLatencyMode.Batch; |
diff --git a/OpenSim/Region/CoreModules/Avatar/Commands/UserCommandsModule.cs b/OpenSim/Region/CoreModules/Avatar/Commands/UserCommandsModule.cs new file mode 100644 index 0000000..4bcd2ac --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/Commands/UserCommandsModule.cs | |||
@@ -0,0 +1,189 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | using System.Text; | ||
32 | using System.Text.RegularExpressions; | ||
33 | using log4net; | ||
34 | using Mono.Addins; | ||
35 | using NDesk.Options; | ||
36 | using Nini.Config; | ||
37 | using OpenMetaverse; | ||
38 | using OpenSim.Framework; | ||
39 | using OpenSim.Framework.Console; | ||
40 | using OpenSim.Framework.Statistics; | ||
41 | using OpenSim.Region.Framework.Interfaces; | ||
42 | using OpenSim.Region.Framework.Scenes; | ||
43 | |||
44 | namespace OpenSim.Region.CoreModules.Avatars.Commands | ||
45 | { | ||
46 | /// <summary> | ||
47 | /// A module that holds commands for manipulating objects in the scene. | ||
48 | /// </summary> | ||
49 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserCommandsModule")] | ||
50 | public class UserCommandsModule : ISharedRegionModule | ||
51 | { | ||
52 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
53 | |||
54 | public const string TeleportUserCommandSyntax = "teleport user <first-name> <last-name> <destination>"; | ||
55 | |||
56 | public static Regex InterRegionDestinationRegex | ||
57 | = new Regex(@"^(?<regionName>.+)/(?<x>\d+)/(?<y>\d+)/(?<z>\d+)$", RegexOptions.Compiled); | ||
58 | |||
59 | public static Regex WithinRegionDestinationRegex | ||
60 | = new Regex(@"^(?<x>\d+)/(?<y>\d+)/(?<z>\d+)$", RegexOptions.Compiled); | ||
61 | |||
62 | private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>(); | ||
63 | |||
64 | public string Name { get { return "User Commands Module"; } } | ||
65 | |||
66 | public Type ReplaceableInterface { get { return null; } } | ||
67 | |||
68 | public void Initialise(IConfigSource source) | ||
69 | { | ||
70 | // m_log.DebugFormat("[USER COMMANDS MODULE]: INITIALIZED MODULE"); | ||
71 | } | ||
72 | |||
73 | public void PostInitialise() | ||
74 | { | ||
75 | // m_log.DebugFormat("[USER COMMANDS MODULE]: POST INITIALIZED MODULE"); | ||
76 | } | ||
77 | |||
78 | public void Close() | ||
79 | { | ||
80 | // m_log.DebugFormat("[USER COMMANDS MODULE]: CLOSED MODULE"); | ||
81 | } | ||
82 | |||
83 | public void AddRegion(Scene scene) | ||
84 | { | ||
85 | // m_log.DebugFormat("[USER COMMANDS MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); | ||
86 | |||
87 | lock (m_scenes) | ||
88 | m_scenes[scene.RegionInfo.RegionID] = scene; | ||
89 | |||
90 | scene.AddCommand( | ||
91 | "Users", | ||
92 | this, | ||
93 | "teleport user", | ||
94 | TeleportUserCommandSyntax, | ||
95 | "Teleport a user in this simulator to the given destination", | ||
96 | "<destination> is in format [<region-name>]/<x>/<y>/<z>, e.g. regionone/20/30/40 or just 20/30/40 to teleport within same region." | ||
97 | + "\nIf the region contains a space then the whole destination must be in quotes, e.g. \"region one/20/30/40\"", | ||
98 | HandleTeleportUser); | ||
99 | } | ||
100 | |||
101 | public void RemoveRegion(Scene scene) | ||
102 | { | ||
103 | // m_log.DebugFormat("[USER COMMANDS MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); | ||
104 | |||
105 | lock (m_scenes) | ||
106 | m_scenes.Remove(scene.RegionInfo.RegionID); | ||
107 | } | ||
108 | |||
109 | public void RegionLoaded(Scene scene) | ||
110 | { | ||
111 | // m_log.DebugFormat("[USER COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); | ||
112 | } | ||
113 | |||
114 | private ScenePresence GetUser(string firstName, string lastName) | ||
115 | { | ||
116 | ScenePresence userFound = null; | ||
117 | |||
118 | lock (m_scenes) | ||
119 | { | ||
120 | foreach (Scene scene in m_scenes.Values) | ||
121 | { | ||
122 | ScenePresence user = scene.GetScenePresence(firstName, lastName); | ||
123 | if (user != null && !user.IsChildAgent) | ||
124 | { | ||
125 | userFound = user; | ||
126 | break; | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | |||
131 | return userFound; | ||
132 | } | ||
133 | |||
134 | private void HandleTeleportUser(string module, string[] cmd) | ||
135 | { | ||
136 | if (cmd.Length < 5) | ||
137 | { | ||
138 | MainConsole.Instance.OutputFormat("Usage: " + TeleportUserCommandSyntax); | ||
139 | return; | ||
140 | } | ||
141 | |||
142 | string firstName = cmd[2]; | ||
143 | string lastName = cmd[3]; | ||
144 | string rawDestination = cmd[4]; | ||
145 | |||
146 | ScenePresence user = GetUser(firstName, lastName); | ||
147 | |||
148 | if (user == null) | ||
149 | { | ||
150 | MainConsole.Instance.OutputFormat("No user found with name {0} {1}", firstName, lastName); | ||
151 | return; | ||
152 | } | ||
153 | |||
154 | // MainConsole.Instance.OutputFormat("rawDestination [{0}]", rawDestination); | ||
155 | |||
156 | Match m = WithinRegionDestinationRegex.Match(rawDestination); | ||
157 | |||
158 | if (!m.Success) | ||
159 | { | ||
160 | m = InterRegionDestinationRegex.Match(rawDestination); | ||
161 | |||
162 | if (!m.Success) | ||
163 | { | ||
164 | MainConsole.Instance.OutputFormat("Invalid destination {0}", rawDestination); | ||
165 | return; | ||
166 | } | ||
167 | } | ||
168 | |||
169 | string regionName | ||
170 | = m.Groups["regionName"].Success ? m.Groups["regionName"].Value : user.Scene.RegionInfo.RegionName; | ||
171 | |||
172 | MainConsole.Instance.OutputFormat( | ||
173 | "Teleporting {0} to {1},{2},{3} in {4}", | ||
174 | user.Name, | ||
175 | m.Groups["x"], m.Groups["y"], m.Groups["z"], | ||
176 | regionName); | ||
177 | |||
178 | user.Scene.RequestTeleportLocation( | ||
179 | user.ControllingClient, | ||
180 | regionName, | ||
181 | new Vector3( | ||
182 | float.Parse(m.Groups["x"].Value), | ||
183 | float.Parse(m.Groups["y"].Value), | ||
184 | float.Parse(m.Groups["z"].Value)), | ||
185 | user.Lookat, | ||
186 | (uint)TeleportFlags.ViaLocation); | ||
187 | } | ||
188 | } | ||
189 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs index 7f8271d..4a8c369 100644 --- a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs | |||
@@ -49,7 +49,16 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
49 | public bool Enabled { get; private set; } | 49 | public bool Enabled { get; private set; } |
50 | 50 | ||
51 | private Scene m_scene; | 51 | private Scene m_scene; |
52 | private readonly List<IMonitor> m_monitors = new List<IMonitor>(); | 52 | |
53 | /// <summary> | ||
54 | /// These are monitors where we know the static details in advance. | ||
55 | /// </summary> | ||
56 | /// <remarks> | ||
57 | /// Dynamic monitors also exist (we don't know any of the details of what stats we get back here) | ||
58 | /// but these are currently hardcoded. | ||
59 | /// </remarks> | ||
60 | private readonly List<IMonitor> m_staticMonitors = new List<IMonitor>(); | ||
61 | |||
53 | private readonly List<IAlert> m_alerts = new List<IAlert>(); | 62 | private readonly List<IAlert> m_alerts = new List<IAlert>(); |
54 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 63 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
55 | 64 | ||
@@ -84,9 +93,18 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
84 | 93 | ||
85 | public void DebugMonitors(string module, string[] args) | 94 | public void DebugMonitors(string module, string[] args) |
86 | { | 95 | { |
87 | foreach (IMonitor monitor in m_monitors) | 96 | foreach (IMonitor monitor in m_staticMonitors) |
88 | { | 97 | { |
89 | m_log.Info("[MonitorModule]: " + m_scene.RegionInfo.RegionName + " reports " + monitor.GetFriendlyName() + " = " + monitor.GetFriendlyValue()); | 98 | m_log.InfoFormat( |
99 | "[MONITOR MODULE]: {0} reports {1} = {2}", | ||
100 | m_scene.RegionInfo.RegionName, monitor.GetFriendlyName(), monitor.GetFriendlyValue()); | ||
101 | } | ||
102 | |||
103 | foreach (KeyValuePair<string, float> tuple in m_scene.StatsReporter.GetExtraSimStats()) | ||
104 | { | ||
105 | m_log.InfoFormat( | ||
106 | "[MONITOR MODULE]: {0} reports {1} = {2}", | ||
107 | m_scene.RegionInfo.RegionName, tuple.Key, tuple.Value); | ||
90 | } | 108 | } |
91 | } | 109 | } |
92 | 110 | ||
@@ -106,11 +124,12 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
106 | { | 124 | { |
107 | string monID = (string) request["monitor"]; | 125 | string monID = (string) request["monitor"]; |
108 | 126 | ||
109 | foreach (IMonitor monitor in m_monitors) | 127 | foreach (IMonitor monitor in m_staticMonitors) |
110 | { | 128 | { |
111 | string elemName = monitor.ToString(); | 129 | string elemName = monitor.ToString(); |
112 | if (elemName.StartsWith(monitor.GetType().Namespace)) | 130 | if (elemName.StartsWith(monitor.GetType().Namespace)) |
113 | elemName = elemName.Substring(monitor.GetType().Namespace.Length + 1); | 131 | elemName = elemName.Substring(monitor.GetType().Namespace.Length + 1); |
132 | |||
114 | if (elemName == monID || monitor.ToString() == monID) | 133 | if (elemName == monID || monitor.ToString() == monID) |
115 | { | 134 | { |
116 | Hashtable ereply3 = new Hashtable(); | 135 | Hashtable ereply3 = new Hashtable(); |
@@ -123,6 +142,9 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
123 | } | 142 | } |
124 | } | 143 | } |
125 | 144 | ||
145 | // FIXME: Arguably this should also be done with dynamic monitors but I'm not sure what the above code | ||
146 | // is even doing. Why are we inspecting the type of the monitor??? | ||
147 | |||
126 | // No monitor with that name | 148 | // No monitor with that name |
127 | Hashtable ereply2 = new Hashtable(); | 149 | Hashtable ereply2 = new Hashtable(); |
128 | 150 | ||
@@ -134,12 +156,18 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
134 | } | 156 | } |
135 | 157 | ||
136 | string xml = "<data>"; | 158 | string xml = "<data>"; |
137 | foreach (IMonitor monitor in m_monitors) | 159 | foreach (IMonitor monitor in m_staticMonitors) |
138 | { | 160 | { |
139 | string elemName = monitor.GetName(); | 161 | string elemName = monitor.GetName(); |
140 | xml += "<" + elemName + ">" + monitor.GetValue().ToString() + "</" + elemName + ">"; | 162 | xml += "<" + elemName + ">" + monitor.GetValue().ToString() + "</" + elemName + ">"; |
141 | // m_log.DebugFormat("[MONITOR MODULE]: {0} = {1}", elemName, monitor.GetValue()); | 163 | // m_log.DebugFormat("[MONITOR MODULE]: {0} = {1}", elemName, monitor.GetValue()); |
142 | } | 164 | } |
165 | |||
166 | foreach (KeyValuePair<string, float> tuple in m_scene.StatsReporter.GetExtraSimStats()) | ||
167 | { | ||
168 | xml += "<" + tuple.Key + ">" + tuple.Value + "</" + tuple.Key + ">"; | ||
169 | } | ||
170 | |||
143 | xml += "</data>"; | 171 | xml += "</data>"; |
144 | 172 | ||
145 | Hashtable ereply = new Hashtable(); | 173 | Hashtable ereply = new Hashtable(); |
@@ -156,20 +184,20 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
156 | if (!Enabled) | 184 | if (!Enabled) |
157 | return; | 185 | return; |
158 | 186 | ||
159 | m_monitors.Add(new AgentCountMonitor(m_scene)); | 187 | m_staticMonitors.Add(new AgentCountMonitor(m_scene)); |
160 | m_monitors.Add(new ChildAgentCountMonitor(m_scene)); | 188 | m_staticMonitors.Add(new ChildAgentCountMonitor(m_scene)); |
161 | m_monitors.Add(new GCMemoryMonitor()); | 189 | m_staticMonitors.Add(new GCMemoryMonitor()); |
162 | m_monitors.Add(new ObjectCountMonitor(m_scene)); | 190 | m_staticMonitors.Add(new ObjectCountMonitor(m_scene)); |
163 | m_monitors.Add(new PhysicsFrameMonitor(m_scene)); | 191 | m_staticMonitors.Add(new PhysicsFrameMonitor(m_scene)); |
164 | m_monitors.Add(new PhysicsUpdateFrameMonitor(m_scene)); | 192 | m_staticMonitors.Add(new PhysicsUpdateFrameMonitor(m_scene)); |
165 | m_monitors.Add(new PWSMemoryMonitor()); | 193 | m_staticMonitors.Add(new PWSMemoryMonitor()); |
166 | m_monitors.Add(new ThreadCountMonitor()); | 194 | m_staticMonitors.Add(new ThreadCountMonitor()); |
167 | m_monitors.Add(new TotalFrameMonitor(m_scene)); | 195 | m_staticMonitors.Add(new TotalFrameMonitor(m_scene)); |
168 | m_monitors.Add(new EventFrameMonitor(m_scene)); | 196 | m_staticMonitors.Add(new EventFrameMonitor(m_scene)); |
169 | m_monitors.Add(new LandFrameMonitor(m_scene)); | 197 | m_staticMonitors.Add(new LandFrameMonitor(m_scene)); |
170 | m_monitors.Add(new LastFrameTimeMonitor(m_scene)); | 198 | m_staticMonitors.Add(new LastFrameTimeMonitor(m_scene)); |
171 | 199 | ||
172 | m_monitors.Add( | 200 | m_staticMonitors.Add( |
173 | new GenericMonitor( | 201 | new GenericMonitor( |
174 | m_scene, | 202 | m_scene, |
175 | "TimeDilationMonitor", | 203 | "TimeDilationMonitor", |
@@ -177,7 +205,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
177 | m => m.Scene.StatsReporter.LastReportedSimStats[0], | 205 | m => m.Scene.StatsReporter.LastReportedSimStats[0], |
178 | m => m.GetValue().ToString())); | 206 | m => m.GetValue().ToString())); |
179 | 207 | ||
180 | m_monitors.Add( | 208 | m_staticMonitors.Add( |
181 | new GenericMonitor( | 209 | new GenericMonitor( |
182 | m_scene, | 210 | m_scene, |
183 | "SimFPSMonitor", | 211 | "SimFPSMonitor", |
@@ -185,7 +213,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
185 | m => m.Scene.StatsReporter.LastReportedSimStats[1], | 213 | m => m.Scene.StatsReporter.LastReportedSimStats[1], |
186 | m => string.Format("{0}", m.GetValue()))); | 214 | m => string.Format("{0}", m.GetValue()))); |
187 | 215 | ||
188 | m_monitors.Add( | 216 | m_staticMonitors.Add( |
189 | new GenericMonitor( | 217 | new GenericMonitor( |
190 | m_scene, | 218 | m_scene, |
191 | "PhysicsFPSMonitor", | 219 | "PhysicsFPSMonitor", |
@@ -193,7 +221,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
193 | m => m.Scene.StatsReporter.LastReportedSimStats[2], | 221 | m => m.Scene.StatsReporter.LastReportedSimStats[2], |
194 | m => string.Format("{0}", m.GetValue()))); | 222 | m => string.Format("{0}", m.GetValue()))); |
195 | 223 | ||
196 | m_monitors.Add( | 224 | m_staticMonitors.Add( |
197 | new GenericMonitor( | 225 | new GenericMonitor( |
198 | m_scene, | 226 | m_scene, |
199 | "AgentUpdatesPerSecondMonitor", | 227 | "AgentUpdatesPerSecondMonitor", |
@@ -201,15 +229,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
201 | m => m.Scene.StatsReporter.LastReportedSimStats[3], | 229 | m => m.Scene.StatsReporter.LastReportedSimStats[3], |
202 | m => string.Format("{0} per second", m.GetValue()))); | 230 | m => string.Format("{0} per second", m.GetValue()))); |
203 | 231 | ||
204 | m_monitors.Add( | 232 | m_staticMonitors.Add( |
205 | new GenericMonitor( | ||
206 | m_scene, | ||
207 | "ObjectUpdatesPerSecondMonitor", | ||
208 | "Object Updates", | ||
209 | m => m.Scene.StatsReporter.LastReportedObjectUpdates, | ||
210 | m => string.Format("{0} per second", m.GetValue()))); | ||
211 | |||
212 | m_monitors.Add( | ||
213 | new GenericMonitor( | 233 | new GenericMonitor( |
214 | m_scene, | 234 | m_scene, |
215 | "ActiveObjectCountMonitor", | 235 | "ActiveObjectCountMonitor", |
@@ -217,7 +237,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
217 | m => m.Scene.StatsReporter.LastReportedSimStats[7], | 237 | m => m.Scene.StatsReporter.LastReportedSimStats[7], |
218 | m => string.Format("{0}", m.GetValue()))); | 238 | m => string.Format("{0}", m.GetValue()))); |
219 | 239 | ||
220 | m_monitors.Add( | 240 | m_staticMonitors.Add( |
221 | new GenericMonitor( | 241 | new GenericMonitor( |
222 | m_scene, | 242 | m_scene, |
223 | "ActiveScriptsMonitor", | 243 | "ActiveScriptsMonitor", |
@@ -225,7 +245,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
225 | m => m.Scene.StatsReporter.LastReportedSimStats[19], | 245 | m => m.Scene.StatsReporter.LastReportedSimStats[19], |
226 | m => string.Format("{0}", m.GetValue()))); | 246 | m => string.Format("{0}", m.GetValue()))); |
227 | 247 | ||
228 | m_monitors.Add( | 248 | m_staticMonitors.Add( |
229 | new GenericMonitor( | 249 | new GenericMonitor( |
230 | m_scene, | 250 | m_scene, |
231 | "ScriptEventsPerSecondMonitor", | 251 | "ScriptEventsPerSecondMonitor", |
@@ -233,7 +253,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
233 | m => m.Scene.StatsReporter.LastReportedSimStats[20], | 253 | m => m.Scene.StatsReporter.LastReportedSimStats[20], |
234 | m => string.Format("{0} per second", m.GetValue()))); | 254 | m => string.Format("{0} per second", m.GetValue()))); |
235 | 255 | ||
236 | m_monitors.Add( | 256 | m_staticMonitors.Add( |
237 | new GenericMonitor( | 257 | new GenericMonitor( |
238 | m_scene, | 258 | m_scene, |
239 | "InPacketsPerSecondMonitor", | 259 | "InPacketsPerSecondMonitor", |
@@ -241,7 +261,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
241 | m => m.Scene.StatsReporter.LastReportedSimStats[13], | 261 | m => m.Scene.StatsReporter.LastReportedSimStats[13], |
242 | m => string.Format("{0} per second", m.GetValue()))); | 262 | m => string.Format("{0} per second", m.GetValue()))); |
243 | 263 | ||
244 | m_monitors.Add( | 264 | m_staticMonitors.Add( |
245 | new GenericMonitor( | 265 | new GenericMonitor( |
246 | m_scene, | 266 | m_scene, |
247 | "OutPacketsPerSecondMonitor", | 267 | "OutPacketsPerSecondMonitor", |
@@ -249,7 +269,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
249 | m => m.Scene.StatsReporter.LastReportedSimStats[14], | 269 | m => m.Scene.StatsReporter.LastReportedSimStats[14], |
250 | m => string.Format("{0} per second", m.GetValue()))); | 270 | m => string.Format("{0} per second", m.GetValue()))); |
251 | 271 | ||
252 | m_monitors.Add( | 272 | m_staticMonitors.Add( |
253 | new GenericMonitor( | 273 | new GenericMonitor( |
254 | m_scene, | 274 | m_scene, |
255 | "UnackedBytesMonitor", | 275 | "UnackedBytesMonitor", |
@@ -257,7 +277,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
257 | m => m.Scene.StatsReporter.LastReportedSimStats[15], | 277 | m => m.Scene.StatsReporter.LastReportedSimStats[15], |
258 | m => string.Format("{0}", m.GetValue()))); | 278 | m => string.Format("{0}", m.GetValue()))); |
259 | 279 | ||
260 | m_monitors.Add( | 280 | m_staticMonitors.Add( |
261 | new GenericMonitor( | 281 | new GenericMonitor( |
262 | m_scene, | 282 | m_scene, |
263 | "PendingDownloadsMonitor", | 283 | "PendingDownloadsMonitor", |
@@ -265,7 +285,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
265 | m => m.Scene.StatsReporter.LastReportedSimStats[17], | 285 | m => m.Scene.StatsReporter.LastReportedSimStats[17], |
266 | m => string.Format("{0}", m.GetValue()))); | 286 | m => string.Format("{0}", m.GetValue()))); |
267 | 287 | ||
268 | m_monitors.Add( | 288 | m_staticMonitors.Add( |
269 | new GenericMonitor( | 289 | new GenericMonitor( |
270 | m_scene, | 290 | m_scene, |
271 | "PendingUploadsMonitor", | 291 | "PendingUploadsMonitor", |
@@ -273,7 +293,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
273 | m => m.Scene.StatsReporter.LastReportedSimStats[18], | 293 | m => m.Scene.StatsReporter.LastReportedSimStats[18], |
274 | m => string.Format("{0}", m.GetValue()))); | 294 | m => string.Format("{0}", m.GetValue()))); |
275 | 295 | ||
276 | m_monitors.Add( | 296 | m_staticMonitors.Add( |
277 | new GenericMonitor( | 297 | new GenericMonitor( |
278 | m_scene, | 298 | m_scene, |
279 | "TotalFrameTimeMonitor", | 299 | "TotalFrameTimeMonitor", |
@@ -281,7 +301,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
281 | m => m.Scene.StatsReporter.LastReportedSimStats[8], | 301 | m => m.Scene.StatsReporter.LastReportedSimStats[8], |
282 | m => string.Format("{0} ms", m.GetValue()))); | 302 | m => string.Format("{0} ms", m.GetValue()))); |
283 | 303 | ||
284 | m_monitors.Add( | 304 | m_staticMonitors.Add( |
285 | new GenericMonitor( | 305 | new GenericMonitor( |
286 | m_scene, | 306 | m_scene, |
287 | "NetFrameTimeMonitor", | 307 | "NetFrameTimeMonitor", |
@@ -289,7 +309,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
289 | m => m.Scene.StatsReporter.LastReportedSimStats[9], | 309 | m => m.Scene.StatsReporter.LastReportedSimStats[9], |
290 | m => string.Format("{0} ms", m.GetValue()))); | 310 | m => string.Format("{0} ms", m.GetValue()))); |
291 | 311 | ||
292 | m_monitors.Add( | 312 | m_staticMonitors.Add( |
293 | new GenericMonitor( | 313 | new GenericMonitor( |
294 | m_scene, | 314 | m_scene, |
295 | "PhysicsFrameTimeMonitor", | 315 | "PhysicsFrameTimeMonitor", |
@@ -297,7 +317,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
297 | m => m.Scene.StatsReporter.LastReportedSimStats[10], | 317 | m => m.Scene.StatsReporter.LastReportedSimStats[10], |
298 | m => string.Format("{0} ms", m.GetValue()))); | 318 | m => string.Format("{0} ms", m.GetValue()))); |
299 | 319 | ||
300 | m_monitors.Add( | 320 | m_staticMonitors.Add( |
301 | new GenericMonitor( | 321 | new GenericMonitor( |
302 | m_scene, | 322 | m_scene, |
303 | "SimulationFrameTimeMonitor", | 323 | "SimulationFrameTimeMonitor", |
@@ -305,7 +325,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
305 | m => m.Scene.StatsReporter.LastReportedSimStats[12], | 325 | m => m.Scene.StatsReporter.LastReportedSimStats[12], |
306 | m => string.Format("{0} ms", m.GetValue()))); | 326 | m => string.Format("{0} ms", m.GetValue()))); |
307 | 327 | ||
308 | m_monitors.Add( | 328 | m_staticMonitors.Add( |
309 | new GenericMonitor( | 329 | new GenericMonitor( |
310 | m_scene, | 330 | m_scene, |
311 | "AgentFrameTimeMonitor", | 331 | "AgentFrameTimeMonitor", |
@@ -313,7 +333,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
313 | m => m.Scene.StatsReporter.LastReportedSimStats[16], | 333 | m => m.Scene.StatsReporter.LastReportedSimStats[16], |
314 | m => string.Format("{0} ms", m.GetValue()))); | 334 | m => string.Format("{0} ms", m.GetValue()))); |
315 | 335 | ||
316 | m_monitors.Add( | 336 | m_staticMonitors.Add( |
317 | new GenericMonitor( | 337 | new GenericMonitor( |
318 | m_scene, | 338 | m_scene, |
319 | "ImagesFrameTimeMonitor", | 339 | "ImagesFrameTimeMonitor", |
@@ -321,7 +341,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
321 | m => m.Scene.StatsReporter.LastReportedSimStats[11], | 341 | m => m.Scene.StatsReporter.LastReportedSimStats[11], |
322 | m => string.Format("{0} ms", m.GetValue()))); | 342 | m => string.Format("{0} ms", m.GetValue()))); |
323 | 343 | ||
324 | m_alerts.Add(new DeadlockAlert(m_monitors.Find(x => x is LastFrameTimeMonitor) as LastFrameTimeMonitor)); | 344 | m_alerts.Add(new DeadlockAlert(m_staticMonitors.Find(x => x is LastFrameTimeMonitor) as LastFrameTimeMonitor)); |
325 | 345 | ||
326 | foreach (IAlert alert in m_alerts) | 346 | foreach (IAlert alert in m_alerts) |
327 | { | 347 | { |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 749b281..f7c6413 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -2509,21 +2509,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
2509 | { | 2509 | { |
2510 | } | 2510 | } |
2511 | 2511 | ||
2512 | private bool CollisionFilteredOut(SceneObjectPart dest, UUID objectID, string objectName) | 2512 | public bool CollisionFilteredOut(UUID objectID, string objectName) |
2513 | { | 2513 | { |
2514 | if(dest.CollisionFilter.Count == 0) | 2514 | if(CollisionFilter.Count == 0) |
2515 | return false; | 2515 | return false; |
2516 | 2516 | ||
2517 | if (dest.CollisionFilter.ContainsValue(objectID.ToString()) || | 2517 | if (CollisionFilter.ContainsValue(objectID.ToString()) || |
2518 | dest.CollisionFilter.ContainsValue(objectID.ToString() + objectName) || | 2518 | CollisionFilter.ContainsValue(objectID.ToString() + objectName) || |
2519 | dest.CollisionFilter.ContainsValue(UUID.Zero.ToString() + objectName)) | 2519 | CollisionFilter.ContainsValue(UUID.Zero.ToString() + objectName)) |
2520 | { | 2520 | { |
2521 | if (dest.CollisionFilter.ContainsKey(1)) | 2521 | if (CollisionFilter.ContainsKey(1)) |
2522 | return false; | 2522 | return false; |
2523 | return true; | 2523 | return true; |
2524 | } | 2524 | } |
2525 | 2525 | ||
2526 | if (dest.CollisionFilter.ContainsKey(1)) | 2526 | if (CollisionFilter.ContainsKey(1)) |
2527 | return true; | 2527 | return true; |
2528 | 2528 | ||
2529 | return false; | 2529 | return false; |
@@ -2586,7 +2586,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2586 | SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId); | 2586 | SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId); |
2587 | if (obj != null) | 2587 | if (obj != null) |
2588 | { | 2588 | { |
2589 | if (!dest.CollisionFilteredOut(this, obj.UUID, obj.Name)) | 2589 | if (!dest.CollisionFilteredOut(obj.UUID, obj.Name)) |
2590 | colliding.Add(CreateDetObject(obj)); | 2590 | colliding.Add(CreateDetObject(obj)); |
2591 | } | 2591 | } |
2592 | else | 2592 | else |
@@ -2594,7 +2594,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2594 | ScenePresence av = ParentGroup.Scene.GetScenePresence(localId); | 2594 | ScenePresence av = ParentGroup.Scene.GetScenePresence(localId); |
2595 | if (av != null && (!av.IsChildAgent)) | 2595 | if (av != null && (!av.IsChildAgent)) |
2596 | { | 2596 | { |
2597 | if (!dest.CollisionFilteredOut(this, av.UUID, av.Name)) | 2597 | if (!dest.CollisionFilteredOut(av.UUID, av.Name)) |
2598 | colliding.Add(CreateDetObject(av)); | 2598 | colliding.Add(CreateDetObject(av)); |
2599 | } | 2599 | } |
2600 | } | 2600 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs index a4afd47..cb102d0 100644 --- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs +++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs | |||
@@ -26,7 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | //using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Timers; | 30 | using System.Timers; |
31 | using OpenMetaverse.Packets; | 31 | using OpenMetaverse.Packets; |
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
@@ -35,10 +35,18 @@ using OpenSim.Region.Framework.Interfaces; | |||
35 | 35 | ||
36 | namespace OpenSim.Region.Framework.Scenes | 36 | namespace OpenSim.Region.Framework.Scenes |
37 | { | 37 | { |
38 | /// <summary> | ||
39 | /// Collect statistics from the scene to send to the client and for access by other monitoring tools. | ||
40 | /// </summary> | ||
41 | /// <remarks> | ||
42 | /// FIXME: This should be a monitoring region module | ||
43 | /// </remarks> | ||
38 | public class SimStatsReporter | 44 | public class SimStatsReporter |
39 | { | 45 | { |
40 | // private static readonly log4net.ILog m_log | 46 | private static readonly log4net.ILog m_log |
41 | // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 47 | = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); |
48 | |||
49 | public const string LastReportedObjectUpdateStatName = "LastReportedObjectUpdates"; | ||
42 | 50 | ||
43 | public delegate void SendStatResult(SimStats stats); | 51 | public delegate void SendStatResult(SimStats stats); |
44 | 52 | ||
@@ -113,6 +121,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
113 | get { return lastReportedSimStats; } | 121 | get { return lastReportedSimStats; } |
114 | } | 122 | } |
115 | 123 | ||
124 | /// <summary> | ||
125 | /// Extra sim statistics that are used by monitors but not sent to the client. | ||
126 | /// </summary> | ||
127 | /// <value> | ||
128 | /// The keys are the stat names. | ||
129 | /// </value> | ||
130 | private Dictionary<string, float> m_lastReportedExtraSimStats = new Dictionary<string, float>(); | ||
131 | |||
116 | // Sending a stats update every 3 seconds- | 132 | // Sending a stats update every 3 seconds- |
117 | private int statsUpdatesEveryMS = 3000; | 133 | private int statsUpdatesEveryMS = 3000; |
118 | private float statsUpdateFactor = 0; | 134 | private float statsUpdateFactor = 0; |
@@ -387,7 +403,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
387 | } | 403 | } |
388 | 404 | ||
389 | // Extra statistics that aren't currently sent to clients | 405 | // Extra statistics that aren't currently sent to clients |
390 | LastReportedObjectUpdates = m_objectUpdates / statsUpdateFactor; | 406 | lock (m_lastReportedExtraSimStats) |
407 | { | ||
408 | m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates / statsUpdateFactor; | ||
409 | |||
410 | Dictionary<string, float> physicsStats = m_scene.PhysicsScene.GetStats(); | ||
411 | |||
412 | if (physicsStats != null) | ||
413 | { | ||
414 | foreach (KeyValuePair<string, float> tuple in physicsStats) | ||
415 | { | ||
416 | m_lastReportedExtraSimStats[tuple.Key] = tuple.Value / statsUpdateFactor; | ||
417 | } | ||
418 | } | ||
419 | } | ||
391 | 420 | ||
392 | resetvalues(); | 421 | resetvalues(); |
393 | } | 422 | } |
@@ -546,7 +575,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
546 | public void AddPendingDownloads(int count) | 575 | public void AddPendingDownloads(int count) |
547 | { | 576 | { |
548 | m_pendingDownloads += count; | 577 | m_pendingDownloads += count; |
549 | if (m_pendingDownloads < 0) m_pendingDownloads = 0; | 578 | |
579 | if (m_pendingDownloads < 0) | ||
580 | m_pendingDownloads = 0; | ||
581 | |||
550 | //m_log.InfoFormat("[stats]: Adding {0} to pending downloads to make {1}", count, m_pendingDownloads); | 582 | //m_log.InfoFormat("[stats]: Adding {0} to pending downloads to make {1}", count, m_pendingDownloads); |
551 | } | 583 | } |
552 | 584 | ||
@@ -568,5 +600,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
568 | } | 600 | } |
569 | 601 | ||
570 | #endregion | 602 | #endregion |
603 | |||
604 | public Dictionary<string, float> GetExtraSimStats() | ||
605 | { | ||
606 | lock (m_lastReportedExtraSimStats) | ||
607 | return new Dictionary<string, float>(m_lastReportedExtraSimStats); | ||
608 | } | ||
571 | } | 609 | } |
572 | } | 610 | } |
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index d10a2aa..cfede55 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs | |||
@@ -241,8 +241,22 @@ namespace OpenSim.Region.Physics.Manager | |||
241 | 241 | ||
242 | public abstract void AddPhysicsActorTaint(PhysicsActor prim); | 242 | public abstract void AddPhysicsActorTaint(PhysicsActor prim); |
243 | 243 | ||
244 | /// <summary> | ||
245 | /// Perform a simulation of the current physics scene over the given timestep. | ||
246 | /// </summary> | ||
247 | /// <param name="timeStep"></param> | ||
248 | /// <returns>The number of frames simulated over that period.</returns> | ||
244 | public abstract float Simulate(float timeStep); | 249 | public abstract float Simulate(float timeStep); |
245 | 250 | ||
251 | /// <summary> | ||
252 | /// Get statistics about this scene. | ||
253 | /// </summary> | ||
254 | /// <remarks>This facility is currently experimental and subject to change.</remarks> | ||
255 | /// <returns> | ||
256 | /// A dictionary where the key is the statistic name. If no statistics are supplied then returns null. | ||
257 | /// </returns> | ||
258 | public virtual Dictionary<string, float> GetStats() { return null; } | ||
259 | |||
246 | public abstract void GetResults(); | 260 | public abstract void GetResults(); |
247 | 261 | ||
248 | public abstract void SetTerrain(float[] heightMap); | 262 | public abstract void SetTerrain(float[] heightMap); |
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 409b27b..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 | { |
@@ -2689,7 +2791,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2689 | /// 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) |
2690 | /// </summary> | 2792 | /// </summary> |
2691 | /// <param name="timeStep"></param> | 2793 | /// <param name="timeStep"></param> |
2692 | /// <returns></returns> | 2794 | /// <returns>The number of frames simulated over that period.</returns> |
2693 | public override float Simulate(float timeStep) | 2795 | public override float Simulate(float timeStep) |
2694 | { | 2796 | { |
2695 | if (framecount >= int.MaxValue) | 2797 | if (framecount >= int.MaxValue) |
@@ -3190,7 +3292,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3190 | public override bool IsThreaded | 3292 | public override bool IsThreaded |
3191 | { | 3293 | { |
3192 | // for now we won't be multithreaded | 3294 | // for now we won't be multithreaded |
3193 | get { return (false); } | 3295 | get { return false; } |
3194 | } | 3296 | } |
3195 | 3297 | ||
3196 | #region ODE Specific Terrain Fixes | 3298 | #region ODE Specific Terrain Fixes |
@@ -3955,5 +4057,22 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
3955 | ds.SetViewpoint(ref xyz, ref hpr); | 4057 | ds.SetViewpoint(ref xyz, ref hpr); |
3956 | } | 4058 | } |
3957 | #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 | } | ||
3958 | } | 4077 | } |
3959 | } \ No newline at end of file | 4078 | } \ No newline at end of file |
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 6718cca..a38a3d0 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini | |||
@@ -675,6 +675,25 @@ | |||
675 | 675 | ||
676 | 676 | ||
677 | [ODEPhysicsSettings] | 677 | [ODEPhysicsSettings] |
678 | ; ## | ||
679 | ; ## Physics stats settings | ||
680 | ; | ||
681 | |||
682 | ; If collect_stats is enabled, then extra stat information is collected which is accessible via the MonitorModule | ||
683 | ; (see http://opensimulator.org/wiki/Monitoring_Module for more details). | ||
684 | collect_stats = false | ||
685 | |||
686 | ; ## | ||
687 | ; ## Physics logging settings - logfiles are saved to *.DIF files | ||
688 | ; ## | ||
689 | |||
690 | ; default is false | ||
691 | ;physics_logging = true | ||
692 | ;; every n simulation iterations, the physics snapshot file is updated | ||
693 | ;physics_logging_interval = 50 | ||
694 | ;; append to existing physics logfile, or overwrite existing logfiles? | ||
695 | ;physics_logging_append_existing_logfile = true | ||
696 | |||
678 | ;## | 697 | ;## |
679 | ;## World Settings | 698 | ;## World Settings |
680 | ;## | 699 | ;## |
@@ -824,17 +843,6 @@ | |||
824 | mesh_physical_lod = 16 | 843 | mesh_physical_lod = 16 |
825 | 844 | ||
826 | ; ## | 845 | ; ## |
827 | ; ## Physics logging settings - logfiles are saved to *.DIF files | ||
828 | ; ## | ||
829 | |||
830 | ; default is false | ||
831 | ;physics_logging = true | ||
832 | ;; every n simulation iterations, the physics snapshot file is updated | ||
833 | ;physics_logging_interval = 50 | ||
834 | ;; append to existing physics logfile, or overwrite existing logfiles? | ||
835 | ;physics_logging_append_existing_logfile = true | ||
836 | |||
837 | ; ## | ||
838 | ; ## Joint support | 846 | ; ## Joint support |
839 | ; ## | 847 | ; ## |
840 | 848 | ||