aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Application/OpenSim.cs3
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Commands/UserCommandsModule.cs189
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs108
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs18
-rw-r--r--OpenSim/Region/Framework/Scenes/SimStatsReporter.cs48
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsScene.cs14
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdeScene.cs139
7 files changed, 450 insertions, 69 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 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics;
31using System.IO; 32using System.IO;
32using System.Reflection; 33using System.Reflection;
33using System.Text; 34using 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
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using System.Text.RegularExpressions;
33using log4net;
34using Mono.Addins;
35using NDesk.Options;
36using Nini.Config;
37using OpenMetaverse;
38using OpenSim.Framework;
39using OpenSim.Framework.Console;
40using OpenSim.Framework.Statistics;
41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.Framework.Scenes;
43
44namespace 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
28using System; 28using System;
29//using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Timers; 30using System.Timers;
31using OpenMetaverse.Packets; 31using OpenMetaverse.Packets;
32using OpenSim.Framework; 32using OpenSim.Framework;
@@ -35,10 +35,18 @@ using OpenSim.Region.Framework.Interfaces;
35 35
36namespace OpenSim.Region.Framework.Scenes 36namespace 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