Merge branch 'master' into careminster

Conflicts:
	OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
avinationmerge
Melanie 2012-10-04 20:16:23 +01:00
commit 637e9a10db
9 changed files with 268 additions and 29 deletions

View File

@ -355,10 +355,19 @@ Asset service request failures: {3}" + Environment.NewLine,
sb.Append(Environment.NewLine); sb.Append(Environment.NewLine);
sb.Append( sb.Append(
string.Format( string.Format(
"{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}", "{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",
inPacketsPerSecond, outPacketsPerSecond, pendingDownloads, pendingUploads, unackedBytes, totalFrameTime, inPacketsPerSecond, outPacketsPerSecond, pendingDownloads, pendingUploads, unackedBytes, totalFrameTime,
netFrameTime, physicsFrameTime, otherFrameTime, agentFrameTime, imageFrameTime)); netFrameTime, physicsFrameTime, otherFrameTime, agentFrameTime, imageFrameTime));
sb.Append(Environment.NewLine);
foreach (KeyValuePair<string, Stat> kvp in StatsManager.RegisteredStats)
{
Stat stat = kvp.Value;
if (stat.Category == "scene" && stat.Verbosity == StatVerbosity.Info)
{
sb.AppendFormat("Slow frames ({0}): {1}\n", stat.Container, stat.Value);
}
}
/* /*
sb.Append(Environment.NewLine); sb.Append(Environment.NewLine);

View File

@ -25,6 +25,9 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System;
using System.Collections.Generic;
namespace OpenSim.Framework.Monitoring namespace OpenSim.Framework.Monitoring
{ {
/// <summary> /// <summary>
@ -32,6 +35,14 @@ namespace OpenSim.Framework.Monitoring
/// </summary> /// </summary>
public class StatsManager public class StatsManager
{ {
/// <summary>
/// Registered stats.
/// </summary>
/// <remarks>
/// Do not add or remove from this dictionary.
/// </remarks>
public static Dictionary<string, Stat> RegisteredStats = new Dictionary<string, Stat>();
private static AssetStatsCollector assetStats; private static AssetStatsCollector assetStats;
private static UserStatsCollector userStats; private static UserStatsCollector userStats;
private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector(); private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector();
@ -61,5 +72,139 @@ namespace OpenSim.Framework.Monitoring
return userStats; return userStats;
} }
public static bool RegisterStat(Stat stat)
{
lock (RegisteredStats)
{
if (RegisteredStats.ContainsKey(stat.UniqueName))
{
// XXX: For now just return false. This is to avoid problems in regression tests where all tests
// in a class are run in the same instance of the VM.
return false;
// throw new Exception(
// "StatsManager already contains stat with ShortName {0} in Category {1}", stat.ShortName, stat.Category);
}
// We take a replace-on-write approach here so that we don't need to generate a new Dictionary
Dictionary<string, Stat> newRegisteredStats = new Dictionary<string, Stat>(RegisteredStats);
newRegisteredStats[stat.UniqueName] = stat;
RegisteredStats = newRegisteredStats;
}
return true;
}
public static bool DeregisterStat(Stat stat)
{
lock (RegisteredStats)
{
if (!RegisteredStats.ContainsKey(stat.UniqueName))
return false;
Dictionary<string, Stat> newRegisteredStats = new Dictionary<string, Stat>(RegisteredStats);
newRegisteredStats.Remove(stat.UniqueName);
RegisteredStats = newRegisteredStats;
return true;
}
}
}
/// <summary>
/// Verbosity of stat.
/// </summary>
/// <remarks>
/// Info will always be displayed.
/// </remarks>
public enum StatVerbosity
{
Debug,
Info
}
/// <summary>
/// Holds individual static details
/// </summary>
public class Stat
{
/// <summary>
/// Unique stat name used for indexing. Each ShortName in a Category must be unique.
/// </summary>
public string UniqueName { get; private set; }
/// <summary>
/// Category of this stat (e.g. cache, scene, etc).
/// </summary>
public string Category { get; private set; }
/// <summary>
/// Containing name for this stat.
/// FIXME: In the case of a scene, this is currently the scene name (though this leaves
/// us with a to-be-resolved problem of non-unique region names).
/// </summary>
/// <value>
/// The container.
/// </value>
public string Container { get; private set; }
public StatVerbosity Verbosity { get; private set; }
public string ShortName { get; private set; }
public string Name { get; private set; }
public string Description { get; private set; }
public virtual string UnitName { get; private set; }
public virtual double Value { get; set; }
public Stat(
string shortName, string name, string unitName, string category, string container, StatVerbosity verbosity, string description)
{
ShortName = shortName;
Name = name;
UnitName = unitName;
Category = category;
Container = container;
Verbosity = verbosity;
Description = description;
UniqueName = GenUniqueName(Container, Category, ShortName);
}
public static string GenUniqueName(string container, string category, string shortName)
{
return string.Format("{0}+{1}+{2}", container, category, shortName);
}
}
public class PercentageStat : Stat
{
public int Antecedent { get; set; }
public int Consequent { get; set; }
public override double Value
{
get
{
int c = Consequent;
// Avoid any chance of a multi-threaded divide-by-zero
if (c == 0)
return 0;
return (double)Antecedent / c;
}
set
{
throw new Exception("Cannot set value on a PercentageStat");
}
}
public PercentageStat(
string shortName, string name, string category, string container, StatVerbosity verbosity, string description)
: base(shortName, name, " %", category, container, verbosity, description)
{
}
} }
} }

View File

@ -525,7 +525,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
{ {
for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
{ {
for (int j = 0; j < appearance.Wearables[j].Count; j++) for (int j = 0; j < appearance.Wearables[i].Count; j++)
{ {
if (appearance.Wearables[i][j].ItemID == UUID.Zero) if (appearance.Wearables[i][j].ItemID == UUID.Zero)
continue; continue;
@ -533,6 +533,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
// Ignore ruth's assets // Ignore ruth's assets
if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID) if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
continue; continue;
InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID); InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
baseItem = invService.GetItem(baseItem); baseItem = invService.GetItem(baseItem);

View File

@ -95,14 +95,14 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
{ {
foreach (IMonitor monitor in m_staticMonitors) foreach (IMonitor monitor in m_staticMonitors)
{ {
m_log.InfoFormat( MainConsole.Instance.OutputFormat(
"[MONITOR MODULE]: {0} reports {1} = {2}", "[MONITOR MODULE]: {0} reports {1} = {2}",
m_scene.RegionInfo.RegionName, monitor.GetFriendlyName(), monitor.GetFriendlyValue()); m_scene.RegionInfo.RegionName, monitor.GetFriendlyName(), monitor.GetFriendlyValue());
} }
foreach (KeyValuePair<string, float> tuple in m_scene.StatsReporter.GetExtraSimStats()) foreach (KeyValuePair<string, float> tuple in m_scene.StatsReporter.GetExtraSimStats())
{ {
m_log.InfoFormat( MainConsole.Instance.OutputFormat(
"[MONITOR MODULE]: {0} reports {1} = {2}", "[MONITOR MODULE]: {0} reports {1} = {2}",
m_scene.RegionInfo.RegionName, tuple.Key, tuple.Value); m_scene.RegionInfo.RegionName, tuple.Key, tuple.Value);
} }

View File

@ -87,7 +87,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
{ {
if (m_defaultAnimation.AnimID == animID) if (m_defaultAnimation.AnimID == animID)
{ {
ResetDefaultAnimation(); m_defaultAnimation = new OpenSim.Framework.Animation(UUID.Zero, 1, UUID.Zero);
} }
else if (HasAnimation(animID)) else if (HasAnimation(animID))
{ {
@ -149,19 +149,26 @@ namespace OpenSim.Region.Framework.Scenes.Animation
{ {
lock (m_animations) lock (m_animations)
{ {
animIDs = new UUID[m_animations.Count + 1]; int defaultSize = 0;
sequenceNums = new int[m_animations.Count + 1]; if (m_defaultAnimation.AnimID != UUID.Zero)
objectIDs = new UUID[m_animations.Count + 1]; defaultSize++;
animIDs = new UUID[m_animations.Count + defaultSize];
sequenceNums = new int[m_animations.Count + defaultSize];
objectIDs = new UUID[m_animations.Count + defaultSize];
if (m_defaultAnimation.AnimID != UUID.Zero)
{
animIDs[0] = m_defaultAnimation.AnimID; animIDs[0] = m_defaultAnimation.AnimID;
sequenceNums[0] = m_defaultAnimation.SequenceNum; sequenceNums[0] = m_defaultAnimation.SequenceNum;
objectIDs[0] = m_defaultAnimation.ObjectID; objectIDs[0] = m_defaultAnimation.ObjectID;
}
for (int i = 0; i < m_animations.Count; ++i) for (int i = 0; i < m_animations.Count; ++i)
{ {
animIDs[i + 1] = m_animations[i].AnimID; animIDs[i + defaultSize] = m_animations[i].AnimID;
sequenceNums[i + 1] = m_animations[i].SequenceNum; sequenceNums[i + defaultSize] = m_animations[i].SequenceNum;
objectIDs[i + 1] = m_animations[i].ObjectID; objectIDs[i + defaultSize] = m_animations[i].ObjectID;
} }
} }
} }

View File

@ -423,6 +423,9 @@ namespace OpenSim.Region.Framework.Scenes.Animation
public void UpdateMovementAnimations() public void UpdateMovementAnimations()
{ {
lock (m_animations) lock (m_animations)
{
string newMovementAnimation = DetermineMovementAnimation();
if (CurrentMovementAnimation != newMovementAnimation)
{ {
CurrentMovementAnimation = DetermineMovementAnimation(); CurrentMovementAnimation = DetermineMovementAnimation();
@ -430,9 +433,12 @@ namespace OpenSim.Region.Framework.Scenes.Animation
// "[SCENE PRESENCE ANIMATOR]: Determined animation {0} for {1} in UpdateMovementAnimations()", // "[SCENE PRESENCE ANIMATOR]: Determined animation {0} for {1} in UpdateMovementAnimations()",
// CurrentMovementAnimation, m_scenePresence.Name); // CurrentMovementAnimation, m_scenePresence.Name);
// Only set it if it's actually changed, give a script
// a chance to stop a default animation
TrySetMovementAnimation(CurrentMovementAnimation); TrySetMovementAnimation(CurrentMovementAnimation);
} }
} }
}
public UUID[] GetAnimationArray() public UUID[] GetAnimationArray()
{ {

View File

@ -47,6 +47,7 @@ namespace OpenSim.Region.Framework.Scenes
= log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public const string LastReportedObjectUpdateStatName = "LastReportedObjectUpdates"; public const string LastReportedObjectUpdateStatName = "LastReportedObjectUpdates";
public const string SlowFramesStatName = "SlowFrames";
public delegate void SendStatResult(SimStats stats); public delegate void SendStatResult(SimStats stats);
@ -128,6 +129,16 @@ namespace OpenSim.Region.Framework.Scenes
get { return lastReportedSimStats; } get { return lastReportedSimStats; }
} }
/// <summary>
/// Number of frames that have taken longer to process than Scene.MIN_FRAME_TIME
/// </summary>
public Stat SlowFramesStat { get; private set; }
/// <summary>
/// The threshold at which we log a slow frame.
/// </summary>
public int SlowFramesStatReportThreshold { get; private set; }
/// <summary> /// <summary>
/// Extra sim statistics that are used by monitors but not sent to the client. /// Extra sim statistics that are used by monitors but not sent to the client.
/// </summary> /// </summary>
@ -226,6 +237,22 @@ namespace OpenSim.Region.Framework.Scenes
if (StatsManager.SimExtraStats != null) if (StatsManager.SimExtraStats != null)
OnSendStatsResult += StatsManager.SimExtraStats.ReceiveClassicSimStatsPacket; OnSendStatsResult += StatsManager.SimExtraStats.ReceiveClassicSimStatsPacket;
/// At the moment, we'll only report if a frame is over 120% of target, since commonly frames are a bit
/// longer than ideal (which in itself is a concern).
SlowFramesStatReportThreshold = (int)Math.Ceiling(m_scene.MinFrameTime * 1000 * 1.2);
SlowFramesStat
= new Stat(
"SlowFrames",
"Slow Frames",
" frames",
"scene",
m_scene.Name,
StatVerbosity.Info,
"Number of frames where frame time has been significantly longer than the desired frame time.");
StatsManager.RegisterStat(SlowFramesStat);
} }
public void Close() public void Close()
@ -443,6 +470,7 @@ namespace OpenSim.Region.Framework.Scenes
lock (m_lastReportedExtraSimStats) lock (m_lastReportedExtraSimStats)
{ {
m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates / m_statsUpdateFactor; m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates / m_statsUpdateFactor;
m_lastReportedExtraSimStats[SlowFramesStat.ShortName] = (float)SlowFramesStat.Value;
Dictionary<string, float> physicsStats = m_scene.PhysicsScene.GetStats(); Dictionary<string, float> physicsStats = m_scene.PhysicsScene.GetStats();
@ -563,6 +591,11 @@ namespace OpenSim.Region.Framework.Scenes
public void addFrameMS(int ms) public void addFrameMS(int ms)
{ {
m_frameMS += ms; m_frameMS += ms;
// At the moment, we'll only report if a frame is over 120% of target, since commonly frames are a bit
// longer than ideal due to the inaccuracy of the Sleep in Scene.Update() (which in itself is a concern).
if (ms > SlowFramesStatReportThreshold)
SlowFramesStat.Value++;
} }
public void addNetMS(int ms) public void addNetMS(int ms)

View File

@ -63,6 +63,9 @@ namespace OpenSim.Region.Physics.OdePlugin
private bool m_isphysical; private bool m_isphysical;
public int ExpectedCollisionContacts { get { return m_expectedCollisionContacts; } }
private int m_expectedCollisionContacts = 0;
/// <summary> /// <summary>
/// Is this prim subject to physics? Even if not, it's still solid for collision purposes. /// Is this prim subject to physics? Even if not, it's still solid for collision purposes.
/// </summary> /// </summary>
@ -840,7 +843,7 @@ namespace OpenSim.Region.Physics.OdePlugin
int vertexStride, triStride; int vertexStride, triStride;
mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap
mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage
m_expectedCollisionContacts = indexCount;
mesh.releaseSourceMeshData(); // free up the original mesh data to save memory mesh.releaseSourceMeshData(); // free up the original mesh data to save memory
// We must lock here since m_MeshToTriMeshMap is static and multiple scene threads may call this method at // 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:");
{ {
//Console.WriteLine(" CreateGeom 1"); //Console.WriteLine(" CreateGeom 1");
SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2)); SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
m_expectedCollisionContacts = 3;
} }
catch (AccessViolationException) catch (AccessViolationException)
{ {
@ -1391,6 +1395,7 @@ Console.WriteLine("CreateGeom:");
{ {
//Console.WriteLine(" CreateGeom 2"); //Console.WriteLine(" CreateGeom 2");
SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
m_expectedCollisionContacts = 4;
} }
catch (AccessViolationException) catch (AccessViolationException)
{ {
@ -1406,6 +1411,7 @@ Console.WriteLine("CreateGeom:");
{ {
//Console.WriteLine(" CreateGeom 3"); //Console.WriteLine(" CreateGeom 3");
SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
m_expectedCollisionContacts = 4;
} }
catch (AccessViolationException) catch (AccessViolationException)
{ {
@ -1421,6 +1427,7 @@ Console.WriteLine("CreateGeom:");
{ {
//Console.WriteLine(" CreateGeom 4"); //Console.WriteLine(" CreateGeom 4");
SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
m_expectedCollisionContacts = 4;
} }
catch (AccessViolationException) catch (AccessViolationException)
{ {
@ -1446,11 +1453,13 @@ Console.WriteLine("CreateGeom:");
_parent_scene.geom_name_map.Remove(prim_geom); _parent_scene.geom_name_map.Remove(prim_geom);
_parent_scene.actor_name_map.Remove(prim_geom); _parent_scene.actor_name_map.Remove(prim_geom);
d.GeomDestroy(prim_geom); d.GeomDestroy(prim_geom);
m_expectedCollisionContacts = 0;
prim_geom = IntPtr.Zero; prim_geom = IntPtr.Zero;
} }
catch (System.AccessViolationException) catch (System.AccessViolationException)
{ {
prim_geom = IntPtr.Zero; prim_geom = IntPtr.Zero;
m_expectedCollisionContacts = 0;
m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name); m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name);
return false; return false;

View File

@ -336,6 +336,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public int geomContactPointsStartthrottle = 3; public int geomContactPointsStartthrottle = 3;
public int geomUpdatesPerThrottledUpdate = 15; public int geomUpdatesPerThrottledUpdate = 15;
private const int avatarExpectedContacts = 3;
public float bodyPIDD = 35f; public float bodyPIDD = 35f;
public float bodyPIDG = 25; public float bodyPIDG = 25;
@ -474,6 +475,8 @@ namespace OpenSim.Region.Physics.OdePlugin
private OdePrim cp1; private OdePrim cp1;
private OdeCharacter cc2; private OdeCharacter cc2;
private OdePrim cp2; private OdePrim cp2;
private int p1ExpectedPoints = 0;
private int p2ExpectedPoints = 0;
//private int cStartStop = 0; //private int cStartStop = 0;
//private string cDictKey = ""; //private string cDictKey = "";
@ -498,6 +501,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public int physics_logging_interval = 0; public int physics_logging_interval = 0;
public bool physics_logging_append_existing_logfile = false; public bool physics_logging_append_existing_logfile = false;
public d.Vector3 xyz = new d.Vector3(128.1640f, 128.3079f, 25.7600f); public d.Vector3 xyz = new d.Vector3(128.1640f, 128.3079f, 25.7600f);
public d.Vector3 hpr = new d.Vector3(125.5000f, -17.0000f, 0.0000f); public d.Vector3 hpr = new d.Vector3(125.5000f, -17.0000f, 0.0000f);
@ -644,7 +648,7 @@ namespace OpenSim.Region.Physics.OdePlugin
contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80); contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80);
geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 3); geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 5);
geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15); geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15);
geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5); geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5);
@ -1065,6 +1069,9 @@ namespace OpenSim.Region.Physics.OdePlugin
PhysicsActor p1; PhysicsActor p1;
PhysicsActor p2; PhysicsActor p2;
p1ExpectedPoints = 0;
p2ExpectedPoints = 0;
if (!actor_name_map.TryGetValue(g1, out p1)) if (!actor_name_map.TryGetValue(g1, out p1))
{ {
p1 = PANull; p1 = PANull;
@ -1121,9 +1128,13 @@ namespace OpenSim.Region.Physics.OdePlugin
switch (p1.PhysicsActorType) switch (p1.PhysicsActorType)
{ {
case (int)ActorTypes.Agent: case (int)ActorTypes.Agent:
p1ExpectedPoints = avatarExpectedContacts;
p2.CollidingObj = true; p2.CollidingObj = true;
break; break;
case (int)ActorTypes.Prim: case (int)ActorTypes.Prim:
if (p1 != null && p1 is OdePrim)
p1ExpectedPoints = ((OdePrim) p1).ExpectedCollisionContacts;
if (p2.Velocity.LengthSquared() > 0.0f) if (p2.Velocity.LengthSquared() > 0.0f)
p2.CollidingObj = true; p2.CollidingObj = true;
break; break;
@ -1319,6 +1330,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if ((p2.PhysicsActorType == (int) ActorTypes.Agent) && if ((p2.PhysicsActorType == (int) ActorTypes.Agent) &&
(Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
{ {
p2ExpectedPoints = avatarExpectedContacts;
// Avatar is moving on terrain, use the movement terrain contact // Avatar is moving on terrain, use the movement terrain contact
AvatarMovementTerrainContact.geom = curContact; AvatarMovementTerrainContact.geom = curContact;
@ -1332,6 +1344,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
if (p2.PhysicsActorType == (int)ActorTypes.Agent) if (p2.PhysicsActorType == (int)ActorTypes.Agent)
{ {
p2ExpectedPoints = avatarExpectedContacts;
// Avatar is standing on terrain, use the non moving terrain contact // Avatar is standing on terrain, use the non moving terrain contact
TerrainContact.geom = curContact; TerrainContact.geom = curContact;
@ -1356,9 +1369,18 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
if (p2 is OdePrim) if (p2 is OdePrim)
{
material = ((OdePrim) p2).m_material; material = ((OdePrim) p2).m_material;
p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts;
}
// Unnessesary because p1 is defined above
//if (p1 is OdePrim)
// {
// p1ExpectedPoints = ((OdePrim)p1).ExpectedCollisionContacts;
// }
//m_log.DebugFormat("Material: {0}", material); //m_log.DebugFormat("Material: {0}", material);
m_materialContacts[material, movintYN].geom = curContact; m_materialContacts[material, movintYN].geom = curContact;
if (m_global_contactcount < maxContactsbeforedeath) if (m_global_contactcount < maxContactsbeforedeath)
@ -1379,7 +1401,10 @@ namespace OpenSim.Region.Physics.OdePlugin
int material = (int)Material.Wood; int material = (int)Material.Wood;
if (p2 is OdePrim) if (p2 is OdePrim)
{
material = ((OdePrim)p2).m_material; material = ((OdePrim)p2).m_material;
p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts;
}
//m_log.DebugFormat("Material: {0}", material); //m_log.DebugFormat("Material: {0}", material);
m_materialContacts[material, movintYN].geom = curContact; m_materialContacts[material, movintYN].geom = curContact;
@ -1429,6 +1454,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
if ((p2.PhysicsActorType == (int)ActorTypes.Agent)) if ((p2.PhysicsActorType == (int)ActorTypes.Agent))
{ {
p2ExpectedPoints = avatarExpectedContacts;
if ((Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) if ((Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
{ {
// Avatar is moving on a prim, use the Movement prim contact // Avatar is moving on a prim, use the Movement prim contact
@ -1458,7 +1484,10 @@ namespace OpenSim.Region.Physics.OdePlugin
int material = (int)Material.Wood; int material = (int)Material.Wood;
if (p2 is OdePrim) if (p2 is OdePrim)
{
material = ((OdePrim)p2).m_material; material = ((OdePrim)p2).m_material;
p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts;
}
//m_log.DebugFormat("Material: {0}", material); //m_log.DebugFormat("Material: {0}", material);
m_materialContacts[material, 0].geom = curContact; m_materialContacts[material, 0].geom = curContact;
@ -1480,7 +1509,7 @@ namespace OpenSim.Region.Physics.OdePlugin
collision_accounting_events(p1, p2, maxDepthContact); collision_accounting_events(p1, p2, maxDepthContact);
if (count > geomContactPointsStartthrottle) if (count > ((p1ExpectedPoints + p2ExpectedPoints) * 0.25) + (geomContactPointsStartthrottle))
{ {
// If there are more then 3 contact points, it's likely // If there are more then 3 contact points, it's likely
// that we've got a pile of objects, so ... // that we've got a pile of objects, so ...