aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs107
-rw-r--r--OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs13
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs112
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs5
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs4
7 files changed, 227 insertions, 20 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 43c3c7c..3b2a604 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -3582,37 +3582,51 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3582 3582
3583 void HandleQueueEmpty(ThrottleOutPacketType queue) 3583 void HandleQueueEmpty(ThrottleOutPacketType queue)
3584 { 3584 {
3585 int count = 0;
3586
3587 switch (queue) 3585 switch (queue)
3588 { 3586 {
3589 case ThrottleOutPacketType.Texture: 3587 case ThrottleOutPacketType.Texture:
3590 ProcessTextureRequests(); 3588 ProcessTextureRequests();
3591 break; 3589 break;
3592 case ThrottleOutPacketType.Task: 3590 case ThrottleOutPacketType.Task:
3593 lock (m_avatarTerseUpdates.SyncRoot) 3591 if (Monitor.TryEnter(m_avatarTerseUpdates.SyncRoot, 1))
3594 count = m_avatarTerseUpdates.Count;
3595 if (count > 0)
3596 { 3592 {
3597 ProcessAvatarTerseUpdates(); 3593 try
3598 return; 3594 {
3595 if (m_avatarTerseUpdates.Count > 0)
3596 {
3597
3598 ProcessAvatarTerseUpdates();
3599 return;
3600 }
3601 }
3602 finally { Monitor.Exit(m_avatarTerseUpdates.SyncRoot); }
3599 } 3603 }
3600 break; 3604 break;
3601 case ThrottleOutPacketType.State: 3605 case ThrottleOutPacketType.State:
3602 lock (m_primFullUpdates.SyncRoot) 3606 if (Monitor.TryEnter(m_primFullUpdates.SyncRoot, 1))
3603 count = m_primFullUpdates.Count;
3604 if (count > 0)
3605 { 3607 {
3606 ProcessPrimFullUpdates(); 3608 try
3607 return; 3609 {
3610 if (m_primFullUpdates.Count > 0)
3611 {
3612 ProcessPrimFullUpdates();
3613 return;
3614 }
3615 }
3616 finally { Monitor.Exit(m_primFullUpdates.SyncRoot); }
3608 } 3617 }
3609 3618
3610 lock (m_primTerseUpdates.SyncRoot) 3619 if (Monitor.TryEnter(m_primTerseUpdates.SyncRoot, 1))
3611 count = m_primTerseUpdates.Count;
3612 if (count > 0)
3613 { 3620 {
3614 ProcessPrimTerseUpdates(); 3621 try
3615 return; 3622 {
3623 if (m_primTerseUpdates.Count > 0)
3624 {
3625 ProcessPrimTerseUpdates();
3626 return;
3627 }
3628 }
3629 finally { Monitor.Exit(m_primTerseUpdates.SyncRoot); }
3616 } 3630 }
3617 break; 3631 break;
3618 } 3632 }
@@ -3703,6 +3717,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3703 } 3717 }
3704 } 3718 }
3705 3719
3720 public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler)
3721 {
3722 PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler terse_update_priority_handler =
3723 delegate(ref double priority, uint local_id)
3724 {
3725 priority = handler(new UpdatePriorityData(priority, local_id));
3726 return priority != double.NaN;
3727 };
3728 PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler update_priority_handler =
3729 delegate(ref double priority, uint local_id)
3730 {
3731 priority = handler(new UpdatePriorityData(priority, local_id));
3732 return priority != double.NaN;
3733 };
3734
3735 if ((type & StateUpdateTypes.AvatarTerse) != 0) {
3736 lock (m_avatarTerseUpdates.SyncRoot)
3737 m_avatarTerseUpdates.Reprioritize(terse_update_priority_handler);
3738 }
3739
3740 if ((type & StateUpdateTypes.PrimitiveFull) != 0) {
3741 lock (m_primFullUpdates.SyncRoot)
3742 m_primFullUpdates.Reprioritize(update_priority_handler);
3743 }
3744
3745 if ((type & StateUpdateTypes.PrimitiveTerse) != 0) {
3746 lock (m_primTerseUpdates.SyncRoot)
3747 m_primTerseUpdates.Reprioritize(terse_update_priority_handler);
3748 }
3749 }
3750
3706 public void FlushPrimUpdates() 3751 public void FlushPrimUpdates()
3707 { 3752 {
3708 while (m_primFullUpdates.Count > 0) 3753 while (m_primFullUpdates.Count > 0)
@@ -10465,6 +10510,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10465 #region PriorityQueue 10510 #region PriorityQueue
10466 private class PriorityQueue<TPriority, TValue> 10511 private class PriorityQueue<TPriority, TValue>
10467 { 10512 {
10513 internal delegate bool UpdatePriorityHandler(ref TPriority priority, uint local_id);
10514
10468 private MinHeap<MinHeapItem>[] heaps = new MinHeap<MinHeapItem>[1]; 10515 private MinHeap<MinHeapItem>[] heaps = new MinHeap<MinHeapItem>[1];
10469 private Dictionary<uint, LookupItem> lookup_table = new Dictionary<uint, LookupItem>(); 10516 private Dictionary<uint, LookupItem> lookup_table = new Dictionary<uint, LookupItem>();
10470 private Comparison<TPriority> comparison; 10517 private Comparison<TPriority> comparison;
@@ -10539,6 +10586,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10539 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); 10586 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString()));
10540 } 10587 }
10541 10588
10589 internal void Reprioritize(UpdatePriorityHandler handler)
10590 {
10591 MinHeapItem item;
10592 TPriority priority;
10593
10594 foreach (LookupItem lookup in new List<LookupItem>(this.lookup_table.Values))
10595 {
10596 if (lookup.Heap.TryGetValue(lookup.Handle, out item))
10597 {
10598 priority = item.Priority;
10599 if (handler(ref priority, item.LocalID))
10600 {
10601 if (lookup.Heap.ContainsHandle(lookup.Handle))
10602 lookup.Heap[lookup.Handle] =
10603 new MinHeapItem(priority, item.Value, item.LocalID);
10604 }
10605 else
10606 {
10607 m_log.Warn("[LLClientView] UpdatePriorityHandle returned false, dropping update");
10608 lookup.Heap.Remove(lookup.Handle);
10609 this.lookup_table.Remove(item.LocalID);
10610 }
10611 }
10612 }
10613 }
10614
10542 #region MinHeapItem 10615 #region MinHeapItem
10543 private struct MinHeapItem : IComparable<MinHeapItem> 10616 private struct MinHeapItem : IComparable<MinHeapItem>
10544 { 10617 {
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
index 3799a02..5a5fcfe 100644
--- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
@@ -527,6 +527,10 @@ namespace OpenSim.Region.Examples.SimpleModule
527 { 527 {
528 } 528 }
529 529
530 public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler)
531 {
532 }
533
530 public void FlushPrimUpdates() 534 public void FlushPrimUpdates()
531 { 535 {
532 } 536 }
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
278 private bool m_firstHeartbeat = true; 278 private bool m_firstHeartbeat = true;
279 279
280 private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; 280 private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
281 private bool m_reprioritization_enabled = true;
282 private double m_reprioritization_interval = 2000.0;
283 private double m_root_reprioritization_distance = 5.0;
284 private double m_child_reprioritization_distance = 10.0;
281 285
282 private object m_deleting_scene_object = new object(); 286 private object m_deleting_scene_object = new object();
283 287
@@ -291,6 +295,10 @@ namespace OpenSim.Region.Framework.Scenes
291 #region Properties 295 #region Properties
292 296
293 public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return this.m_update_prioritization_scheme; } } 297 public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return this.m_update_prioritization_scheme; } }
298 public bool IsReprioritizationEnabled { get { return m_reprioritization_enabled; } }
299 public double ReprioritizationInterval { get { return m_reprioritization_interval; } }
300 public double RootReprioritizationDistance { get { return m_root_reprioritization_distance; } }
301 public double ChildReprioritizationDistance { get { return m_child_reprioritization_distance; } }
294 302
295 public AgentCircuitManager AuthenticateHandler 303 public AgentCircuitManager AuthenticateHandler
296 { 304 {
@@ -542,6 +550,11 @@ namespace OpenSim.Region.Framework.Scenes
542 m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; 550 m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
543 break; 551 break;
544 } 552 }
553
554 m_reprioritization_enabled = interest_management_config.GetBoolean("ReprioritizationEnabled", true);
555 m_reprioritization_interval = interest_management_config.GetDouble("ReprioritizationInterval", 5000.0);
556 m_root_reprioritization_distance = interest_management_config.GetDouble("RootReprioritizationDistance", 10.0);
557 m_child_reprioritization_distance = interest_management_config.GetDouble("ChildReprioritizationDistance", 20.0);
545 } 558 }
546 559
547 m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme"); 560 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
846 /// </summary> 846 /// </summary>
847 /// <param name="localID"></param> 847 /// <param name="localID"></param>
848 /// <returns>null if no scene object group containing that prim is found</returns> 848 /// <returns>null if no scene object group containing that prim is found</returns>
849 private SceneObjectGroup GetGroupByPrim(uint localID) 849 public SceneObjectGroup GetGroupByPrim(uint localID)
850 { 850 {
851 if (Entities.ContainsKey(localID)) 851 if (Entities.ContainsKey(localID))
852 return Entities[localID] as SceneObjectGroup; 852 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 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using System.Timers;
31using OpenMetaverse; 32using OpenMetaverse;
32using log4net; 33using log4net;
33using OpenSim.Framework; 34using OpenSim.Framework;
@@ -172,6 +173,11 @@ namespace OpenSim.Region.Framework.Scenes
172 173
173 // Position of agent's camera in world (region cordinates) 174 // Position of agent's camera in world (region cordinates)
174 protected Vector3 m_CameraCenter = Vector3.Zero; 175 protected Vector3 m_CameraCenter = Vector3.Zero;
176 protected Vector3 m_lastCameraCenter = Vector3.Zero;
177
178 protected Timer m_reprioritization_timer;
179 protected bool m_reprioritizing = false;
180 protected bool m_reprioritization_called = false;
175 181
176 // Use these three vectors to figure out what the agent is looking at 182 // Use these three vectors to figure out what the agent is looking at
177 // Convert it to a Matrix and/or Quaternion 183 // Convert it to a Matrix and/or Quaternion
@@ -639,7 +645,14 @@ namespace OpenSim.Region.Framework.Scenes
639 645
640 m_scriptEngines = m_scene.RequestModuleInterfaces<IScriptModule>(); 646 m_scriptEngines = m_scene.RequestModuleInterfaces<IScriptModule>();
641 647
642 AbsolutePosition = m_controllingClient.StartPos; 648 AbsolutePosition = posLastSignificantMove = m_CameraCenter =
649 m_lastCameraCenter = m_controllingClient.StartPos;
650
651 m_reprioritization_timer = new Timer(world.ReprioritizationInterval);
652 m_reprioritization_timer.Elapsed += new ElapsedEventHandler(Reprioritize);
653 m_reprioritization_timer.AutoReset = false;
654
655
643 AdjustKnownSeeds(); 656 AdjustKnownSeeds();
644 657
645 TrySetMovementAnimation("STAND"); // TODO: I think, this won't send anything, as we are still a child here... 658 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
1219 // Camera location in world. We'll need to raytrace 1232 // Camera location in world. We'll need to raytrace
1220 // from this location from time to time. 1233 // from this location from time to time.
1221 m_CameraCenter = agentData.CameraCenter; 1234 m_CameraCenter = agentData.CameraCenter;
1235 if (Vector3.Distance(m_lastCameraCenter, m_CameraCenter) >= Scene.RootReprioritizationDistance)
1236 {
1237 ReprioritizeUpdates();
1238 m_lastCameraCenter = m_CameraCenter;
1239 }
1222 1240
1223 // Use these three vectors to figure out what the agent is looking at 1241 // Use these three vectors to figure out what the agent is looking at
1224 // Convert it to a Matrix and/or Quaternion 1242 // Convert it to a Matrix and/or Quaternion
@@ -2823,7 +2841,7 @@ namespace OpenSim.Region.Framework.Scenes
2823 } 2841 }
2824 2842
2825 // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m 2843 // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m
2826 if (Util.GetDistanceTo(AbsolutePosition,m_LastChildAgentUpdatePosition) > 32) 2844 if (Util.GetDistanceTo(AbsolutePosition, m_LastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance)
2827 { 2845 {
2828 ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); 2846 ChildAgentDataUpdate cadu = new ChildAgentDataUpdate();
2829 cadu.ActiveGroupID = UUID.Zero.Guid; 2847 cadu.ActiveGroupID = UUID.Zero.Guid;
@@ -3118,6 +3136,12 @@ namespace OpenSim.Region.Framework.Scenes
3118 if (cAgentData.Position != new Vector3(-1, -1, -1)) // UGH!! 3136 if (cAgentData.Position != new Vector3(-1, -1, -1)) // UGH!!
3119 m_pos = new Vector3(cAgentData.Position.X + shiftx, cAgentData.Position.Y + shifty, cAgentData.Position.Z); 3137 m_pos = new Vector3(cAgentData.Position.X + shiftx, cAgentData.Position.Y + shifty, cAgentData.Position.Z);
3120 3138
3139 if (Vector3.Distance(AbsolutePosition, posLastSignificantMove) >= Scene.ChildReprioritizationDistance)
3140 {
3141 posLastSignificantMove = AbsolutePosition;
3142 ReprioritizeUpdates();
3143 }
3144
3121 // 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 3145 // 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
3122 m_CameraCenter = cAgentData.Center; 3146 m_CameraCenter = cAgentData.Center;
3123 3147
@@ -3498,6 +3522,16 @@ namespace OpenSim.Region.Framework.Scenes
3498 { 3522 {
3499 m_knownChildRegions.Clear(); 3523 m_knownChildRegions.Clear();
3500 } 3524 }
3525
3526 lock (m_reprioritization_timer)
3527 {
3528 m_reprioritization_timer.Enabled = false;
3529 m_reprioritization_timer.Elapsed -= new ElapsedEventHandler(Reprioritize);
3530 }
3531 // I don't get it but mono crashes when you try to dispose of this timer,
3532 // unsetting the elapsed callback should be enough to allow for cleanup however.
3533 //m_reprioritizationTimer.Dispose();
3534
3501 m_sceneViewer.Close(); 3535 m_sceneViewer.Close();
3502 3536
3503 RemoveFromPhysicalScene(); 3537 RemoveFromPhysicalScene();
@@ -3913,5 +3947,79 @@ namespace OpenSim.Region.Framework.Scenes
3913 { 3947 {
3914 return Vector3.Distance(AbsolutePosition, position); 3948 return Vector3.Distance(AbsolutePosition, position);
3915 } 3949 }
3950
3951 private double GetSOGUpdatePriority(SceneObjectGroup sog)
3952 {
3953 switch (Scene.UpdatePrioritizationScheme)
3954 {
3955 case Scene.UpdatePrioritizationSchemes.Time:
3956 throw new InvalidOperationException("UpdatePrioritizationScheme for time not supported for reprioritization");
3957 case Scene.UpdatePrioritizationSchemes.Distance:
3958 return sog.GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition);
3959 case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance:
3960 return sog.GetPriorityBySimpleAngularDistance((IsChildAgent) ? AbsolutePosition : CameraPosition);
3961 default:
3962 throw new InvalidOperationException("UpdatePrioritizationScheme not defined");
3963 }
3964 }
3965
3966 private double UpdatePriority(UpdatePriorityData data)
3967 {
3968 EntityBase entity;
3969 SceneObjectGroup group;
3970
3971 if (Scene.Entities.TryGetValue(data.localID, out entity))
3972 {
3973 group = entity as SceneObjectGroup;
3974 if (group != null)
3975 return GetSOGUpdatePriority(group);
3976
3977 ScenePresence presence = entity as ScenePresence;
3978 if (presence == null)
3979 throw new InvalidOperationException("entity found is neither SceneObjectGroup nor ScenePresence");
3980 switch (Scene.UpdatePrioritizationScheme)
3981 {
3982 case Scene.UpdatePrioritizationSchemes.Time:
3983 throw new InvalidOperationException("UpdatePrioritization for time not supported for reprioritization");
3984 case Scene.UpdatePrioritizationSchemes.Distance:
3985 case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance:
3986 return GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition);
3987 default:
3988 throw new InvalidOperationException("UpdatePrioritizationScheme not defined");
3989 }
3990 }
3991 else
3992 {
3993 group = Scene.SceneGraph.GetGroupByPrim(data.localID);
3994 if (group != null)
3995 return GetSOGUpdatePriority(group);
3996 }
3997 return double.NaN;
3998 }
3999
4000 private void ReprioritizeUpdates()
4001 {
4002 if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != Scene.UpdatePrioritizationSchemes.Time)
4003 {
4004 lock (m_reprioritization_timer)
4005 {
4006 if (!m_reprioritizing)
4007 m_reprioritization_timer.Enabled = m_reprioritizing = true;
4008 else
4009 m_reprioritization_called = true;
4010 }
4011 }
4012 }
4013
4014 private void Reprioritize(object sender, ElapsedEventArgs e)
4015 {
4016 m_controllingClient.ReprioritizeUpdates(StateUpdateTypes.All, UpdatePriority);
4017
4018 lock (m_reprioritization_timer)
4019 {
4020 m_reprioritization_timer.Enabled = m_reprioritizing = m_reprioritization_called;
4021 m_reprioritization_called = false;
4022 }
4023 }
3916 } 4024 }
3917} 4025}
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 1a24dec..df03b8d 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -1048,6 +1048,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
1048 1048
1049 } 1049 }
1050 1050
1051 public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler)
1052 {
1053
1054 }
1055
1051 public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, bool fetchFolders, bool fetchItems) 1056 public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, bool fetchFolders, bool fetchItems)
1052 { 1057 {
1053 1058
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index 6c58f2d..f7cadaa 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -616,6 +616,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC
616 { 616 {
617 } 617 }
618 618
619 public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler)
620 {
621 }
622
619 public void FlushPrimUpdates() 623 public void FlushPrimUpdates()
620 { 624 {
621 } 625 }