several changes related to culling option

UbitUmarov [2016-08-07 13:30:27]
several changes related to culling option
Filename
OpenSim/Framework/IClientAPI.cs
OpenSim/Framework/PriorityQueue.cs
OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 018f194..0140733 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 4f05f65..fec01da 100644
--- a/OpenSim/Framework/PriorityQueue.cs
+++ b/OpenSim/Framework/PriorityQueue.cs
@@ -113,7 +113,7 @@ namespace OpenSim.Framework
         /// <summary>
         /// Enqueue an item into the specified priority queue
         /// </summary>
-        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
         /// </summary>
-        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<MinHeapItem>
         {
-            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 e3b2fd1..b823abe 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));
         }

         /// <summary>
@@ -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<SceneObjectGroup> GroupsNeedFullUpdate = new HashSet<SceneObjectGroup>();
+            List<SceneObjectGroup> kills = new List<SceneObjectGroup>();
 //            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)
-            {
-                CheckGroupsInViewOverRun = true;
                 return;
-            }
+
             CheckGroupsInViewBusy = true;
-            do
-            {
-                CheckGroupsInViewOverRun = false;

-                float cullingrange = 64.0f;
+            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;
+            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;
-                    return;
-                }
+                mypos = mysp.AbsolutePosition;
+            }
+            else
+            {
+                CheckGroupsInViewBusy= false;
+                return;
+            }

-                HashSet<SceneObjectGroup> NewGroupsInView = new HashSet<SceneObjectGroup>();
-                HashSet<SceneObjectGroup> GroupsNeedFullUpdate = new HashSet<SceneObjectGroup>();
-                List<uint> kills = new List<uint>();
-                int killedParst = 0;
+            HashSet<SceneObjectGroup> NewGroupsInView = new HashSet<SceneObjectGroup>();
+            HashSet<SceneObjectGroup> GroupsNeedFullUpdate = new HashSet<SceneObjectGroup>();
+            List<SceneObjectGroup> kills = new List<SceneObjectGroup>();

-                EntityBase[] entities = m_scene.Entities.GetEntities();
-                foreach (EntityBase e in entities)
-                {
-                    if(!IsActive)
-                        return;
+            EntityBase[] entities = m_scene.Entities.GetEntities();
+            foreach (EntityBase e in entities)
+            {
+                if(!IsActive)
+                    return;

-                    if (e != null && e is SceneObjectGroup)
-                    {
-                        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);
-
-                        if(dpos > cullingrange)
-                        {
-                            if(inview)
-                            {
-                                kills.Add(grp.LocalId);
-                                killedParst += grp.PrimCount;
+                    bool inview;
+                    lock(GroupsInView)
+                        inview = GroupsInView.Contains(grp);

-                                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<List<ObjectPropertyUpdate>> propertyUpdates =
                 new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>();

-            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;
ViewGit