diff options
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 43 | ||||
-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 |
5 files changed, 130 insertions, 18 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index fe8475a..7090855 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -331,6 +331,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
331 | /// </value> | 331 | /// </value> |
332 | protected HashSet<uint> m_killRecord; | 332 | protected HashSet<uint> m_killRecord; |
333 | 333 | ||
334 | // protected HashSet<uint> m_attachmentsSent; | ||
335 | |||
334 | private int m_moneyBalance; | 336 | private int m_moneyBalance; |
335 | private int m_animationSequenceNumber = 1; | 337 | private int m_animationSequenceNumber = 1; |
336 | private bool m_SendLogoutPacketWhenClosing = true; | 338 | private bool m_SendLogoutPacketWhenClosing = true; |
@@ -430,6 +432,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
430 | m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); | 432 | m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); |
431 | m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); | 433 | m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); |
432 | m_killRecord = new HashSet<uint>(); | 434 | m_killRecord = new HashSet<uint>(); |
435 | // m_attachmentsSent = new HashSet<uint>(); | ||
433 | 436 | ||
434 | m_assetService = m_scene.RequestModuleInterface<IAssetService>(); | 437 | m_assetService = m_scene.RequestModuleInterface<IAssetService>(); |
435 | m_hyperAssets = m_scene.RequestModuleInterface<IHyperAssetService>(); | 438 | m_hyperAssets = m_scene.RequestModuleInterface<IHyperAssetService>(); |
@@ -3411,6 +3414,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3411 | objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence); | 3414 | objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence); |
3412 | 3415 | ||
3413 | OutPacket(objupdate, ThrottleOutPacketType.Task); | 3416 | OutPacket(objupdate, ThrottleOutPacketType.Task); |
3417 | |||
3418 | // We need to record the avatar local id since the root prim of an attachment points to this. | ||
3419 | // m_attachmentsSent.Add(avatar.LocalId); | ||
3414 | } | 3420 | } |
3415 | 3421 | ||
3416 | public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) | 3422 | public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) |
@@ -3466,7 +3472,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3466 | double priority = m_prioritizer.GetUpdatePriority(this, entity); | 3472 | double priority = m_prioritizer.GetUpdatePriority(this, entity); |
3467 | 3473 | ||
3468 | lock (m_entityUpdates.SyncRoot) | 3474 | lock (m_entityUpdates.SyncRoot) |
3469 | m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags), entity.LocalId); | 3475 | m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags), entity.LocalId); |
3470 | } | 3476 | } |
3471 | 3477 | ||
3472 | private void ProcessEntityUpdates(int maxUpdates) | 3478 | private void ProcessEntityUpdates(int maxUpdates) |
@@ -3542,9 +3548,42 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3542 | if (!canUseImproved && !canUseCompressed) | 3548 | if (!canUseImproved && !canUseCompressed) |
3543 | { | 3549 | { |
3544 | if (update.Entity is ScenePresence) | 3550 | if (update.Entity is ScenePresence) |
3551 | { | ||
3545 | objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); | 3552 | objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); |
3553 | } | ||
3546 | else | 3554 | else |
3547 | objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); | 3555 | { |
3556 | // if (update.Entity is SceneObjectPart && ((SceneObjectPart)update.Entity).IsAttachment) | ||
3557 | // { | ||
3558 | // SceneObjectPart sop = (SceneObjectPart)update.Entity; | ||
3559 | // string text = sop.Text; | ||
3560 | // if (text.IndexOf("\n") >= 0) | ||
3561 | // text = text.Remove(text.IndexOf("\n")); | ||
3562 | // | ||
3563 | // if (m_attachmentsSent.Contains(sop.ParentID)) | ||
3564 | // { | ||
3565 | //// m_log.DebugFormat( | ||
3566 | //// "[CLIENT]: Sending full info about attached prim {0} text {1}", | ||
3567 | //// sop.LocalId, text); | ||
3568 | // | ||
3569 | // objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock(sop, this.m_agentId)); | ||
3570 | // | ||
3571 | // m_attachmentsSent.Add(sop.LocalId); | ||
3572 | // } | ||
3573 | // else | ||
3574 | // { | ||
3575 | // m_log.DebugFormat( | ||
3576 | // "[CLIENT]: Requeueing full update of prim {0} text {1} since we haven't sent its parent {2} yet", | ||
3577 | // sop.LocalId, text, sop.ParentID); | ||
3578 | // | ||
3579 | // m_entityUpdates.Enqueue(double.MaxValue, update, sop.LocalId); | ||
3580 | // } | ||
3581 | // } | ||
3582 | // else | ||
3583 | // { | ||
3584 | objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); | ||
3585 | // } | ||
3586 | } | ||
3548 | } | 3587 | } |
3549 | else if (!canUseImproved) | 3588 | else if (!canUseImproved) |
3550 | { | 3589 | { |
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 756b81e..48ffbce 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -2094,8 +2094,34 @@ namespace OpenSim.Region.Framework.Scenes | |||
2094 | sceneObject.ScheduleGroupForFullUpdate(); | 2094 | sceneObject.ScheduleGroupForFullUpdate(); |
2095 | 2095 | ||
2096 | return sceneObject; | 2096 | return sceneObject; |
2097 | } | ||
2098 | |||
2099 | /// <summary> | ||
2100 | /// Add an object into the scene that has come from storage | ||
2101 | /// </summary> | ||
2102 | /// | ||
2103 | /// <param name="sceneObject"></param> | ||
2104 | /// <param name="attachToBackup"> | ||
2105 | /// If true, changes to the object will be reflected in its persisted data | ||
2106 | /// If false, the persisted data will not be changed even if the object in the scene is changed | ||
2107 | /// </param> | ||
2108 | /// <param name="alreadyPersisted"> | ||
2109 | /// If true, we won't persist this object until it changes | ||
2110 | /// If false, we'll persist this object immediately | ||
2111 | /// </param> | ||
2112 | /// <param name="sendClientUpdates"> | ||
2113 | /// If true, we send updates to the client to tell it about this object | ||
2114 | /// If false, we leave it up to the caller to do this | ||
2115 | /// </param> | ||
2116 | /// <returns> | ||
2117 | /// true if the object was added, false if an object with the same uuid was already in the scene | ||
2118 | /// </returns> | ||
2119 | public bool AddRestoredSceneObject( | ||
2120 | SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) | ||
2121 | { | ||
2122 | return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); | ||
2097 | } | 2123 | } |
2098 | 2124 | ||
2099 | /// <summary> | 2125 | /// <summary> |
2100 | /// Add an object into the scene that has come from storage | 2126 | /// Add an object into the scene that has come from storage |
2101 | /// </summary> | 2127 | /// </summary> |
@@ -2115,7 +2141,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2115 | public bool AddRestoredSceneObject( | 2141 | public bool AddRestoredSceneObject( |
2116 | SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) | 2142 | SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) |
2117 | { | 2143 | { |
2118 | return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted); | 2144 | return AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, true); |
2119 | } | 2145 | } |
2120 | 2146 | ||
2121 | /// <summary> | 2147 | /// <summary> |
@@ -2555,7 +2581,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
2555 | sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez); | 2581 | sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez); |
2556 | sceneObject.RootPart.AddFlag(PrimFlags.Phantom); | 2582 | sceneObject.RootPart.AddFlag(PrimFlags.Phantom); |
2557 | 2583 | ||
2558 | AddRestoredSceneObject(sceneObject, false, false); | 2584 | |
2585 | // Don't sent a full update here because this will cause full updates to be sent twice for | ||
2586 | // attachments on region crossings, resulting in viewer glitches. | ||
2587 | AddRestoredSceneObject(sceneObject, false, false, false); | ||
2559 | 2588 | ||
2560 | // Handle attachment special case | 2589 | // Handle attachment special case |
2561 | SceneObjectPart RootPrim = sceneObject.RootPart; | 2590 | SceneObjectPart RootPrim = sceneObject.RootPart; |
@@ -2582,12 +2611,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2582 | m_log.DebugFormat( | 2611 | m_log.DebugFormat( |
2583 | "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); | 2612 | "[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition); |
2584 | 2613 | ||
2614 | RootPrim.RemFlag(PrimFlags.TemporaryOnRez); | ||
2615 | |||
2585 | if (AttachmentsModule != null) | 2616 | if (AttachmentsModule != null) |
2586 | AttachmentsModule.AttachObject( | 2617 | AttachmentsModule.AttachObject( |
2587 | sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition, false); | 2618 | sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition, false); |
2588 | 2619 | ||
2589 | RootPrim.RemFlag(PrimFlags.TemporaryOnRez); | 2620 | //grp.SendGroupFullUpdate(); |
2590 | grp.SendGroupFullUpdate(); | ||
2591 | } | 2621 | } |
2592 | else | 2622 | else |
2593 | { | 2623 | { |
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 5fbc658..1dab4df 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -227,11 +227,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
227 | /// If true, we won't persist this object until it changes | 227 | /// If true, we won't persist this object until it changes |
228 | /// If false, we'll persist this object immediately | 228 | /// If false, we'll persist this object immediately |
229 | /// </param> | 229 | /// </param> |
230 | /// <param name="sendClientUpdates"> | ||
231 | /// If true, we send updates to the client to tell it about this object | ||
232 | /// If false, we leave it up to the caller to do this | ||
233 | /// </param> | ||
230 | /// <returns> | 234 | /// <returns> |
231 | /// true if the object was added, false if an object with the same uuid was already in the scene | 235 | /// true if the object was added, false if an object with the same uuid was already in the scene |
232 | /// </returns> | 236 | /// </returns> |
233 | protected internal bool AddRestoredSceneObject( | 237 | protected internal bool AddRestoredSceneObject( |
234 | SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) | 238 | SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) |
235 | { | 239 | { |
236 | // KF: Check for out-of-region, move inside and make static. | 240 | // KF: Check for out-of-region, move inside and make static. |
237 | Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X, | 241 | Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X, |
@@ -263,9 +267,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
263 | sceneObject.HasGroupChanged = true; | 267 | sceneObject.HasGroupChanged = true; |
264 | } | 268 | } |
265 | 269 | ||
266 | return AddSceneObject(sceneObject, attachToBackup, true); | 270 | return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates); |
267 | } | 271 | } |
268 | 272 | ||
269 | /// <summary> | 273 | /// <summary> |
270 | /// Add a newly created object to the scene. This will both update the scene, and send information about the | 274 | /// Add a newly created object to the scene. This will both update the scene, and send information about the |
271 | /// new object to all clients interested in the scene. | 275 | /// 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 7e73f91..f918291 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -2229,7 +2229,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2229 | /// </summary> | 2229 | /// </summary> |
2230 | public void ScheduleGroupForFullUpdate() | 2230 | public void ScheduleGroupForFullUpdate() |
2231 | { | 2231 | { |
2232 | // m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, UUID); | 2232 | if (IsAttachment) |
2233 | m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, LocalId); | ||
2233 | 2234 | ||
2234 | checkAtTargets(); | 2235 | checkAtTargets(); |
2235 | RootPart.ScheduleFullUpdate(); | 2236 | RootPart.ScheduleFullUpdate(); |