aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r--OpenSim/Region/Framework/Scenes/EntityBase.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/Prioritizer.cs191
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs99
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs93
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs103
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs118
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs52
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/UuidGatherer.cs8
9 files changed, 349 insertions, 321 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 @@
28using System; 28using System;
29using System.Runtime.Serialization; 29using System.Runtime.Serialization;
30using System.Security.Permissions; 30using System.Security.Permissions;
31using OpenSim.Framework;
31using OpenMetaverse; 32using OpenMetaverse;
32 33
33namespace OpenSim.Region.Framework.Scenes 34namespace 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..1eb0c28
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs
@@ -0,0 +1,191 @@
1using System;
2using System.Collections.Generic;
3using log4net;
4using Nini.Config;
5using OpenSim.Framework;
6using OpenMetaverse;
7using OpenSim.Region.Physics.Manager;
8
9/*
10 * Steps to add a new prioritization policy:
11 *
12 * - Add a new value to the UpdatePrioritizationSchemes enum.
13 * - Specify this new value in the [InterestManagement] section of your
14 * OpenSim.ini. The name in the config file must match the enum value name
15 * (although it is not case sensitive).
16 * - Write a new GetPriorityBy*() method in this class.
17 * - Add a new entry to the switch statement in GetUpdatePriority() that calls
18 * your method.
19 */
20
21namespace OpenSim.Region.Framework.Scenes
22{
23 public enum UpdatePrioritizationSchemes
24 {
25 Time = 0,
26 Distance = 1,
27 SimpleAngularDistance = 2,
28 FrontBack = 3,
29 BestAvatarResponsiveness = 4,
30 }
31
32 public class Prioritizer
33 {
34 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
35
36 private Scene m_scene;
37
38 public Prioritizer(Scene scene)
39 {
40 m_scene = scene;
41 }
42
43 public double GetUpdatePriority(IClientAPI client, ISceneEntity entity)
44 {
45 switch (m_scene.UpdatePrioritizationScheme)
46 {
47 case UpdatePrioritizationSchemes.Time:
48 return GetPriorityByTime();
49 case UpdatePrioritizationSchemes.Distance:
50 return GetPriorityByDistance(client, entity);
51 case UpdatePrioritizationSchemes.SimpleAngularDistance:
52 return GetPriorityByDistance(client, entity); // TODO: Reimplement SimpleAngularDistance
53 case UpdatePrioritizationSchemes.FrontBack:
54 return GetPriorityByFrontBack(client, entity);
55 case UpdatePrioritizationSchemes.BestAvatarResponsiveness:
56 return GetPriorityByBestAvatarResponsiveness(client, entity);
57 default:
58 throw new InvalidOperationException("UpdatePrioritizationScheme not defined.");
59 }
60 }
61
62 private double GetPriorityByTime()
63 {
64 return DateTime.UtcNow.ToOADate();
65 }
66
67 private double GetPriorityByDistance(IClientAPI client, ISceneEntity entity)
68 {
69 ScenePresence presence = m_scene.GetScenePresence(client.AgentId);
70 if (presence != null)
71 {
72 // If this is an update for our own avatar give it the highest priority
73 if (presence == entity)
74 return 0.0;
75
76 // Use the camera position for local agents and avatar position for remote agents
77 Vector3 presencePos = (presence.IsChildAgent) ?
78 presence.AbsolutePosition :
79 presence.CameraPosition;
80
81 // Use group position for child prims
82 Vector3 entityPos;
83 if (entity is SceneObjectPart)
84 entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition;
85 else
86 entityPos = entity.AbsolutePosition;
87
88 return Vector3.DistanceSquared(presencePos, entityPos);
89 }
90
91 return double.NaN;
92 }
93
94 private double GetPriorityByFrontBack(IClientAPI client, ISceneEntity entity)
95 {
96 ScenePresence presence = m_scene.GetScenePresence(client.AgentId);
97 if (presence != null)
98 {
99 // If this is an update for our own avatar give it the highest priority
100 if (presence == entity)
101 return 0.0;
102
103 // Use group position for child prims
104 Vector3 entityPos = entity.AbsolutePosition;
105 if (entity is SceneObjectPart)
106 entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition;
107 else
108 entityPos = entity.AbsolutePosition;
109
110 if (!presence.IsChildAgent)
111 {
112 // Root agent. Use distance from camera and a priority decrease for objects behind us
113 Vector3 camPosition = presence.CameraPosition;
114 Vector3 camAtAxis = presence.CameraAtAxis;
115
116 // Distance
117 double priority = Vector3.DistanceSquared(camPosition, entityPos);
118
119 // Plane equation
120 float d = -Vector3.Dot(camPosition, camAtAxis);
121 float p = Vector3.Dot(camAtAxis, entityPos) + d;
122 if (p < 0.0f) priority *= 2.0;
123
124 return priority;
125 }
126 else
127 {
128 // Child agent. Use the normal distance method
129 Vector3 presencePos = presence.AbsolutePosition;
130
131 return Vector3.DistanceSquared(presencePos, entityPos);
132 }
133 }
134
135 return double.NaN;
136 }
137
138 private double GetPriorityByBestAvatarResponsiveness(IClientAPI client, ISceneEntity entity)
139 {
140 ScenePresence presence = m_scene.GetScenePresence(client.AgentId);
141 if (presence != null)
142 {
143 // If this is an update for our own avatar give it the highest priority
144 if (presence == entity)
145 return 0.0;
146
147 // Use group position for child prims
148 Vector3 entityPos = entity.AbsolutePosition;
149 if (entity is SceneObjectPart)
150 entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition;
151 else
152 entityPos = entity.AbsolutePosition;
153
154 if (!presence.IsChildAgent)
155 {
156 if (entity is ScenePresence)
157 return 1.0;
158
159 // Root agent. Use distance from camera and a priority decrease for objects behind us
160 Vector3 camPosition = presence.CameraPosition;
161 Vector3 camAtAxis = presence.CameraAtAxis;
162
163 // Distance
164 double priority = Vector3.DistanceSquared(camPosition, entityPos);
165
166 // Plane equation
167 float d = -Vector3.Dot(camPosition, camAtAxis);
168 float p = Vector3.Dot(camAtAxis, entityPos) + d;
169 if (p < 0.0f) priority *= 2.0;
170
171 if (entity is SceneObjectPart)
172 {
173 PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor;
174 if (physActor == null || !physActor.IsPhysical)
175 priority+=100;
176 }
177 return priority;
178 }
179 else
180 {
181 // Child agent. Use the normal distance method
182 Vector3 presencePos = presence.AbsolutePosition;
183
184 return Vector3.DistanceSquared(presencePos, entityPos);
185 }
186 }
187
188 return double.NaN;
189 }
190 }
191}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 377abe3..3e20766 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
@@ -402,12 +395,6 @@ namespace OpenSim.Region.Framework.Scenes
402 private int m_lastUpdate; 395 private int m_lastUpdate;
403 private bool m_firstHeartbeat = true; 396 private bool m_firstHeartbeat = true;
404 397
405 private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
406 private bool m_reprioritization_enabled = true;
407 private double m_reprioritization_interval = 5000.0;
408 private double m_root_reprioritization_distance = 10.0;
409 private double m_child_reprioritization_distance = 20.0;
410
411 private object m_deleting_scene_object = new object(); 398 private object m_deleting_scene_object = new object();
412 399
413 // the minimum time that must elapse before a changed object will be considered for persisted 400 // the minimum time that must elapse before a changed object will be considered for persisted
@@ -415,15 +402,21 @@ namespace OpenSim.Region.Framework.Scenes
415 // the maximum time that must elapse before a changed object will be considered for persisted 402 // the maximum time that must elapse before a changed object will be considered for persisted
416 public long m_persistAfter = DEFAULT_MAX_TIME_FOR_PERSISTENCE * 10000000L; 403 public long m_persistAfter = DEFAULT_MAX_TIME_FOR_PERSISTENCE * 10000000L;
417 404
405 private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time;
406 private bool m_reprioritizationEnabled = true;
407 private double m_reprioritizationInterval = 5000.0;
408 private double m_rootReprioritizationDistance = 10.0;
409 private double m_childReprioritizationDistance = 20.0;
410
418 #endregion 411 #endregion
419 412
420 #region Properties 413 #region Properties
421 414
422 public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return this.m_update_prioritization_scheme; } } 415 public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return m_priorityScheme; } }
423 public bool IsReprioritizationEnabled { get { return m_reprioritization_enabled; } } 416 public bool IsReprioritizationEnabled { get { return m_reprioritizationEnabled; } }
424 public double ReprioritizationInterval { get { return m_reprioritization_interval; } } 417 public double ReprioritizationInterval { get { return m_reprioritizationInterval; } }
425 public double RootReprioritizationDistance { get { return m_root_reprioritization_distance; } } 418 public double RootReprioritizationDistance { get { return m_rootReprioritizationDistance; } }
426 public double ChildReprioritizationDistance { get { return m_child_reprioritization_distance; } } 419 public double ChildReprioritizationDistance { get { return m_childReprioritizationDistance; } }
427 420
428 public AgentCircuitManager AuthenticateHandler 421 public AgentCircuitManager AuthenticateHandler
429 { 422 {
@@ -625,6 +618,8 @@ namespace OpenSim.Region.Framework.Scenes
625 m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this); 618 m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this);
626 m_asyncSceneObjectDeleter.Enabled = true; 619 m_asyncSceneObjectDeleter.Enabled = true;
627 620
621 #region Region Settings
622
628 // Load region settings 623 // Load region settings
629 m_regInfo.RegionSettings = m_storageManager.DataStore.LoadRegionSettings(m_regInfo.RegionID); 624 m_regInfo.RegionSettings = m_storageManager.DataStore.LoadRegionSettings(m_regInfo.RegionID);
630 m_regInfo.WindlightSettings = m_storageManager.DataStore.LoadRegionWindlightSettings(m_regInfo.RegionID); 625 m_regInfo.WindlightSettings = m_storageManager.DataStore.LoadRegionWindlightSettings(m_regInfo.RegionID);
@@ -673,6 +668,8 @@ namespace OpenSim.Region.Framework.Scenes
673 } 668 }
674 } 669 }
675 670
671 #endregion Region Settings
672
676 MainConsole.Instance.Commands.AddCommand("region", false, "reload estate", 673 MainConsole.Instance.Commands.AddCommand("region", false, "reload estate",
677 "reload estate", 674 "reload estate",
678 "Reload the estate data", HandleReloadEstate); 675 "Reload the estate data", HandleReloadEstate);
@@ -717,6 +714,8 @@ namespace OpenSim.Region.Framework.Scenes
717 714
718 m_simulatorVersion = simulatorVersion + " (" + Util.GetRuntimeInformation() + ")"; 715 m_simulatorVersion = simulatorVersion + " (" + Util.GetRuntimeInformation() + ")";
719 716
717 #region Region Config
718
720 try 719 try
721 { 720 {
722 // Region config overrides global config 721 // Region config overrides global config
@@ -770,38 +769,6 @@ namespace OpenSim.Region.Framework.Scenes
770 769
771 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); 770 m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl);
772 771
773 IConfig interest_management_config = m_config.Configs["InterestManagement"];
774 if (interest_management_config != null)
775 {
776 string update_prioritization_scheme = interest_management_config.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower();
777 switch (update_prioritization_scheme)
778 {
779 case "time":
780 m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
781 break;
782 case "distance":
783 m_update_prioritization_scheme = UpdatePrioritizationSchemes.Distance;
784 break;
785 case "simpleangulardistance":
786 m_update_prioritization_scheme = UpdatePrioritizationSchemes.SimpleAngularDistance;
787 break;
788 case "frontback":
789 m_update_prioritization_scheme = UpdatePrioritizationSchemes.FrontBack;
790 break;
791 default:
792 m_log.Warn("[SCENE]: UpdatePrioritizationScheme was not recognized, setting to default settomg of Time");
793 m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
794 break;
795 }
796
797 m_reprioritization_enabled = interest_management_config.GetBoolean("ReprioritizationEnabled", true);
798 m_reprioritization_interval = interest_management_config.GetDouble("ReprioritizationInterval", 5000.0);
799 m_root_reprioritization_distance = interest_management_config.GetDouble("RootReprioritizationDistance", 10.0);
800 m_child_reprioritization_distance = interest_management_config.GetDouble("ChildReprioritizationDistance", 20.0);
801 }
802
803 m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme");
804
805 #region BinaryStats 772 #region BinaryStats
806 773
807 try 774 try
@@ -838,6 +805,38 @@ namespace OpenSim.Region.Framework.Scenes
838 { 805 {
839 m_log.Warn("[SCENE]: Failed to load StartupConfig"); 806 m_log.Warn("[SCENE]: Failed to load StartupConfig");
840 } 807 }
808
809 #endregion Region Config
810
811 #region Interest Management
812
813 if (m_config != null)
814 {
815 IConfig interestConfig = m_config.Configs["InterestManagement"];
816 if (interestConfig != null)
817 {
818 string update_prioritization_scheme = interestConfig.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower();
819
820 try
821 {
822 m_priorityScheme = (UpdatePrioritizationSchemes)Enum.Parse(typeof(UpdatePrioritizationSchemes), update_prioritization_scheme, true);
823 }
824 catch (Exception)
825 {
826 m_log.Warn("[PRIORITIZER]: UpdatePrioritizationScheme was not recognized, setting to default prioritizer Time");
827 m_priorityScheme = UpdatePrioritizationSchemes.Time;
828 }
829
830 m_reprioritizationEnabled = interestConfig.GetBoolean("ReprioritizationEnabled", true);
831 m_reprioritizationInterval = interestConfig.GetDouble("ReprioritizationInterval", 5000.0);
832 m_rootReprioritizationDistance = interestConfig.GetDouble("RootReprioritizationDistance", 10.0);
833 m_childReprioritizationDistance = interestConfig.GetDouble("ChildReprioritizationDistance", 20.0);
834 }
835 }
836
837 m_log.Info("[SCENE]: Using the " + m_priorityScheme + " prioritization scheme");
838
839 #endregion Interest Management
841 } 840 }
842 841
843 /// <summary> 842 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 3c2203c..d4658ec 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -307,61 +307,64 @@ namespace OpenSim.Region.Framework.Scenes
307 if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero) 307 if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero)
308 return false; 308 return false;
309 309
310 bool alreadyExisted = false; 310 lock (sceneObject)
311 311 {
312 if (m_parentScene.m_clampPrimSize) 312 if (Entities.ContainsKey(sceneObject.UUID))
313 {
314 foreach (SceneObjectPart part in sceneObject.Children.Values)
315 { 313 {
316 Vector3 scale = part.Shape.Scale; 314// m_log.WarnFormat(
317 315// "[SCENE GRAPH]: Scene object {0} {1} was already in region {2} on add request",
318 if (scale.X > m_parentScene.m_maxNonphys) 316// sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName);
319 scale.X = m_parentScene.m_maxNonphys; 317 return false;
320 if (scale.Y > m_parentScene.m_maxNonphys)
321 scale.Y = m_parentScene.m_maxNonphys;
322 if (scale.Z > m_parentScene.m_maxNonphys)
323 scale.Z = m_parentScene.m_maxNonphys;
324
325 part.Shape.Scale = scale;
326 } 318 }
327 } 319
328 320// m_log.DebugFormat(
329 sceneObject.AttachToScene(m_parentScene); 321// "[SCENE GRAPH]: Adding object {0} {1} to region {2}",
330 322// sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName);
331 if (sendClientUpdates) 323
332 sceneObject.ScheduleGroupForFullUpdate(); 324 if (m_parentScene.m_clampPrimSize)
333
334 lock (sceneObject)
335 {
336 if (!Entities.ContainsKey(sceneObject.UUID))
337 { 325 {
338 Entities.Add(sceneObject); 326 foreach (SceneObjectPart part in sceneObject.Children.Values)
339 m_numPrim += sceneObject.Children.Count;
340
341 if (attachToBackup)
342 sceneObject.AttachToBackup();
343
344 if (OnObjectCreate != null)
345 OnObjectCreate(sceneObject);
346
347 lock (m_dictionary_lock)
348 { 327 {
349 SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; 328 Vector3 scale = part.Shape.Scale;
350 SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; 329
351 foreach (SceneObjectPart part in sceneObject.Children.Values) 330 if (scale.X > m_parentScene.m_maxNonphys)
352 { 331 scale.X = m_parentScene.m_maxNonphys;
353 SceneObjectGroupsByFullID[part.UUID] = sceneObject; 332 if (scale.Y > m_parentScene.m_maxNonphys)
354 SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; 333 scale.Y = m_parentScene.m_maxNonphys;
355 } 334 if (scale.Z > m_parentScene.m_maxNonphys)
335 scale.Z = m_parentScene.m_maxNonphys;
336
337 part.Shape.Scale = scale;
356 } 338 }
357 } 339 }
358 else 340
341 sceneObject.AttachToScene(m_parentScene);
342
343 if (sendClientUpdates)
344 sceneObject.ScheduleGroupForFullUpdate();
345
346 Entities.Add(sceneObject);
347 m_numPrim += sceneObject.Children.Count;
348
349 if (attachToBackup)
350 sceneObject.AttachToBackup();
351
352 if (OnObjectCreate != null)
353 OnObjectCreate(sceneObject);
354
355 lock (m_dictionary_lock)
359 { 356 {
360 alreadyExisted = true; 357 SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
358 SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject;
359 foreach (SceneObjectPart part in sceneObject.Children.Values)
360 {
361 SceneObjectGroupsByFullID[part.UUID] = sceneObject;
362 SceneObjectGroupsByLocalID[part.LocalId] = sceneObject;
363 }
361 } 364 }
362 } 365 }
363 366
364 return alreadyExisted; 367 return true;
365 } 368 }
366 369
367 /// <summary> 370 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index a4b8944..cee2be3 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -3841,107 +3841,6 @@ namespace OpenSim.Region.Framework.Scenes
3841 3841
3842 SetFromItemID(uuid); 3842 SetFromItemID(uuid);
3843 } 3843 }
3844 #endregion
3845
3846 public double GetUpdatePriority(IClientAPI client)
3847 {
3848 switch (Scene.UpdatePrioritizationScheme)
3849 {
3850 case Scene.UpdatePrioritizationSchemes.Time:
3851 return GetPriorityByTime();
3852 case Scene.UpdatePrioritizationSchemes.Distance:
3853 return GetPriorityByDistance(client);
3854 case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance:
3855 return GetPriorityBySimpleAngularDistance(client);
3856 case Scenes.Scene.UpdatePrioritizationSchemes.FrontBack:
3857 return GetPriorityByFrontBack(client);
3858 default:
3859 throw new InvalidOperationException("UpdatePrioritizationScheme not defined");
3860 }
3861 }
3862
3863 private double GetPriorityByTime()
3864 {
3865 return DateTime.Now.ToOADate();
3866 }
3867
3868 private double GetPriorityByDistance(IClientAPI client)
3869 {
3870 ScenePresence presence = Scene.GetScenePresence(client.AgentId);
3871 if (presence != null)
3872 {
3873 return GetPriorityByDistance((presence.IsChildAgent) ?
3874 presence.AbsolutePosition : presence.CameraPosition);
3875 }
3876 return double.NaN;
3877 }
3878
3879 private double GetPriorityBySimpleAngularDistance(IClientAPI client)
3880 {
3881 ScenePresence presence = Scene.GetScenePresence(client.AgentId);
3882 if (presence != null)
3883 {
3884 return GetPriorityBySimpleAngularDistance((presence.IsChildAgent) ?
3885 presence.AbsolutePosition : presence.CameraPosition);
3886 }
3887 return double.NaN;
3888 }
3889
3890 private double GetPriorityByFrontBack(IClientAPI client)
3891 {
3892 ScenePresence presence = Scene.GetScenePresence(client.AgentId);
3893 if (presence != null)
3894 {
3895 return GetPriorityByFrontBack(presence.CameraPosition, presence.CameraAtAxis);
3896 }
3897 return double.NaN;
3898 }
3899
3900 public double GetPriorityByDistance(Vector3 position)
3901 {
3902 return Vector3.Distance(AbsolutePosition, position);
3903 }
3904
3905 public double GetPriorityBySimpleAngularDistance(Vector3 position)
3906 {
3907 double distance = Vector3.Distance(position, AbsolutePosition);
3908 if (distance >= double.Epsilon)
3909 {
3910 float height;
3911 Vector3 box = GetAxisAlignedBoundingBox(out height);
3912
3913 double angle = box.X / distance;
3914 double max = angle;
3915
3916 angle = box.Y / distance;
3917 if (max < angle)
3918 max = angle;
3919
3920 angle = box.Z / distance;
3921 if (max < angle)
3922 max = angle;
3923
3924 return -max;
3925 }
3926 else
3927 return double.MinValue;
3928 }
3929
3930 public double GetPriorityByFrontBack(Vector3 camPosition, Vector3 camAtAxis)
3931 {
3932 // Distance
3933 double priority = Vector3.Distance(camPosition, AbsolutePosition);
3934
3935 // Scale
3936 //priority -= GroupScale().Length();
3937
3938 // Plane equation
3939 float d = -Vector3.Dot(camPosition, camAtAxis);
3940 float p = Vector3.Dot(camAtAxis, AbsolutePosition) + d;
3941 if (p < 0.0f) priority *= 2.0f;
3942
3943 return priority;
3944 }
3945 3844
3946 public void ResetOwnerChangeFlag() 3845 public void ResetOwnerChangeFlag()
3947 { 3846 {
@@ -3950,5 +3849,7 @@ namespace OpenSim.Region.Framework.Scenes
3950 part.ResetOwnerChangeFlag(); 3849 part.ResetOwnerChangeFlag();
3951 }); 3850 });
3952 } 3851 }
3852
3853 #endregion
3953 } 3854 }
3954} 3855}
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 179ecdc..c45fc0f 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -4090,123 +4090,9 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos);
4090 } 4090 }
4091 } 4091 }
4092 4092
4093 public double GetUpdatePriority(IClientAPI client)
4094 {
4095 switch (Scene.UpdatePrioritizationScheme)
4096 {
4097 case Scene.UpdatePrioritizationSchemes.Time:
4098 return GetPriorityByTime();
4099 case Scene.UpdatePrioritizationSchemes.Distance:
4100 return GetPriorityByDistance(client);
4101 case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance:
4102 return GetPriorityByDistance(client);
4103 case Scenes.Scene.UpdatePrioritizationSchemes.FrontBack:
4104 return GetPriorityByFrontBack(client);
4105 default:
4106 throw new InvalidOperationException("UpdatePrioritizationScheme not defined.");
4107 }
4108 }
4109
4110 private double GetPriorityByTime()
4111 {
4112 return DateTime.Now.ToOADate();
4113 }
4114
4115 private double GetPriorityByDistance(IClientAPI client)
4116 {
4117 ScenePresence presence = Scene.GetScenePresence(client.AgentId);
4118 if (presence != null)
4119 {
4120 return GetPriorityByDistance((presence.IsChildAgent) ?
4121 presence.AbsolutePosition : presence.CameraPosition);
4122 }
4123 return double.NaN;
4124 }
4125
4126 private double GetPriorityByFrontBack(IClientAPI client)
4127 {
4128 ScenePresence presence = Scene.GetScenePresence(client.AgentId);
4129 if (presence != null)
4130 {
4131 return GetPriorityByFrontBack(presence.CameraPosition, presence.CameraAtAxis);
4132 }
4133 return double.NaN;
4134 }
4135
4136 private double GetPriorityByDistance(Vector3 position)
4137 {
4138 return Vector3.Distance(AbsolutePosition, position);
4139 }
4140
4141 private double GetPriorityByFrontBack(Vector3 camPosition, Vector3 camAtAxis)
4142 {
4143 // Distance
4144 double priority = Vector3.Distance(camPosition, AbsolutePosition);
4145
4146 // Plane equation
4147 float d = -Vector3.Dot(camPosition, camAtAxis);
4148 float p = Vector3.Dot(camAtAxis, AbsolutePosition) + d;
4149 if (p < 0.0f) priority *= 2.0f;
4150
4151 return priority;
4152 }
4153
4154 private double GetSOGUpdatePriority(SceneObjectGroup sog)
4155 {
4156 switch (Scene.UpdatePrioritizationScheme)
4157 {
4158 case Scene.UpdatePrioritizationSchemes.Time:
4159 throw new InvalidOperationException("UpdatePrioritizationScheme for time not supported for reprioritization");
4160 case Scene.UpdatePrioritizationSchemes.Distance:
4161 return sog.GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition);
4162 case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance:
4163 return sog.GetPriorityBySimpleAngularDistance((IsChildAgent) ? AbsolutePosition : CameraPosition);
4164 case Scenes.Scene.UpdatePrioritizationSchemes.FrontBack:
4165 return sog.GetPriorityByFrontBack(CameraPosition, CameraAtAxis);
4166 default:
4167 throw new InvalidOperationException("UpdatePrioritizationScheme not defined");
4168 }
4169 }
4170
4171 private double UpdatePriority(UpdatePriorityData data)
4172 {
4173 EntityBase entity;
4174 SceneObjectGroup group;
4175
4176 if (Scene.Entities.TryGetValue(data.localID, out entity))
4177 {
4178 group = entity as SceneObjectGroup;
4179 if (group != null)
4180 return GetSOGUpdatePriority(group);
4181
4182 ScenePresence presence = entity as ScenePresence;
4183 if (presence == null)
4184 throw new InvalidOperationException("entity found is neither SceneObjectGroup nor ScenePresence");
4185 switch (Scene.UpdatePrioritizationScheme)
4186 {
4187 case Scene.UpdatePrioritizationSchemes.Time:
4188 throw new InvalidOperationException("UpdatePrioritization for time not supported for reprioritization");
4189 case Scene.UpdatePrioritizationSchemes.Distance:
4190 case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance:
4191 return GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition);
4192 case Scenes.Scene.UpdatePrioritizationSchemes.FrontBack:
4193 return GetPriorityByFrontBack(CameraPosition, CameraAtAxis);
4194 default:
4195 throw new InvalidOperationException("UpdatePrioritizationScheme not defined");
4196 }
4197 }
4198 else
4199 {
4200 group = Scene.GetGroupByPrim(data.localID);
4201 if (group != null)
4202 return GetSOGUpdatePriority(group);
4203 }
4204 return double.NaN;
4205 }
4206
4207 private void ReprioritizeUpdates() 4093 private void ReprioritizeUpdates()
4208 { 4094 {
4209 if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != Scene.UpdatePrioritizationSchemes.Time) 4095 if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != UpdatePrioritizationSchemes.Time)
4210 { 4096 {
4211 lock (m_reprioritization_timer) 4097 lock (m_reprioritization_timer)
4212 { 4098 {
@@ -4220,7 +4106,7 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos);
4220 4106
4221 private void Reprioritize(object sender, ElapsedEventArgs e) 4107 private void Reprioritize(object sender, ElapsedEventArgs e)
4222 { 4108 {
4223 m_controllingClient.ReprioritizeUpdates(UpdatePriority); 4109 m_controllingClient.ReprioritizeUpdates();
4224 4110
4225 lock (m_reprioritization_timer) 4111 lock (m_reprioritization_timer)
4226 { 4112 {
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
index 78f2ae3..4baa22c 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs
@@ -49,18 +49,62 @@ namespace OpenSim.Region.Framework.Scenes.Tests
49 /// <summary> 49 /// <summary>
50 /// Test adding an object to a scene. 50 /// Test adding an object to a scene.
51 /// </summary> 51 /// </summary>
52 [Test, LongRunning] 52 [Test]
53 public void TestAddSceneObject() 53 public void TestAddSceneObject()
54 { 54 {
55 TestHelper.InMethod(); 55 TestHelper.InMethod();
56 56
57 Scene scene = SceneSetupHelpers.SetupScene(); 57 Scene scene = SceneSetupHelpers.SetupScene();
58 SceneObjectPart part = SceneSetupHelpers.AddSceneObject(scene); 58
59 SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); 59 string objName = "obj1";
60 UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001");
61
62 SceneObjectPart part
63 = new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero)
64 { Name = objName, UUID = objUuid };
65
66 Assert.That(scene.AddNewSceneObject(new SceneObjectGroup(part), false), Is.True);
67
68 SceneObjectPart retrievedPart = scene.GetSceneObjectPart(objUuid);
69
70 //m_log.Debug("retrievedPart : {0}", retrievedPart);
71 // If the parts have the same UUID then we will consider them as one and the same
72 Assert.That(retrievedPart.Name, Is.EqualTo(objName));
73 Assert.That(retrievedPart.UUID, Is.EqualTo(objUuid));
74 }
75
76 [Test]
77 /// <summary>
78 /// It shouldn't be possible to add a scene object if one with that uuid already exists in the scene.
79 /// </summary>
80 public void TestAddExistingSceneObjectUuid()
81 {
82 TestHelper.InMethod();
83
84 Scene scene = SceneSetupHelpers.SetupScene();
85
86 string obj1Name = "Alfred";
87 string obj2Name = "Betty";
88 UUID objUuid = new UUID("00000000-0000-0000-0000-000000000001");
89
90 SceneObjectPart part1
91 = new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero)
92 { Name = obj1Name, UUID = objUuid };
93
94 Assert.That(scene.AddNewSceneObject(new SceneObjectGroup(part1), false), Is.True);
95
96 SceneObjectPart part2
97 = new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero)
98 { Name = obj2Name, UUID = objUuid };
99
100 Assert.That(scene.AddNewSceneObject(new SceneObjectGroup(part2), false), Is.False);
101
102 SceneObjectPart retrievedPart = scene.GetSceneObjectPart(objUuid);
60 103
61 //m_log.Debug("retrievedPart : {0}", retrievedPart); 104 //m_log.Debug("retrievedPart : {0}", retrievedPart);
62 // If the parts have the same UUID then we will consider them as one and the same 105 // If the parts have the same UUID then we will consider them as one and the same
63 Assert.That(retrievedPart.UUID, Is.EqualTo(part.UUID)); 106 Assert.That(retrievedPart.Name, Is.EqualTo(obj1Name));
107 Assert.That(retrievedPart.UUID, Is.EqualTo(objUuid));
64 } 108 }
65 109
66 /// <summary> 110 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
index 8b80ebe..5e6124b 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
@@ -58,7 +58,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
58 TestHelper.InMethod(); 58 TestHelper.InMethod();
59 59
60 UUID corruptAssetUuid = UUID.Parse("00000000-0000-0000-0000-000000000666"); 60 UUID corruptAssetUuid = UUID.Parse("00000000-0000-0000-0000-000000000666");
61 AssetBase corruptAsset = AssetHelpers.CreateAsset(corruptAssetUuid, "CORRUPT ASSET", UUID.Zero); 61 AssetBase corruptAsset
62 = AssetHelpers.CreateAsset(corruptAssetUuid, AssetType.Notecard, "CORRUPT ASSET", UUID.Zero);
62 m_assetService.Store(corruptAsset); 63 m_assetService.Store(corruptAsset);
63 64
64 IDictionary<UUID, AssetType> foundAssetUuids = new Dictionary<UUID, AssetType>(); 65 IDictionary<UUID, AssetType> foundAssetUuids = new Dictionary<UUID, AssetType>();
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
index 0ec3cc3..e3965ce 100644
--- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
+++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
@@ -123,8 +123,8 @@ namespace OpenSim.Region.Framework.Scenes
123 123
124 foreach (SceneObjectPart part in sceneObject.GetParts()) 124 foreach (SceneObjectPart part in sceneObject.GetParts())
125 { 125 {
126 //m_log.DebugFormat( 126// m_log.DebugFormat(
127 // "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID); 127// "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID);
128 128
129 try 129 try
130 { 130 {
@@ -155,7 +155,9 @@ namespace OpenSim.Region.Framework.Scenes
155 // Now analyze this prim's inventory items to preserve all the uuids that they reference 155 // Now analyze this prim's inventory items to preserve all the uuids that they reference
156 foreach (TaskInventoryItem tii in taskDictionary.Values) 156 foreach (TaskInventoryItem tii in taskDictionary.Values)
157 { 157 {
158 //m_log.DebugFormat("[ARCHIVER]: Analysing item asset type {0}", tii.Type); 158// m_log.DebugFormat(
159// "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}",
160// tii.Name, tii.Type, part.Name, part.UUID);
159 161
160 if (!assetUuids.ContainsKey(tii.AssetID)) 162 if (!assetUuids.ContainsKey(tii.AssetID))
161 GatherAssetUuids(tii.AssetID, (AssetType)tii.Type, assetUuids); 163 GatherAssetUuids(tii.AssetID, (AssetType)tii.Type, assetUuids);