diff options
author | John Hurliman | 2010-05-21 13:55:36 -0700 |
---|---|---|
committer | John Hurliman | 2010-05-21 13:55:36 -0700 |
commit | 93ef65c69055157e0b7d51e544abe5a1035f40f0 (patch) | |
tree | 0afcfd50591e34f0a5d7efa474f300cf09083f69 /OpenSim/Region/Framework | |
parent | minor: remove LongRunning test designator from TestAddSceneObject() since it ... (diff) | |
download | opensim-SC_OLD-93ef65c69055157e0b7d51e544abe5a1035f40f0.zip opensim-SC_OLD-93ef65c69055157e0b7d51e544abe5a1035f40f0.tar.gz opensim-SC_OLD-93ef65c69055157e0b7d51e544abe5a1035f40f0.tar.bz2 opensim-SC_OLD-93ef65c69055157e0b7d51e544abe5a1035f40f0.tar.xz |
* Moving all of the prioritization/reprioritization code into a new file Prioritizer.cs
* Simplified the interest management code to make it easier to add new policies. Prioritization and reprioritization share code paths now
* Improved the distance and front back policies to always give your avatar the highest priority
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/EntityBase.cs | 3 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Prioritizer.cs | 122 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 96 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 101 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 118 |
5 files changed, 173 insertions, 267 deletions
diff --git a/OpenSim/Region/Framework/Scenes/EntityBase.cs b/OpenSim/Region/Framework/Scenes/EntityBase.cs index 1c76c54..4e25c46 100644 --- a/OpenSim/Region/Framework/Scenes/EntityBase.cs +++ b/OpenSim/Region/Framework/Scenes/EntityBase.cs | |||
@@ -28,11 +28,12 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Runtime.Serialization; | 29 | using System.Runtime.Serialization; |
30 | using System.Security.Permissions; | 30 | using System.Security.Permissions; |
31 | using OpenSim.Framework; | ||
31 | using OpenMetaverse; | 32 | using OpenMetaverse; |
32 | 33 | ||
33 | namespace OpenSim.Region.Framework.Scenes | 34 | namespace OpenSim.Region.Framework.Scenes |
34 | { | 35 | { |
35 | public abstract class EntityBase | 36 | public abstract class EntityBase : ISceneEntity |
36 | { | 37 | { |
37 | /// <summary> | 38 | /// <summary> |
38 | /// The scene to which this entity belongs | 39 | /// The scene to which this entity belongs |
diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs new file mode 100644 index 0000000..af25014 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs | |||
@@ -0,0 +1,122 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using log4net; | ||
4 | using Nini.Config; | ||
5 | using OpenSim.Framework; | ||
6 | using OpenMetaverse; | ||
7 | |||
8 | namespace OpenSim.Region.Framework.Scenes | ||
9 | { | ||
10 | public enum UpdatePrioritizationSchemes | ||
11 | { | ||
12 | Time = 0, | ||
13 | Distance = 1, | ||
14 | SimpleAngularDistance = 2, | ||
15 | FrontBack = 3, | ||
16 | } | ||
17 | |||
18 | public class Prioritizer | ||
19 | { | ||
20 | private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||
21 | |||
22 | private Scene m_scene; | ||
23 | |||
24 | public Prioritizer(Scene scene) | ||
25 | { | ||
26 | m_scene = scene; | ||
27 | } | ||
28 | |||
29 | public double GetUpdatePriority(IClientAPI client, ISceneEntity entity) | ||
30 | { | ||
31 | switch (m_scene.UpdatePrioritizationScheme) | ||
32 | { | ||
33 | case UpdatePrioritizationSchemes.Time: | ||
34 | return GetPriorityByTime(); | ||
35 | case UpdatePrioritizationSchemes.Distance: | ||
36 | return GetPriorityByDistance(client, entity); | ||
37 | case UpdatePrioritizationSchemes.SimpleAngularDistance: | ||
38 | return GetPriorityByDistance(client, entity); | ||
39 | case UpdatePrioritizationSchemes.FrontBack: | ||
40 | return GetPriorityByFrontBack(client, entity); | ||
41 | default: | ||
42 | throw new InvalidOperationException("UpdatePrioritizationScheme not defined."); | ||
43 | } | ||
44 | } | ||
45 | |||
46 | private double GetPriorityByTime() | ||
47 | { | ||
48 | return DateTime.UtcNow.ToOADate(); | ||
49 | } | ||
50 | |||
51 | private double GetPriorityByDistance(IClientAPI client, ISceneEntity entity) | ||
52 | { | ||
53 | ScenePresence presence = m_scene.GetScenePresence(client.AgentId); | ||
54 | if (presence != null) | ||
55 | { | ||
56 | // If this is an update for our own avatar give it the highest priority | ||
57 | if (presence == entity) | ||
58 | return 0.0; | ||
59 | |||
60 | // Use the camera position for local agents and avatar position for remote agents | ||
61 | Vector3 presencePos = (presence.IsChildAgent) ? | ||
62 | presence.AbsolutePosition : | ||
63 | presence.CameraPosition; | ||
64 | |||
65 | // Use group position for child prims | ||
66 | Vector3 entityPos; | ||
67 | if (entity is SceneObjectPart) | ||
68 | entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition; | ||
69 | else | ||
70 | entityPos = entity.AbsolutePosition; | ||
71 | |||
72 | return Vector3.DistanceSquared(presencePos, entityPos); | ||
73 | } | ||
74 | |||
75 | return double.NaN; | ||
76 | } | ||
77 | |||
78 | private double GetPriorityByFrontBack(IClientAPI client, ISceneEntity entity) | ||
79 | { | ||
80 | ScenePresence presence = m_scene.GetScenePresence(client.AgentId); | ||
81 | if (presence != null) | ||
82 | { | ||
83 | // If this is an update for our own avatar give it the highest priority | ||
84 | if (presence == entity) | ||
85 | return 0.0; | ||
86 | |||
87 | // Use group position for child prims | ||
88 | Vector3 entityPos = entity.AbsolutePosition; | ||
89 | if (entity is SceneObjectPart) | ||
90 | entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition; | ||
91 | else | ||
92 | entityPos = entity.AbsolutePosition; | ||
93 | |||
94 | if (!presence.IsChildAgent) | ||
95 | { | ||
96 | // Root agent. Use distance from camera and a priority decrease for objects behind us | ||
97 | Vector3 camPosition = presence.CameraPosition; | ||
98 | Vector3 camAtAxis = presence.CameraAtAxis; | ||
99 | |||
100 | // Distance | ||
101 | double priority = Vector3.DistanceSquared(camPosition, entityPos); | ||
102 | |||
103 | // Plane equation | ||
104 | float d = -Vector3.Dot(camPosition, camAtAxis); | ||
105 | float p = Vector3.Dot(camAtAxis, entityPos) + d; | ||
106 | if (p < 0.0f) priority *= 2.0; | ||
107 | |||
108 | return priority; | ||
109 | } | ||
110 | else | ||
111 | { | ||
112 | // Child agent. Use the normal distance method | ||
113 | Vector3 presencePos = presence.AbsolutePosition; | ||
114 | |||
115 | return Vector3.DistanceSquared(presencePos, entityPos); | ||
116 | } | ||
117 | } | ||
118 | |||
119 | return double.NaN; | ||
120 | } | ||
121 | } | ||
122 | } | ||
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index de8ecc2..f35dffc 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -58,13 +58,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
58 | 58 | ||
59 | public partial class Scene : SceneBase | 59 | public partial class Scene : SceneBase |
60 | { | 60 | { |
61 | public enum UpdatePrioritizationSchemes { | ||
62 | Time = 0, | ||
63 | Distance = 1, | ||
64 | SimpleAngularDistance = 2, | ||
65 | FrontBack = 3, | ||
66 | } | ||
67 | |||
68 | public delegate void SynchronizeSceneHandler(Scene scene); | 61 | public delegate void SynchronizeSceneHandler(Scene scene); |
69 | public SynchronizeSceneHandler SynchronizeScene = null; | 62 | public SynchronizeSceneHandler SynchronizeScene = null; |
70 | 63 | ||
@@ -388,12 +381,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
388 | private int m_lastUpdate; | 381 | private int m_lastUpdate; |
389 | private bool m_firstHeartbeat = true; | 382 | private bool m_firstHeartbeat = true; |
390 | 383 | ||
391 | private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; | ||
392 | private bool m_reprioritization_enabled = true; | ||
393 | private double m_reprioritization_interval = 5000.0; | ||
394 | private double m_root_reprioritization_distance = 10.0; | ||
395 | private double m_child_reprioritization_distance = 20.0; | ||
396 | |||
397 | private object m_deleting_scene_object = new object(); | 384 | private object m_deleting_scene_object = new object(); |
398 | 385 | ||
399 | // the minimum time that must elapse before a changed object will be considered for persisted | 386 | // the minimum time that must elapse before a changed object will be considered for persisted |
@@ -401,15 +388,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
401 | // the maximum time that must elapse before a changed object will be considered for persisted | 388 | // the maximum time that must elapse before a changed object will be considered for persisted |
402 | public long m_persistAfter = DEFAULT_MAX_TIME_FOR_PERSISTENCE * 10000000L; | 389 | public long m_persistAfter = DEFAULT_MAX_TIME_FOR_PERSISTENCE * 10000000L; |
403 | 390 | ||
391 | private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time; | ||
392 | private bool m_reprioritizationEnabled = true; | ||
393 | private double m_reprioritizationInterval = 5000.0; | ||
394 | private double m_rootReprioritizationDistance = 10.0; | ||
395 | private double m_childReprioritizationDistance = 20.0; | ||
396 | |||
404 | #endregion | 397 | #endregion |
405 | 398 | ||
406 | #region Properties | 399 | #region Properties |
407 | 400 | ||
408 | public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return this.m_update_prioritization_scheme; } } | 401 | public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return m_priorityScheme; } } |
409 | public bool IsReprioritizationEnabled { get { return m_reprioritization_enabled; } } | 402 | public bool IsReprioritizationEnabled { get { return m_reprioritizationEnabled; } } |
410 | public double ReprioritizationInterval { get { return m_reprioritization_interval; } } | 403 | public double ReprioritizationInterval { get { return m_reprioritizationInterval; } } |
411 | public double RootReprioritizationDistance { get { return m_root_reprioritization_distance; } } | 404 | public double RootReprioritizationDistance { get { return m_rootReprioritizationDistance; } } |
412 | public double ChildReprioritizationDistance { get { return m_child_reprioritization_distance; } } | 405 | public double ChildReprioritizationDistance { get { return m_childReprioritizationDistance; } } |
413 | 406 | ||
414 | public AgentCircuitManager AuthenticateHandler | 407 | public AgentCircuitManager AuthenticateHandler |
415 | { | 408 | { |
@@ -611,6 +604,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
611 | m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this); | 604 | m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this); |
612 | m_asyncSceneObjectDeleter.Enabled = true; | 605 | m_asyncSceneObjectDeleter.Enabled = true; |
613 | 606 | ||
607 | #region Region Settings | ||
608 | |||
614 | // Load region settings | 609 | // Load region settings |
615 | m_regInfo.RegionSettings = m_storageManager.DataStore.LoadRegionSettings(m_regInfo.RegionID); | 610 | m_regInfo.RegionSettings = m_storageManager.DataStore.LoadRegionSettings(m_regInfo.RegionID); |
616 | if (m_storageManager.EstateDataStore != null) | 611 | if (m_storageManager.EstateDataStore != null) |
@@ -657,6 +652,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
657 | } | 652 | } |
658 | } | 653 | } |
659 | 654 | ||
655 | #endregion Region Settings | ||
656 | |||
660 | MainConsole.Instance.Commands.AddCommand("region", false, "reload estate", | 657 | MainConsole.Instance.Commands.AddCommand("region", false, "reload estate", |
661 | "reload estate", | 658 | "reload estate", |
662 | "Reload the estate data", HandleReloadEstate); | 659 | "Reload the estate data", HandleReloadEstate); |
@@ -701,6 +698,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
701 | 698 | ||
702 | m_simulatorVersion = simulatorVersion + " (" + Util.GetRuntimeInformation() + ")"; | 699 | m_simulatorVersion = simulatorVersion + " (" + Util.GetRuntimeInformation() + ")"; |
703 | 700 | ||
701 | #region Region Config | ||
702 | |||
704 | try | 703 | try |
705 | { | 704 | { |
706 | // Region config overrides global config | 705 | // Region config overrides global config |
@@ -754,38 +753,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
754 | 753 | ||
755 | m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); | 754 | m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); |
756 | 755 | ||
757 | IConfig interest_management_config = m_config.Configs["InterestManagement"]; | ||
758 | if (interest_management_config != null) | ||
759 | { | ||
760 | string update_prioritization_scheme = interest_management_config.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower(); | ||
761 | switch (update_prioritization_scheme) | ||
762 | { | ||
763 | case "time": | ||
764 | m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; | ||
765 | break; | ||
766 | case "distance": | ||
767 | m_update_prioritization_scheme = UpdatePrioritizationSchemes.Distance; | ||
768 | break; | ||
769 | case "simpleangulardistance": | ||
770 | m_update_prioritization_scheme = UpdatePrioritizationSchemes.SimpleAngularDistance; | ||
771 | break; | ||
772 | case "frontback": | ||
773 | m_update_prioritization_scheme = UpdatePrioritizationSchemes.FrontBack; | ||
774 | break; | ||
775 | default: | ||
776 | m_log.Warn("[SCENE]: UpdatePrioritizationScheme was not recognized, setting to default settomg of Time"); | ||
777 | m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; | ||
778 | break; | ||
779 | } | ||
780 | |||
781 | m_reprioritization_enabled = interest_management_config.GetBoolean("ReprioritizationEnabled", true); | ||
782 | m_reprioritization_interval = interest_management_config.GetDouble("ReprioritizationInterval", 5000.0); | ||
783 | m_root_reprioritization_distance = interest_management_config.GetDouble("RootReprioritizationDistance", 10.0); | ||
784 | m_child_reprioritization_distance = interest_management_config.GetDouble("ChildReprioritizationDistance", 20.0); | ||
785 | } | ||
786 | |||
787 | m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme"); | ||
788 | |||
789 | #region BinaryStats | 756 | #region BinaryStats |
790 | 757 | ||
791 | try | 758 | try |
@@ -822,6 +789,35 @@ namespace OpenSim.Region.Framework.Scenes | |||
822 | { | 789 | { |
823 | m_log.Warn("[SCENE]: Failed to load StartupConfig"); | 790 | m_log.Warn("[SCENE]: Failed to load StartupConfig"); |
824 | } | 791 | } |
792 | |||
793 | #endregion Region Config | ||
794 | |||
795 | #region Interest Management | ||
796 | |||
797 | IConfig interestConfig = m_config.Configs["InterestManagement"]; | ||
798 | if (interestConfig != null) | ||
799 | { | ||
800 | string update_prioritization_scheme = interestConfig.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower(); | ||
801 | |||
802 | try | ||
803 | { | ||
804 | m_priorityScheme = (UpdatePrioritizationSchemes)Enum.Parse(typeof(UpdatePrioritizationSchemes), update_prioritization_scheme, true); | ||
805 | } | ||
806 | catch (Exception) | ||
807 | { | ||
808 | m_log.Warn("[PRIORITIZER]: UpdatePrioritizationScheme was not recognized, setting to default prioritizer Time"); | ||
809 | m_priorityScheme = UpdatePrioritizationSchemes.Time; | ||
810 | } | ||
811 | |||
812 | m_reprioritizationEnabled = interestConfig.GetBoolean("ReprioritizationEnabled", true); | ||
813 | m_reprioritizationInterval = interestConfig.GetDouble("ReprioritizationInterval", 5000.0); | ||
814 | m_rootReprioritizationDistance = interestConfig.GetDouble("RootReprioritizationDistance", 10.0); | ||
815 | m_childReprioritizationDistance = interestConfig.GetDouble("ChildReprioritizationDistance", 20.0); | ||
816 | } | ||
817 | |||
818 | m_log.Info("[SCENE]: Using the " + m_priorityScheme + " prioritization scheme"); | ||
819 | |||
820 | #endregion Interest Management | ||
825 | } | 821 | } |
826 | 822 | ||
827 | /// <summary> | 823 | /// <summary> |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 8aefd50..4453beb 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -3602,106 +3602,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3602 | 3602 | ||
3603 | SetFromItemID(uuid); | 3603 | SetFromItemID(uuid); |
3604 | } | 3604 | } |
3605 | #endregion | ||
3606 | 3605 | ||
3607 | public double GetUpdatePriority(IClientAPI client) | 3606 | #endregion |
3608 | { | ||
3609 | switch (Scene.UpdatePrioritizationScheme) | ||
3610 | { | ||
3611 | case Scene.UpdatePrioritizationSchemes.Time: | ||
3612 | return GetPriorityByTime(); | ||
3613 | case Scene.UpdatePrioritizationSchemes.Distance: | ||
3614 | return GetPriorityByDistance(client); | ||
3615 | case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: | ||
3616 | return GetPriorityBySimpleAngularDistance(client); | ||
3617 | case Scenes.Scene.UpdatePrioritizationSchemes.FrontBack: | ||
3618 | return GetPriorityByFrontBack(client); | ||
3619 | default: | ||
3620 | throw new InvalidOperationException("UpdatePrioritizationScheme not defined"); | ||
3621 | } | ||
3622 | } | ||
3623 | |||
3624 | private double GetPriorityByTime() | ||
3625 | { | ||
3626 | return DateTime.Now.ToOADate(); | ||
3627 | } | ||
3628 | |||
3629 | private double GetPriorityByDistance(IClientAPI client) | ||
3630 | { | ||
3631 | ScenePresence presence = Scene.GetScenePresence(client.AgentId); | ||
3632 | if (presence != null) | ||
3633 | { | ||
3634 | return GetPriorityByDistance((presence.IsChildAgent) ? | ||
3635 | presence.AbsolutePosition : presence.CameraPosition); | ||
3636 | } | ||
3637 | return double.NaN; | ||
3638 | } | ||
3639 | |||
3640 | private double GetPriorityBySimpleAngularDistance(IClientAPI client) | ||
3641 | { | ||
3642 | ScenePresence presence = Scene.GetScenePresence(client.AgentId); | ||
3643 | if (presence != null) | ||
3644 | { | ||
3645 | return GetPriorityBySimpleAngularDistance((presence.IsChildAgent) ? | ||
3646 | presence.AbsolutePosition : presence.CameraPosition); | ||
3647 | } | ||
3648 | return double.NaN; | ||
3649 | } | ||
3650 | |||
3651 | private double GetPriorityByFrontBack(IClientAPI client) | ||
3652 | { | ||
3653 | ScenePresence presence = Scene.GetScenePresence(client.AgentId); | ||
3654 | if (presence != null) | ||
3655 | { | ||
3656 | return GetPriorityByFrontBack(presence.CameraPosition, presence.CameraAtAxis); | ||
3657 | } | ||
3658 | return double.NaN; | ||
3659 | } | ||
3660 | |||
3661 | public double GetPriorityByDistance(Vector3 position) | ||
3662 | { | ||
3663 | return Vector3.Distance(AbsolutePosition, position); | ||
3664 | } | ||
3665 | |||
3666 | public double GetPriorityBySimpleAngularDistance(Vector3 position) | ||
3667 | { | ||
3668 | double distance = Vector3.Distance(position, AbsolutePosition); | ||
3669 | if (distance >= double.Epsilon) | ||
3670 | { | ||
3671 | float height; | ||
3672 | Vector3 box = GetAxisAlignedBoundingBox(out height); | ||
3673 | |||
3674 | double angle = box.X / distance; | ||
3675 | double max = angle; | ||
3676 | |||
3677 | angle = box.Y / distance; | ||
3678 | if (max < angle) | ||
3679 | max = angle; | ||
3680 | |||
3681 | angle = box.Z / distance; | ||
3682 | if (max < angle) | ||
3683 | max = angle; | ||
3684 | |||
3685 | return -max; | ||
3686 | } | ||
3687 | else | ||
3688 | return double.MinValue; | ||
3689 | } | ||
3690 | |||
3691 | public double GetPriorityByFrontBack(Vector3 camPosition, Vector3 camAtAxis) | ||
3692 | { | ||
3693 | // Distance | ||
3694 | double priority = Vector3.Distance(camPosition, AbsolutePosition); | ||
3695 | |||
3696 | // Scale | ||
3697 | //priority -= GroupScale().Length(); | ||
3698 | |||
3699 | // Plane equation | ||
3700 | float d = -Vector3.Dot(camPosition, camAtAxis); | ||
3701 | float p = Vector3.Dot(camAtAxis, AbsolutePosition) + d; | ||
3702 | if (p < 0.0f) priority *= 2.0f; | ||
3703 | |||
3704 | return priority; | ||
3705 | } | ||
3706 | } | 3607 | } |
3707 | } | 3608 | } |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index ee0eb07..2ce1b68 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -3777,123 +3777,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
3777 | } | 3777 | } |
3778 | } | 3778 | } |
3779 | 3779 | ||
3780 | public double GetUpdatePriority(IClientAPI client) | ||
3781 | { | ||
3782 | switch (Scene.UpdatePrioritizationScheme) | ||
3783 | { | ||
3784 | case Scene.UpdatePrioritizationSchemes.Time: | ||
3785 | return GetPriorityByTime(); | ||
3786 | case Scene.UpdatePrioritizationSchemes.Distance: | ||
3787 | return GetPriorityByDistance(client); | ||
3788 | case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: | ||
3789 | return GetPriorityByDistance(client); | ||
3790 | case Scenes.Scene.UpdatePrioritizationSchemes.FrontBack: | ||
3791 | return GetPriorityByFrontBack(client); | ||
3792 | default: | ||
3793 | throw new InvalidOperationException("UpdatePrioritizationScheme not defined."); | ||
3794 | } | ||
3795 | } | ||
3796 | |||
3797 | private double GetPriorityByTime() | ||
3798 | { | ||
3799 | return DateTime.Now.ToOADate(); | ||
3800 | } | ||
3801 | |||
3802 | private double GetPriorityByDistance(IClientAPI client) | ||
3803 | { | ||
3804 | ScenePresence presence = Scene.GetScenePresence(client.AgentId); | ||
3805 | if (presence != null) | ||
3806 | { | ||
3807 | return GetPriorityByDistance((presence.IsChildAgent) ? | ||
3808 | presence.AbsolutePosition : presence.CameraPosition); | ||
3809 | } | ||
3810 | return double.NaN; | ||
3811 | } | ||
3812 | |||
3813 | private double GetPriorityByFrontBack(IClientAPI client) | ||
3814 | { | ||
3815 | ScenePresence presence = Scene.GetScenePresence(client.AgentId); | ||
3816 | if (presence != null) | ||
3817 | { | ||
3818 | return GetPriorityByFrontBack(presence.CameraPosition, presence.CameraAtAxis); | ||
3819 | } | ||
3820 | return double.NaN; | ||
3821 | } | ||
3822 | |||
3823 | private double GetPriorityByDistance(Vector3 position) | ||
3824 | { | ||
3825 | return Vector3.Distance(AbsolutePosition, position); | ||
3826 | } | ||
3827 | |||
3828 | private double GetPriorityByFrontBack(Vector3 camPosition, Vector3 camAtAxis) | ||
3829 | { | ||
3830 | // Distance | ||
3831 | double priority = Vector3.Distance(camPosition, AbsolutePosition); | ||
3832 | |||
3833 | // Plane equation | ||
3834 | float d = -Vector3.Dot(camPosition, camAtAxis); | ||
3835 | float p = Vector3.Dot(camAtAxis, AbsolutePosition) + d; | ||
3836 | if (p < 0.0f) priority *= 2.0f; | ||
3837 | |||
3838 | return priority; | ||
3839 | } | ||
3840 | |||
3841 | private double GetSOGUpdatePriority(SceneObjectGroup sog) | ||
3842 | { | ||
3843 | switch (Scene.UpdatePrioritizationScheme) | ||
3844 | { | ||
3845 | case Scene.UpdatePrioritizationSchemes.Time: | ||
3846 | throw new InvalidOperationException("UpdatePrioritizationScheme for time not supported for reprioritization"); | ||
3847 | case Scene.UpdatePrioritizationSchemes.Distance: | ||
3848 | return sog.GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition); | ||
3849 | case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: | ||
3850 | return sog.GetPriorityBySimpleAngularDistance((IsChildAgent) ? AbsolutePosition : CameraPosition); | ||
3851 | case Scenes.Scene.UpdatePrioritizationSchemes.FrontBack: | ||
3852 | return sog.GetPriorityByFrontBack(CameraPosition, CameraAtAxis); | ||
3853 | default: | ||
3854 | throw new InvalidOperationException("UpdatePrioritizationScheme not defined"); | ||
3855 | } | ||
3856 | } | ||
3857 | |||
3858 | private double UpdatePriority(UpdatePriorityData data) | ||
3859 | { | ||
3860 | EntityBase entity; | ||
3861 | SceneObjectGroup group; | ||
3862 | |||
3863 | if (Scene.Entities.TryGetValue(data.localID, out entity)) | ||
3864 | { | ||
3865 | group = entity as SceneObjectGroup; | ||
3866 | if (group != null) | ||
3867 | return GetSOGUpdatePriority(group); | ||
3868 | |||
3869 | ScenePresence presence = entity as ScenePresence; | ||
3870 | if (presence == null) | ||
3871 | throw new InvalidOperationException("entity found is neither SceneObjectGroup nor ScenePresence"); | ||
3872 | switch (Scene.UpdatePrioritizationScheme) | ||
3873 | { | ||
3874 | case Scene.UpdatePrioritizationSchemes.Time: | ||
3875 | throw new InvalidOperationException("UpdatePrioritization for time not supported for reprioritization"); | ||
3876 | case Scene.UpdatePrioritizationSchemes.Distance: | ||
3877 | case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: | ||
3878 | return GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition); | ||
3879 | case Scenes.Scene.UpdatePrioritizationSchemes.FrontBack: | ||
3880 | return GetPriorityByFrontBack(CameraPosition, CameraAtAxis); | ||
3881 | default: | ||
3882 | throw new InvalidOperationException("UpdatePrioritizationScheme not defined"); | ||
3883 | } | ||
3884 | } | ||
3885 | else | ||
3886 | { | ||
3887 | group = Scene.GetGroupByPrim(data.localID); | ||
3888 | if (group != null) | ||
3889 | return GetSOGUpdatePriority(group); | ||
3890 | } | ||
3891 | return double.NaN; | ||
3892 | } | ||
3893 | |||
3894 | private void ReprioritizeUpdates() | 3780 | private void ReprioritizeUpdates() |
3895 | { | 3781 | { |
3896 | if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != Scene.UpdatePrioritizationSchemes.Time) | 3782 | if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != UpdatePrioritizationSchemes.Time) |
3897 | { | 3783 | { |
3898 | lock (m_reprioritization_timer) | 3784 | lock (m_reprioritization_timer) |
3899 | { | 3785 | { |
@@ -3907,7 +3793,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3907 | 3793 | ||
3908 | private void Reprioritize(object sender, ElapsedEventArgs e) | 3794 | private void Reprioritize(object sender, ElapsedEventArgs e) |
3909 | { | 3795 | { |
3910 | m_controllingClient.ReprioritizeUpdates(UpdatePriority); | 3796 | m_controllingClient.ReprioritizeUpdates(); |
3911 | 3797 | ||
3912 | lock (m_reprioritization_timer) | 3798 | lock (m_reprioritization_timer) |
3913 | { | 3799 | { |