aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs43
-rw-r--r--OpenSim/Region/Framework/Scenes/Prioritizer.cs50
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs42
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs10
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs3
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 @@
1using System; 1using System;
2using System.Collections.Generic; 2using System.Collections.Generic;
3using log4net; 3using log4net;
4using Nini.Config; 4using 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();