aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs48
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs134
4 files changed, 151 insertions, 39 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 49c1ebf..70b11c3 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 {
@@ -349,13 +357,6 @@ namespace OpenSim.Region.Framework.Scenes
349 get { return m_defaultScriptEngine; } 357 get { return m_defaultScriptEngine; }
350 } 358 }
351 359
352 // Reference to all of the agents in the scene (root and child)
353 protected Dictionary<UUID, ScenePresence> m_scenePresences
354 {
355 get { return m_sceneGraph.ScenePresences; }
356 set { m_sceneGraph.ScenePresences = value; }
357 }
358
359 public EntityManager Entities 360 public EntityManager Entities
360 { 361 {
361 get { return m_sceneGraph.Entities; } 362 get { return m_sceneGraph.Entities; }
@@ -542,6 +543,11 @@ namespace OpenSim.Region.Framework.Scenes
542 m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; 543 m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
543 break; 544 break;
544 } 545 }
546
547 m_reprioritization_enabled = interest_management_config.GetBoolean("ReprioritizationEnabled", true);
548 m_reprioritization_interval = interest_management_config.GetDouble("ReprioritizationInterval", 5000.0);
549 m_root_reprioritization_distance = interest_management_config.GetDouble("RootReprioritizationDistance", 10.0);
550 m_child_reprioritization_distance = interest_management_config.GetDouble("ChildReprioritizationDistance", 20.0);
545 } 551 }
546 552
547 m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme"); 553 m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme");
@@ -1170,14 +1176,13 @@ namespace OpenSim.Region.Framework.Scenes
1170 /// <param name="stats">Stats on the Simulator's performance</param> 1176 /// <param name="stats">Stats on the Simulator's performance</param>
1171 private void SendSimStatsPackets(SimStats stats) 1177 private void SendSimStatsPackets(SimStats stats)
1172 { 1178 {
1173 List<ScenePresence> StatSendAgents = GetScenePresences(); 1179 ForEachScenePresence(
1174 foreach (ScenePresence agent in StatSendAgents) 1180 delegate(ScenePresence agent)
1175 {
1176 if (!agent.IsChildAgent)
1177 { 1181 {
1178 agent.ControllingClient.SendSimStats(stats); 1182 if (!agent.IsChildAgent)
1183 agent.ControllingClient.SendSimStats(stats);
1179 } 1184 }
1180 } 1185 );
1181 } 1186 }
1182 1187
1183 /// <summary> 1188 /// <summary>
@@ -3488,10 +3493,8 @@ namespace OpenSim.Region.Framework.Scenes
3488 { 3493 {
3489 ScenePresence presence; 3494 ScenePresence presence;
3490 3495
3491 lock (m_scenePresences) 3496 lock (m_sceneGraph.ScenePresences)
3492 { 3497 m_sceneGraph.ScenePresences.TryGetValue(agentID, out presence);
3493 m_scenePresences.TryGetValue(agentID, out presence);
3494 }
3495 3498
3496 if (presence != null) 3499 if (presence != null)
3497 { 3500 {
@@ -3701,12 +3704,9 @@ namespace OpenSim.Region.Framework.Scenes
3701 public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position, 3704 public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position,
3702 Vector3 lookAt, uint teleportFlags) 3705 Vector3 lookAt, uint teleportFlags)
3703 { 3706 {
3704 ScenePresence sp = null; 3707 ScenePresence sp;
3705 lock (m_scenePresences) 3708 lock (m_sceneGraph.ScenePresences)
3706 { 3709 m_sceneGraph.ScenePresences.TryGetValue(remoteClient.AgentId, out sp);
3707 if (m_scenePresences.ContainsKey(remoteClient.AgentId))
3708 sp = m_scenePresences[remoteClient.AgentId];
3709 }
3710 3710
3711 if (sp != null) 3711 if (sp != null)
3712 { 3712 {
@@ -4155,7 +4155,7 @@ namespace OpenSim.Region.Framework.Scenes
4155 public void ForEachScenePresence(Action<ScenePresence> action) 4155 public void ForEachScenePresence(Action<ScenePresence> action)
4156 { 4156 {
4157 // We don't want to try to send messages if there are no avatars. 4157 // We don't want to try to send messages if there are no avatars.
4158 if (m_scenePresences != null) 4158 if (m_sceneGraph != null && m_sceneGraph.ScenePresences != null)
4159 { 4159 {
4160 try 4160 try
4161 { 4161 {
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/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) {
3791 if (ParentGroup.RootPart == this) 3791 if (ParentGroup.RootPart == this)
3792 lPos = AbsolutePosition; 3792 lPos = AbsolutePosition;
3793 } 3793 }
3794 3794
3795 // Causes this thread to dig into the Client Thread Data. 3795 // Causes this thread to dig into the Client Thread Data.
3796 // Remember your locking here! 3796 // Remember your locking here!
3797 remoteClient.SendPrimTerseUpdate(new SendPrimitiveTerseData(m_regionHandle, 3797 remoteClient.SendPrimTerseUpdate(new SendPrimitiveTerseData(m_regionHandle,
3798 (ushort)(m_parentGroup.GetTimeDilation() * 3798 (ushort)(m_parentGroup.GetTimeDilation() *
3799 (float)ushort.MaxValue), LocalId, lPos, 3799 (float)ushort.MaxValue), LocalId, lPos,
3800 RotationOffset, Velocity, 3800 RotationOffset, Velocity, Acceleration,
3801 RotationalVelocity, state, FromItemID, 3801 RotationalVelocity, state, FromItemID,
3802 OwnerID, (int)AttachmentPoint, ParentGroup.GetUpdatePriority(remoteClient))); 3802 OwnerID, (int)AttachmentPoint, null, ParentGroup.GetUpdatePriority(remoteClient)));
3803 } 3803 }
3804 3804
3805 public void AddScriptLPS(int count) 3805 public void AddScriptLPS(int count)
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 9d13ad4..bdd80c6 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...
@@ -1147,15 +1160,21 @@ namespace OpenSim.Region.Framework.Scenes
1147 /// </summary> 1160 /// </summary>
1148 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1161 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1149 { 1162 {
1150 lock (m_agentUpdates) 1163 const int AGENT_UPDATE_TIMEOUT_MS = 1000 * 3;
1164
1165 if (System.Threading.Monitor.TryEnter(m_agentUpdates, AGENT_UPDATE_TIMEOUT_MS))
1151 { 1166 {
1152 if (m_updatesAllowed) 1167 try
1153 { 1168 {
1154 RealHandleAgentUpdate(remoteClient, agentData); 1169 if (m_updatesAllowed)
1155 return; 1170 {
1171 RealHandleAgentUpdate(remoteClient, agentData);
1172 return;
1173 }
1174
1175 m_agentUpdates.Add(agentData);
1156 } 1176 }
1157 1177 finally { System.Threading.Monitor.Exit(m_agentUpdates); }
1158 m_agentUpdates.Add(agentData);
1159 } 1178 }
1160 } 1179 }
1161 1180
@@ -1219,6 +1238,11 @@ namespace OpenSim.Region.Framework.Scenes
1219 // Camera location in world. We'll need to raytrace 1238 // Camera location in world. We'll need to raytrace
1220 // from this location from time to time. 1239 // from this location from time to time.
1221 m_CameraCenter = agentData.CameraCenter; 1240 m_CameraCenter = agentData.CameraCenter;
1241 if (Vector3.Distance(m_lastCameraCenter, m_CameraCenter) >= Scene.RootReprioritizationDistance)
1242 {
1243 ReprioritizeUpdates();
1244 m_lastCameraCenter = m_CameraCenter;
1245 }
1222 1246
1223 // Use these three vectors to figure out what the agent is looking at 1247 // Use these three vectors to figure out what the agent is looking at
1224 // Convert it to a Matrix and/or Quaternion 1248 // Convert it to a Matrix and/or Quaternion
@@ -2453,7 +2477,7 @@ namespace OpenSim.Region.Framework.Scenes
2453 pos.Z -= m_appearance.HipOffset; 2477 pos.Z -= m_appearance.HipOffset;
2454 2478
2455 remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 2479 remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
2456 pos, m_velocity, m_rotation, m_uuid, GetUpdatePriority(remoteClient))); 2480 pos, m_velocity, Vector3.Zero, m_rotation, Vector4.Zero, m_uuid, null, GetUpdatePriority(remoteClient)));
2457 2481
2458 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); 2482 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS);
2459 m_scene.StatsReporter.AddAgentUpdates(1); 2483 m_scene.StatsReporter.AddAgentUpdates(1);
@@ -2823,7 +2847,7 @@ namespace OpenSim.Region.Framework.Scenes
2823 } 2847 }
2824 2848
2825 // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m 2849 // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m
2826 if (Util.GetDistanceTo(AbsolutePosition,m_LastChildAgentUpdatePosition) > 32) 2850 if (Util.GetDistanceTo(AbsolutePosition, m_LastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance)
2827 { 2851 {
2828 ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); 2852 ChildAgentDataUpdate cadu = new ChildAgentDataUpdate();
2829 cadu.ActiveGroupID = UUID.Zero.Guid; 2853 cadu.ActiveGroupID = UUID.Zero.Guid;
@@ -3118,6 +3142,12 @@ namespace OpenSim.Region.Framework.Scenes
3118 if (cAgentData.Position != new Vector3(-1, -1, -1)) // UGH!! 3142 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); 3143 m_pos = new Vector3(cAgentData.Position.X + shiftx, cAgentData.Position.Y + shifty, cAgentData.Position.Z);
3120 3144
3145 if (Vector3.Distance(AbsolutePosition, posLastSignificantMove) >= Scene.ChildReprioritizationDistance)
3146 {
3147 posLastSignificantMove = AbsolutePosition;
3148 ReprioritizeUpdates();
3149 }
3150
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 3151 // 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; 3152 m_CameraCenter = cAgentData.Center;
3123 3153
@@ -3480,7 +3510,6 @@ namespace OpenSim.Region.Framework.Scenes
3480 3510
3481 public void Close() 3511 public void Close()
3482 { 3512 {
3483
3484 lock (m_attachments) 3513 lock (m_attachments)
3485 { 3514 {
3486 // Delete attachments from scene 3515 // Delete attachments from scene
@@ -3498,10 +3527,19 @@ namespace OpenSim.Region.Framework.Scenes
3498 { 3527 {
3499 m_knownChildRegions.Clear(); 3528 m_knownChildRegions.Clear();
3500 } 3529 }
3530
3531 lock (m_reprioritization_timer)
3532 {
3533 m_reprioritization_timer.Enabled = false;
3534 m_reprioritization_timer.Elapsed -= new ElapsedEventHandler(Reprioritize);
3535 }
3536 // I don't get it but mono crashes when you try to dispose of this timer,
3537 // unsetting the elapsed callback should be enough to allow for cleanup however.
3538 //m_reprioritizationTimer.Dispose();
3539
3501 m_sceneViewer.Close(); 3540 m_sceneViewer.Close();
3502 3541
3503 RemoveFromPhysicalScene(); 3542 RemoveFromPhysicalScene();
3504 GC.Collect();
3505 } 3543 }
3506 3544
3507 public ScenePresence() 3545 public ScenePresence()
@@ -3913,5 +3951,79 @@ namespace OpenSim.Region.Framework.Scenes
3913 { 3951 {
3914 return Vector3.Distance(AbsolutePosition, position); 3952 return Vector3.Distance(AbsolutePosition, position);
3915 } 3953 }
3954
3955 private double GetSOGUpdatePriority(SceneObjectGroup sog)
3956 {
3957 switch (Scene.UpdatePrioritizationScheme)
3958 {
3959 case Scene.UpdatePrioritizationSchemes.Time:
3960 throw new InvalidOperationException("UpdatePrioritizationScheme for time not supported for reprioritization");
3961 case Scene.UpdatePrioritizationSchemes.Distance:
3962 return sog.GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition);
3963 case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance:
3964 return sog.GetPriorityBySimpleAngularDistance((IsChildAgent) ? AbsolutePosition : CameraPosition);
3965 default:
3966 throw new InvalidOperationException("UpdatePrioritizationScheme not defined");
3967 }
3968 }
3969
3970 private double UpdatePriority(UpdatePriorityData data)
3971 {
3972 EntityBase entity;
3973 SceneObjectGroup group;
3974
3975 if (Scene.Entities.TryGetValue(data.localID, out entity))
3976 {
3977 group = entity as SceneObjectGroup;
3978 if (group != null)
3979 return GetSOGUpdatePriority(group);
3980
3981 ScenePresence presence = entity as ScenePresence;
3982 if (presence == null)
3983 throw new InvalidOperationException("entity found is neither SceneObjectGroup nor ScenePresence");
3984 switch (Scene.UpdatePrioritizationScheme)
3985 {
3986 case Scene.UpdatePrioritizationSchemes.Time:
3987 throw new InvalidOperationException("UpdatePrioritization for time not supported for reprioritization");
3988 case Scene.UpdatePrioritizationSchemes.Distance:
3989 case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance:
3990 return GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition);
3991 default:
3992 throw new InvalidOperationException("UpdatePrioritizationScheme not defined");
3993 }
3994 }
3995 else
3996 {
3997 group = Scene.SceneGraph.GetGroupByPrim(data.localID);
3998 if (group != null)
3999 return GetSOGUpdatePriority(group);
4000 }
4001 return double.NaN;
4002 }
4003
4004 private void ReprioritizeUpdates()
4005 {
4006 if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != Scene.UpdatePrioritizationSchemes.Time)
4007 {
4008 lock (m_reprioritization_timer)
4009 {
4010 if (!m_reprioritizing)
4011 m_reprioritization_timer.Enabled = m_reprioritizing = true;
4012 else
4013 m_reprioritization_called = true;
4014 }
4015 }
4016 }
4017
4018 private void Reprioritize(object sender, ElapsedEventArgs e)
4019 {
4020 m_controllingClient.ReprioritizeUpdates(StateUpdateTypes.All, UpdatePriority);
4021
4022 lock (m_reprioritization_timer)
4023 {
4024 m_reprioritization_timer.Enabled = m_reprioritizing = m_reprioritization_called;
4025 m_reprioritization_called = false;
4026 }
4027 }
3916 } 4028 }
3917} 4029}