diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 018f19435b..0140733064 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -585,10 +585,10 @@ namespace OpenSim.Framework
public float dwell;
}
- public class IEntityUpdate
+ public class EntityUpdate
{
private ISceneEntity m_entity;
- private uint m_flags;
+ private PrimUpdateFlags m_flags;
private int m_updateTime;
public ISceneEntity Entity
@@ -596,7 +596,7 @@ namespace OpenSim.Framework
get { return m_entity; }
}
- public uint Flags
+ public PrimUpdateFlags Flags
{
get { return m_flags; }
}
@@ -606,23 +606,31 @@ namespace OpenSim.Framework
get { return m_updateTime; }
}
- public virtual void Update(IEntityUpdate update)
+ public virtual void Update(EntityUpdate update)
{
- m_flags |= update.Flags;
+ PrimUpdateFlags updateFlags = update.Flags;
+ if(updateFlags.HasFlag(PrimUpdateFlags.CancelKill))
+ m_flags = PrimUpdateFlags.FullUpdate;
+ else if(m_flags.HasFlag(PrimUpdateFlags.Kill))
+ return;
+ else if(updateFlags.HasFlag(PrimUpdateFlags.Kill))
+ m_flags = PrimUpdateFlags.Kill;
+ else
+ m_flags |= updateFlags;
// Use the older of the updates as the updateTime
if (Util.EnvironmentTickCountCompare(UpdateTime, update.UpdateTime) > 0)
m_updateTime = update.UpdateTime;
}
- public IEntityUpdate(ISceneEntity entity, uint flags)
+ public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags)
{
m_entity = entity;
m_flags = flags;
m_updateTime = Util.EnvironmentTickCount();
}
- public IEntityUpdate(ISceneEntity entity, uint flags, Int32 updateTime)
+ public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, Int32 updateTime)
{
m_entity = entity;
m_flags = flags;
@@ -630,29 +638,6 @@ namespace OpenSim.Framework
}
}
- public class EntityUpdate : IEntityUpdate
- {
- private float m_timeDilation;
-
- public float TimeDilation
- {
- get { return m_timeDilation; }
- }
-
- public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, float timedilation)
- : base(entity, (uint)flags)
- {
- // Flags = flags;
- m_timeDilation = timedilation;
- }
-
- public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, float timedilation, Int32 updateTime)
- : base(entity,(uint)flags,updateTime)
- {
- m_timeDilation = timedilation;
- }
- }
-
public class PlacesReplyData
{
public UUID OwnerID;
@@ -701,9 +686,12 @@ namespace OpenSim.Framework
ExtraData = 1 << 20,
Sound = 1 << 21,
Joint = 1 << 22,
- FullUpdate = UInt32.MaxValue
+ FullUpdate = 0x3fffffff,
+ CancelKill = 0x7fffffff,
+ Kill = 0x80000000
}
+/* included in .net 4.0
public static class PrimUpdateFlagsExtensions
{
public static bool HasFlag(this PrimUpdateFlags updateFlags, PrimUpdateFlags flag)
@@ -711,7 +699,7 @@ namespace OpenSim.Framework
return (updateFlags & flag) == flag;
}
}
-
+*/
public interface IClientAPI
{
Vector3 StartPos { get; set; }
diff --git a/OpenSim/Framework/PriorityQueue.cs b/OpenSim/Framework/PriorityQueue.cs
index 4f05f6540a..fec01da4bf 100644
--- a/OpenSim/Framework/PriorityQueue.cs
+++ b/OpenSim/Framework/PriorityQueue.cs
@@ -113,7 +113,7 @@ namespace OpenSim.Framework
///
/// Enqueue an item into the specified priority queue
///
- public bool Enqueue(uint pqueue, IEntityUpdate value)
+ public bool Enqueue(uint pqueue, EntityUpdate value)
{
LookupItem lookup;
@@ -154,7 +154,7 @@ namespace OpenSim.Framework
/// oldest item from the next queue in order to provide fair access to
/// all of the queues
///
- public bool TryDequeue(out IEntityUpdate value, out Int32 timeinqueue)
+ public bool TryDequeue(out EntityUpdate value, out Int32 timeinqueue)
{
// If there is anything in imediate queues, return it first no
// matter what else. Breaks fairness. But very useful.
@@ -212,7 +212,7 @@ namespace OpenSim.Framework
}
timeinqueue = 0;
- value = default(IEntityUpdate);
+ value = default(EntityUpdate);
return false;
}
@@ -270,8 +270,8 @@ namespace OpenSim.Framework
#region MinHeapItem
private struct MinHeapItem : IComparable
{
- private IEntityUpdate value;
- internal IEntityUpdate Value {
+ private EntityUpdate value;
+ internal EntityUpdate Value {
get {
return this.value;
}
@@ -307,7 +307,7 @@ namespace OpenSim.Framework
this.pqueue = pqueue;
}
- internal MinHeapItem(uint pqueue, UInt64 entryorder, IEntityUpdate value)
+ internal MinHeapItem(uint pqueue, UInt64 entryorder, EntityUpdate value)
{
this.entrytime = Util.EnvironmentTickCount();
this.entryorder = entryorder;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index e3b2fd1f85..b823abe592 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -3937,7 +3937,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
uint priority = m_prioritizer.GetUpdatePriority(this, entity);
lock (m_entityUpdates.SyncRoot)
- m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation));
+ m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags));
}
///
@@ -4006,12 +4006,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
// condition where a kill can be processed before an out-of-date update for the same object.
// float avgTimeDilation = 0.0f;
- IEntityUpdate iupdate;
+ EntityUpdate update;
Int32 timeinqueue; // this is just debugging code & can be dropped later
bool doCulling = m_scene.ObjectsCullingByDistance;
float cullingrange = 64.0f;
HashSet GroupsNeedFullUpdate = new HashSet();
+ List kills = new List();
// Vector3 mycamera = Vector3.Zero;
Vector3 mypos = Vector3.Zero;
ScenePresence mysp = (ScenePresence)SceneAgent;
@@ -4027,12 +4028,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
while (updatesThisCall < maxUpdates)
{
lock (m_entityUpdates.SyncRoot)
- if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
+ if (!m_entityUpdates.TryDequeue(out update, out timeinqueue))
break;
-
- EntityUpdate update = (EntityUpdate)iupdate;
-
+
// avgTimeDilation += update.TimeDilation;
+ PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
+
+ if(updateFlags.HasFlag(PrimUpdateFlags.Kill))
+ {
+ m_killRecord.Add(update.Entity.LocalId);
+ continue;
+ }
if (update.Entity is SceneObjectPart)
{
@@ -4156,11 +4162,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region UpdateFlags to packet type conversion
- PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
-
bool canUseCompressed = true;
bool canUseImproved = true;
+
// Compressed object updates only make sense for LL primitives
if (!(update.Entity is SceneObjectPart))
{
@@ -4319,17 +4324,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_killRecord.Clear();
}
+ if (kills.Count > 0)
+ {
+ foreach(SceneObjectGroup grp in kills)
+ {
+ foreach(SceneObjectPart p in grp.Parts)
+ SendEntityUpdate(p,PrimUpdateFlags.Kill);
+ }
+ kills.Clear();
+ }
+
if(GroupsNeedFullUpdate.Count > 0)
{
foreach(SceneObjectGroup grp in GroupsNeedFullUpdate)
{
- grp.ScheduleGroupForFullUpdate();
+ foreach(SceneObjectPart p in grp.Parts)
+ SendEntityUpdate(p,PrimUpdateFlags.CancelKill);
lock(GroupsInView)
GroupsInView.Add(grp);
}
}
#endregion
-
}
// hack.. dont use
@@ -4368,7 +4383,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
private bool CheckGroupsInViewBusy = false;
- private bool CheckGroupsInViewOverRun = false;
public void CheckGroupsInView()
{
@@ -4377,112 +4391,90 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return;
if(CheckGroupsInViewBusy)
+ return;
+
+ CheckGroupsInViewBusy = true;
+
+ float cullingrange = 64.0f;
+// Vector3 mycamera = Vector3.Zero;
+ Vector3 mypos = Vector3.Zero;
+ ScenePresence mysp = (ScenePresence)SceneAgent;
+ if(mysp != null && !mysp.IsDeleted)
{
- CheckGroupsInViewOverRun = true;
+ cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f;
+// mycamera = mysp.CameraPosition;
+ mypos = mysp.AbsolutePosition;
+ }
+ else
+ {
+ CheckGroupsInViewBusy= false;
return;
}
- CheckGroupsInViewBusy = true;
- do
+
+ HashSet NewGroupsInView = new HashSet();
+ HashSet GroupsNeedFullUpdate = new HashSet();
+ List kills = new List();
+
+ EntityBase[] entities = m_scene.Entities.GetEntities();
+ foreach (EntityBase e in entities)
{
- CheckGroupsInViewOverRun = false;
-
- float cullingrange = 64.0f;
-// Vector3 mycamera = Vector3.Zero;
- Vector3 mypos = Vector3.Zero;
- ScenePresence mysp = (ScenePresence)SceneAgent;
- if(mysp != null && !mysp.IsDeleted)
- {
- cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f;
-// mycamera = mysp.CameraPosition;
- mypos = mysp.AbsolutePosition;
- }
- else
- {
- CheckGroupsInViewBusy= false;
+ if(!IsActive)
return;
- }
- HashSet NewGroupsInView = new HashSet();
- HashSet GroupsNeedFullUpdate = new HashSet();
- List kills = new List();
- int killedParst = 0;
-
- EntityBase[] entities = m_scene.Entities.GetEntities();
- foreach (EntityBase e in entities)
+ if (e != null && e is SceneObjectGroup)
{
- if(!IsActive)
- return;
+ SceneObjectGroup grp = (SceneObjectGroup)e;
+ if(grp.IsDeleted || grp.IsAttachment)
+ continue;
- if (e != null && e is SceneObjectGroup)
- {
- SceneObjectGroup grp = (SceneObjectGroup)e;
- if(grp.IsDeleted || grp.IsAttachment)
- continue;
-
- float bradius = grp.GetBoundsRadius();
- Vector3 grppos = grp.AbsolutePosition + grp.getBoundsCenter();
+ float bradius = grp.GetBoundsRadius();
+ Vector3 grppos = grp.AbsolutePosition + grp.getBoundsCenter();
// float dcam = (grppos - mycamera).LengthSquared();
- float dpos = (grppos - mypos).LengthSquared();
+ float dpos = (grppos - mypos).LengthSquared();
// if(dcam < dpos)
// dpos = dcam;
- dpos = (float)Math.Sqrt(dpos) - bradius;
+ dpos = (float)Math.Sqrt(dpos) - bradius;
- bool inview;
- lock(GroupsInView)
- inview = GroupsInView.Contains(grp);
+ bool inview;
+ lock(GroupsInView)
+ inview = GroupsInView.Contains(grp);
- if(dpos > cullingrange)
- {
- if(inview)
- {
- kills.Add(grp.LocalId);
- killedParst += grp.PrimCount;
-
- if (killedParst > 199 )
- {
- SendKillObject(kills);
- kills.Clear();
- killedParst = 0;
- Thread.Sleep(50);
- if(mysp != null && !mysp.IsDeleted)
- {
- cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f;
-// mycamera = mysp.CameraPosition;
- mypos = mysp.AbsolutePosition;
- }
- else
- {
- CheckGroupsInViewBusy= false;
- return;
- }
- }
- }
- }
- else
- {
- if(!inview)
- GroupsNeedFullUpdate.Add(grp);
- NewGroupsInView.Add(grp);
- }
+ if(dpos > cullingrange)
+ {
+ if(inview)
+ kills.Add(grp);
+ }
+ else
+ {
+ if(!inview)
+ GroupsNeedFullUpdate.Add(grp);
+ NewGroupsInView.Add(grp);
}
}
+ }
- lock(GroupsInView)
- GroupsInView = NewGroupsInView;
+ lock(GroupsInView)
+ GroupsInView = NewGroupsInView;
- if (kills.Count > 0)
+ if (kills.Count > 0)
+ {
+ foreach(SceneObjectGroup grp in kills)
{
- SendKillObject(kills);
- kills.Clear();
+ foreach(SceneObjectPart p in grp.Parts)
+ SendEntityUpdate(p,PrimUpdateFlags.Kill);
}
+ kills.Clear();
+ }
- if(GroupsNeedFullUpdate.Count > 0)
+ if(GroupsNeedFullUpdate.Count > 0)
+ {
+ foreach(SceneObjectGroup grp in GroupsNeedFullUpdate)
{
- foreach(SceneObjectGroup grp in GroupsNeedFullUpdate)
- grp.ScheduleGroupForFullUpdate();
+ foreach(SceneObjectPart p in grp.Parts)
+ SendEntityUpdate(p,PrimUpdateFlags.CancelKill);
}
- } while(CheckGroupsInViewOverRun);
+ }
CheckGroupsInViewBusy = false;
}
@@ -4670,13 +4662,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
OutPacket(pack, ThrottleOutPacketType.Task);
}
- private class ObjectPropertyUpdate : IEntityUpdate
+ private class ObjectPropertyUpdate : EntityUpdate
{
internal bool SendFamilyProps;
internal bool SendObjectProps;
public ObjectPropertyUpdate(ISceneEntity entity, uint flags, bool sendfam, bool sendobj)
- : base(entity,flags)
+ : base(entity,(PrimUpdateFlags)flags)
{
SendFamilyProps = sendfam;
SendObjectProps = sendobj;
@@ -4745,7 +4737,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
OpenSim.Framework.Lazy> propertyUpdates =
new OpenSim.Framework.Lazy>();
- IEntityUpdate iupdate;
+ EntityUpdate iupdate;
Int32 timeinqueue; // this is just debugging code & can be dropped later
int updatesThisCall = 0;
@@ -4849,11 +4841,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// m_log.WarnFormat("[PACKETCOUNTS] queued {0} family property packets with {1} blocks",fpcnt,fbcnt);
}
- private ObjectPropertiesFamilyPacket.ObjectDataBlock CreateObjectPropertiesFamilyBlock(SceneObjectPart sop, uint requestFlags)
+ private ObjectPropertiesFamilyPacket.ObjectDataBlock CreateObjectPropertiesFamilyBlock(SceneObjectPart sop, PrimUpdateFlags requestFlags)
{
ObjectPropertiesFamilyPacket.ObjectDataBlock block = new ObjectPropertiesFamilyPacket.ObjectDataBlock();
- block.RequestFlags = requestFlags;
+ block.RequestFlags = (uint)requestFlags;
block.ObjectID = sop.UUID;
if (sop.OwnerID == sop.GroupID)
block.OwnerID = UUID.Zero;