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.cs197
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 @@
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
@@ -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}