Merge branch 'master' into careminster
Conflicts: OpenSim/Region/Framework/Scenes/SimStatsReporter.csavinationmerge
commit
637e9a10db
|
@ -355,10 +355,19 @@ Asset service request failures: {3}" + Environment.NewLine,
|
|||
sb.Append(Environment.NewLine);
|
||||
sb.Append(
|
||||
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,
|
||||
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);
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OpenSim.Framework.Monitoring
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -32,6 +35,14 @@ namespace OpenSim.Framework.Monitoring
|
|||
/// </summary>
|
||||
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 UserStatsCollector userStats;
|
||||
private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector();
|
||||
|
@ -61,5 +72,139 @@ namespace OpenSim.Framework.Monitoring
|
|||
|
||||
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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -525,7 +525,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
{
|
||||
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)
|
||||
continue;
|
||||
|
@ -533,6 +533,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
|||
// Ignore ruth's assets
|
||||
if (appearance.Wearables[i][j].ItemID == AvatarWearable.DefaultWearables[i][0].ItemID)
|
||||
continue;
|
||||
|
||||
InventoryItemBase baseItem = new InventoryItemBase(appearance.Wearables[i][j].ItemID, userID);
|
||||
baseItem = invService.GetItem(baseItem);
|
||||
|
||||
|
|
|
@ -95,14 +95,14 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
|||
{
|
||||
foreach (IMonitor monitor in m_staticMonitors)
|
||||
{
|
||||
m_log.InfoFormat(
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"[MONITOR MODULE]: {0} reports {1} = {2}",
|
||||
m_scene.RegionInfo.RegionName, monitor.GetFriendlyName(), monitor.GetFriendlyValue());
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, float> tuple in m_scene.StatsReporter.GetExtraSimStats())
|
||||
{
|
||||
m_log.InfoFormat(
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"[MONITOR MODULE]: {0} reports {1} = {2}",
|
||||
m_scene.RegionInfo.RegionName, tuple.Key, tuple.Value);
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
|
|||
{
|
||||
if (m_defaultAnimation.AnimID == animID)
|
||||
{
|
||||
ResetDefaultAnimation();
|
||||
m_defaultAnimation = new OpenSim.Framework.Animation(UUID.Zero, 1, UUID.Zero);
|
||||
}
|
||||
else if (HasAnimation(animID))
|
||||
{
|
||||
|
@ -149,19 +149,26 @@ namespace OpenSim.Region.Framework.Scenes.Animation
|
|||
{
|
||||
lock (m_animations)
|
||||
{
|
||||
animIDs = new UUID[m_animations.Count + 1];
|
||||
sequenceNums = new int[m_animations.Count + 1];
|
||||
objectIDs = new UUID[m_animations.Count + 1];
|
||||
int defaultSize = 0;
|
||||
if (m_defaultAnimation.AnimID != UUID.Zero)
|
||||
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;
|
||||
sequenceNums[0] = m_defaultAnimation.SequenceNum;
|
||||
objectIDs[0] = m_defaultAnimation.ObjectID;
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_animations.Count; ++i)
|
||||
{
|
||||
animIDs[i + 1] = m_animations[i].AnimID;
|
||||
sequenceNums[i + 1] = m_animations[i].SequenceNum;
|
||||
objectIDs[i + 1] = m_animations[i].ObjectID;
|
||||
animIDs[i + defaultSize] = m_animations[i].AnimID;
|
||||
sequenceNums[i + defaultSize] = m_animations[i].SequenceNum;
|
||||
objectIDs[i + defaultSize] = m_animations[i].ObjectID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -423,6 +423,9 @@ namespace OpenSim.Region.Framework.Scenes.Animation
|
|||
public void UpdateMovementAnimations()
|
||||
{
|
||||
lock (m_animations)
|
||||
{
|
||||
string newMovementAnimation = DetermineMovementAnimation();
|
||||
if (CurrentMovementAnimation != newMovementAnimation)
|
||||
{
|
||||
CurrentMovementAnimation = DetermineMovementAnimation();
|
||||
|
||||
|
@ -430,9 +433,12 @@ namespace OpenSim.Region.Framework.Scenes.Animation
|
|||
// "[SCENE PRESENCE ANIMATOR]: Determined animation {0} for {1} in UpdateMovementAnimations()",
|
||||
// CurrentMovementAnimation, m_scenePresence.Name);
|
||||
|
||||
// Only set it if it's actually changed, give a script
|
||||
// a chance to stop a default animation
|
||||
TrySetMovementAnimation(CurrentMovementAnimation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public UUID[] GetAnimationArray()
|
||||
{
|
||||
|
|
|
@ -47,6 +47,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
= log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public const string LastReportedObjectUpdateStatName = "LastReportedObjectUpdates";
|
||||
public const string SlowFramesStatName = "SlowFrames";
|
||||
|
||||
public delegate void SendStatResult(SimStats stats);
|
||||
|
||||
|
@ -128,6 +129,16 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
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>
|
||||
/// Extra sim statistics that are used by monitors but not sent to the client.
|
||||
/// </summary>
|
||||
|
@ -226,6 +237,22 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
if (StatsManager.SimExtraStats != null)
|
||||
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()
|
||||
|
@ -443,6 +470,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
lock (m_lastReportedExtraSimStats)
|
||||
{
|
||||
m_lastReportedExtraSimStats[LastReportedObjectUpdateStatName] = m_objectUpdates / m_statsUpdateFactor;
|
||||
m_lastReportedExtraSimStats[SlowFramesStat.ShortName] = (float)SlowFramesStat.Value;
|
||||
|
||||
Dictionary<string, float> physicsStats = m_scene.PhysicsScene.GetStats();
|
||||
|
||||
|
@ -563,6 +591,11 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
public void addFrameMS(int 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)
|
||||
|
|
|
@ -63,6 +63,9 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
private bool m_isphysical;
|
||||
|
||||
public int ExpectedCollisionContacts { get { return m_expectedCollisionContacts; } }
|
||||
private int m_expectedCollisionContacts = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Is this prim subject to physics? Even if not, it's still solid for collision purposes.
|
||||
/// </summary>
|
||||
|
@ -840,7 +843,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
int vertexStride, triStride;
|
||||
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
|
||||
|
||||
m_expectedCollisionContacts = indexCount;
|
||||
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
|
||||
|
@ -1377,6 +1380,7 @@ Console.WriteLine("CreateGeom:");
|
|||
{
|
||||
//Console.WriteLine(" CreateGeom 1");
|
||||
SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
|
||||
m_expectedCollisionContacts = 3;
|
||||
}
|
||||
catch (AccessViolationException)
|
||||
{
|
||||
|
@ -1391,6 +1395,7 @@ Console.WriteLine("CreateGeom:");
|
|||
{
|
||||
//Console.WriteLine(" CreateGeom 2");
|
||||
SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
|
||||
m_expectedCollisionContacts = 4;
|
||||
}
|
||||
catch (AccessViolationException)
|
||||
{
|
||||
|
@ -1406,6 +1411,7 @@ Console.WriteLine("CreateGeom:");
|
|||
{
|
||||
//Console.WriteLine(" CreateGeom 3");
|
||||
SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
|
||||
m_expectedCollisionContacts = 4;
|
||||
}
|
||||
catch (AccessViolationException)
|
||||
{
|
||||
|
@ -1421,6 +1427,7 @@ Console.WriteLine("CreateGeom:");
|
|||
{
|
||||
//Console.WriteLine(" CreateGeom 4");
|
||||
SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
|
||||
m_expectedCollisionContacts = 4;
|
||||
}
|
||||
catch (AccessViolationException)
|
||||
{
|
||||
|
@ -1446,11 +1453,13 @@ Console.WriteLine("CreateGeom:");
|
|||
_parent_scene.geom_name_map.Remove(prim_geom);
|
||||
_parent_scene.actor_name_map.Remove(prim_geom);
|
||||
d.GeomDestroy(prim_geom);
|
||||
m_expectedCollisionContacts = 0;
|
||||
prim_geom = IntPtr.Zero;
|
||||
}
|
||||
catch (System.AccessViolationException)
|
||||
{
|
||||
prim_geom = IntPtr.Zero;
|
||||
m_expectedCollisionContacts = 0;
|
||||
m_log.ErrorFormat("[PHYSICS]: PrimGeom dead for {0}", Name);
|
||||
|
||||
return false;
|
||||
|
|
|
@ -336,6 +336,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
public int geomContactPointsStartthrottle = 3;
|
||||
public int geomUpdatesPerThrottledUpdate = 15;
|
||||
private const int avatarExpectedContacts = 3;
|
||||
|
||||
public float bodyPIDD = 35f;
|
||||
public float bodyPIDG = 25;
|
||||
|
@ -474,6 +475,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
private OdePrim cp1;
|
||||
private OdeCharacter cc2;
|
||||
private OdePrim cp2;
|
||||
private int p1ExpectedPoints = 0;
|
||||
private int p2ExpectedPoints = 0;
|
||||
//private int cStartStop = 0;
|
||||
//private string cDictKey = "";
|
||||
|
||||
|
@ -498,6 +501,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
public int physics_logging_interval = 0;
|
||||
public bool physics_logging_append_existing_logfile = false;
|
||||
|
||||
|
||||
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);
|
||||
|
||||
|
@ -644,7 +648,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
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);
|
||||
geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5);
|
||||
|
||||
|
@ -1065,6 +1069,9 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
PhysicsActor p1;
|
||||
PhysicsActor p2;
|
||||
|
||||
p1ExpectedPoints = 0;
|
||||
p2ExpectedPoints = 0;
|
||||
|
||||
if (!actor_name_map.TryGetValue(g1, out p1))
|
||||
{
|
||||
p1 = PANull;
|
||||
|
@ -1121,9 +1128,13 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
switch (p1.PhysicsActorType)
|
||||
{
|
||||
case (int)ActorTypes.Agent:
|
||||
p1ExpectedPoints = avatarExpectedContacts;
|
||||
p2.CollidingObj = true;
|
||||
break;
|
||||
case (int)ActorTypes.Prim:
|
||||
if (p1 != null && p1 is OdePrim)
|
||||
p1ExpectedPoints = ((OdePrim) p1).ExpectedCollisionContacts;
|
||||
|
||||
if (p2.Velocity.LengthSquared() > 0.0f)
|
||||
p2.CollidingObj = true;
|
||||
break;
|
||||
|
@ -1319,6 +1330,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
if ((p2.PhysicsActorType == (int) ActorTypes.Agent) &&
|
||||
(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
|
||||
AvatarMovementTerrainContact.geom = curContact;
|
||||
|
||||
|
@ -1332,6 +1344,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
{
|
||||
if (p2.PhysicsActorType == (int)ActorTypes.Agent)
|
||||
{
|
||||
p2ExpectedPoints = avatarExpectedContacts;
|
||||
// Avatar is standing on terrain, use the non moving terrain contact
|
||||
TerrainContact.geom = curContact;
|
||||
|
||||
|
@ -1356,9 +1369,18 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
}
|
||||
|
||||
if (p2 is OdePrim)
|
||||
{
|
||||
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_materialContacts[material, movintYN].geom = curContact;
|
||||
|
||||
if (m_global_contactcount < maxContactsbeforedeath)
|
||||
|
@ -1379,7 +1401,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
int material = (int)Material.Wood;
|
||||
|
||||
if (p2 is OdePrim)
|
||||
{
|
||||
material = ((OdePrim)p2).m_material;
|
||||
p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts;
|
||||
}
|
||||
|
||||
//m_log.DebugFormat("Material: {0}", material);
|
||||
m_materialContacts[material, movintYN].geom = curContact;
|
||||
|
@ -1429,6 +1454,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
{
|
||||
if ((p2.PhysicsActorType == (int)ActorTypes.Agent))
|
||||
{
|
||||
p2ExpectedPoints = avatarExpectedContacts;
|
||||
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
|
||||
|
@ -1458,7 +1484,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
int material = (int)Material.Wood;
|
||||
|
||||
if (p2 is OdePrim)
|
||||
{
|
||||
material = ((OdePrim)p2).m_material;
|
||||
p2ExpectedPoints = ((OdePrim)p2).ExpectedCollisionContacts;
|
||||
}
|
||||
|
||||
//m_log.DebugFormat("Material: {0}", material);
|
||||
m_materialContacts[material, 0].geom = curContact;
|
||||
|
@ -1480,7 +1509,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
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
|
||||
// that we've got a pile of objects, so ...
|
||||
|
|
Loading…
Reference in New Issue