aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/ScenePresence.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs134
1 files changed, 123 insertions, 11 deletions
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}