From 4b75353cbf50de3cae4c48ec90b55f30c1612c92 Mon Sep 17 00:00:00 2001
From: John Hurliman
Date: Thu, 15 Oct 2009 16:35:27 -0700
Subject: Object update prioritization by Jim Greensky of Intel Labs, part one.
This implements a simple distance prioritizer based on initial agent
positions. Re-prioritizing and more advanced priority algorithms will follow
soon
---
OpenSim/Region/Framework/Scenes/Scene.cs | 40 +++++++++---
OpenSim/Region/Framework/Scenes/SceneGraph.cs | 1 -
.../Region/Framework/Scenes/SceneObjectGroup.cs | 74 +++++++++++++++++++++-
OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 8 +--
OpenSim/Region/Framework/Scenes/ScenePresence.cs | 58 +++++++++++++----
OpenSim/Region/Framework/Scenes/SceneViewer.cs | 23 +------
.../Framework/Scenes/Scripting/IScriptHost.cs | 4 +-
.../Framework/Scenes/Scripting/NullScriptHost.cs | 4 +-
8 files changed, 159 insertions(+), 53 deletions(-)
(limited to 'OpenSim/Region/Framework/Scenes')
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index d13d4fb..c7efc19 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -57,6 +57,12 @@ namespace OpenSim.Region.Framework.Scenes
public partial class Scene : SceneBase
{
+ public enum UpdatePrioritizationSchemes {
+ Time = 0,
+ Distance = 1,
+ SimpleAngularDistance = 2,
+ }
+
public delegate void SynchronizeSceneHandler(Scene scene);
public SynchronizeSceneHandler SynchronizeScene = null;
@@ -268,9 +274,10 @@ namespace OpenSim.Region.Framework.Scenes
private volatile bool shuttingdown = false;
private int m_lastUpdate = Environment.TickCount;
- private int m_maxPrimsPerFrame = 200;
private bool m_firstHeartbeat = true;
+ private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
+
private object m_deleting_scene_object = new object();
// the minimum time that must elapse before a changed object will be considered for persisted
@@ -282,6 +289,8 @@ namespace OpenSim.Region.Framework.Scenes
#region Properties
+ public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return this.m_update_prioritization_scheme; } }
+
public AgentCircuitManager AuthenticateHandler
{
get { return m_authenticateHandler; }
@@ -326,12 +335,6 @@ namespace OpenSim.Region.Framework.Scenes
get { return m_sceneGraph.m_syncRoot; }
}
- public int MaxPrimsPerFrame
- {
- get { return m_maxPrimsPerFrame; }
- set { m_maxPrimsPerFrame = value; }
- }
-
///
/// This is for llGetRegionFPS
///
@@ -509,7 +512,6 @@ namespace OpenSim.Region.Framework.Scenes
m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "DotNetEngine");
- m_maxPrimsPerFrame = startupConfig.GetInt("MaxPrimsPerFrame", 200);
IConfig packetConfig = m_config.Configs["PacketPool"];
if (packetConfig != null)
{
@@ -518,6 +520,28 @@ namespace OpenSim.Region.Framework.Scenes
}
m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
+
+ IConfig interest_management_config = m_config.Configs["InterestManagement"];
+ if (interest_management_config != null)
+ {
+ string update_prioritization_scheme = interest_management_config.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower();
+ switch (update_prioritization_scheme)
+ {
+ case "time":
+ m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
+ break;
+ case "distance":
+ m_update_prioritization_scheme = UpdatePrioritizationSchemes.Distance;
+ break;
+ case "simpleangulardistance":
+ m_update_prioritization_scheme = UpdatePrioritizationSchemes.SimpleAngularDistance;
+ break;
+ default:
+ m_log.Warn("[SCENE]: UpdatePrioritizationScheme was not recognized, setting to default settomg of Time");
+ m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
+ break;
+ }
+ }
}
catch
{
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 04397ad..b9872ca 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -613,7 +613,6 @@ namespace OpenSim.Region.Framework.Scenes
newAvatar = new ScenePresence(client, m_parentScene, m_regInfo, appearance);
newAvatar.IsChildAgent = true;
- newAvatar.MaxPrimsPerFrame = m_parentScene.MaxPrimsPerFrame;
AddScenePresence(newAvatar);
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index d4cef7d..2153b9b 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -1817,7 +1817,7 @@ namespace OpenSim.Region.Framework.Scenes
public void ServiceObjectPropertiesFamilyRequest(IClientAPI remoteClient, UUID AgentID, uint RequestFlags)
{
- remoteClient.SendObjectPropertiesFamilyData(RequestFlags, RootPart.UUID, RootPart.ObjectOwner, RootPart.GroupID, RootPart.BaseMask,
+ remoteClient.SendObjectPropertiesFamilyData(RequestFlags, RootPart.UUID, RootPart.OwnerID, RootPart.GroupID, RootPart.BaseMask,
RootPart.OwnerMask, RootPart.GroupMask, RootPart.EveryoneMask, RootPart.NextOwnerMask,
RootPart.OwnershipCost, RootPart.ObjectSaleType, RootPart.SalePrice, RootPart.Category,
RootPart.CreatorID, RootPart.Name, RootPart.Description);
@@ -3343,5 +3343,77 @@ namespace OpenSim.Region.Framework.Scenes
return true;
}
+
+ public double GetUpdatePriority(IClientAPI client)
+ {
+ switch (Scene.UpdatePrioritizationScheme)
+ {
+ case Scene.UpdatePrioritizationSchemes.Time:
+ return GetPriorityByTime();
+ case Scene.UpdatePrioritizationSchemes.Distance:
+ return GetPriorityByDistance(client);
+ case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance:
+ return GetPriorityBySimpleAngularDistance(client);
+ default:
+ throw new InvalidOperationException("UpdatePrioritizationScheme not defined");
+ }
+ }
+
+ private double GetPriorityByTime()
+ {
+ return DateTime.Now.ToOADate();
+ }
+
+ private double GetPriorityByDistance(IClientAPI client)
+ {
+ ScenePresence presence = Scene.GetScenePresence(client.AgentId);
+ if (presence != null)
+ {
+ return GetPriorityByDistance((presence.IsChildAgent) ?
+ presence.AbsolutePosition : presence.CameraPosition);
+ }
+ return double.NaN;
+ }
+
+ private double GetPriorityBySimpleAngularDistance(IClientAPI client)
+ {
+ ScenePresence presence = Scene.GetScenePresence(client.AgentId);
+ if (presence != null)
+ {
+ return GetPriorityBySimpleAngularDistance((presence.IsChildAgent) ?
+ presence.AbsolutePosition : presence.CameraPosition);
+ }
+ return double.NaN;
+ }
+
+ public double GetPriorityByDistance(Vector3 position)
+ {
+ return Vector3.Distance(AbsolutePosition, position);
+ }
+
+ public double GetPriorityBySimpleAngularDistance(Vector3 position)
+ {
+ double distance = Vector3.Distance(position, AbsolutePosition);
+ if (distance >= double.Epsilon)
+ {
+ float height;
+ Vector3 box = GetAxisAlignedBoundingBox(out height);
+
+ double angle = box.X / distance;
+ double max = angle;
+
+ angle = box.Y / distance;
+ if (max < angle)
+ max = angle;
+
+ angle = box.Z / distance;
+ if (max < angle)
+ max = angle;
+
+ return -max;
+ }
+ else
+ return double.MinValue;
+ }
}
}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 377cb6e..79f6366 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -2400,10 +2400,10 @@ if (m_shape != null) {
//isattachment = ParentGroup.RootPart.IsAttachment;
byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A};
- remoteClient.SendPrimitiveToClient(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, m_shape,
+ remoteClient.SendPrimitiveToClient(new SendPrimitiveData(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, m_shape,
lPos, Velocity, Acceleration, RotationOffset, RotationalVelocity, clientFlags, m_uuid, _ownerID,
m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment,
- AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius);
+ AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius, ParentGroup.GetUpdatePriority(remoteClient)));
}
///
@@ -3794,12 +3794,12 @@ if (m_shape != null) {
// Causes this thread to dig into the Client Thread Data.
// Remember your locking here!
- remoteClient.SendPrimTerseUpdate(m_regionHandle,
+ remoteClient.SendPrimTerseUpdate(new SendPrimitiveTerseData(m_regionHandle,
(ushort)(m_parentGroup.GetTimeDilation() *
(float)ushort.MaxValue), LocalId, lPos,
RotationOffset, Velocity,
RotationalVelocity, state, FromItemID,
- OwnerID, (int)AttachmentPoint);
+ OwnerID, (int)AttachmentPoint, ParentGroup.GetUpdatePriority(remoteClient)));
}
public void AddScriptLPS(int count)
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 387db44..a5b88c6 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -403,12 +403,6 @@ namespace OpenSim.Region.Framework.Scenes
set { m_parentPosition = value; }
}
- public int MaxPrimsPerFrame
- {
- get { return m_sceneViewer.MaxPrimsPerFrame; }
- set { m_sceneViewer.MaxPrimsPerFrame = value; }
- }
-
///
/// Absolute position of this avatar in 'region cordinates'
///
@@ -2457,8 +2451,8 @@ namespace OpenSim.Region.Framework.Scenes
Vector3 pos = m_pos;
pos.Z -= m_appearance.HipOffset;
- remoteClient.SendAvatarTerseUpdate(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue),
- LocalId, pos, Velocity, m_bodyRot, m_uuid);
+ remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
+ pos, m_velocity, m_rotation, m_uuid, GetUpdatePriority(remoteClient)));
m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS);
m_scene.StatsReporter.AddAgentUpdates(1);
@@ -2563,9 +2557,9 @@ namespace OpenSim.Region.Framework.Scenes
Vector3 pos = m_pos;
pos.Z -= m_appearance.HipOffset;
- remoteAvatar.m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid,
+ remoteAvatar.m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid,
LocalId, m_pos, m_appearance.Texture.GetBytes(),
- m_parentID, rot);
+ m_parentID, rot));
m_scene.StatsReporter.AddAgentUpdates(1);
}
@@ -2634,8 +2628,8 @@ namespace OpenSim.Region.Framework.Scenes
Vector3 pos = m_pos;
pos.Z -= m_appearance.HipOffset;
- m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId,
- m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot);
+ m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId,
+ m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot));
if (!m_isChildAgent)
{
@@ -2741,8 +2735,8 @@ namespace OpenSim.Region.Framework.Scenes
}
Quaternion rot = m_bodyRot;
- m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId,
- m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot);
+ m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId,
+ m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot));
}
@@ -3870,5 +3864,41 @@ namespace OpenSim.Region.Framework.Scenes
}
}
}
+
+ public double GetUpdatePriority(IClientAPI client)
+ {
+ switch (Scene.UpdatePrioritizationScheme)
+ {
+ case Scene.UpdatePrioritizationSchemes.Time:
+ return GetPriorityByTime();
+ case Scene.UpdatePrioritizationSchemes.Distance:
+ return GetPriorityByDistance(client);
+ case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance:
+ return GetPriorityByDistance(client);
+ default:
+ throw new InvalidOperationException("UpdatePrioritizationScheme not defined.");
+ }
+ }
+
+ private double GetPriorityByTime()
+ {
+ return DateTime.Now.ToOADate();
+ }
+
+ private double GetPriorityByDistance(IClientAPI client)
+ {
+ ScenePresence presence = Scene.GetScenePresence(client.AgentId);
+ if (presence != null)
+ {
+ return GetPriorityByDistance((presence.IsChildAgent) ?
+ presence.AbsolutePosition : presence.CameraPosition);
+ }
+ return double.NaN;
+ }
+
+ private double GetPriorityByDistance(Vector3 position)
+ {
+ return Vector3.Distance(AbsolutePosition, position);
+ }
}
}
diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
index 8ab0552..e4296ef 100644
--- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs
@@ -45,14 +45,6 @@ namespace OpenSim.Region.Framework.Scenes
protected Dictionary m_updateTimes = new Dictionary();
- protected int m_maxPrimsPerFrame = 200;
-
- public int MaxPrimsPerFrame
- {
- get { return m_maxPrimsPerFrame; }
- set { m_maxPrimsPerFrame = value; }
- }
-
public SceneViewer()
{
}
@@ -82,16 +74,7 @@ namespace OpenSim.Region.Framework.Scenes
{
m_pendingObjects = new Queue();
- List ents = new List(m_presence.Scene.Entities);
- if (!m_presence.IsChildAgent) // Proximity sort makes no sense for
- { // Child agents
- ents.Sort(delegate(EntityBase a, EntityBase b)
- {
- return Vector3.Distance(m_presence.AbsolutePosition, a.AbsolutePosition).CompareTo(Vector3.Distance(m_presence.AbsolutePosition, b.AbsolutePosition));
- });
- }
-
- foreach (EntityBase e in ents)
+ foreach (EntityBase e in m_presence.Scene.Entities)
{
if (e is SceneObjectGroup)
m_pendingObjects.Enqueue((SceneObjectGroup)e);
@@ -99,7 +82,7 @@ namespace OpenSim.Region.Framework.Scenes
}
}
- while (m_pendingObjects != null && m_pendingObjects.Count > 0 && m_partsUpdateQueue.Count < m_maxPrimsPerFrame)
+ while (m_pendingObjects != null && m_pendingObjects.Count > 0)
{
SceneObjectGroup g = m_pendingObjects.Dequeue();
@@ -183,8 +166,6 @@ namespace OpenSim.Region.Framework.Scenes
m_presence.GenerateClientFlags(part.UUID));
}
}
-
- m_presence.ControllingClient.FlushPrimUpdates();
}
public void Reset()
diff --git a/OpenSim/Region/Framework/Scenes/Scripting/IScriptHost.cs b/OpenSim/Region/Framework/Scenes/Scripting/IScriptHost.cs
index 29c4672..f3be028 100644
--- a/OpenSim/Region/Framework/Scenes/Scripting/IScriptHost.cs
+++ b/OpenSim/Region/Framework/Scenes/Scripting/IScriptHost.cs
@@ -35,8 +35,8 @@ namespace OpenSim.Region.Framework.Scenes.Scripting
string Description { get; set; }
UUID UUID { get; }
- UUID ObjectOwner { get; }
- UUID ObjectCreator { get; }
+ UUID OwnerID { get; }
+ UUID CreatorID { get; }
Vector3 AbsolutePosition { get; }
string SitName { get; set; }
diff --git a/OpenSim/Region/Framework/Scenes/Scripting/NullScriptHost.cs b/OpenSim/Region/Framework/Scenes/Scripting/NullScriptHost.cs
index af18a98..d7198f0 100644
--- a/OpenSim/Region/Framework/Scenes/Scripting/NullScriptHost.cs
+++ b/OpenSim/Region/Framework/Scenes/Scripting/NullScriptHost.cs
@@ -68,12 +68,12 @@ namespace OpenSim.Region.Framework.Scenes.Scripting
get { return UUID.Zero; }
}
- public UUID ObjectOwner
+ public UUID OwnerID
{
get { return UUID.Zero; }
}
- public UUID ObjectCreator
+ public UUID CreatorID
{
get { return UUID.Zero; }
}
--
cgit v1.1