aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs13
-rw-r--r--OpenSim/Framework/Monitoring/StatsManager.cs145
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs3
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs27
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs18
-rw-r--r--OpenSim/Region/Framework/Scenes/SimStatsReporter.cs33
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs13
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdeScene.cs41
9 files changed, 268 insertions, 29 deletions
diff --git a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
index cdd7cc7..8ac9090 100644
--- a/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
+++ b/OpenSim/Framework/Monitoring/SimExtraStatsCollector.cs
@@ -355,10 +355,19 @@ Asset service request failures: {3}" + Environment.NewLine,
355 sb.Append(Environment.NewLine); 355 sb.Append(Environment.NewLine);
356 sb.Append( 356 sb.Append(
357 string.Format( 357 string.Format(
358 "{0,6:0} {1,6:0} {2,6:0} {3,6:0} {4,6:0} {5,6:0.0} {6,6:0.0} {7,6:0.0} {8,6:0.0} {9,6:0.0} {10,6:0.0}", 358 "{0,6:0} {1,6:0} {2,6:0} {3,6:0} {4,6:0} {5,6:0.0} {6,6:0.0} {7,6:0.0} {8,6:0.0} {9,6:0.0} {10,6:0.0}\n\n",
359 inPacketsPerSecond, outPacketsPerSecond, pendingDownloads, pendingUploads, unackedBytes, totalFrameTime, 359 inPacketsPerSecond, outPacketsPerSecond, pendingDownloads, pendingUploads, unackedBytes, totalFrameTime,
360 netFrameTime, physicsFrameTime, otherFrameTime, agentFrameTime, imageFrameTime)); 360 netFrameTime, physicsFrameTime, otherFrameTime, agentFrameTime, imageFrameTime));
361 sb.Append(Environment.NewLine); 361
362 foreach (KeyValuePair<string, Stat> kvp in StatsManager.RegisteredStats)
363 {
364 Stat stat = kvp.Value;
365
366 if (stat.Category == "scene" && stat.Verbosity == StatVerbosity.Info)
367 {
368 sb.AppendFormat("Slow frames ({0}): {1}\n", stat.Container, stat.Value);
369 }
370 }
362 371
363 /* 372 /*
364 sb.Append(Environment.NewLine); 373 sb.Append(Environment.NewLine);
diff --git a/OpenSim/Framework/Monitoring/StatsManager.cs b/OpenSim/Framework/Monitoring/StatsManager.cs
index d78fa6a..b5dc24f 100644
--- a/OpenSim/Framework/Monitoring/StatsManager.cs
+++ b/OpenSim/Framework/Monitoring/StatsManager.cs
@@ -25,6 +25,9 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System;
29using System.Collections.Generic;
30
28namespace OpenSim.Framework.Monitoring 31namespace OpenSim.Framework.Monitoring
29{ 32{
30 /// <summary> 33 /// <summary>
@@ -32,6 +35,14 @@ namespace OpenSim.Framework.Monitoring
32 /// </summary> 35 /// </summary>
33 public class StatsManager 36 public class StatsManager
34 { 37 {
38 /// <summary>
39 /// Registered stats.
40 /// </summary>
41 /// <remarks>
42 /// Do not add or remove from this dictionary.
43 /// </remarks>
44 public static Dictionary<string, Stat> RegisteredStats = new Dictionary<string, Stat>();
45
35 private static AssetStatsCollector assetStats; 46 private static AssetStatsCollector assetStats;
36 private static UserStatsCollector userStats; 47 private static UserStatsCollector userStats;
37 private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector(); 48 private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector();
@@ -61,5 +72,139 @@ namespace OpenSim.Framework.Monitoring
61 72
62 return userStats; 73 return userStats;
63 } 74 }
75
76 public static bool RegisterStat(Stat stat)
77 {
78 lock (RegisteredStats)
79 {
80 if (RegisteredStats.ContainsKey(stat.UniqueName))
81 {
82 // XXX: For now just return false. This is to avoid problems in regression tests where all tests
83 // in a class are run in the same instance of the VM.
84 return false;
85
86// throw new Exception(
87// "StatsManager already contains stat with ShortName {0} in Category {1}", stat.ShortName, stat.Category);
88 }
89
90 // We take a replace-on-write approach here so that we don't need to generate a new Dictionary
91 Dictionary<string, Stat> newRegisteredStats = new Dictionary<string, Stat>(RegisteredStats);
92 newRegisteredStats[stat.UniqueName] = stat;
93 RegisteredStats = newRegisteredStats;
94 }
95
96 return true;
97 }
98
99 public static bool DeregisterStat(Stat stat)
100 {
101 lock (RegisteredStats)
102 {
103 if (!RegisteredStats.ContainsKey(stat.UniqueName))
104 return false;
105
106 Dictionary<string, Stat> newRegisteredStats = new Dictionary<string, Stat>(RegisteredStats);
107 newRegisteredStats.Remove(stat.UniqueName);
108 RegisteredStats = newRegisteredStats;
109
110 return true;
111 }
112 }
113 }
114
115 /// <summary>
116 /// Verbosity of stat.
117 /// </summary>
118 /// <remarks>
119 /// Info will always be displayed.
120 /// </remarks>
121 public enum StatVerbosity
122 {
123 Debug,
124 Info
125 }
126
127 /// <summary>
128 /// Holds individual static details
129 /// </summary>
130 public class Stat
131 {
132 /// <summary>
133 /// Unique stat name used for indexing. Each ShortName in a Category must be unique.
134 /// </summary>
135 public string UniqueName { get; private set; }
136
137 /// <summary>
138 /// Category of this stat (e.g. cache, scene, etc).
139 /// </summary>
140 public string Category { get; private set; }
141
142 /// <summary>
143 /// Containing name for this stat.
144 /// FIXME: In the case of a scene, this is currently the scene name (though this leaves
145 /// us with a to-be-resolved problem of non-unique region names).
146 /// </summary>
147 /// <value>
148 /// The container.
149 /// </value>
150 public string Container { get; private set; }
151
152 public StatVerbosity Verbosity { get; private set; }
153 public string ShortName { get; private set; }
154 public string Name { get; private set; }
155 public string Description { get; private set; }
156 public virtual string UnitName { get; private set; }
157
158 public virtual double Value { get; set; }
159
160 public Stat(
161 string shortName, string name, string unitName, string category, string container, StatVerbosity verbosity, string description)
162 {
163 ShortName = shortName;
164 Name = name;
165 UnitName = unitName;
166 Category = category;
167 Container = container;
168 Verbosity = verbosity;
169 Description = description;
170
171 UniqueName = GenUniqueName(Container, Category, ShortName);
172 }
173
174 public static string GenUniqueName(string container, string category, string shortName)
175 {
176 return string.Format("{0}+{1}+{2}", container, category, shortName);
177 }
178 }
179
180 public class PercentageStat : Stat
181 {
182 public int Antecedent { get; set; }
183 public int Consequent { get; set; }
184
185 public override double Value
186 {
187 get
188 {
189 int c = Consequent;
190
191 // Avoid any chance of a multi-threaded divide-by-zero
192 if (c == 0)
193 return 0;
194
195 return (double)Antecedent / c;
196 }
197
198 set
199 {
200 throw new Exception("Cannot set value on a PercentageStat");
201 }
202 }
203
204 public PercentageStat(
205 string shortName, string name, string category, string container, StatVerbosity verbosity, string description)
206 : base(shortName, name, " %", category, container, verbosity, description)
207 {
208 }
64 } 209 }
65} \ No newline at end of file 210} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index bd7bd82..e3bf997 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -525,7 +525,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
525 { 525 {
526 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) 526 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
527 { 527 {
528 for (int j = 0; j < appearance.Wearables[j].Count; j++) 528 for (int j = 0; j < appearance.Wearables[i].Count; j++)
529 { 529 {
530 if (appearance.Wearables[i][j].ItemID == UUID.Zero) 530 if (appearance.Wearables[i][j].ItemID == UUID.Zero)
531 continue; 531 continue;
@@ -533,6 +533,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
533 // Ignore ruth's assets 533 // Ignore ruth's assets
534 if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID) 534 if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
535 continue; 535 continue;
536
536 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); 537 InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
537 baseItem = invService.GetItem(baseItem); 538 baseItem = invService.GetItem(baseItem);
538 539
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
index e135c21..e411585 100644
--- a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
@@ -95,14 +95,14 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
95 { 95 {
96 foreach (IMonitor monitor in m_staticMonitors) 96 foreach (IMonitor monitor in m_staticMonitors)
97 { 97 {
98 m_log.InfoFormat( 98 MainConsole.Instance.OutputFormat(
99 "[MONITOR MODULE]: {0} reports {1} = {2}", 99 "[MONITOR MODULE]: {0} reports {1} = {2}",
100 m_scene.RegionInfo.RegionName, monitor.GetFriendlyName(), monitor.GetFriendlyValue()); 100 m_scene.RegionInfo.RegionName, monitor.GetFriendlyName(), monitor.GetFriendlyValue());
101 } 101 }
102 102
103 foreach (KeyValuePair<string, float> tuple in m_scene.StatsReporter.GetExtraSimStats()) 103 foreach (KeyValuePair<string, float> tuple in m_scene.StatsReporter.GetExtraSimStats())
104 { 104 {
105 m_log.InfoFormat( 105 MainConsole.Instance.OutputFormat(
106 "[MONITOR MODULE]: {0} reports {1} = {2}", 106 "[MONITOR MODULE]: {0} reports {1} = {2}",
107 m_scene.RegionInfo.RegionName, tuple.Key, tuple.Value); 107 m_scene.RegionInfo.RegionName, tuple.Key, tuple.Value);
108 } 108 }
diff --git a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs
index 33041e9..ad421ee 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs
@@ -87,7 +87,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
87 { 87 {
88 if (m_defaultAnimation.AnimID == animID) 88 if (m_defaultAnimation.AnimID == animID)
89 { 89 {
90 ResetDefaultAnimation(); 90 m_defaultAnimation = new OpenSim.Framework.Animation(UUID.Zero, 1, UUID.Zero);
91 } 91 }
92 else if (HasAnimation(animID)) 92 else if (HasAnimation(animID))
93 { 93 {
@@ -149,19 +149,26 @@ namespace OpenSim.Region.Framework.Scenes.Animation
149 { 149 {
150 lock (m_animations) 150 lock (m_animations)
151 { 151 {
152 animIDs = new UUID[m_animations.Count + 1]; 152 int defaultSize = 0;
153 sequenceNums = new int[m_animations.Count + 1]; 153 if (m_defaultAnimation.AnimID != UUID.Zero)
154 objectIDs = new UUID[m_animations.Count + 1]; 154 defaultSize++;
155 155
156 animIDs[0] = m_defaultAnimation.AnimID; 156 animIDs = new UUID[m_animations.Count + defaultSize];
157 sequenceNums[0] = m_defaultAnimation.SequenceNum; 157 sequenceNums = new int[m_animations.Count + defaultSize];
158 objectIDs[0] = m_defaultAnimation.ObjectID; 158 objectIDs = new UUID[m_animations.Count + defaultSize];
159
160 if (m_defaultAnimation.AnimID != UUID.Zero)
161 {
162 animIDs[0] = m_defaultAnimation.AnimID;
163 sequenceNums[0] = m_defaultAnimation.SequenceNum;
164 objectIDs[0] = m_defaultAnimation.ObjectID;
165 }
159 166
160 for (int i = 0; i < m_animations.Count; ++i) 167 for (int i = 0; i < m_animations.Count; ++i)
161 { 168 {
162 animIDs[i + 1] = m_animations[i].AnimID; 169 animIDs[i + defaultSize] = m_animations[i].AnimID;
163 sequenceNums[i + 1] = m_animations[i].SequenceNum; 170 sequenceNums[i + defaultSize] = m_animations[i].SequenceNum;
164 objectIDs[i + 1] = m_animations[i].ObjectID; 171 objectIDs[i + defaultSize] = m_animations[i].ObjectID;
165 } 172 }
166 } 173 }
167 } 174 }
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index 50a176b..9458079 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -424,13 +424,19 @@ namespace OpenSim.Region.Framework.Scenes.Animation
424 { 424 {
425 lock (m_animations) 425 lock (m_animations)
426 { 426 {
427 CurrentMovementAnimation = DetermineMovementAnimation(); 427 string newMovementAnimation = DetermineMovementAnimation();
428 if (CurrentMovementAnimation != newMovementAnimation)
429 {
430 CurrentMovementAnimation = DetermineMovementAnimation();
428 431
429// m_log.DebugFormat( 432// m_log.DebugFormat(
430// "[SCENE PRESENCE ANIMATOR]: Determined animation {0} for {1} in UpdateMovementAnimations()", 433// "[SCENE PRESENCE ANIMATOR]: Determined animation {0} for {1} in UpdateMovementAnimations()",
431// CurrentMovementAnimation, m_scenePresence.Name); 434// CurrentMovementAnimation, m_scenePresence.Name);
432 435
433 TrySetMovementAnimation(CurrentMovementAnimation); 436 // Only set it if it's actually changed, give a script
437 // a chance to stop a default animation
438 TrySetMovementAnimation(CurrentMovementAnimation);
439 }
434 } 440 }
435 } 441 }
436 442
@@ -552,4 +558,4 @@ namespace OpenSim.Region.Framework.Scenes.Animation
552 SendAnimPack(animIDs, sequenceNums, objectIDs); 558 SendAnimPack(animIDs, sequenceNums, objectIDs);
553 } 559 }
554 } 560 }
555} \ No newline at end of file 561}
diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
index 756b1f4..0d359b9 100644
--- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
+++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
@@ -47,6 +47,7 @@ namespace OpenSim.Region.Framework.Scenes
47 = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 47 = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
48 48
49 public const string LastReportedObjectUpdateStatName = "LastReportedObjectUpdates"; 49 public const string LastReportedObjectUpdateStatName = "LastReportedObjectUpdates";
50 public const string SlowFramesStatName = "SlowFrames";
50 51
51 public delegate void SendStatResult(SimStats stats); 52 public delegate void SendStatResult(SimStats stats);
52 53
@@ -129,6 +130,16 @@ namespace OpenSim.Region.Framework.Scenes
129 } 130 }
130 131
131 /// <summary> 132 /// <summary>
133 /// Number of frames that have taken longer to process than Scene.MIN_FRAME_TIME
134 /// </summary>
135 public Stat SlowFramesStat { get; private set; }
136
137 /// <summary>
138 /// The threshold at which we log a slow frame.
139 /// </summary>
140 public int SlowFramesStatReportThreshold { get; private set; }
141
142 /// <summary>
132 /// Extra sim statistics that are used by monitors but not sent to the client. 143 /// Extra sim statistics that are used by monitors but not sent to the client.
133 /// </summary> 144 /// </summary>
134 /// <value> 145 /// <value>
@@ -226,6 +237,22 @@ namespace OpenSim.Region.Framework.Scenes
226 237
227 if (StatsManager.SimExtraStats != null) 238 if (StatsManager.SimExtraStats != null)
228 OnSendStatsResult += StatsManager.SimExtraStats.ReceiveClassicSimStatsPacket; 239 OnSendStatsResult += StatsManager.SimExtraStats.ReceiveClassicSimStatsPacket;
240
241 /// At the moment, we'll only report if a frame is over 120% of target, since commonly frames are a bit
242 /// longer than ideal (which in itself is a concern).
243 SlowFramesStatReportThreshold = (int)Math.Ceiling(m_scene.MinFrameTime * 1000 * 1.2);
244
245 SlowFramesStat
246 = new Stat(
247 "SlowFrames",
248 "Slow Frames",
249 " frames",
250 "scene",
251 m_scene.Name,
252 StatVerbosity.Info,
253 "Number of frames where frame time has been significantly longer than the desired frame time.");
254
255 StatsManager.RegisterStat(SlowFramesStat);
229 } 256 }
230 257
231 public void Close() 258 public void Close()
@@ -443,6 +470,7 @@ namespace OpenSim.Region.Framework.Scenes
443 lock (m_lastReportedExtraSimStats) 470 lock (m_lastReportedExtraSimStats)
444 { 471 {
445 m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates / m_statsUpdateFactor; 472 m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates / m_statsUpdateFactor;
473 m_lastReportedExtraSimStats[SlowFramesStat.ShortName] = (float)SlowFramesStat.Value;
446 474
447 Dictionary<string, float> physicsStats = m_scene.PhysicsScene.GetStats(); 475 Dictionary<string, float> physicsStats = m_scene.PhysicsScene.GetStats();
448 476
@@ -563,6 +591,11 @@ namespace OpenSim.Region.Framework.Scenes
563 public void addFrameMS(int ms) 591 public void addFrameMS(int ms)
564 { 592 {
565 m_frameMS += ms; 593 m_frameMS += ms;
594
595 // At the moment, we'll only report if a frame is over 120% of target, since commonly frames are a bit
596 // longer than ideal due to the inaccuracy of the Sleep in Scene.Update() (which in itself is a concern).
597 if (ms > SlowFramesStatReportThreshold)
598 SlowFramesStat.Value++;
566 } 599 }
567 600
568 public void addNetMS(int ms) 601 public void addNetMS(int ms)
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 6efa4d1..eb02536 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -63,6 +63,9 @@ namespace OpenSim.Region.Physics.OdePlugin
63 63
64 private bool m_isphysical; 64 private bool m_isphysical;
65 65
66 public int ExpectedCollisionContacts { get { return m_expectedCollisionContacts; } }
67 private int m_expectedCollisionContacts = 0;
68
66 /// <summary> 69 /// <summary>
67 /// Is this prim subject to physics? Even if not, it's still solid for collision purposes. 70 /// Is this prim subject to physics? Even if not, it's still solid for collision purposes.
68 /// </summary> 71 /// </summary>
@@ -150,7 +153,7 @@ namespace OpenSim.Region.Physics.OdePlugin
150 153
151 private PrimitiveBaseShape _pbs; 154 private PrimitiveBaseShape _pbs;
152 private OdeScene _parent_scene; 155 private OdeScene _parent_scene;
153 156
154 /// <summary> 157 /// <summary>
155 /// The physics space which contains prim geometries 158 /// The physics space which contains prim geometries
156 /// </summary> 159 /// </summary>
@@ -840,7 +843,7 @@ namespace OpenSim.Region.Physics.OdePlugin
840 int vertexStride, triStride; 843 int vertexStride, triStride;
841 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap 844 mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap
842 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage 845 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage
843 846 m_expectedCollisionContacts = indexCount;
844 mesh.releaseSourceMeshData(); // free up the original mesh data to save memory 847 mesh.releaseSourceMeshData(); // free up the original mesh data to save memory
845 848
846 // We must lock here since m_MeshToTriMeshMap is static and multiple scene threads may call this method at 849 // We must lock here since m_MeshToTriMeshMap is static and multiple scene threads may call this method at
@@ -1377,6 +1380,7 @@ Console.WriteLine("CreateGeom:");
1377 { 1380 {
1378//Console.WriteLine(" CreateGeom 1"); 1381//Console.WriteLine(" CreateGeom 1");
1379 SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2)); 1382 SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
1383 m_expectedCollisionContacts = 3;
1380 } 1384 }
1381 catch (AccessViolationException) 1385 catch (AccessViolationException)
1382 { 1386 {
@@ -1391,6 +1395,7 @@ Console.WriteLine("CreateGeom:");
1391 { 1395 {
1392//Console.WriteLine(" CreateGeom 2"); 1396//Console.WriteLine(" CreateGeom 2");
1393 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); 1397 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
1398 m_expectedCollisionContacts = 4;
1394 } 1399 }
1395 catch (AccessViolationException) 1400 catch (AccessViolationException)
1396 { 1401 {
@@ -1406,6 +1411,7 @@ Console.WriteLine("CreateGeom:");
1406 { 1411 {
1407//Console.WriteLine(" CreateGeom 3"); 1412//Console.WriteLine(" CreateGeom 3");
1408 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); 1413 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
1414 m_expectedCollisionContacts = 4;
1409 } 1415 }
1410 catch (AccessViolationException) 1416 catch (AccessViolationException)
1411 { 1417 {
@@ -1421,6 +1427,7 @@ Console.WriteLine("CreateGeom:");
1421 { 1427 {
1422//Console.WriteLine(" CreateGeom 4"); 1428//Console.WriteLine(" CreateGeom 4");
1423 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); 1429 SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
1430 m_expectedCollisionContacts = 4;
1424 } 1431 }
1425 catch (AccessViolationException) 1432 catch (AccessViolationException)
1426 { 1433 {
@@ -1446,11 +1453,13 @@ Console.WriteLine("CreateGeom:");
1446 _parent_scene.geom_name_map.Remove(prim_geom); 1453 _parent_scene.geom_name_map.Remove(prim_geom);
1447 _parent_scene.actor_name_map.Remove(prim_geom); 1454 _parent_scene.actor_name_map.Remove(prim_geom);
1448 d.GeomDestroy(prim_geom); 1455 d.GeomDestroy(prim_geom);
1456 m_expectedCollisionContacts = 0;
1449 prim_geom = IntPtr.Zero; 1457 prim_geom = IntPtr.Zero;
1450 } 1458 }
1451 catch (System.AccessViolationException) 1459 catch (System.AccessViolationException)
1452 { 1460 {
1453 prim_geom = IntPtr.Zero; 1461 prim_geom = IntPtr.Zero;
1462 m_expectedCollisionContacts = 0;
1454 m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name); 1463 m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name);
1455 1464
1456 return false; 1465 return false;
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
index 929b019..7a50c4c 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
@@ -336,6 +336,7 @@ namespace OpenSim.Region.Physics.OdePlugin
336 336
337 public int geomContactPointsStartthrottle = 3; 337 public int geomContactPointsStartthrottle = 3;
338 public int geomUpdatesPerThrottledUpdate = 15; 338 public int geomUpdatesPerThrottledUpdate = 15;
339 private const int avatarExpectedContacts = 3;
339 340
340 public float bodyPIDD = 35f; 341 public float bodyPIDD = 35f;
341 public float bodyPIDG = 25; 342 public float bodyPIDG = 25;
@@ -474,6 +475,8 @@ namespace OpenSim.Region.Physics.OdePlugin
474 private OdePrim cp1; 475 private OdePrim cp1;
475 private OdeCharacter cc2; 476 private OdeCharacter cc2;
476 private OdePrim cp2; 477 private OdePrim cp2;
478 private int p1ExpectedPoints = 0;
479 private int p2ExpectedPoints = 0;
477 //private int cStartStop = 0; 480 //private int cStartStop = 0;
478 //private string cDictKey = ""; 481 //private string cDictKey = "";
479 482
@@ -498,6 +501,7 @@ namespace OpenSim.Region.Physics.OdePlugin
498 public int physics_logging_interval = 0; 501 public int physics_logging_interval = 0;
499 public bool physics_logging_append_existing_logfile = false; 502 public bool physics_logging_append_existing_logfile = false;
500 503
504
501 public d.Vector3 xyz = new d.Vector3(128.1640f, 128.3079f, 25.7600f); 505 public d.Vector3 xyz = new d.Vector3(128.1640f, 128.3079f, 25.7600f);
502 public d.Vector3 hpr = new d.Vector3(125.5000f, -17.0000f, 0.0000f); 506 public d.Vector3 hpr = new d.Vector3(125.5000f, -17.0000f, 0.0000f);
503 507
@@ -644,7 +648,7 @@ namespace OpenSim.Region.Physics.OdePlugin
644 648
645 contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80); 649 contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80);
646 650
647 geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 3); 651 geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 5);
648 geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15); 652 geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15);
649 geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5); 653 geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5);
650 654
@@ -1064,7 +1068,10 @@ namespace OpenSim.Region.Physics.OdePlugin
1064 1068
1065 PhysicsActor p1; 1069 PhysicsActor p1;
1066 PhysicsActor p2; 1070 PhysicsActor p2;
1067 1071
1072 p1ExpectedPoints = 0;
1073 p2ExpectedPoints = 0;
1074
1068 if (!actor_name_map.TryGetValue(g1, out p1)) 1075 if (!actor_name_map.TryGetValue(g1, out p1))
1069 { 1076 {
1070 p1 = PANull; 1077 p1 = PANull;
@@ -1121,9 +1128,13 @@ namespace OpenSim.Region.Physics.OdePlugin
1121 switch (p1.PhysicsActorType) 1128 switch (p1.PhysicsActorType)
1122 { 1129 {
1123 case (int)ActorTypes.Agent: 1130 case (int)ActorTypes.Agent:
1131 p1ExpectedPoints = avatarExpectedContacts;
1124 p2.CollidingObj = true; 1132 p2.CollidingObj = true;
1125 break; 1133 break;
1126 case (int)ActorTypes.Prim: 1134 case (int)ActorTypes.Prim:
1135 if (p1 != null && p1 is OdePrim)
1136 p1ExpectedPoints = ((OdePrim) p1).ExpectedCollisionContacts;
1137
1127 if (p2.Velocity.LengthSquared() > 0.0f) 1138 if (p2.Velocity.LengthSquared() > 0.0f)
1128 p2.CollidingObj = true; 1139 p2.CollidingObj = true;
1129 break; 1140 break;
@@ -1319,6 +1330,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1319 if ((p2.PhysicsActorType == (int) ActorTypes.Agent) && 1330 if ((p2.PhysicsActorType == (int) ActorTypes.Agent) &&
1320 (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) 1331 (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
1321 { 1332 {
1333 p2ExpectedPoints = avatarExpectedContacts;
1322 // Avatar is moving on terrain, use the movement terrain contact 1334 // Avatar is moving on terrain, use the movement terrain contact
1323 AvatarMovementTerrainContact.geom = curContact; 1335 AvatarMovementTerrainContact.geom = curContact;
1324 1336
@@ -1332,6 +1344,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1332 { 1344 {
1333 if (p2.PhysicsActorType == (int)ActorTypes.Agent) 1345 if (p2.PhysicsActorType == (int)ActorTypes.Agent)
1334 { 1346 {
1347 p2ExpectedPoints = avatarExpectedContacts;
1335 // Avatar is standing on terrain, use the non moving terrain contact 1348 // Avatar is standing on terrain, use the non moving terrain contact
1336 TerrainContact.geom = curContact; 1349 TerrainContact.geom = curContact;
1337 1350
@@ -1356,9 +1369,18 @@ namespace OpenSim.Region.Physics.OdePlugin
1356 } 1369 }
1357 1370
1358 if (p2 is OdePrim) 1371 if (p2 is OdePrim)
1359 material = ((OdePrim)p2).m_material; 1372 {
1360 1373 material = ((OdePrim) p2).m_material;
1374 p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts;
1375 }
1376
1377 // Unnessesary because p1 is defined above
1378 //if (p1 is OdePrim)
1379 // {
1380 // p1ExpectedPoints = ((OdePrim)p1).ExpectedCollisionContacts;
1381 // }
1361 //m_log.DebugFormat("Material: {0}", material); 1382 //m_log.DebugFormat("Material: {0}", material);
1383
1362 m_materialContacts[material, movintYN].geom = curContact; 1384 m_materialContacts[material, movintYN].geom = curContact;
1363 1385
1364 if (m_global_contactcount < maxContactsbeforedeath) 1386 if (m_global_contactcount < maxContactsbeforedeath)
@@ -1379,7 +1401,10 @@ namespace OpenSim.Region.Physics.OdePlugin
1379 int material = (int)Material.Wood; 1401 int material = (int)Material.Wood;
1380 1402
1381 if (p2 is OdePrim) 1403 if (p2 is OdePrim)
1404 {
1382 material = ((OdePrim)p2).m_material; 1405 material = ((OdePrim)p2).m_material;
1406 p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts;
1407 }
1383 1408
1384 //m_log.DebugFormat("Material: {0}", material); 1409 //m_log.DebugFormat("Material: {0}", material);
1385 m_materialContacts[material, movintYN].geom = curContact; 1410 m_materialContacts[material, movintYN].geom = curContact;
@@ -1429,6 +1454,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1429 { 1454 {
1430 if ((p2.PhysicsActorType == (int)ActorTypes.Agent)) 1455 if ((p2.PhysicsActorType == (int)ActorTypes.Agent))
1431 { 1456 {
1457 p2ExpectedPoints = avatarExpectedContacts;
1432 if ((Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) 1458 if ((Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
1433 { 1459 {
1434 // Avatar is moving on a prim, use the Movement prim contact 1460 // Avatar is moving on a prim, use the Movement prim contact
@@ -1458,7 +1484,10 @@ namespace OpenSim.Region.Physics.OdePlugin
1458 int material = (int)Material.Wood; 1484 int material = (int)Material.Wood;
1459 1485
1460 if (p2 is OdePrim) 1486 if (p2 is OdePrim)
1487 {
1461 material = ((OdePrim)p2).m_material; 1488 material = ((OdePrim)p2).m_material;
1489 p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts;
1490 }
1462 1491
1463 //m_log.DebugFormat("Material: {0}", material); 1492 //m_log.DebugFormat("Material: {0}", material);
1464 m_materialContacts[material, 0].geom = curContact; 1493 m_materialContacts[material, 0].geom = curContact;
@@ -1479,8 +1508,8 @@ namespace OpenSim.Region.Physics.OdePlugin
1479 } 1508 }
1480 1509
1481 collision_accounting_events(p1, p2, maxDepthContact); 1510 collision_accounting_events(p1, p2, maxDepthContact);
1482 1511
1483 if (count > geomContactPointsStartthrottle) 1512 if (count > ((p1ExpectedPoints + p2ExpectedPoints) * 0.25) + (geomContactPointsStartthrottle))
1484 { 1513 {
1485 // If there are more then 3 contact points, it's likely 1514 // If there are more then 3 contact points, it's likely
1486 // that we've got a pile of objects, so ... 1515 // that we've got a pile of objects, so ...