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;