add test option ObjectsCullingByDistance. In future, if true, it may

prevent sending objects outside view range to viewers. DO NOT SET TRUE
 unless testing it. Code still not completei!!!
This commit is contained in:
UbitUmarov
2016-07-06 16:10:44 +01:00
parent 259824fbc4
commit c02fe98b7d
7 changed files with 189 additions and 61 deletions

View File

@@ -340,6 +340,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private Prioritizer m_prioritizer;
private bool m_disableFacelights = false;
// needs optimazation
private HashSet<SceneObjectGroup> GroupsInView = new HashSet<SceneObjectGroup>();
private bool m_VelocityInterpolate = false;
private const uint MaxTransferBytesPerPacket = 600;
@@ -3978,7 +3981,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// float avgTimeDilation = 0.0f;
IEntityUpdate iupdate;
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>();
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
doCulling = false;
while (updatesThisCall < maxUpdates)
{
lock (m_entityUpdates.SyncRoot)
@@ -4059,6 +4077,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
}
if(doCulling && !part.ParentGroup.IsAttachment)
{
lock(GroupsInView)
{
if(!GroupsInView.Contains(part.ParentGroup))
{
Vector3 partpos = part.ParentGroup.AbsolutePosition;
float dcam = (partpos - mycamera).LengthSquared();
float dpos = (partpos - mypos).LengthSquared();
if(dcam < dpos)
dpos = dcam;
dpos = (float)Math.Sqrt(dpos) + part.ParentGroup.GetBoundsRadius();
if(dpos > cullingrange)
continue;
if(!GroupsNeedFullUpdate.Contains(part.ParentGroup))
GroupsNeedFullUpdate.Add(part.ParentGroup);
continue;
}
}
}
if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh))
{
// Ensure that mesh has at least 8 valid faces
@@ -4247,8 +4287,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
SendKillObject(m_killRecord);
m_killRecord.Clear();
}
#endregion
lock(GroupsNeedFullUpdate)
{
if(GroupsNeedFullUpdate.Count > 0)
{
foreach(SceneObjectGroup grp in GroupsNeedFullUpdate)
{
grp.ScheduleGroupForFullUpdate();
lock(GroupsInView)
GroupsInView.Add(grp);
}
GroupsNeedFullUpdate.Clear();
}
}
#endregion
}
@@ -4282,10 +4335,81 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void ReprioritizeUpdates()
{
CheckGroupsInView();
lock (m_entityUpdates.SyncRoot)
m_entityUpdates.Reprioritize(UpdatePriorityHandler);
}
public void CheckGroupsInView()
{
bool doCulling = m_scene.ObjectsCullingByDistance;
if(!doCulling)
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>();
HashSet<SceneObjectGroup> GroupsNeedFullUpdate = new HashSet<SceneObjectGroup>();
lock(GroupsInView)
{
EntityBase[] entities = m_scene.Entities.GetEntities();
foreach (EntityBase e in entities)
{
if (e != null && e is SceneObjectGroup && !((SceneObjectGroup)e).IsAttachment)
{
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();
if(dpos > cullingrange)
{
if(GroupsInView.Contains(grp))
{
GroupsInView.Remove(grp);
if (!m_killRecord.Contains(grp.LocalId))
m_killRecord.Add(grp.LocalId);
}
}
else
{
if(!GroupsInView.Contains(grp) && !GroupsNeedFullUpdate.Contains(grp))
GroupsNeedFullUpdate.Add(grp);
NewGroupsInView.Add(grp);
}
}
}
}
GroupsInView = NewGroupsInView;
if (m_killRecord.Count > 0)
{
SendKillObject(m_killRecord);
m_killRecord.Clear();
}
if(GroupsNeedFullUpdate.Count > 0)
{
foreach(SceneObjectGroup grp in GroupsNeedFullUpdate)
grp.ScheduleGroupForFullUpdate();
}
GroupsNeedFullUpdate.Clear();
}
private bool UpdatePriorityHandler(ref uint priority, ISceneEntity entity)
{
if (entity != null)