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!!!LSLKeyTest
parent
259824fbc4
commit
c02fe98b7d
|
@ -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)
|
||||
|
|
|
@ -803,9 +803,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get; set; }
|
||||
public bool IsReprioritizationEnabled { get; set; }
|
||||
public float ReprioritizationInterval { get; set; }
|
||||
public float RootReprioritizationDistance { get; set; }
|
||||
public float ChildReprioritizationDistance { get; set; }
|
||||
public float ReprioritizationDistance { get; set; }
|
||||
private float m_minReprioritizationDistance = 32f;
|
||||
public bool ObjectsCullingByDistance = false;
|
||||
|
||||
public AgentCircuitManager AuthenticateHandler
|
||||
{
|
||||
|
@ -1185,15 +1185,15 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
= interestConfig.GetBoolean("ReprioritizationEnabled", IsReprioritizationEnabled);
|
||||
ReprioritizationInterval
|
||||
= interestConfig.GetFloat("ReprioritizationInterval", ReprioritizationInterval);
|
||||
RootReprioritizationDistance
|
||||
= interestConfig.GetFloat("RootReprioritizationDistance", RootReprioritizationDistance);
|
||||
ChildReprioritizationDistance
|
||||
= interestConfig.GetFloat("ChildReprioritizationDistance", ChildReprioritizationDistance);
|
||||
ReprioritizationDistance
|
||||
= interestConfig.GetFloat("RootReprioritizationDistance", ReprioritizationDistance);
|
||||
|
||||
if(ReprioritizationDistance < m_minReprioritizationDistance)
|
||||
ReprioritizationDistance = m_minReprioritizationDistance;
|
||||
|
||||
ObjectsCullingByDistance
|
||||
= interestConfig.GetBoolean("ObjectsCullingByDistance", ObjectsCullingByDistance);
|
||||
|
||||
if(RootReprioritizationDistance < m_minReprioritizationDistance)
|
||||
RootReprioritizationDistance = m_minReprioritizationDistance;
|
||||
if(ChildReprioritizationDistance < m_minReprioritizationDistance)
|
||||
ChildReprioritizationDistance = m_minReprioritizationDistance;
|
||||
|
||||
RootTerseUpdatePeriod = interestConfig.GetInt("RootTerseUpdatePeriod", RootTerseUpdatePeriod);
|
||||
ChildTerseUpdatePeriod = interestConfig.GetInt("ChildTerseUpdatePeriod", ChildTerseUpdatePeriod);
|
||||
|
@ -1252,8 +1252,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
RootRotationUpdateTolerance = 0.1f;
|
||||
RootVelocityUpdateTolerance = 0.001f;
|
||||
RootPositionUpdateTolerance = 0.05f;
|
||||
RootReprioritizationDistance = m_minReprioritizationDistance;
|
||||
ChildReprioritizationDistance = m_minReprioritizationDistance;
|
||||
ReprioritizationDistance = m_minReprioritizationDistance;
|
||||
|
||||
m_eventManager = new EventManager();
|
||||
|
||||
|
|
|
@ -1567,6 +1567,39 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
#endregion
|
||||
|
||||
private float? m_boundsRadius = null;
|
||||
|
||||
public float GetBoundsRadius()
|
||||
{
|
||||
// this may need more threading work
|
||||
if(m_boundsRadius == null)
|
||||
{
|
||||
float res = 0;
|
||||
SceneObjectPart p;
|
||||
SceneObjectPart[] parts;
|
||||
float partR;
|
||||
lock (m_parts)
|
||||
{
|
||||
parts = m_parts.GetArray();
|
||||
}
|
||||
|
||||
int nparts = parts.Length;
|
||||
for (int i = 0; i < nparts; i++)
|
||||
{
|
||||
p = parts[i];
|
||||
partR = p.Scale.Length();
|
||||
if(p != RootPart)
|
||||
partR += p.OffsetPosition.Length();
|
||||
if(partR > res)
|
||||
res = partR;
|
||||
}
|
||||
m_boundsRadius = res;
|
||||
return res;
|
||||
}
|
||||
|
||||
return m_boundsRadius.Value;
|
||||
}
|
||||
|
||||
public void GetResourcesCosts(SceneObjectPart apart,
|
||||
out float linksetResCost, out float linksetPhysCost, out float partCost, out float partPhysCost)
|
||||
{
|
||||
|
@ -4596,14 +4629,11 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
if (nparts <= 1)
|
||||
return gc;
|
||||
|
||||
Quaternion parentRot = RootPart.RotationOffset;
|
||||
Vector3 pPos;
|
||||
|
||||
// average all parts positions
|
||||
for (int i = 0; i < nparts; i++)
|
||||
{
|
||||
// do it directly
|
||||
// gc += parts[i].GetWorldPosition();
|
||||
if (parts[i] != RootPart)
|
||||
{
|
||||
pPos = parts[i].OffsetPosition;
|
||||
|
@ -4613,8 +4643,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
gc /= nparts;
|
||||
|
||||
// relative to root:
|
||||
// gc -= AbsolutePosition;
|
||||
return gc;
|
||||
}
|
||||
|
||||
|
@ -4661,30 +4689,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
return Ptot;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the object is a sculpt/mesh, retrieve the mesh data for each part and reinsert it into each shape so that
|
||||
/// the physics engine can use it.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// When the physics engine has finished with it, the sculpt data is discarded to save memory.
|
||||
/// </remarks>
|
||||
/*
|
||||
public void CheckSculptAndLoad()
|
||||
{
|
||||
if (IsDeleted)
|
||||
return;
|
||||
|
||||
if ((RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0)
|
||||
return;
|
||||
|
||||
// m_log.Debug("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
|
||||
|
||||
SceneObjectPart[] parts = m_parts.GetArray();
|
||||
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
parts[i].CheckSculptAndLoad();
|
||||
}
|
||||
*/
|
||||
/// <summary>
|
||||
/// Set the user group to which this scene object belongs.
|
||||
/// </summary>
|
||||
|
|
|
@ -350,6 +350,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
protected int m_reprioritizationLastTime;
|
||||
protected bool m_reprioritizationBusy;
|
||||
protected Vector3 m_reprioritizationLastPosition;
|
||||
protected float m_reprioritizationLastDrawDistance;
|
||||
|
||||
private Quaternion m_headrotation = Quaternion.Identity;
|
||||
|
||||
|
@ -1047,6 +1048,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
AbsolutePosition = posLastMove = posLastSignificantMove = CameraPosition =
|
||||
m_reprioritizationLastPosition = ControllingClient.StartPos;
|
||||
|
||||
m_reprioritizationLastDrawDistance = DrawDistance;
|
||||
|
||||
// disable updates workjobs for now
|
||||
childUpdatesBusy = true;
|
||||
m_reprioritizationBusy = true;
|
||||
|
@ -2130,6 +2133,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
// priority uses avatar position only
|
||||
m_reprioritizationLastPosition = AbsolutePosition;
|
||||
m_reprioritizationLastDrawDistance = DrawDistance;
|
||||
m_reprioritizationLastTime = Util.EnvironmentTickCount() + 15000; // delay it
|
||||
m_reprioritizationBusy = false;
|
||||
|
||||
|
@ -3986,24 +3990,24 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
if(m_reprioritizationBusy)
|
||||
return;
|
||||
|
||||
float limit = Scene.ReprioritizationDistance;
|
||||
bool byDrawdistance = Scene.ObjectsCullingByDistance;
|
||||
if(byDrawdistance)
|
||||
byDrawdistance = (Math.Abs(DrawDistance-m_reprioritizationLastDrawDistance) > 0.5f * limit);
|
||||
|
||||
int tdiff = Util.EnvironmentTickCountSubtract(m_reprioritizationLastTime);
|
||||
if(tdiff < Scene.ReprioritizationInterval)
|
||||
if(!byDrawdistance && tdiff < Scene.ReprioritizationInterval)
|
||||
return;
|
||||
// priority uses avatar position
|
||||
Vector3 pos = AbsolutePosition;
|
||||
Vector3 diff = pos - m_reprioritizationLastPosition;
|
||||
float limit;
|
||||
if(IsChildAgent)
|
||||
limit = (float)Scene.ChildReprioritizationDistance;
|
||||
else
|
||||
limit = (float)Scene.RootReprioritizationDistance;
|
||||
|
||||
limit *= limit;
|
||||
if (diff.LengthSquared() < limit)
|
||||
if (!byDrawdistance && diff.LengthSquared() < limit)
|
||||
return;
|
||||
|
||||
m_reprioritizationBusy = true;
|
||||
m_reprioritizationLastPosition = pos;
|
||||
m_reprioritizationLastDrawDistance = DrawDistance;
|
||||
|
||||
Util.FireAndForget(
|
||||
o =>
|
||||
|
|
|
@ -156,7 +156,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
|
|||
cdl.AddRow("active", m_scene.Active);
|
||||
cdl.AddRow("animations", m_scene.DebugAnimations);
|
||||
cdl.AddRow("appear-refresh", m_scene.SendPeriodicAppearanceUpdates);
|
||||
cdl.AddRow("child-repri", m_scene.ChildReprioritizationDistance);
|
||||
cdl.AddRow("client-pos-upd", m_scene.RootPositionUpdateTolerance);
|
||||
cdl.AddRow("client-rot-upd", m_scene.RootRotationUpdateTolerance);
|
||||
cdl.AddRow("client-vel-upd", m_scene.RootVelocityUpdateTolerance);
|
||||
|
@ -219,15 +218,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
|
|||
m_scene.SendPeriodicAppearanceUpdates = newValue;
|
||||
}
|
||||
|
||||
if (options.ContainsKey("child-repri"))
|
||||
{
|
||||
double newValue;
|
||||
|
||||
// FIXME: This can only come from the console at the moment but might not always be true.
|
||||
if (ConsoleUtil.TryParseConsoleDouble(MainConsole.Instance, options["child-repri"], out newValue))
|
||||
m_scene.ChildReprioritizationDistance = (float)newValue;
|
||||
}
|
||||
|
||||
if (options.ContainsKey("client-pos-upd"))
|
||||
{
|
||||
float newValue;
|
||||
|
|
|
@ -1122,6 +1122,9 @@
|
|||
;; SimpleAngularDistance, FrontBack
|
||||
; UpdatePrioritizationScheme = BestAvatarResponsiveness
|
||||
|
||||
; TEST OPTION KEEP AS FALSE
|
||||
; if true, don't send object updates if outside view range
|
||||
; ObjectsCullingByDistance = false
|
||||
|
||||
[MediaOnAPrim]
|
||||
;# {Enabled} {} {Enable Media-on-a-Prim (MOAP)} {true false} true
|
||||
|
|
|
@ -2016,6 +2016,10 @@
|
|||
ReprioritizationInterval = 2000.0
|
||||
RootReprioritizationDistance = 10.0
|
||||
ChildReprioritizationDistance = 20.0
|
||||
|
||||
; TEST OPTION KEEP AS FALSE
|
||||
; if true, don't send object updates if outside view range
|
||||
ObjectsCullingByDistance = false
|
||||
|
||||
; If n > 1, only every n UDP terse updates will be sent to observers of an avatar that are in the same region
|
||||
; Updates will always be sent to the avatar that the update addresses and if av velocity is effectively zero (to prevent drift due to missing updates).
|
||||
|
|
Loading…
Reference in New Issue