ugly culling

LSLKeyTest
UbitUmarov 2016-07-13 14:00:33 +01:00
parent 14296bc792
commit 7131703244
1 changed files with 122 additions and 71 deletions

View File

@ -1722,17 +1722,43 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_entityUpdates.Remove(localIDs); m_entityUpdates.Remove(localIDs);
KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
// TODO: don't create new blocks if recycling an old packet
kill.ObjectData = new KillObjectPacket.ObjectDataBlock[localIDs.Count]; int perpacket = localIDs.Count;
if(perpacket > 200)
perpacket = 200;
int nsent = 0;
kill.ObjectData = new KillObjectPacket.ObjectDataBlock[perpacket];
for (int i = 0 ; i < localIDs.Count ; i++ ) for (int i = 0 ; i < localIDs.Count ; i++ )
{ {
kill.ObjectData[i] = new KillObjectPacket.ObjectDataBlock(); kill.ObjectData[nsent] = new KillObjectPacket.ObjectDataBlock();
kill.ObjectData[i].ID = localIDs[i]; kill.ObjectData[nsent].ID = localIDs[i];
}
kill.Header.Reliable = true;
kill.Header.Zerocoded = true;
OutPacket(kill, ThrottleOutPacketType.Task); if(++nsent >= 200)
{
kill.Header.Reliable = true;
kill.Header.Zerocoded = true;
OutPacket(kill, ThrottleOutPacketType.Task);
perpacket = localIDs.Count - i - 1;
if(perpacket == 0)
break;
if(perpacket > 200)
perpacket = 200;
kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
kill.ObjectData = new KillObjectPacket.ObjectDataBlock[perpacket];
nsent = 0;
}
}
if(nsent != 0)
{
kill.Header.Reliable = true;
kill.Header.Zerocoded = true;
OutPacket(kill, ThrottleOutPacketType.Task);
}
} }
/// <summary> /// <summary>
@ -4292,17 +4318,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_killRecord.Clear(); m_killRecord.Clear();
} }
lock(GroupsNeedFullUpdate) if(GroupsNeedFullUpdate.Count > 0)
{ {
if(GroupsNeedFullUpdate.Count > 0) foreach(SceneObjectGroup grp in GroupsNeedFullUpdate)
{ {
foreach(SceneObjectGroup grp in GroupsNeedFullUpdate) grp.ScheduleGroupForFullUpdate();
{ lock(GroupsInView)
grp.ScheduleGroupForFullUpdate(); GroupsInView.Add(grp);
lock(GroupsInView)
GroupsInView.Add(grp);
}
GroupsNeedFullUpdate.Clear();
} }
} }
#endregion #endregion
@ -4339,81 +4361,110 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void ReprioritizeUpdates() public void ReprioritizeUpdates()
{ {
CheckGroupsInView();
lock (m_entityUpdates.SyncRoot) lock (m_entityUpdates.SyncRoot)
m_entityUpdates.Reprioritize(UpdatePriorityHandler); m_entityUpdates.Reprioritize(UpdatePriorityHandler);
CheckGroupsInView();
} }
private bool CheckGroupsInViewBusy = false;
private bool CheckGroupsInViewOverRun = false;
public void CheckGroupsInView() public void CheckGroupsInView()
{ {
bool doCulling = m_scene.ObjectsCullingByDistance; bool doCulling = m_scene.ObjectsCullingByDistance;
if(!doCulling) if(!doCulling)
return; return;
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
return;
HashSet<SceneObjectGroup> NewGroupsInView = new HashSet<SceneObjectGroup>(); if(CheckGroupsInViewBusy)
HashSet<SceneObjectGroup> GroupsNeedFullUpdate = new HashSet<SceneObjectGroup>();
List<uint> kills = new List<uint>();
// will this take for ever ?
EntityBase[] entities = m_scene.Entities.GetEntities();
foreach (EntityBase e in entities)
{ {
if (e != null && e is SceneObjectGroup && !((SceneObjectGroup)e).IsAttachment) CheckGroupsInViewOverRun = true;
return;
}
CheckGroupsInViewBusy = true;
do
{
CheckGroupsInViewOverRun = false;
float cullingrange = 64.0f;
Vector3 mycamera = Vector3.Zero;
Vector3 mypos = Vector3.Zero;
ScenePresence mysp = (ScenePresence)SceneAgent;
if(mysp != null && !mysp.IsDeleted)
{ {
SceneObjectGroup grp = (SceneObjectGroup)e; cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f;
Vector3 grppos = grp.AbsolutePosition; mycamera = mysp.CameraPosition;
float dcam = (grppos - mycamera).LengthSquared(); mypos = mysp.AbsolutePosition;
float dpos = (grppos - mypos).LengthSquared(); }
if(dcam < dpos) else
dpos = dcam; {
dpos = (float)Math.Sqrt(dpos) - grp.GetBoundsRadius(); CheckGroupsInViewBusy= false;
bool inview; return;
lock(GroupsInView) }
inview = GroupsInView.Contains(grp);
if(dpos > cullingrange) HashSet<SceneObjectGroup> NewGroupsInView = new HashSet<SceneObjectGroup>();
HashSet<SceneObjectGroup> GroupsNeedFullUpdate = new HashSet<SceneObjectGroup>();
List<uint> kills = new List<uint>();
EntityBase[] entities = m_scene.Entities.GetEntities();
foreach (EntityBase e in entities)
{
if(!IsActive)
return;
if (e != null && e is SceneObjectGroup && !((SceneObjectGroup)e).IsAttachment)
{ {
if(inview) SceneObjectGroup grp = (SceneObjectGroup)e;
Vector3 grppos = grp.AbsolutePosition;
float dcam = (grppos - mycamera).LengthSquared();
float dpos = (grppos - mypos).LengthSquared();
if(dcam < dpos)
dpos = dcam;
dpos = (float)Math.Sqrt(dpos) - grp.GetBoundsRadius();
bool inview;
lock(GroupsInView)
inview = GroupsInView.Contains(grp);
if(dpos > cullingrange)
{ {
// GroupsInView.Remove(grp); if(inview)
if (!kills.Contains(grp.LocalId)) {
kills.Add(grp.LocalId); kills.Add(grp.LocalId);
if (kills.Count > 100)
{
SendKillObject(kills);
kills.Clear();
Thread.Sleep(50);
}
}
}
else
{
if(!inview)
GroupsNeedFullUpdate.Add(grp);
NewGroupsInView.Add(grp);
} }
} }
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)
{ {
SendKillObject(kills); SendKillObject(kills);
kills.Clear(); kills.Clear();
} }
if(GroupsNeedFullUpdate.Count > 0) if(GroupsNeedFullUpdate.Count > 0)
{ {
foreach(SceneObjectGroup grp in GroupsNeedFullUpdate) foreach(SceneObjectGroup grp in GroupsNeedFullUpdate)
grp.ScheduleGroupForFullUpdate(); grp.ScheduleGroupForFullUpdate();
} }
GroupsNeedFullUpdate.Clear(); } while(CheckGroupsInViewOverRun);
CheckGroupsInViewBusy = false;
} }
private bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity) private bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity)