diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 197 |
1 files changed, 169 insertions, 28 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index c25fa55..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 |
@@ -403,12 +409,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
403 | set { m_parentPosition = value; } | 409 | set { m_parentPosition = value; } |
404 | } | 410 | } |
405 | 411 | ||
406 | public int MaxPrimsPerFrame | ||
407 | { | ||
408 | get { return m_sceneViewer.MaxPrimsPerFrame; } | ||
409 | set { m_sceneViewer.MaxPrimsPerFrame = value; } | ||
410 | } | ||
411 | |||
412 | /// <summary> | 412 | /// <summary> |
413 | /// Absolute position of this avatar in 'region cordinates' | 413 | /// Absolute position of this avatar in 'region cordinates' |
414 | /// </summary> | 414 | /// </summary> |
@@ -645,7 +645,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
645 | 645 | ||
646 | m_scriptEngines = m_scene.RequestModuleInterfaces<IScriptModule>(); | 646 | m_scriptEngines = m_scene.RequestModuleInterfaces<IScriptModule>(); |
647 | 647 | ||
648 | 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 | |||
649 | AdjustKnownSeeds(); | 656 | AdjustKnownSeeds(); |
650 | 657 | ||
651 | 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... |
@@ -1153,15 +1160,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
1153 | /// </summary> | 1160 | /// </summary> |
1154 | public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) | 1161 | public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) |
1155 | { | 1162 | { |
1156 | 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)) | ||
1157 | { | 1166 | { |
1158 | if (m_updatesAllowed) | 1167 | try |
1159 | { | 1168 | { |
1160 | RealHandleAgentUpdate(remoteClient, agentData); | 1169 | if (m_updatesAllowed) |
1161 | return; | 1170 | { |
1171 | RealHandleAgentUpdate(remoteClient, agentData); | ||
1172 | return; | ||
1173 | } | ||
1174 | |||
1175 | m_agentUpdates.Add(agentData); | ||
1162 | } | 1176 | } |
1163 | 1177 | finally { System.Threading.Monitor.Exit(m_agentUpdates); } | |
1164 | m_agentUpdates.Add(agentData); | ||
1165 | } | 1178 | } |
1166 | } | 1179 | } |
1167 | 1180 | ||
@@ -1225,6 +1238,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1225 | // Camera location in world. We'll need to raytrace | 1238 | // Camera location in world. We'll need to raytrace |
1226 | // from this location from time to time. | 1239 | // from this location from time to time. |
1227 | 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 | } | ||
1228 | 1246 | ||
1229 | // 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 |
1230 | // Convert it to a Matrix and/or Quaternion | 1248 | // Convert it to a Matrix and/or Quaternion |
@@ -2456,11 +2474,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
2456 | m_perfMonMS = Environment.TickCount; | 2474 | m_perfMonMS = Environment.TickCount; |
2457 | 2475 | ||
2458 | Vector3 pos = m_pos; | 2476 | Vector3 pos = m_pos; |
2459 | Vector3 vel = Velocity; | ||
2460 | Quaternion rot = m_bodyRot; | ||
2461 | pos.Z -= m_appearance.HipOffset; | 2477 | pos.Z -= m_appearance.HipOffset; |
2462 | remoteClient.SendAvatarTerseUpdate(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, new Vector3(pos.X, pos.Y, pos.Z), | 2478 | |
2463 | new Vector3(vel.X, vel.Y, vel.Z), rot, m_uuid); | 2479 | remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, |
2480 | pos, m_velocity, Vector3.Zero, m_rotation, Vector4.Zero, m_uuid, null, GetUpdatePriority(remoteClient))); | ||
2464 | 2481 | ||
2465 | m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); | 2482 | m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); |
2466 | m_scene.StatsReporter.AddAgentUpdates(1); | 2483 | m_scene.StatsReporter.AddAgentUpdates(1); |
@@ -2474,7 +2491,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2474 | { | 2491 | { |
2475 | m_perfMonMS = Environment.TickCount; | 2492 | m_perfMonMS = Environment.TickCount; |
2476 | 2493 | ||
2477 | m_scene.Broadcast(SendTerseUpdateToClient); | 2494 | m_scene.ForEachClient(SendTerseUpdateToClient); |
2478 | 2495 | ||
2479 | m_lastVelocity = m_velocity; | 2496 | m_lastVelocity = m_velocity; |
2480 | lastPhysPos = AbsolutePosition; | 2497 | lastPhysPos = AbsolutePosition; |
@@ -2566,9 +2583,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2566 | Vector3 pos = m_pos; | 2583 | Vector3 pos = m_pos; |
2567 | pos.Z -= m_appearance.HipOffset; | 2584 | pos.Z -= m_appearance.HipOffset; |
2568 | 2585 | ||
2569 | remoteAvatar.m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, | 2586 | remoteAvatar.m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, |
2570 | LocalId, m_pos, m_appearance.Texture.GetBytes(), | 2587 | LocalId, m_pos, m_appearance.Texture.GetBytes(), |
2571 | m_parentID, rot); | 2588 | m_parentID, rot)); |
2572 | m_scene.StatsReporter.AddAgentUpdates(1); | 2589 | m_scene.StatsReporter.AddAgentUpdates(1); |
2573 | } | 2590 | } |
2574 | 2591 | ||
@@ -2637,8 +2654,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2637 | Vector3 pos = m_pos; | 2654 | Vector3 pos = m_pos; |
2638 | pos.Z -= m_appearance.HipOffset; | 2655 | pos.Z -= m_appearance.HipOffset; |
2639 | 2656 | ||
2640 | m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, | 2657 | m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, |
2641 | m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot); | 2658 | m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot)); |
2642 | 2659 | ||
2643 | if (!m_isChildAgent) | 2660 | if (!m_isChildAgent) |
2644 | { | 2661 | { |
@@ -2744,8 +2761,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2744 | } | 2761 | } |
2745 | 2762 | ||
2746 | Quaternion rot = m_bodyRot; | 2763 | Quaternion rot = m_bodyRot; |
2747 | m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, | 2764 | m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, |
2748 | m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot); | 2765 | m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot)); |
2749 | 2766 | ||
2750 | } | 2767 | } |
2751 | 2768 | ||
@@ -2776,7 +2793,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2776 | if (m_isChildAgent) | 2793 | if (m_isChildAgent) |
2777 | return; | 2794 | return; |
2778 | 2795 | ||
2779 | m_scene.Broadcast( | 2796 | m_scene.ForEachClient( |
2780 | delegate(IClientAPI client) { client.SendAnimations(animations, seqs, m_controllingClient.AgentId, objectIDs); }); | 2797 | delegate(IClientAPI client) { client.SendAnimations(animations, seqs, m_controllingClient.AgentId, objectIDs); }); |
2781 | } | 2798 | } |
2782 | 2799 | ||
@@ -2830,7 +2847,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2830 | } | 2847 | } |
2831 | 2848 | ||
2832 | // 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 |
2833 | if (Util.GetDistanceTo(AbsolutePosition,m_LastChildAgentUpdatePosition) > 32) | 2850 | if (Util.GetDistanceTo(AbsolutePosition, m_LastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance) |
2834 | { | 2851 | { |
2835 | ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); | 2852 | ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); |
2836 | cadu.ActiveGroupID = UUID.Zero.Guid; | 2853 | cadu.ActiveGroupID = UUID.Zero.Guid; |
@@ -3125,6 +3142,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
3125 | if (cAgentData.Position != new Vector3(-1, -1, -1)) // UGH!! | 3142 | if (cAgentData.Position != new Vector3(-1, -1, -1)) // UGH!! |
3126 | 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); |
3127 | 3144 | ||
3145 | if (Vector3.Distance(AbsolutePosition, posLastSignificantMove) >= Scene.ChildReprioritizationDistance) | ||
3146 | { | ||
3147 | posLastSignificantMove = AbsolutePosition; | ||
3148 | ReprioritizeUpdates(); | ||
3149 | } | ||
3150 | |||
3128 | // 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 |
3129 | m_CameraCenter = cAgentData.Center; | 3152 | m_CameraCenter = cAgentData.Center; |
3130 | 3153 | ||
@@ -3487,7 +3510,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
3487 | 3510 | ||
3488 | public void Close() | 3511 | public void Close() |
3489 | { | 3512 | { |
3490 | |||
3491 | lock (m_attachments) | 3513 | lock (m_attachments) |
3492 | { | 3514 | { |
3493 | // Delete attachments from scene | 3515 | // Delete attachments from scene |
@@ -3505,10 +3527,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
3505 | { | 3527 | { |
3506 | m_knownChildRegions.Clear(); | 3528 | m_knownChildRegions.Clear(); |
3507 | } | 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 | |||
3508 | m_sceneViewer.Close(); | 3540 | m_sceneViewer.Close(); |
3509 | 3541 | ||
3510 | RemoveFromPhysicalScene(); | 3542 | RemoveFromPhysicalScene(); |
3511 | GC.Collect(); | ||
3512 | } | 3543 | } |
3513 | 3544 | ||
3514 | public ScenePresence() | 3545 | public ScenePresence() |
@@ -3884,5 +3915,115 @@ namespace OpenSim.Region.Framework.Scenes | |||
3884 | } | 3915 | } |
3885 | } | 3916 | } |
3886 | } | 3917 | } |
3918 | |||
3919 | public double GetUpdatePriority(IClientAPI client) | ||
3920 | { | ||
3921 | switch (Scene.UpdatePrioritizationScheme) | ||
3922 | { | ||
3923 | case Scene.UpdatePrioritizationSchemes.Time: | ||
3924 | return GetPriorityByTime(); | ||
3925 | case Scene.UpdatePrioritizationSchemes.Distance: | ||
3926 | return GetPriorityByDistance(client); | ||
3927 | case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: | ||
3928 | return GetPriorityByDistance(client); | ||
3929 | default: | ||
3930 | throw new InvalidOperationException("UpdatePrioritizationScheme not defined."); | ||
3931 | } | ||
3932 | } | ||
3933 | |||
3934 | private double GetPriorityByTime() | ||
3935 | { | ||
3936 | return DateTime.Now.ToOADate(); | ||
3937 | } | ||
3938 | |||
3939 | private double GetPriorityByDistance(IClientAPI client) | ||
3940 | { | ||
3941 | ScenePresence presence = Scene.GetScenePresence(client.AgentId); | ||
3942 | if (presence != null) | ||
3943 | { | ||
3944 | return GetPriorityByDistance((presence.IsChildAgent) ? | ||
3945 | presence.AbsolutePosition : presence.CameraPosition); | ||
3946 | } | ||
3947 | return double.NaN; | ||
3948 | } | ||
3949 | |||
3950 | private double GetPriorityByDistance(Vector3 position) | ||
3951 | { | ||
3952 | return Vector3.Distance(AbsolutePosition, position); | ||
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 | } | ||
3887 | } | 4028 | } |
3888 | } | 4029 | } |