add a SimpleAngularDistance Updates prioritazition scheme. Results don't look that great so don't use it still.

LSLKeyTest
UbitUmarov 2016-08-09 21:46:19 +01:00
parent 6c00016447
commit 6f5f6431a4
3 changed files with 97 additions and 11 deletions

View File

@ -108,6 +108,9 @@ namespace OpenSim.Region.Framework.Scenes
priority = GetPriorityByFrontBack(client, entity); priority = GetPriorityByFrontBack(client, entity);
break; break;
*/ */
case UpdatePrioritizationSchemes.SimpleAngularDistance:
priority = GetPriorityByAngularDistance(client, entity); // TODO: Reimplement SimpleAngularDistance
break;
case UpdatePrioritizationSchemes.BestAvatarResponsiveness: case UpdatePrioritizationSchemes.BestAvatarResponsiveness:
default: default:
priority = GetPriorityByBestAvatarResponsiveness(client, entity); priority = GetPriorityByBestAvatarResponsiveness(client, entity);
@ -241,7 +244,7 @@ namespace OpenSim.Region.Framework.Scenes
*/ */
if (distance > 10f) if (distance > 10f)
{ {
float tmp = (float)Math.Log((double)distance) * 1.4426950408889634073599246810019f - 3.3219280948873623478703194294894f; float tmp = (float)Math.Log((double)distance) * 1.442695f - 3.321928f;
// for a map identical to original: // for a map identical to original:
// now // now
// 1st constant is 1/(log(2)) (natural log) so we get log2(distance) // 1st constant is 1/(log(2)) (natural log) so we get log2(distance)
@ -269,5 +272,67 @@ namespace OpenSim.Region.Framework.Scenes
return pqueue; return pqueue;
} }
private uint GetPriorityByAngularDistance(IClientAPI client, ISceneEntity entity)
{
uint pqueue = 2; // keep compiler happy
ScenePresence presence = m_scene.GetScenePresence(client.AgentId);
if (presence == null)
return PriorityQueue.NumberOfQueues - 1;
// All avatars other than our own go into pqueue 1
if (entity is ScenePresence)
return 1;
if (entity is SceneObjectPart)
{
// Attachments are high priority,
if (((SceneObjectPart)entity).ParentGroup.IsAttachment)
return 2;
pqueue = ComputeAngleDistancePriority(presence, entity);
// Non physical prims are lower priority than physical prims
PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor;
if (physActor == null || !physActor.IsPhysical)
pqueue++;
}
return pqueue;
}
private uint ComputeAngleDistancePriority(ScenePresence presence, ISceneEntity entity)
{
double distance;
Vector3 presencePos = presence.AbsolutePosition;
SceneObjectGroup group = (entity as SceneObjectPart).ParentGroup;
float bradius = group.GetBoundsRadius();
Vector3 grppos = group.AbsolutePosition + group.getBoundsCenter();
distance = Vector3.Distance(presencePos, grppos);
distance -= bradius;
distance *= group.getAreaFactor();
// And convert the distance to a priority queue, this computation gives queues
// at 10, 20, 40, 80, 160, 320, 640, and 1280m
uint pqueue = PriorityQueue.NumberOfImmediateQueues + 1; // reserve attachments queue
uint queues = PriorityQueue.NumberOfQueues - PriorityQueue.NumberOfImmediateQueues;
if (distance > 10f)
{
float tmp = (float)Math.Log(distance) * 1.442695f - 3.321928f;
// for a map identical to original:
// now
// 1st constant is 1/(log(2)) (natural log) so we get log2(distance)
// 2st constant makes it be log2(distance/10)
pqueue += (uint)tmp;
if (pqueue > queues - 1)
pqueue = queues - 1;
}
return pqueue;
}
} }
} }

View File

@ -1586,12 +1586,22 @@ namespace OpenSim.Region.Framework.Scenes
return m_boundsCenter; return m_boundsCenter;
} }
private float m_areaFactor;
public float getAreaFactor()
{
// math is done in GetBoundsRadius();
if(m_boundsRadius == null)
GetBoundsRadius();
return m_areaFactor;
}
public float GetBoundsRadius() public float GetBoundsRadius()
{ {
// this may need more threading work // this may need more threading work
if(m_boundsRadius == null) if(m_boundsRadius == null)
{ {
float res = 0; float res = 0;
float areaF = 0;
SceneObjectPart p; SceneObjectPart p;
SceneObjectPart[] parts; SceneObjectPart[] parts;
float partR; float partR;
@ -1613,12 +1623,19 @@ namespace OpenSim.Region.Framework.Scenes
} }
if(partR > res) if(partR > res)
res = partR; res = partR;
if(p.maxSimpleArea() > areaF)
areaF = p.maxSimpleArea();
} }
if(parts.Length > 1) if(parts.Length > 1)
{ {
offset /= parts.Length; // basicly geometric center offset /= parts.Length; // basicly geometric center
offset = offset * RootPart.RotationOffset; offset = offset * RootPart.RotationOffset;
} }
areaF = 10.0f / areaF; // scale it
areaF = Util.Clamp(areaF, 0.001f, 1000f); // clamp it
m_areaFactor = (float)Math.Sqrt(areaF);
m_boundsCenter = offset; m_boundsCenter = offset;
m_boundsRadius = res; m_boundsRadius = res;
return res; return res;

View File

@ -1191,24 +1191,28 @@ namespace OpenSim.Region.Framework.Scenes
public float maxSimpleArea() public float maxSimpleArea()
{ {
float a,b; float a,b;
if(m_shape.Scale.X > m_shape.Scale.Y) float sx = m_shape.Scale.X;
float sy = m_shape.Scale.Y;
float sz = m_shape.Scale.Z;
if( sx > sy)
{ {
a = m_shape.Scale.X; a = sx;
if(m_shape.Scale.Y > m_shape.Scale.Z) if(sy > sz)
b = m_shape.Scale.Y; b = sy;
else else
b = m_shape.Scale.Z; b = sz;
} }
else else
{ {
a = m_shape.Scale.Y; a = sy;
if(m_shape.Scale.X > m_shape.Scale.Z) if(sx > sz)
b = m_shape.Scale.X; b = sx;
else else
b = m_shape.Scale.Z; b = sz;
} }
return a*b; return a * b;
} }
public UpdateRequired UpdateFlag { get; set; } public UpdateRequired UpdateFlag { get; set; }