diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Prioritizer.cs | 50 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 42 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 10 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 3 |
4 files changed, 89 insertions, 16 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index 1eb0c28..4780cdd 100644 --- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs | |||
@@ -1,4 +1,4 @@ | |||
1 | using System; | 1 | using System; |
2 | using System.Collections.Generic; | 2 | using System.Collections.Generic; |
3 | using log4net; | 3 | using log4net; |
4 | using Nini.Config; | 4 | using Nini.Config; |
@@ -32,6 +32,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
32 | public class Prioritizer | 32 | public class Prioritizer |
33 | { | 33 | { |
34 | private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 34 | private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); |
35 | |||
36 | /// <summary> | ||
37 | /// This is added to the priority of all child prims, to make sure that the root prim update is sent to the | ||
38 | /// viewer before child prim updates. | ||
39 | /// The adjustment is added to child prims and subtracted from root prims, so the gap ends up | ||
40 | /// being double. We do it both ways so that there is a still a priority delta even if the priority is already | ||
41 | /// double.MinValue or double.MaxValue. | ||
42 | /// </summary> | ||
43 | private double m_childPrimAdjustmentFactor = 0.05; | ||
35 | 44 | ||
36 | private Scene m_scene; | 45 | private Scene m_scene; |
37 | 46 | ||
@@ -42,21 +51,50 @@ namespace OpenSim.Region.Framework.Scenes | |||
42 | 51 | ||
43 | public double GetUpdatePriority(IClientAPI client, ISceneEntity entity) | 52 | public double GetUpdatePriority(IClientAPI client, ISceneEntity entity) |
44 | { | 53 | { |
54 | double priority = 0; | ||
55 | |||
45 | switch (m_scene.UpdatePrioritizationScheme) | 56 | switch (m_scene.UpdatePrioritizationScheme) |
46 | { | 57 | { |
47 | case UpdatePrioritizationSchemes.Time: | 58 | case UpdatePrioritizationSchemes.Time: |
48 | return GetPriorityByTime(); | 59 | priority = GetPriorityByTime(); |
60 | break; | ||
49 | case UpdatePrioritizationSchemes.Distance: | 61 | case UpdatePrioritizationSchemes.Distance: |
50 | return GetPriorityByDistance(client, entity); | 62 | priority = GetPriorityByDistance(client, entity); |
63 | break; | ||
51 | case UpdatePrioritizationSchemes.SimpleAngularDistance: | 64 | case UpdatePrioritizationSchemes.SimpleAngularDistance: |
52 | return GetPriorityByDistance(client, entity); // TODO: Reimplement SimpleAngularDistance | 65 | priority = GetPriorityByDistance(client, entity); // TODO: Reimplement SimpleAngularDistance |
66 | break; | ||
53 | case UpdatePrioritizationSchemes.FrontBack: | 67 | case UpdatePrioritizationSchemes.FrontBack: |
54 | return GetPriorityByFrontBack(client, entity); | 68 | priority = GetPriorityByFrontBack(client, entity); |
69 | break; | ||
55 | case UpdatePrioritizationSchemes.BestAvatarResponsiveness: | 70 | case UpdatePrioritizationSchemes.BestAvatarResponsiveness: |
56 | return GetPriorityByBestAvatarResponsiveness(client, entity); | 71 | priority = GetPriorityByBestAvatarResponsiveness(client, entity); |
72 | break; | ||
57 | default: | 73 | default: |
58 | throw new InvalidOperationException("UpdatePrioritizationScheme not defined."); | 74 | throw new InvalidOperationException("UpdatePrioritizationScheme not defined."); |
75 | break; | ||
59 | } | 76 | } |
77 | |||
78 | // Adjust priority so that root prims are sent to the viewer first. This is especially important for | ||
79 | // attachments acting as huds, since current viewers fail to display hud child prims if their updates | ||
80 | // arrive before the root one. | ||
81 | if (entity is SceneObjectPart) | ||
82 | { | ||
83 | SceneObjectPart sop = ((SceneObjectPart)entity); | ||
84 | |||
85 | if (sop.IsRoot) | ||
86 | { | ||
87 | if (priority >= double.MinValue + m_childPrimAdjustmentFactor) | ||
88 | priority -= m_childPrimAdjustmentFactor; | ||
89 | } | ||
90 | else | ||
91 | { | ||
92 | if (priority <= double.MaxValue - m_childPrimAdjustmentFactor) | ||
93 | priority += m_childPrimAdjustmentFactor; | ||
94 | } | ||
95 | } | ||
96 | |||
97 | return priority; | ||
60 | } | 98 | } |
61 | 99 | ||
62 | private double GetPriorityByTime() | 100 | private double GetPriorityByTime() |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 2544359..4e90d09 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -2066,8 +2066,34 @@ namespace OpenSim.Region.Framework.Scenes | |||
2066 | sceneObject.ScheduleGroupForFullUpdate(); | 2066 | sceneObject.ScheduleGroupForFullUpdate(); |
2067 | 2067 | ||
2068 | return sceneObject; | 2068 | return sceneObject; |
2069 | } | ||
2070 | |||
2071 | /// <summary> | ||
2072 | /// Add an object into the scene that has come from storage | ||
2073 | /// </summary> | ||
2074 | /// | ||
2075 | /// <param name="sceneObject"></param> | ||
2076 | /// <param name="attachToBackup"> | ||
2077 | /// If true, changes to the object will be reflected in its persisted data | ||
2078 | /// If false, the persisted data will not be changed even if the object in the scene is changed | ||
2079 | /// </param> | ||
2080 | /// <param name="alreadyPersisted"> | ||
2081 | /// If true, we won't persist this object until it changes | ||
2082 | /// If false, we'll persist this object immediately | ||
2083 | /// </param> | ||
2084 | /// <param name="sendClientUpdates"> | ||
2085 | /// If true, we send updates to the client to tell it about this object | ||
2086 | /// If false, we leave it up to the caller to do this | ||
2087 | /// </param> | ||
2088 | /// <returns> | ||
2089 | /// true if the object was added, false if an object with the same uuid was already in the scene | ||
2090 | /// </returns> | ||
2091 | public bool AddRestoredSceneObject( | ||
2092 | SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) | ||
2093 | { | ||
2094 | return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); | ||
2069 | } | 2095 | } |
2070 | 2096 | ||
2071 | /// <summary> | 2097 | /// <summary> |
2072 | /// Add an object into the scene that has come from storage | 2098 | /// Add an object into the scene that has come from storage |
2073 | /// </summary> | 2099 | /// </summary> |
@@ -2087,7 +2113,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2087 | public bool AddRestoredSceneObject( | 2113 | public bool AddRestoredSceneObject( |
2088 | SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) | 2114 | SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) |
2089 | { | 2115 | { |
2090 | return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted); | 2116 | return AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, true); |
2091 | } | 2117 | } |
2092 | 2118 | ||
2093 | /// <summary> | 2119 | /// <summary> |
@@ -2527,7 +2553,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
2527 | sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez); | 2553 | sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez); |
2528 | sceneObject.RootPart.AddFlag(PrimFlags.Phantom); | 2554 | sceneObject.RootPart.AddFlag(PrimFlags.Phantom); |
2529 | 2555 | ||
2530 | AddRestoredSceneObject(sceneObject, false, false); | 2556 | |
2557 | // Don't sent a full update here because this will cause full updates to be sent twice for | ||
2558 | // attachments on region crossings, resulting in viewer glitches. | ||
2559 | AddRestoredSceneObject(sceneObject, false, false, false); | ||
2531 | 2560 | ||
2532 | // Handle attachment special case | 2561 | // Handle attachment special case |
2533 | SceneObjectPart RootPrim = sceneObject.RootPart; | 2562 | SceneObjectPart RootPrim = sceneObject.RootPart; |
@@ -2554,12 +2583,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2554 | m_log.DebugFormat( | 2583 | m_log.DebugFormat( |
2555 | "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); | 2584 | "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); |
2556 | 2585 | ||
2586 | RootPrim.RemFlag(PrimFlags.TemporaryOnRez); | ||
2587 | |||
2557 | if (AttachmentsModule != null) | 2588 | if (AttachmentsModule != null) |
2558 | AttachmentsModule.AttachObject( | 2589 | AttachmentsModule.AttachObject( |
2559 | sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition, false); | 2590 | sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition, false); |
2560 | 2591 | ||
2561 | RootPrim.RemFlag(PrimFlags.TemporaryOnRez); | 2592 | //grp.SendGroupFullUpdate(); |
2562 | grp.SendGroupFullUpdate(); | ||
2563 | } | 2593 | } |
2564 | else | 2594 | else |
2565 | { | 2595 | { |
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index a02f614..5902080 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -222,11 +222,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
222 | /// If true, we won't persist this object until it changes | 222 | /// If true, we won't persist this object until it changes |
223 | /// If false, we'll persist this object immediately | 223 | /// If false, we'll persist this object immediately |
224 | /// </param> | 224 | /// </param> |
225 | /// <param name="sendClientUpdates"> | ||
226 | /// If true, we send updates to the client to tell it about this object | ||
227 | /// If false, we leave it up to the caller to do this | ||
228 | /// </param> | ||
225 | /// <returns> | 229 | /// <returns> |
226 | /// true if the object was added, false if an object with the same uuid was already in the scene | 230 | /// true if the object was added, false if an object with the same uuid was already in the scene |
227 | /// </returns> | 231 | /// </returns> |
228 | protected internal bool AddRestoredSceneObject( | 232 | protected internal bool AddRestoredSceneObject( |
229 | SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) | 233 | SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) |
230 | { | 234 | { |
231 | if (!alreadyPersisted) | 235 | if (!alreadyPersisted) |
232 | { | 236 | { |
@@ -234,9 +238,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
234 | sceneObject.HasGroupChanged = true; | 238 | sceneObject.HasGroupChanged = true; |
235 | } | 239 | } |
236 | 240 | ||
237 | return AddSceneObject(sceneObject, attachToBackup, true); | 241 | return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates); |
238 | } | 242 | } |
239 | 243 | ||
240 | /// <summary> | 244 | /// <summary> |
241 | /// Add a newly created object to the scene. This will both update the scene, and send information about the | 245 | /// Add a newly created object to the scene. This will both update the scene, and send information about the |
242 | /// new object to all clients interested in the scene. | 246 | /// new object to all clients interested in the scene. |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 837d3a2..78c2566 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -2012,7 +2012,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2012 | /// </summary> | 2012 | /// </summary> |
2013 | public void ScheduleGroupForFullUpdate() | 2013 | public void ScheduleGroupForFullUpdate() |
2014 | { | 2014 | { |
2015 | // m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, UUID); | 2015 | if (IsAttachment) |
2016 | m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, LocalId); | ||
2016 | 2017 | ||
2017 | checkAtTargets(); | 2018 | checkAtTargets(); |
2018 | RootPart.ScheduleFullUpdate(); | 2019 | RootPart.ScheduleFullUpdate(); |