diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 134 |
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 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using System.Timers; | ||
31 | using OpenMetaverse; | 32 | using OpenMetaverse; |
32 | using log4net; | 33 | using log4net; |
33 | using OpenSim.Framework; | 34 | using 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 | } |