mirror of
https://github.com/opensim/opensim.git
synced 2026-08-11 03:45:35 +08:00
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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user