several changes related to culling option

httptests
UbitUmarov 2016-08-07 14:30:27 +01:00
parent 68a4e363dd
commit 8d22b79ba4
3 changed files with 117 additions and 137 deletions

View File

@ -585,10 +585,10 @@ namespace OpenSim.Framework
public float dwell; public float dwell;
} }
public class IEntityUpdate public class EntityUpdate
{ {
private ISceneEntity m_entity; private ISceneEntity m_entity;
private uint m_flags; private PrimUpdateFlags m_flags;
private int m_updateTime; private int m_updateTime;
public ISceneEntity Entity public ISceneEntity Entity
@ -596,7 +596,7 @@ namespace OpenSim.Framework
get { return m_entity; } get { return m_entity; }
} }
public uint Flags public PrimUpdateFlags Flags
{ {
get { return m_flags; } get { return m_flags; }
} }
@ -606,23 +606,31 @@ namespace OpenSim.Framework
get { return m_updateTime; } 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 // Use the older of the updates as the updateTime
if (Util.EnvironmentTickCountCompare(UpdateTime, update.UpdateTime) > 0) if (Util.EnvironmentTickCountCompare(UpdateTime, update.UpdateTime) > 0)
m_updateTime = update.UpdateTime; m_updateTime = update.UpdateTime;
} }
public IEntityUpdate(ISceneEntity entity, uint flags) public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags)
{ {
m_entity = entity; m_entity = entity;
m_flags = flags; m_flags = flags;
m_updateTime = Util.EnvironmentTickCount(); m_updateTime = Util.EnvironmentTickCount();
} }
public IEntityUpdate(ISceneEntity entity, uint flags, Int32 updateTime) public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, Int32 updateTime)
{ {
m_entity = entity; m_entity = entity;
m_flags = flags; 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 class PlacesReplyData
{ {
public UUID OwnerID; public UUID OwnerID;
@ -701,9 +686,12 @@ namespace OpenSim.Framework
ExtraData = 1 << 20, ExtraData = 1 << 20,
Sound = 1 << 21, Sound = 1 << 21,
Joint = 1 << 22, Joint = 1 << 22,
FullUpdate = UInt32.MaxValue FullUpdate = 0x3fffffff,
CancelKill = 0x7fffffff,
Kill = 0x80000000
} }
/* included in .net 4.0
public static class PrimUpdateFlagsExtensions public static class PrimUpdateFlagsExtensions
{ {
public static bool HasFlag(this PrimUpdateFlags updateFlags, PrimUpdateFlags flag) public static bool HasFlag(this PrimUpdateFlags updateFlags, PrimUpdateFlags flag)
@ -711,7 +699,7 @@ namespace OpenSim.Framework
return (updateFlags & flag) == flag; return (updateFlags & flag) == flag;
} }
} }
*/
public interface IClientAPI public interface IClientAPI
{ {
Vector3 StartPos { get; set; } Vector3 StartPos { get; set; }

View File

@ -113,7 +113,7 @@ namespace OpenSim.Framework
/// <summary> /// <summary>
/// Enqueue an item into the specified priority queue /// Enqueue an item into the specified priority queue
/// </summary> /// </summary>
public bool Enqueue(uint pqueue, IEntityUpdate value) public bool Enqueue(uint pqueue, EntityUpdate value)
{ {
LookupItem lookup; LookupItem lookup;
@ -154,7 +154,7 @@ namespace OpenSim.Framework
/// oldest item from the next queue in order to provide fair access to /// oldest item from the next queue in order to provide fair access to
/// all of the queues /// all of the queues
/// </summary> /// </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 // If there is anything in imediate queues, return it first no
// matter what else. Breaks fairness. But very useful. // matter what else. Breaks fairness. But very useful.
@ -212,7 +212,7 @@ namespace OpenSim.Framework
} }
timeinqueue = 0; timeinqueue = 0;
value = default(IEntityUpdate); value = default(EntityUpdate);
return false; return false;
} }
@ -270,8 +270,8 @@ namespace OpenSim.Framework
#region MinHeapItem #region MinHeapItem
private struct MinHeapItem : IComparable<MinHeapItem> private struct MinHeapItem : IComparable<MinHeapItem>
{ {
private IEntityUpdate value; private EntityUpdate value;
internal IEntityUpdate Value { internal EntityUpdate Value {
get { get {
return this.value; return this.value;
} }
@ -307,7 +307,7 @@ namespace OpenSim.Framework
this.pqueue = pqueue; this.pqueue = pqueue;
} }
internal MinHeapItem(uint pqueue, UInt64 entryorder, IEntityUpdate value) internal MinHeapItem(uint pqueue, UInt64 entryorder, EntityUpdate value)
{ {
this.entrytime = Util.EnvironmentTickCount(); this.entrytime = Util.EnvironmentTickCount();
this.entryorder = entryorder; this.entryorder = entryorder;

View File

@ -3937,7 +3937,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
uint priority = m_prioritizer.GetUpdatePriority(this, entity); uint priority = m_prioritizer.GetUpdatePriority(this, entity);
lock (m_entityUpdates.SyncRoot) lock (m_entityUpdates.SyncRoot)
m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation)); m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags));
} }
/// <summary> /// <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 // 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. // condition where a kill can be processed before an out-of-date update for the same object.
// float avgTimeDilation = 0.0f; // float avgTimeDilation = 0.0f;
IEntityUpdate iupdate; EntityUpdate update;
Int32 timeinqueue; // this is just debugging code & can be dropped later Int32 timeinqueue; // this is just debugging code & can be dropped later
bool doCulling = m_scene.ObjectsCullingByDistance; bool doCulling = m_scene.ObjectsCullingByDistance;
float cullingrange = 64.0f; float cullingrange = 64.0f;
HashSet<SceneObjectGroup> GroupsNeedFullUpdate = new HashSet<SceneObjectGroup>(); HashSet<SceneObjectGroup> GroupsNeedFullUpdate = new HashSet<SceneObjectGroup>();
List<SceneObjectGroup> kills = new List<SceneObjectGroup>();
// Vector3 mycamera = Vector3.Zero; // Vector3 mycamera = Vector3.Zero;
Vector3 mypos = Vector3.Zero; Vector3 mypos = Vector3.Zero;
ScenePresence mysp = (ScenePresence)SceneAgent; ScenePresence mysp = (ScenePresence)SceneAgent;
@ -4027,12 +4028,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
while (updatesThisCall < maxUpdates) while (updatesThisCall < maxUpdates)
{ {
lock (m_entityUpdates.SyncRoot) lock (m_entityUpdates.SyncRoot)
if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue)) if (!m_entityUpdates.TryDequeue(out update, out timeinqueue))
break; break;
EntityUpdate update = (EntityUpdate)iupdate;
// avgTimeDilation += update.TimeDilation; // 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) if (update.Entity is SceneObjectPart)
{ {
@ -4156,11 +4162,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region UpdateFlags to packet type conversion #region UpdateFlags to packet type conversion
PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
bool canUseCompressed = true; bool canUseCompressed = true;
bool canUseImproved = true; bool canUseImproved = true;
// Compressed object updates only make sense for LL primitives // Compressed object updates only make sense for LL primitives
if (!(update.Entity is SceneObjectPart)) if (!(update.Entity is SceneObjectPart))
{ {
@ -4319,17 +4324,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_killRecord.Clear(); 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) 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);
lock(GroupsInView) lock(GroupsInView)
GroupsInView.Add(grp); GroupsInView.Add(grp);
} }
} }
#endregion #endregion
} }
// hack.. dont use // hack.. dont use
@ -4368,7 +4383,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
private bool CheckGroupsInViewBusy = false; private bool CheckGroupsInViewBusy = false;
private bool CheckGroupsInViewOverRun = false;
public void CheckGroupsInView() public void CheckGroupsInView()
{ {
@ -4377,112 +4391,90 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return; return;
if(CheckGroupsInViewBusy) 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; return;
} }
CheckGroupsInViewBusy = true;
do 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)
{ {
CheckGroupsInViewOverRun = false; if(!IsActive)
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;
return; return;
}
HashSet<SceneObjectGroup> NewGroupsInView = new HashSet<SceneObjectGroup>(); if (e != null && e is SceneObjectGroup)
HashSet<SceneObjectGroup> GroupsNeedFullUpdate = new HashSet<SceneObjectGroup>();
List<uint> kills = new List<uint>();
int killedParst = 0;
EntityBase[] entities = m_scene.Entities.GetEntities();
foreach (EntityBase e in entities)
{ {
if(!IsActive) SceneObjectGroup grp = (SceneObjectGroup)e;
return; if(grp.IsDeleted || grp.IsAttachment)
continue;
if (e != null && e is SceneObjectGroup) float bradius = grp.GetBoundsRadius();
{ Vector3 grppos = grp.AbsolutePosition + grp.getBoundsCenter();
SceneObjectGroup grp = (SceneObjectGroup)e;
if(grp.IsDeleted || grp.IsAttachment)
continue;
float bradius = grp.GetBoundsRadius();
Vector3 grppos = grp.AbsolutePosition + grp.getBoundsCenter();
// float dcam = (grppos - mycamera).LengthSquared(); // float dcam = (grppos - mycamera).LengthSquared();
float dpos = (grppos - mypos).LengthSquared(); float dpos = (grppos - mypos).LengthSquared();
// if(dcam < dpos) // if(dcam < dpos)
// dpos = dcam; // dpos = dcam;
dpos = (float)Math.Sqrt(dpos) - bradius; dpos = (float)Math.Sqrt(dpos) - bradius;
bool inview; bool inview;
lock(GroupsInView) lock(GroupsInView)
inview = GroupsInView.Contains(grp); inview = GroupsInView.Contains(grp);
if(dpos > cullingrange) if(dpos > cullingrange)
{ {
if(inview) if(inview)
{ kills.Add(grp);
kills.Add(grp.LocalId); }
killedParst += grp.PrimCount; else
{
if (killedParst > 199 ) if(!inview)
{ GroupsNeedFullUpdate.Add(grp);
SendKillObject(kills); NewGroupsInView.Add(grp);
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);
}
} }
} }
}
lock(GroupsInView) lock(GroupsInView)
GroupsInView = NewGroupsInView; GroupsInView = NewGroupsInView;
if (kills.Count > 0) if (kills.Count > 0)
{
foreach(SceneObjectGroup grp in kills)
{ {
SendKillObject(kills); foreach(SceneObjectPart p in grp.Parts)
kills.Clear(); SendEntityUpdate(p,PrimUpdateFlags.Kill);
} }
kills.Clear();
}
if(GroupsNeedFullUpdate.Count > 0) if(GroupsNeedFullUpdate.Count > 0)
{
foreach(SceneObjectGroup grp in GroupsNeedFullUpdate)
{ {
foreach(SceneObjectGroup grp in GroupsNeedFullUpdate) foreach(SceneObjectPart p in grp.Parts)
grp.ScheduleGroupForFullUpdate(); SendEntityUpdate(p,PrimUpdateFlags.CancelKill);
} }
} while(CheckGroupsInViewOverRun); }
CheckGroupsInViewBusy = false; CheckGroupsInViewBusy = false;
} }
@ -4670,13 +4662,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
OutPacket(pack, ThrottleOutPacketType.Task); OutPacket(pack, ThrottleOutPacketType.Task);
} }
private class ObjectPropertyUpdate : IEntityUpdate private class ObjectPropertyUpdate : EntityUpdate
{ {
internal bool SendFamilyProps; internal bool SendFamilyProps;
internal bool SendObjectProps; internal bool SendObjectProps;
public ObjectPropertyUpdate(ISceneEntity entity, uint flags, bool sendfam, bool sendobj) public ObjectPropertyUpdate(ISceneEntity entity, uint flags, bool sendfam, bool sendobj)
: base(entity,flags) : base(entity,(PrimUpdateFlags)flags)
{ {
SendFamilyProps = sendfam; SendFamilyProps = sendfam;
SendObjectProps = sendobj; SendObjectProps = sendobj;
@ -4745,7 +4737,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> propertyUpdates = OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> propertyUpdates =
new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>(); new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>();
IEntityUpdate iupdate; EntityUpdate iupdate;
Int32 timeinqueue; // this is just debugging code & can be dropped later Int32 timeinqueue; // this is just debugging code & can be dropped later
int updatesThisCall = 0; 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); // 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(); ObjectPropertiesFamilyPacket.ObjectDataBlock block = new ObjectPropertiesFamilyPacket.ObjectDataBlock();
block.RequestFlags = requestFlags; block.RequestFlags = (uint)requestFlags;
block.ObjectID = sop.UUID; block.ObjectID = sop.UUID;
if (sop.OwnerID == sop.GroupID) if (sop.OwnerID == sop.GroupID)
block.OwnerID = UUID.Zero; block.OwnerID = UUID.Zero;