diff options
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/EntityBase.cs | 3 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Prioritizer.cs | 191 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 99 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 93 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 103 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 118 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs | 52 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs | 3 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/UuidGatherer.cs | 8 |
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 @@ | |||
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..1eb0c28 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs | |||
@@ -0,0 +1,191 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using log4net; | ||
4 | using Nini.Config; | ||
5 | using OpenSim.Framework; | ||
6 | using OpenMetaverse; | ||
7 | using 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 | |||
21 | namespace 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); |