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(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);
|
||||||
|
|
|
@ -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)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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[0] = m_defaultAnimation.AnimID;
|
animIDs = new UUID[m_animations.Count + defaultSize];
|
||||||
sequenceNums[0] = m_defaultAnimation.SequenceNum;
|
sequenceNums = new int[m_animations.Count + defaultSize];
|
||||||
objectIDs[0] = m_defaultAnimation.ObjectID;
|
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)
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -424,13 +424,19 @@ namespace OpenSim.Region.Framework.Scenes.Animation
|
||||||
{
|
{
|
||||||
lock (m_animations)
|
lock (m_animations)
|
||||||
{
|
{
|
||||||
CurrentMovementAnimation = DetermineMovementAnimation();
|
string newMovementAnimation = DetermineMovementAnimation();
|
||||||
|
if (CurrentMovementAnimation != newMovementAnimation)
|
||||||
|
{
|
||||||
|
CurrentMovementAnimation = DetermineMovementAnimation();
|
||||||
|
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[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);
|
||||||
|
|
||||||
TrySetMovementAnimation(CurrentMovementAnimation);
|
// Only set it if it's actually changed, give a script
|
||||||
|
// a chance to stop a default animation
|
||||||
|
TrySetMovementAnimation(CurrentMovementAnimation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -552,4 +558,4 @@ namespace OpenSim.Region.Framework.Scenes.Animation
|
||||||
SendAnimPack(animIDs, sequenceNums, objectIDs);
|
SendAnimPack(animIDs, sequenceNums, objectIDs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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>
|
||||||
|
@ -150,7 +153,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
private PrimitiveBaseShape _pbs;
|
private PrimitiveBaseShape _pbs;
|
||||||
private OdeScene _parent_scene;
|
private OdeScene _parent_scene;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The physics space which contains prim geometries
|
/// The physics space which contains prim geometries
|
||||||
/// </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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
@ -1064,7 +1068,10 @@ 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;
|
||||||
|
@ -1479,8 +1508,8 @@ 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 ...
|
||||||
|
|
Loading…
Reference in New Issue