From d44b50ee462978b4899c0b142f6ecbfb553f06b6 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Thu, 15 Oct 2009 15:25:02 -0700 Subject: * Removed some of the redundant broadcast functions in Scene and SceneGraph so it is clear who/what the broadcast is going to each time * Removed two redundant parameters from SceneObjectPart * Changed some code in terse update sending that was meant to work with references to work with value types (since Vector3 and Quaternion are structs) * Committing a preview of a new method for sending object updates efficiently (all commented out for now) --- OpenSim/Region/Framework/Scenes/Scene.cs | 31 +++++++--------------- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 17 ------------ OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 12 +-------- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 11 ++++---- 4 files changed, 15 insertions(+), 56 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index d3d397d..d13d4fb 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1194,15 +1194,6 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Perform delegate action on all clients subscribing to updates from this region. - /// - /// - public void Broadcast(Action whatToDo) - { - ForEachScenePresence(delegate(ScenePresence presence) { whatToDo(presence.ControllingClient); }); - } - - /// /// Backup the scene. This acts as the main method of the backup thread. /// /// @@ -3048,17 +3039,13 @@ namespace OpenSim.Region.Framework.Scenes } m_eventManager.TriggerOnRemovePresence(agentID); - Broadcast(delegate(IClientAPI client) - { - try - { - client.SendKillObject(avatar.RegionHandle, avatar.LocalId); - } - catch (NullReferenceException) - { - //We can safely ignore null reference exceptions. It means the avatar are dead and cleaned up anyway. - } - }); + ForEachClient( + delegate(IClientAPI client) + { + //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway + try { client.SendKillObject(avatar.RegionHandle, avatar.LocalId); } + catch (NullReferenceException) { } + }); ForEachScenePresence( delegate(ScenePresence presence) { presence.CoarseLocationChange(); }); @@ -3143,7 +3130,7 @@ namespace OpenSim.Region.Framework.Scenes return; } } - Broadcast(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); }); + ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); }); } #endregion @@ -4211,7 +4198,7 @@ namespace OpenSim.Region.Framework.Scenes public void ForEachClient(Action action) { - m_sceneGraph.ForEachClient(action); + ClientManager.ForEach(action); } public void ForEachSOG(Action action) diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 9cd2247..04397ad 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1107,23 +1107,6 @@ namespace OpenSim.Region.Framework.Scenes return UUID.Zero; } - protected internal void ForEachClient(Action action) - { - List splist = GetScenePresences(); - foreach (ScenePresence presence in splist) - { - try - { - action(presence.ControllingClient); - } - catch (Exception e) - { - // Catch it and move on. This includes situations where splist has inconsistent info - m_log.WarnFormat("[SCENE]: Problem processing action in ForEachClient: ", e.Message); - } - } - } - protected internal void ForEachSOG(Action action) { List objlist = new List(SceneObjectGroupsByFullID.Values); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 801a7db..377cb6e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -853,16 +853,6 @@ if (m_shape != null) { return m_offsetPosition + m_groupPosition; } } - public UUID ObjectCreator - { - get { return _creatorID; } - } - - public UUID ObjectOwner - { - get { return _ownerID; } - } - public SceneObjectGroup ParentGroup { get { return m_parentGroup; } @@ -1440,7 +1430,7 @@ if (m_shape != null) { // Move afterwards ResetIDs as it clears the localID dupe.LocalId = localID; // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. - dupe._lastOwnerID = ObjectOwner; + dupe._lastOwnerID = OwnerID; byte[] extraP = new byte[Shape.ExtraParams.Length]; Array.Copy(Shape.ExtraParams, extraP, extraP.Length); diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 2a06f9e..387db44 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2455,11 +2455,10 @@ namespace OpenSim.Region.Framework.Scenes m_perfMonMS = Environment.TickCount; Vector3 pos = m_pos; - Vector3 vel = Velocity; - Quaternion rot = m_bodyRot; pos.Z -= m_appearance.HipOffset; - remoteClient.SendAvatarTerseUpdate(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, new Vector3(pos.X, pos.Y, pos.Z), - new Vector3(vel.X, vel.Y, vel.Z), rot, m_uuid); + + remoteClient.SendAvatarTerseUpdate(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), + LocalId, pos, Velocity, m_bodyRot, m_uuid); m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); m_scene.StatsReporter.AddAgentUpdates(1); @@ -2473,7 +2472,7 @@ namespace OpenSim.Region.Framework.Scenes { m_perfMonMS = Environment.TickCount; - m_scene.Broadcast(SendTerseUpdateToClient); + m_scene.ForEachClient(SendTerseUpdateToClient); m_lastVelocity = m_velocity; lastPhysPos = AbsolutePosition; @@ -2774,7 +2773,7 @@ namespace OpenSim.Region.Framework.Scenes if (m_isChildAgent) return; - m_scene.Broadcast( + m_scene.ForEachClient( delegate(IClientAPI client) { client.SendAnimations(animations, seqs, m_controllingClient.AgentId, objectIDs); }); } -- cgit v1.1 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 From 5a4fda9dc3aca873bcf034877eed1f9c5914493f Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Fri, 16 Oct 2009 11:09:18 -0700 Subject: Updating OpenSim.ini.example with the section required to enable a useful prioritization scheme --- OpenSim/Region/Framework/Scenes/Scene.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim/Region/Framework/Scenes') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index c7efc19..0d8c241 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -542,6 +542,8 @@ namespace OpenSim.Region.Framework.Scenes break; } } + + m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme"); } catch { -- cgit v1.1 From fdb2a75ad357668b860fc5055e0630ef75a3ad20 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Sat, 17 Oct 2009 18:01:22 -0700 Subject: Committing the second part of Jim Greensky @ Intel Lab's patch, re-prioritizing updates --- OpenSim/Region/Framework/Scenes/Scene.cs | 13 +++ OpenSim/Region/Framework/Scenes/SceneGraph.cs | 2 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 112 ++++++++++++++++++++++- 3 files changed, 124 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 49c1ebf..30fe976 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -278,6 +278,10 @@ namespace OpenSim.Region.Framework.Scenes private bool m_firstHeartbeat = true; private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; + private bool m_reprioritization_enabled = true; + private double m_reprioritization_interval = 2000.0; + private double m_root_reprioritization_distance = 5.0; + private double m_child_reprioritization_distance = 10.0; private object m_deleting_scene_object = new object(); @@ -291,6 +295,10 @@ namespace OpenSim.Region.Framework.Scenes #region Properties public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return this.m_update_prioritization_scheme; } } + public bool IsReprioritizationEnabled { get { return m_reprioritization_enabled; } } + public double ReprioritizationInterval { get { return m_reprioritization_interval; } } + public double RootReprioritizationDistance { get { return m_root_reprioritization_distance; } } + public double ChildReprioritizationDistance { get { return m_child_reprioritization_distance; } } public AgentCircuitManager AuthenticateHandler { @@ -542,6 +550,11 @@ namespace OpenSim.Region.Framework.Scenes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; break; } + + m_reprioritization_enabled = interest_management_config.GetBoolean("ReprioritizationEnabled", true); + m_reprioritization_interval = interest_management_config.GetDouble("ReprioritizationInterval", 5000.0); + m_root_reprioritization_distance = interest_management_config.GetDouble("RootReprioritizationDistance", 10.0); + m_child_reprioritization_distance = interest_management_config.GetDouble("ChildReprioritizationDistance", 20.0); } m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme"); diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index b9872ca..8ee26c3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -846,7 +846,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// null if no scene object group containing that prim is found - private SceneObjectGroup GetGroupByPrim(uint localID) + public SceneObjectGroup GetGroupByPrim(uint localID) { if (Entities.ContainsKey(localID)) return Entities[localID] as SceneObjectGroup; diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 9d13ad4..f05c3d8 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -28,6 +28,7 @@ using System; using System.Collections.Generic; using System.Reflection; +using System.Timers; using OpenMetaverse; using log4net; using OpenSim.Framework; @@ -172,6 +173,11 @@ namespace OpenSim.Region.Framework.Scenes // Position of agent's camera in world (region cordinates) protected Vector3 m_CameraCenter = Vector3.Zero; + protected Vector3 m_lastCameraCenter = Vector3.Zero; + + protected Timer m_reprioritization_timer; + protected bool m_reprioritizing = false; + protected bool m_reprioritization_called = false; // Use these three vectors to figure out what the agent is looking at // Convert it to a Matrix and/or Quaternion @@ -639,7 +645,14 @@ namespace OpenSim.Region.Framework.Scenes m_scriptEngines = m_scene.RequestModuleInterfaces(); - AbsolutePosition = m_controllingClient.StartPos; + AbsolutePosition = posLastSignificantMove = m_CameraCenter = + m_lastCameraCenter = m_controllingClient.StartPos; + + m_reprioritization_timer = new Timer(world.ReprioritizationInterval); + m_reprioritization_timer.Elapsed += new ElapsedEventHandler(Reprioritize); + m_reprioritization_timer.AutoReset = false; + + AdjustKnownSeeds(); TrySetMovementAnimation("STAND"); // TODO: I think, this won't send anything, as we are still a child here... @@ -1219,6 +1232,11 @@ namespace OpenSim.Region.Framework.Scenes // Camera location in world. We'll need to raytrace // from this location from time to time. m_CameraCenter = agentData.CameraCenter; + if (Vector3.Distance(m_lastCameraCenter, m_CameraCenter) >= Scene.RootReprioritizationDistance) + { + ReprioritizeUpdates(); + m_lastCameraCenter = m_CameraCenter; + } // Use these three vectors to figure out what the agent is looking at // Convert it to a Matrix and/or Quaternion @@ -2823,7 +2841,7 @@ namespace OpenSim.Region.Framework.Scenes } // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m - if (Util.GetDistanceTo(AbsolutePosition,m_LastChildAgentUpdatePosition) > 32) + if (Util.GetDistanceTo(AbsolutePosition, m_LastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance) { ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); cadu.ActiveGroupID = UUID.Zero.Guid; @@ -3118,6 +3136,12 @@ namespace OpenSim.Region.Framework.Scenes if (cAgentData.Position != new Vector3(-1, -1, -1)) // UGH!! m_pos = new Vector3(cAgentData.Position.X + shiftx, cAgentData.Position.Y + shifty, cAgentData.Position.Z); + if (Vector3.Distance(AbsolutePosition, posLastSignificantMove) >= Scene.ChildReprioritizationDistance) + { + posLastSignificantMove = AbsolutePosition; + ReprioritizeUpdates(); + } + // It's hard to say here.. We can't really tell where the camera position is unless it's in world cordinates from the sending region m_CameraCenter = cAgentData.Center; @@ -3498,6 +3522,16 @@ namespace OpenSim.Region.Framework.Scenes { m_knownChildRegions.Clear(); } + + lock (m_reprioritization_timer) + { + m_reprioritization_timer.Enabled = false; + m_reprioritization_timer.Elapsed -= new ElapsedEventHandler(Reprioritize); + } + // I don't get it but mono crashes when you try to dispose of this timer, + // unsetting the elapsed callback should be enough to allow for cleanup however. + //m_reprioritizationTimer.Dispose(); + m_sceneViewer.Close(); RemoveFromPhysicalScene(); @@ -3913,5 +3947,79 @@ namespace OpenSim.Region.Framework.Scenes { return Vector3.Distance(AbsolutePosition, position); } + + private double GetSOGUpdatePriority(SceneObjectGroup sog) + { + switch (Scene.UpdatePrioritizationScheme) + { + case Scene.UpdatePrioritizationSchemes.Time: + throw new InvalidOperationException("UpdatePrioritizationScheme for time not supported for reprioritization"); + case Scene.UpdatePrioritizationSchemes.Distance: + return sog.GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition); + case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: + return sog.GetPriorityBySimpleAngularDistance((IsChildAgent) ? AbsolutePosition : CameraPosition); + default: + throw new InvalidOperationException("UpdatePrioritizationScheme not defined"); + } + } + + private double UpdatePriority(UpdatePriorityData data) + { + EntityBase entity; + SceneObjectGroup group; + + if (Scene.Entities.TryGetValue(data.localID, out entity)) + { + group = entity as SceneObjectGroup; + if (group != null) + return GetSOGUpdatePriority(group); + + ScenePresence presence = entity as ScenePresence; + if (presence == null) + throw new InvalidOperationException("entity found is neither SceneObjectGroup nor ScenePresence"); + switch (Scene.UpdatePrioritizationScheme) + { + case Scene.UpdatePrioritizationSchemes.Time: + throw new InvalidOperationException("UpdatePrioritization for time not supported for reprioritization"); + case Scene.UpdatePrioritizationSchemes.Distance: + case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: + return GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition); + default: + throw new InvalidOperationException("UpdatePrioritizationScheme not defined"); + } + } + else + { + group = Scene.SceneGraph.GetGroupByPrim(data.localID); + if (group != null) + return GetSOGUpdatePriority(group); + } + return double.NaN; + } + + private void ReprioritizeUpdates() + { + if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != Scene.UpdatePrioritizationSchemes.Time) + { + lock (m_reprioritization_timer) + { + if (!m_reprioritizing) + m_reprioritization_timer.Enabled = m_reprioritizing = true; + else + m_reprioritization_called = true; + } + } + } + + private void Reprioritize(object sender, ElapsedEventArgs e) + { + m_controllingClient.ReprioritizeUpdates(StateUpdateTypes.All, UpdatePriority); + + lock (m_reprioritization_timer) + { + m_reprioritization_timer.Enabled = m_reprioritizing = m_reprioritization_called; + m_reprioritization_called = false; + } + } } } -- cgit v1.1 From 233e16b99cc80190d41143ecdfe01308eb39932a Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Sun, 18 Oct 2009 20:24:20 -0700 Subject: * Rewrote the methods that build ObjectUpdate and ImprovedTerseObjectUpdate packets to fill in the data more accurately and avoid allocating memory that is immediately thrown away * Changed the Send*Data structs in IClientAPI to use public readonly members instead of private members and getters * Made Parallel.ProcessorCount public * Started switching over packet building methods in LLClientView to use Util.StringToBytes[256/1024]() instead of Utils.StringToBytes() * More cleanup of the ScenePresences vs. ClientManager nightmare * ScenePresence.HandleAgentUpdate() will now time out and drop incoming AgentUpdate packets after three seconds. This fixes a deadlock on m_AgentUpdates that was blocking up the LLUDP server --- OpenSim/Region/Framework/Scenes/Scene.cs | 35 +++++++--------------- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 6 ++-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 22 ++++++++------ 3 files changed, 27 insertions(+), 36 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 30fe976..70b11c3 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -357,13 +357,6 @@ namespace OpenSim.Region.Framework.Scenes get { return m_defaultScriptEngine; } } - // Reference to all of the agents in the scene (root and child) - protected Dictionary m_scenePresences - { - get { return m_sceneGraph.ScenePresences; } - set { m_sceneGraph.ScenePresences = value; } - } - public EntityManager Entities { get { return m_sceneGraph.Entities; } @@ -1183,14 +1176,13 @@ namespace OpenSim.Region.Framework.Scenes /// Stats on the Simulator's performance private void SendSimStatsPackets(SimStats stats) { - List StatSendAgents = GetScenePresences(); - foreach (ScenePresence agent in StatSendAgents) - { - if (!agent.IsChildAgent) + ForEachScenePresence( + delegate(ScenePresence agent) { - agent.ControllingClient.SendSimStats(stats); + if (!agent.IsChildAgent) + agent.ControllingClient.SendSimStats(stats); } - } + ); } /// @@ -3501,10 +3493,8 @@ namespace OpenSim.Region.Framework.Scenes { ScenePresence presence; - lock (m_scenePresences) - { - m_scenePresences.TryGetValue(agentID, out presence); - } + lock (m_sceneGraph.ScenePresences) + m_sceneGraph.ScenePresences.TryGetValue(agentID, out presence); if (presence != null) { @@ -3714,12 +3704,9 @@ namespace OpenSim.Region.Framework.Scenes public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) { - ScenePresence sp = null; - lock (m_scenePresences) - { - if (m_scenePresences.ContainsKey(remoteClient.AgentId)) - sp = m_scenePresences[remoteClient.AgentId]; - } + ScenePresence sp; + lock (m_sceneGraph.ScenePresences) + m_sceneGraph.ScenePresences.TryGetValue(remoteClient.AgentId, out sp); if (sp != null) { @@ -4168,7 +4155,7 @@ namespace OpenSim.Region.Framework.Scenes public void ForEachScenePresence(Action action) { // We don't want to try to send messages if there are no avatars. - if (m_scenePresences != null) + if (m_sceneGraph != null && m_sceneGraph.ScenePresences != null) { try { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 79f6366..a078b3d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3791,15 +3791,15 @@ if (m_shape != null) { if (ParentGroup.RootPart == this) lPos = AbsolutePosition; } - + // Causes this thread to dig into the Client Thread Data. // Remember your locking here! remoteClient.SendPrimTerseUpdate(new SendPrimitiveTerseData(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, - RotationOffset, Velocity, + RotationOffset, Velocity, Acceleration, RotationalVelocity, state, FromItemID, - OwnerID, (int)AttachmentPoint, ParentGroup.GetUpdatePriority(remoteClient))); + OwnerID, (int)AttachmentPoint, null, 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 f05c3d8..bdd80c6 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1160,15 +1160,21 @@ namespace OpenSim.Region.Framework.Scenes /// public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) { - lock (m_agentUpdates) + const int AGENT_UPDATE_TIMEOUT_MS = 1000 * 3; + + if (System.Threading.Monitor.TryEnter(m_agentUpdates, AGENT_UPDATE_TIMEOUT_MS)) { - if (m_updatesAllowed) + try { - RealHandleAgentUpdate(remoteClient, agentData); - return; + if (m_updatesAllowed) + { + RealHandleAgentUpdate(remoteClient, agentData); + return; + } + + m_agentUpdates.Add(agentData); } - - m_agentUpdates.Add(agentData); + finally { System.Threading.Monitor.Exit(m_agentUpdates); } } } @@ -2471,7 +2477,7 @@ namespace OpenSim.Region.Framework.Scenes pos.Z -= m_appearance.HipOffset; remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, - pos, m_velocity, m_rotation, m_uuid, GetUpdatePriority(remoteClient))); + pos, m_velocity, Vector3.Zero, m_rotation, Vector4.Zero, m_uuid, null, GetUpdatePriority(remoteClient))); m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); m_scene.StatsReporter.AddAgentUpdates(1); @@ -3504,7 +3510,6 @@ namespace OpenSim.Region.Framework.Scenes public void Close() { - lock (m_attachments) { // Delete attachments from scene @@ -3535,7 +3540,6 @@ namespace OpenSim.Region.Framework.Scenes m_sceneViewer.Close(); RemoveFromPhysicalScene(); - GC.Collect(); } public ScenePresence() -- cgit v1.1 From 142008121e2e9c5ca5fca5de07b8a14e37279800 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Mon, 19 Oct 2009 15:19:09 -0700 Subject: * Change Util.FireAndForget to use ThreadPool.UnsafeQueueUserWorkItem(). This avoids .NET remoting and a managed->unmanaged->managed jump. Overall, a night and day performance difference * Initialize the LLClientView prim full update queue to the number of prims in the scene for a big performance boost * Reordered some comparisons on hot code paths for a minor speed boost * Removed an unnecessary call to the expensive DateTime.Now function (if you *have* to get the current time as opposed to Environment.TickCount, always use DateTime.UtcNow) * Don't fire the queue empty callback for the Resend category * Run the outgoing packet handler thread loop for each client synchronously. It seems like more time was being spent doing the execution asynchronously, and it made deadlocks very difficult to track down * Rewrote some expensive math in LandObject.cs * Optimized EntityManager to only lock on operations that need locking, and use TryGetValue() where possible * Only update the attachment database when an object is attached or detached * Other small misc. performance improvements --- OpenSim/Region/Framework/Scenes/EntityManager.cs | 69 ++++++++++------------ OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 21 ++----- OpenSim/Region/Framework/Scenes/Scene.cs | 4 ++ OpenSim/Region/Framework/Scenes/SceneGraph.cs | 12 +++- .../Region/Framework/Scenes/SceneObjectGroup.cs | 2 +- 5 files changed, 50 insertions(+), 58 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes') diff --git a/OpenSim/Region/Framework/Scenes/EntityManager.cs b/OpenSim/Region/Framework/Scenes/EntityManager.cs index 0ceef39..099fcce 100644 --- a/OpenSim/Region/Framework/Scenes/EntityManager.cs +++ b/OpenSim/Region/Framework/Scenes/EntityManager.cs @@ -93,40 +93,31 @@ namespace OpenSim.Region.Framework.Scenes { get { - lock (m_lock) - { - return m_eb_uuid.Count; - } + return m_eb_uuid.Count; } } public bool ContainsKey(UUID id) { - lock (m_lock) + try { - try - { - return m_eb_uuid.ContainsKey(id); - } - catch - { - return false; - } + return m_eb_uuid.ContainsKey(id); + } + catch + { + return false; } } public bool ContainsKey(uint localID) { - lock (m_lock) + try { - try - { - return m_eb_localID.ContainsKey(localID); - } - catch - { - return false; - } + return m_eb_localID.ContainsKey(localID); + } + catch + { + return false; } } @@ -136,7 +127,11 @@ namespace OpenSim.Region.Framework.Scenes { try { - bool a = m_eb_uuid.Remove(m_eb_localID[localID].UUID); + bool a = false; + EntityBase entity; + if (m_eb_localID.TryGetValue(localID, out entity)) + a = m_eb_uuid.Remove(entity.UUID); + bool b = m_eb_localID.Remove(localID); return a && b; } @@ -154,7 +149,11 @@ namespace OpenSim.Region.Framework.Scenes { try { - bool a = m_eb_localID.Remove(m_eb_uuid[id].LocalId); + bool a = false; + EntityBase entity; + if (m_eb_uuid.TryGetValue(id, out entity)) + a = m_eb_localID.Remove(entity.LocalId); + bool b = m_eb_uuid.Remove(id); return a && b; } @@ -206,14 +205,11 @@ namespace OpenSim.Region.Framework.Scenes { lock (m_lock) { - try - { - return m_eb_uuid[id]; - } - catch - { + EntityBase entity; + if (m_eb_uuid.TryGetValue(id, out entity)) + return entity; + else return null; - } } } set @@ -228,14 +224,11 @@ namespace OpenSim.Region.Framework.Scenes { lock (m_lock) { - try - { - return m_eb_localID[localID]; - } - catch - { + EntityBase entity; + if (m_eb_localID.TryGetValue(localID, out entity)) + return entity; + else return null; - } } } set diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index c44c4c7..c2b9e73 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -2351,12 +2351,6 @@ namespace OpenSim.Region.Framework.Scenes item = InventoryService.GetItem(item); presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/); - IAvatarFactory ava = RequestModuleInterface(); - if (ava != null) - { - ava.UpdateDatabase(remoteClient.AgentId, presence.Appearance); - } - } return att.UUID; } @@ -2402,12 +2396,6 @@ namespace OpenSim.Region.Framework.Scenes InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = InventoryService.GetItem(item); presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/); - - if (m_AvatarFactory != null) - { - m_log.InfoFormat("[SCENE INVENTORY]: Saving avatar attachment. AgentID:{0} ItemID:{1} AttachmentPoint:{2}", remoteClient.AgentId, itemID, AttachmentPt); - m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); - } } } @@ -2447,12 +2435,13 @@ namespace OpenSim.Region.Framework.Scenes if (TryGetAvatar(remoteClient.AgentId, out presence)) { presence.Appearance.DetachAttachment(itemID); - IAvatarFactory ava = RequestModuleInterface(); - if (ava != null) + + // Save avatar attachment information + if (m_AvatarFactory != null) { - ava.UpdateDatabase(remoteClient.AgentId, presence.Appearance); + m_log.Info("[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId + ", ItemID: " + itemID); + m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); } - } m_sceneGraph.DetachSingleAttachmentToInv(itemID, remoteClient); diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 70b11c3..4f3cc98 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -228,6 +228,10 @@ namespace OpenSim.Region.Framework.Scenes protected IXMLRPC m_xmlrpcModule; protected IWorldComm m_worldCommModule; protected IAvatarFactory m_AvatarFactory; + public IAvatarFactory AvatarFactory + { + get { return m_AvatarFactory; } + } protected IConfigSource m_config; protected IRegionSerialiserModule m_serialiser; protected IInterregionCommsOut m_interregionCommsOut; diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 8ee26c3..e51f6ef 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -467,7 +467,6 @@ namespace OpenSim.Region.Framework.Scenes protected internal void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, bool silent) { // If we can't take it, we can't attach it! - // SceneObjectPart part = m_parentScene.GetSceneObjectPart(objectLocalID); if (part == null) return; @@ -477,9 +476,16 @@ namespace OpenSim.Region.Framework.Scenes return; // Calls attach with a Zero position - // AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false); m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); + + // Save avatar attachment information + ScenePresence presence; + if (m_parentScene.AvatarFactory != null && m_parentScene.TryGetAvatar(remoteClient.AgentId, out presence)) + { + m_log.Info("[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId + ", AttachmentPoint: " + AttachmentPt); + m_parentScene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); + } } public SceneObjectGroup RezSingleAttachment( @@ -574,7 +580,7 @@ namespace OpenSim.Region.Framework.Scenes } - group.SetAttachmentPoint(Convert.ToByte(AttachmentPt)); + group.SetAttachmentPoint((byte)AttachmentPt); group.AbsolutePosition = attachPos; // Saves and gets itemID diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 2153b9b..810dfd1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -899,7 +899,7 @@ namespace OpenSim.Region.Framework.Scenes SetAttachmentPoint(Convert.ToByte(attachmentpoint)); avatar.AddAttachment(this); - m_log.DebugFormat("[SOG]: Added att {0} to avie {1}", UUID, avatar.UUID); + m_log.Debug("[SOG]: Added attachment " + UUID + " to avatar " + avatar.UUID); if (!silent) { -- cgit v1.1 From 1833c6956892f1c8324ecbe0179103bff2079151 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 20 Oct 2009 15:19:19 -0700 Subject: * Removed the unused m_agentUpdates collection and some extra work that was being done for AgentUpdate packets * Start LLUDPClients unpaused (this variable is not being used yet) --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 126 ++++++----------------- 1 file changed, 33 insertions(+), 93 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index bdd80c6..d7113bf 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -128,8 +128,6 @@ namespace OpenSim.Region.Framework.Scenes private bool m_setAlwaysRun; - private bool m_updatesAllowed = true; - private List m_agentUpdates = new List(); private string m_movementAnimation = "DEFAULT"; private long m_animPersistUntil = 0; private bool m_allowFalling = false; @@ -1090,34 +1088,6 @@ namespace OpenSim.Region.Framework.Scenes } - // These methods allow to queue up agent updates (like key presses) - // until all attachment scripts are running and the animations from - // AgentDataUpdate have been started. It is essential for combat - // devices, weapons and AOs that keypresses are not processed - // until scripts that are potentially interested in them are - // up and running and that animations a script knows to be running - // from before a crossing are running again - // - public void LockAgentUpdates() - { - m_updatesAllowed = false; - } - - public void UnlockAgentUpdates() - { - lock (m_agentUpdates) - { - if (m_updatesAllowed == false) - { - foreach (AgentUpdateArgs a in m_agentUpdates) - RealHandleAgentUpdate(ControllingClient, a); - m_agentUpdates.Clear(); - m_updatesAllowed = true; - } - } - } - - /// /// Callback for the Camera view block check. Gets called with the results of the camera view block test /// hitYN is true when there's something in the way. @@ -1155,49 +1125,30 @@ namespace OpenSim.Region.Framework.Scenes } } + Array m_dirControlFlags = Enum.GetValues(typeof(Dir_ControlFlags)); + /// /// This is the event handler for client movement. If a client is moving, this event is triggering. /// public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) { - const int AGENT_UPDATE_TIMEOUT_MS = 1000 * 3; - - if (System.Threading.Monitor.TryEnter(m_agentUpdates, AGENT_UPDATE_TIMEOUT_MS)) - { - try - { - if (m_updatesAllowed) - { - RealHandleAgentUpdate(remoteClient, agentData); - return; - } - - m_agentUpdates.Add(agentData); - } - finally { System.Threading.Monitor.Exit(m_agentUpdates); } - } - } - - private void RealHandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) - { //if (m_isChildAgent) //{ // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); // return; //} - - m_movementUpdateCount++; - if (m_movementUpdateCount >= int.MaxValue) - m_movementUpdateCount = 1; + m_perfMonMS = Environment.TickCount; + ++m_movementUpdateCount; + if (m_movementUpdateCount < 1) + m_movementUpdateCount = 1; // Must check for standing up even when PhysicsActor is null, // since sitting currently removes avatar from physical scene //m_log.Debug("agentPos:" + AbsolutePosition.ToString()); // This is irritating. Really. - if (!AbsolutePosition.IsFinite()) { RemoveFromPhysicalScene(); @@ -1218,19 +1169,17 @@ namespace OpenSim.Region.Framework.Scenes { m_LastFinitePos = m_pos; } - //m_physicsActor.AddForce(new PhysicsVector(999999999, 99999999, 999999999999999), true); + //m_physicsActor.AddForce(new PhysicsVector(999999999, 99999999, 999999999999999), true); //ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y); //if (land != null) //{ - //if (land.landData.landingType == (byte)1 && land.landData.userLocation != Vector3.Zero) - //{ - // agent.startpos = land.landData.userLocation; - //} + //if (land.landData.landingType == (byte)1 && land.landData.userLocation != Vector3.Zero) + //{ + // agent.startpos = land.landData.userLocation; + //} //} - - m_perfMonMS = Environment.TickCount; uint flags = agentData.ControlFlags; Quaternion bodyRotation = agentData.BodyRotation; @@ -1253,7 +1202,7 @@ namespace OpenSim.Region.Framework.Scenes // The Agent's Draw distance setting m_DrawDistance = agentData.Far; - if ((flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0) + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0) { StandUp(); } @@ -1261,14 +1210,13 @@ namespace OpenSim.Region.Framework.Scenes // Check if Client has camera in 'follow cam' or 'build' mode. Vector3 camdif = (Vector3.One * m_bodyRot - Vector3.One * CameraRotation); - m_followCamAuto = ((m_CameraUpAxis.Z > 0.959f && m_CameraUpAxis.Z < 0.98f) + m_followCamAuto = ((m_CameraUpAxis.Z > 0.959f && m_CameraUpAxis.Z < 0.98f) && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false; //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto); // Raycast from the avatar's head to the camera to see if there's anything blocking the view if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast()) { - if (m_followCamAuto) { Vector3 headadjustment = new Vector3(0, 0, 0.3f); @@ -1276,24 +1224,18 @@ namespace OpenSim.Region.Framework.Scenes } } - m_mouseLook = (flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0; - - - + m_mouseLook = (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0; m_leftButtonDown = (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0; - - lock (scriptedcontrols) { if (scriptedcontrols.Count > 0) { SendControlToScripts(flags); flags = RemoveIgnoredControls(flags, IgnoredControls); - } } - + if (PhysicsActor == null) { return; @@ -1302,7 +1244,7 @@ namespace OpenSim.Region.Framework.Scenes if (m_autopilotMoving) CheckAtSitTarget(); - if ((flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) { // TODO: This doesn't prevent the user from walking yet. // Setting parent ID would fix this, if we knew what value @@ -1335,13 +1277,13 @@ namespace OpenSim.Region.Framework.Scenes PhysicsActor.Flying = false; else PhysicsActor.Flying = ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); - + if (PhysicsActor.Flying != oldflying) { update_movementflag = true; } } - + if (q != m_bodyRot) { m_bodyRot = q; @@ -1357,15 +1299,15 @@ namespace OpenSim.Region.Framework.Scenes // use camera up angle when in mouselook and not flying or when holding the left mouse button down and not flying // this prevents 'jumping' in inappropriate situations. - if ((m_mouseLook && !m_physicsActor.Flying) || (m_leftButtonDown && !m_physicsActor.Flying)) + if ((m_mouseLook && !m_physicsActor.Flying) || (m_leftButtonDown && !m_physicsActor.Flying)) dirVectors = GetWalkDirectionVectors(); else dirVectors = Dir_Vectors; - foreach (Dir_ControlFlags DCF in Enum.GetValues(typeof (Dir_ControlFlags))) + foreach (Dir_ControlFlags DCF in m_dirControlFlags) { - if ((flags & (uint) DCF) != 0) + if ((flags & (uint)DCF) != 0) { bResetMoveToPosition = true; DCFlagKeyPressed = true; @@ -1377,18 +1319,18 @@ namespace OpenSim.Region.Framework.Scenes { // Why did I get this? } - - if ((m_movementflag & (uint) DCF) == 0) + + if ((m_movementflag & (uint)DCF) == 0) { - m_movementflag += (byte) (uint) DCF; + m_movementflag += (byte)(uint)DCF; update_movementflag = true; } } else { - if ((m_movementflag & (uint) DCF) != 0) + if ((m_movementflag & (uint)DCF) != 0) { - m_movementflag -= (byte) (uint) DCF; + m_movementflag -= (byte)(uint)DCF; update_movementflag = true; } else @@ -1479,14 +1421,12 @@ namespace OpenSim.Region.Framework.Scenes } catch (Exception) { - //Avoid system crash, can be slower but... } - } } } - + // Cause the avatar to stop flying if it's colliding // with something with the down arrow pressed. @@ -1494,8 +1434,8 @@ namespace OpenSim.Region.Framework.Scenes if (m_physicsActor != null && m_physicsActor.Flying && !m_forceFly) { // Are the landing controls requirements filled? - bool controlland = (((flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || - ((flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); + bool controlland = (((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || + ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); // Are the collision requirements fulfilled? bool colliding = (m_physicsActor.IsColliding == true); @@ -1508,10 +1448,10 @@ namespace OpenSim.Region.Framework.Scenes if (update_movementflag || (update_rotation && DCFlagKeyPressed)) { -// m_log.DebugFormat("{0} {1}", update_movementflag, (update_rotation && DCFlagKeyPressed)); -// m_log.DebugFormat( -// "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); - + // m_log.DebugFormat("{0} {1}", update_movementflag, (update_rotation && DCFlagKeyPressed)); + // m_log.DebugFormat( + // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); + AddNewMovement(agent_control_v3, q); if (update_movementflag) -- cgit v1.1 From 45dc4e0a5442d1d03f7387164070145386a9b4e1 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 20 Oct 2009 18:19:17 -0700 Subject: * Added a sanity check to GetScriptAssemblies() and GetScriptStates() for the case where no scripting engine is enabled * Added TokenBucket.cs to OpenSim, with some fixes for setting a more accurate MaxBurst value and getting a more accurate Content value (by Drip()ing each get) --- .../Framework/Scenes/SceneObjectPartInventory.cs | 26 +++++++++++++--------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 098e010..f4ca877 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -871,12 +871,15 @@ namespace OpenSim.Region.Framework.Scenes { foreach (IScriptModule e in engines) { - string n = e.GetAssemblyName(item.ItemID); - if (n != "") + if (e != null) { - if (!ret.Contains(n)) - ret.Add(n); - break; + string n = e.GetAssemblyName(item.ItemID); + if (n != String.Empty) + { + if (!ret.Contains(n)) + ret.Add(n); + break; + } } } } @@ -898,12 +901,15 @@ namespace OpenSim.Region.Framework.Scenes { foreach (IScriptModule e in engines) { - string n = e.GetXMLState(item.ItemID); - if (n != "") + if (e != null) { - if (!ret.ContainsKey(item.ItemID)) - ret[item.ItemID] = n; - break; + string n = e.GetXMLState(item.ItemID); + if (n != String.Empty) + { + if (!ret.ContainsKey(item.ItemID)) + ret[item.ItemID] = n; + break; + } } } } -- cgit v1.1